From 2403881fb303256d494c4f7238e7eece747d3ae7 Mon Sep 17 00:00:00 2001 From: pnenzi Date: Thu, 14 Aug 2003 20:17:21 +0000 Subject: [PATCH] Added files for an old (and unsupported) sensitivity analysis. --- src/unsupported/cktsenac.c | 47 ++++++ src/unsupported/cktsenup.c | 41 ++++++ src/unsupported/cktsncom.c | 178 +++++++++++++++++++++++ src/unsupported/cktsndct.c | 78 ++++++++++ src/unsupported/cktsnld.c | 69 +++++++++ src/unsupported/cktsnprt.c | 36 +++++ src/unsupported/cktsnset.c | 55 +++++++ src/unsupported/readme | 5 + src/unsupported/sen2dest.c | 67 +++++++++ src/unsupported/sen2setp.c | 98 +++++++++++++ src/unsupported/snaskq.c | 29 ++++ src/unsupported/snstart.c | 56 ++++++++ src/unsupported/spiced.c | 286 +++++++++++++++++++++++++++++++++++++ 13 files changed, 1045 insertions(+) create mode 100644 src/unsupported/cktsenac.c create mode 100644 src/unsupported/cktsenup.c create mode 100644 src/unsupported/cktsncom.c create mode 100644 src/unsupported/cktsndct.c create mode 100644 src/unsupported/cktsnld.c create mode 100644 src/unsupported/cktsnprt.c create mode 100644 src/unsupported/cktsnset.c create mode 100644 src/unsupported/readme create mode 100644 src/unsupported/sen2dest.c create mode 100644 src/unsupported/sen2setp.c create mode 100644 src/unsupported/snaskq.c create mode 100644 src/unsupported/snstart.c create mode 100644 src/unsupported/spiced.c diff --git a/src/unsupported/cktsenac.c b/src/unsupported/cktsenac.c new file mode 100644 index 000000000..3bb0429a9 --- /dev/null +++ b/src/unsupported/cktsenac.c @@ -0,0 +1,47 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +/* CKTsenAC(ckt) + * this is a routine for AC sensitivity calculations + */ + +int +CKTsenAC(ckt) +register CKTcircuit *ckt; +{ + int error; + +#ifdef SENSDEBUG + printf("CKTsenAC\n"); +#endif /* SENSDEBUG */ + + + if(error = CKTsenLoad(ckt)) return(error); + +#ifdef SENSDEBUG + printf("after CKTsenLoad\n"); +#endif /* SENSDEBUG */ + + if(error = CKTsenComp(ckt)) return(error); + +#ifdef SENSDEBUG + printf("after CKTsenComp\n"); +#endif /* SENSDEBUG */ + + return(OK); +} + diff --git a/src/unsupported/cktsenup.c b/src/unsupported/cktsenup.c new file mode 100644 index 000000000..2a72feaad --- /dev/null +++ b/src/unsupported/cktsenup.c @@ -0,0 +1,41 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* CKTsenUpdate(ckt) + * this is a driver program to iterate through all the various + * sensitivity update functions provided for the circuit elements + * in the given circuit + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +int +CKTsenUpdate(ckt) +register CKTcircuit *ckt; +{ + extern SPICEdev *DEVices[]; + register int i; + int error; + + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsenUpdate))(ckt->CKThead[i],ckt); + if(error) return(error); + } + } + return(OK); +} diff --git a/src/unsupported/cktsncom.c b/src/unsupported/cktsncom.c new file mode 100644 index 000000000..8e2209132 --- /dev/null +++ b/src/unsupported/cktsncom.c @@ -0,0 +1,178 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* CKTsenComp(ckt) + * this is a program to solve the sensitivity equation + * of the given circuit + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +int +CKTsenComp(ckt) +register CKTcircuit *ckt; +{ + register int size; + int row; + int col; + SENstruct *info; +#ifdef SENSDEBUG + char *rowe; + SMPelement *elt; +#endif /* SENSDEBUG */ + +#ifdef SENSDEBUG + printf("CKTsenComp\n"); +#endif /* SENSDEBUG */ + + size = SMPmatSize(ckt->CKTmatrix); + info = ckt->CKTsenInfo; + + if((info->SENmode == DCSEN)|| + (info->SENmode == TRANSEN)) + { + + /* loop throgh all the columns of RHS + matrix - each column corresponding to a design + parameter */ + + for (col=1;col<=info->SENparms;col++) { + for(row=1;row<=size;row++){ + *(ckt->CKTsenRhs + row ) = *(info->SEN_RHS[row] + col); + } + /* solve for the sensitivity values */ + SMPsolve(ckt->CKTmatrix,ckt->CKTsenRhs,ckt->CKTrhsSpare); + + /* store the sensitivity values */ + for(row=1;row<=size;row++){ + *(info->SEN_Sap[row] + col) = *(ckt->CKTsenRhs+row); + *(info->SEN_RHS[row] + col) = *(ckt->CKTsenRhs+row); + } + } +#ifdef SENSDEBUG + printf("\n"); + printf("Sensitivity matrix :\n"); + + for(row=1;row<=size;row++){ + rowe=CKTnodName(ckt,row) ; + if(strcmp("4",rowe)==0){ + for (col=1;col<=info->SENparms;col++) { + printf("\t"); + printf("Sap(%s,%d) = %.5e\t",rowe,col, + *(info->SEN_Sap[row] + col)); + } + printf("\n\n"); + } + } + + printf(" RHS matrix :\n"); + for(row=1;row<=size;row++){ + for (col=1;col<=info->SENparms;col++) { + printf(" "); + printf("RHS(%d,%d) = %.7e ",row,col, + *(info->SEN_RHS[row] + col)); + } + printf("\n"); + } + + printf(" Jacobian matrix :\n"); + for(row=1; row<=size; row++){ + for(col=1; col<=size; col++){ + if(elt = SMPfindElt(ckt->CKTmatrix, row , col , 0)){ + printf("%.7e ",elt->SMPvalue); + } + else{ + printf("0.0000000e+00 "); + } + } + printf("\n"); + } +#endif + + } + + if(info->SENmode == ACSEN){ + + /* loop throgh all the columns of RHS + matrix - each column corresponding to a design + parameter */ + + for (col=1;col<=info->SENparms;col++) { + + for(row=1;row<=size;row++){ + *(ckt->CKTsenRhs+row) = *(info->SEN_RHS[row] + col); + *(ckt->CKTseniRhs+row) = *(info->SEN_iRHS[row] + col); + } + + /* solve for the sensitivity values ( both real and imag parts)*/ + SMPcSolve(ckt->CKTmatrix,ckt->CKTsenRhs,ckt->CKTseniRhs, + ckt->CKTrhsSpare,ckt->CKTirhsSpare); + + /* store the sensitivity values ( both real and imag parts)*/ + for(row=1;row<=size;row++){ + *(info->SEN_RHS[row] + col) = *(ckt->CKTsenRhs+row); + *(info->SEN_iRHS[row] + col) = *(ckt->CKTseniRhs+row); + } + } +#ifdef SENSDEBUG + printf("\n"); + printf("CKTomega = %.7e rad/sec\t\n",ckt->CKTomega); + printf("Sensitivity matrix :\n"); + for(row=1;row<=size;row++){ + rowe=CKTnodName(ckt,row); + for (col=1;col<=info->SENparms;col++) { + printf("\t"); + printf("RHS(%s,%d) = %.5e",rowe,col, + *(info->SEN_RHS[row] + col)); + printf(" + j %.5e\t",*(info->SEN_iRHS[row] + col)); + printf("\n\n"); + + } + printf("\n"); + } + + + printf("CKTomega = %.7e rad/sec\t\n",ckt->CKTomega); + printf(" RHS matrix :\n"); + for(row=1;row<=size;row++){ + for (col=1;col<=info->SENparms;col++) { + printf(" "); + printf("RHS(%d,%d) = %.7e ",row,col, + *(info->SEN_RHS[row] + col)); + printf("+j %.7e ",*(info->SEN_iRHS[row] + col)); + } + printf("\n"); + } + + printf(" Jacobian matrix for AC :\n"); + for(row=1; row<=size; row++){ + for(col=1; col<=size; col++){ + if(elt = SMPfindElt(ckt->CKTmatrix, row , col , 0)){ + printf("%.7e ",elt->SMPvalue); + printf("+j%.7e\t",elt->SMPiValue); + } + else{ + printf("0.0000000e+00 "); + printf("+j0.0000000e+00\t"); + } + } + printf("\n\n"); + } +#endif + + } + return(OK); +} + diff --git a/src/unsupported/cktsndct.c b/src/unsupported/cktsndct.c new file mode 100644 index 000000000..d9edf811c --- /dev/null +++ b/src/unsupported/cktsndct.c @@ -0,0 +1,78 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* + * This routine performs the DC and Transient sensitivity + * calculations + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +int +CKTsenDCtran(ckt) +register CKTcircuit *ckt; +{ + int error; + +#ifdef SENSDEBUG + printf("time = %.7e\n",ckt->CKTtime); + printf("CKTsenDCtran\n"); +#endif /* SENSDEBUG */ + + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) && + (ckt->CKTmode & MODEINITTRAN)){ + + error = CKTsenLoad(ckt); + if(error) return(error); +#ifdef SENSDEBUG + printf("after inittran senload\n"); +#endif /* SENSDEBUG */ + error = CKTsenUpdate(ckt); + if(error) return(error); +#ifdef SENSDEBUG + printf("after inittran senupdate\n"); +#endif /* SENSDEBUG */ + } + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)&& + !(ckt->CKTmode&MODETRANOP)) + ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT; + + error = CKTsenLoad(ckt); + if(error) return(error); + +#ifdef SENSDEBUG + printf("after CKTsenLoad\n"); +#endif /* SENSDEBUG */ + + error = CKTsenComp(ckt); + if(error) return(error); + +#ifdef SENSDEBUG + printf("after CKTsenComp\n"); +#endif /* SENSDEBUG */ + + if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&TRANSEN) ){ + error = CKTsenUpdate(ckt); + if(error) return(error); + +#ifdef SENSDEBUG + printf("after CKTsenUpdate\n"); +#endif /* SENSDEBUG */ + + } + + + return(OK); +} diff --git a/src/unsupported/cktsnld.c b/src/unsupported/cktsnld.c new file mode 100644 index 000000000..a6f6f0b77 --- /dev/null +++ b/src/unsupported/cktsnld.c @@ -0,0 +1,69 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* + * CKTsenLoad(ckt) + * this is a driver program to iterate through all the various + * sensitivity load functions provided for the circuit elements + * in the given circuit + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +int +CKTsenLoad(ckt) +register CKTcircuit *ckt; +{ + extern SPICEdev *DEVices[]; + register int i; + int size,row,col; + int error; + + size = SMPmatSize(ckt->CKTmatrix); +#ifdef SENSDEBUG + printf("CKTsenLoad\n"); +#endif /* SENSDEBUG */ + + if((ckt->CKTsenInfo->SENmode == DCSEN)|| + (ckt->CKTsenInfo->SENmode == TRANSEN)) { + for (col=0;col<=ckt->CKTsenInfo->SENparms;col++) { + for(row=0;row<=size;row++){ + *(ckt->CKTsenInfo->SEN_RHS[row] + col)= 0; + } + } + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsenLoad))(ckt->CKThead[i],ckt); + if(error) return(error); + } + } + } else{ + for (col=0;col<=ckt->CKTsenInfo->SENparms;col++) { + for(row=0;row<=size;row++){ + *(ckt->CKTsenInfo->SEN_RHS[row] + col)= 0; + *(ckt->CKTsenInfo->SEN_iRHS[row] + col)= 0; + } + } + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsenAcLoad))(ckt->CKThead[i],ckt); + if(error) return(error); + } + } + } + return(OK); +} diff --git a/src/unsupported/cktsnprt.c b/src/unsupported/cktsnprt.c new file mode 100644 index 000000000..77fe432c8 --- /dev/null +++ b/src/unsupported/cktsnprt.c @@ -0,0 +1,36 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + + /* CKTsenPrint(ckt) + * this is a driver program to iterate through all the + * various sensitivity print functions provided for + * the circuit elements in the given circuit + */ + +void +CKTsenPrint(ckt) +register CKTcircuit *ckt; +{ + extern SPICEdev *DEVices[]; + register int i; + + for (i=0;iCKThead[i] != NULL) ){ + (*((*DEVices[i]).DEVsenPrint))(ckt->CKThead[i],ckt); + } + } +} diff --git a/src/unsupported/cktsnset.c b/src/unsupported/cktsnset.c new file mode 100644 index 000000000..9392e7956 --- /dev/null +++ b/src/unsupported/cktsnset.c @@ -0,0 +1,55 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + + +/* + * CKTsenSetup(ckt) + * this is a driver program to iterate through all the various + * sensitivity setup functions provided for the circuit elements + * in the given circuit + */ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "sperror.h" +#include "trandefs.h" +#include "suffix.h" + + +int +CKTsenSetup(ckt) +register CKTcircuit *ckt; + +{ + extern SPICEdev *DEVices[]; + + register int i; + int error; + register SENstruct *info; +#ifdef SENSDEBUG + printf("CKTsenSetup\n"); +#endif /* SENSDEBUG */ + info = ckt->CKTsenInfo; + info->SENparms = 0; + + for (i=0;iCKThead[i] != NULL) ){ + error = (*((*DEVices[i]).DEVsenSetup))(info,ckt->CKThead[i]); + if(error) return(error); + } + } +#ifdef SENSDEBUG + printf("CKTsenSetup end\n"); +#endif /* SENSDEBUG */ + return(OK); +} + + diff --git a/src/unsupported/readme b/src/unsupported/readme new file mode 100644 index 000000000..85678fdb8 --- /dev/null +++ b/src/unsupported/readme @@ -0,0 +1,5 @@ + +This directory contains code for an old, unsupported sensitivity analysis. +It is not used in the current distribution and will be removed in the +future. + diff --git a/src/unsupported/sen2dest.c b/src/unsupported/sen2dest.c new file mode 100644 index 000000000..29c58f886 --- /dev/null +++ b/src/unsupported/sen2dest.c @@ -0,0 +1,67 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + + /* SENdestroy(ckt) + * this is a driver program to iterate through all the various + * destroy functions provided for the circuit elements in the + * given circuit + */ + +#include "spice.h" +#include +#include "cktdefs.h" +#include "devdefs.h" +#include "util.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + +void +SENdestroy(info) + SENstruct *info; +{ + register int i; + int size; + + + size = info->SENsize; +#ifdef SENSDEBUG + printf("size = %d\n",size); + printf("freeing sensitivity structure in SENdestroy\n"); +#endif /* SENSDEBUG */ + /* + if(info->SENdevices) FREE(info->SENdevices); + if(info->SENparmNames) FREE(info->SENparmNames); + */ + if(info->SEN_Sap){ +#ifdef SENSDEBUG + printf("freeing SEN_Sap in SENdestroy\n"); +#endif /* SENSDEBUG */ + for(i=0;i<=size;i++){ + if(info->SEN_Sap[i]) FREE(info->SEN_Sap[i]); + } + FREE(info->SEN_Sap); + } + if(info->SEN_RHS){ + for(i=0;i<=size;i++){ + if(info->SEN_RHS[i]) FREE(info->SEN_RHS[i]); + } + FREE(info->SEN_RHS); + } + if(info->SEN_iRHS){ + for(i=0;i<=size;i++){ + if(info->SEN_iRHS[i]) FREE(info->SEN_iRHS[i]); + } + FREE(info->SEN_Sap); + } + /* + FREE(info); + */ +#ifdef SENSDEBUG + printf("SENdestroy end\n"); +#endif /* SENSDEBUG */ + + return; +} diff --git a/src/unsupported/sen2setp.c b/src/unsupported/sen2setp.c new file mode 100644 index 000000000..679d9325b --- /dev/null +++ b/src/unsupported/sen2setp.c @@ -0,0 +1,98 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "sen2defs.h" +#include "cktdefs.h" +#include "util.h" +#include "suffix.h" + +/* ARGSUSED */ +int +SENsetParm(ckt,anal,which,value) + CKTcircuit *ckt; + GENERIC *anal; + int which; + IFvalue *value; +{ + switch(which) { + + case SEN_DC: + if(value->iValue) { + ((SENstruct *)anal)->SENmode |= DCSEN; + } + break; + case SEN_AC: + if(value->iValue) { + ((SENstruct *)anal)->SENmode |= ACSEN; + } + break; + case SEN_TRAN: + if(value->iValue) { + ((SENstruct *)anal)->SENmode |= TRANSEN; + } + break; + case SEN_DEV: + ((SENstruct *)anal)->SENnumVal += 1; + if( ! ((SENstruct *)anal)->SENdevices ) { + ((SENstruct *)anal)->SENdevices = (char **) + MALLOC( ((SENstruct *)anal)->SENnumVal * sizeof(char *)); + if( ((SENstruct *)anal)->SENdevices == NULL) return(E_NOMEM); + ((SENstruct *)anal)->SENparmNames = (char **) + MALLOC( ((SENstruct *)anal)->SENnumVal * sizeof(char *)); + if( ((SENstruct *)anal)->SENparmNames == NULL) return(E_NOMEM); + } else { + ((SENstruct *)anal)->SENdevices = (char **) + REALLOC( ((SENstruct *)anal)->SENdevices , + ((SENstruct *)anal)->SENnumVal * sizeof(char *)); + if( ((SENstruct *)anal)->SENdevices == NULL) return(E_NOMEM); + ((SENstruct *)anal)->SENparmNames = (char **) REALLOC( + ((SENstruct *)anal)->SENparmNames, + ((SENstruct *)anal)->SENnumVal * sizeof(char *)) ; + if( ((SENstruct *)anal)->SENparmNames == NULL) return(E_NOMEM); + } + *(((SENstruct *)anal)->SENdevices+((SENstruct *)anal)->SENnumVal-1)= + value->sValue; + break; + case SEN_PARM: + *(((SENstruct *)anal)->SENparmNames+((SENstruct *)anal)->SENnumVal-1)= + value->sValue; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + + +static IFparm SENparms[] = { + { "dc", SEN_DC, IF_SET|IF_FLAG, "sensitivity in DC analysis" }, + { "op", SEN_DC, IF_SET|IF_FLAG, "sensitivity in DCop analysis" }, + { "ac", SEN_AC, IF_SET|IF_FLAG, "sensitivity in AC analysis" }, + { "tran", SEN_TRAN, IF_SET|IF_FLAG, "sensitivity in transient analysis"}, + { "dev", SEN_DEV, IF_SET|IF_INSTANCE, "instance with design param." }, + { "parm", SEN_PARM, IF_SET|IF_STRING, "name of design parameter" }, +}; + +SPICEanalysis SEN2info = { + { + "SENS2", + "Sensitivity analysis", + + sizeof(SENparms)/sizeof(IFparm), + SENparms + }, + sizeof(SENstruct), + NODOMAIN, + 0, + SENsetParm, + SENaskQuest, + NULL, + SENstartup +}; diff --git a/src/unsupported/snaskq.c b/src/unsupported/snaskq.c new file mode 100644 index 000000000..99c855084 --- /dev/null +++ b/src/unsupported/snaskq.c @@ -0,0 +1,29 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "iferrmsg.h" +#include "sen2defs.h" +#include "cktdefs.h" +#include "suffix.h" + +/* ARGSUSED */ +int +SENaskQuest(ckt,anal,which,value) + CKTcircuit *ckt; + GENERIC *anal; + int which; + IFvalue *value; +{ + switch(which) { + + default: + break; + } + return(E_BADPARM); +} + diff --git a/src/unsupported/snstart.c b/src/unsupported/snstart.c new file mode 100644 index 000000000..d2bc528c2 --- /dev/null +++ b/src/unsupported/snstart.c @@ -0,0 +1,56 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "util.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +/* This is a routine to initialize the sensitivity + * data structure + */ + +int +SENstartup(ckt) + CKTcircuit *ckt; +{ + int i; + int err; + IFvalue parmtemp; + int type; + GENinstance *fast; + +#ifdef SENSDEBUG + printf("SENstartup\n"); +#endif /* SENSDEBUG */ + ckt->CKTsenInfo->SENstatus = NORMAL; + ckt->CKTsenInfo->SENpertfac = 1e-4; + ckt->CKTsenInfo->SENinitflag = ON;/* allocate memory in + NIsenReinit */ + + parmtemp.iValue = 1; + for(i=0;iCKTsenInfo->SENnumVal;i++) { + type = -1; + fast = (GENinstance *)NULL; + err = CKTfndDev((GENERIC*)ckt,&type,(GENERIC**)&fast, + (*((ckt->CKTsenInfo->SENdevices)+i)), + (GENERIC *)NULL, (GENERIC *)NULL); + if(err != OK) return(err); + err = CKTpName( + (*((ckt->CKTsenInfo->SENparmNames)+i)), + &parmtemp,ckt ,type, + (*((ckt->CKTsenInfo->SENdevices)+i)), + &fast); + if(err != OK) return(err); + } +#ifdef SENSDEBUG + printf("SENstartup end\n"); +#endif /* SENSDEBUG */ + return(OK); +} diff --git a/src/unsupported/spiced.c b/src/unsupported/spiced.c new file mode 100644 index 000000000..8f391cb84 --- /dev/null +++ b/src/unsupported/spiced.c @@ -0,0 +1,286 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group +**********/ + +/* + * Do remote spice jobs. The first line transmitted will be of the + * format: "user host program". The program field may be left out, + * in which case it defaults to SPICE_PATH. The program is then + * executed, with the single argument "-S". The remote host should + * wait for a response from spiced before sending any data -- so + * far the only response sent is "ok". + * Eventually we will want to deal with load-balancing + * of spice jobs. + */ + +#include "spice.h" +#include +#include "strext.h" +#include +#include + +#ifdef HAS_BSDSOCKETS +#include +#include +#include + +#ifdef HAS_BSDRUSAGE +#include +#include +#else + +#ifdef HAS_SYSVRUSAGE +#include +#include +#endif +#endif + +#include +#include + +/* Better have #ifdef HAS_UNIX_SIGS XXX */ +#include +/* Better have #ifdef HAS_WAIT XXX */ +#include + +#include "suffix.h" + +#define MAXJOBS 2 + +int nrunning = 0; +int maxjobs = MAXJOBS; + +extern int errno; +extern char *sys_errlist[]; +extern char **environ; + +/* ARGSUSED */ +void +main(ac, av) + char **av; +{ + int s, inetd = 0; + struct servent *sp; + struct protoent *pp; + struct sockaddr_in from, sin; + int g, i, len = sizeof (struct sockaddr_in); + void dostuff(); + int sigchild(); + FILE *fp; + char *datestring(); + + /* Process arguments. */ + + ivars( ); + + av++; + while (*av) { + if (!strcmp(*av, "-i")) + inetd++; + else + maxjobs = atoi(av[1]); + av++; + } + + if (inetd == 0) { + /* Find out who we are. */ + sp = getservbyname("spice", "tcp"); + if (sp == NULL) { + fprintf(stderr, "Error: spice/tcp: unknown service\n"); + exit(1); + } + pp = getprotobyname("tcp"); + if (pp == NULL) { + fprintf(stderr, "Error: tcp: unknown protocol\n"); + exit(1); + } + + /* Create the socket. */ + s = socket(AF_INET, SOCK_STREAM, pp->p_proto); + if (s < 0) { + perror("spiced: socket"); + exit(1); + } + sin.sin_port = sp->s_port; + if (bind(s, (struct sockaddr *) &sin, sizeof + (struct sockaddr_in)) < 0) { + perror("spiced: bind"); + exit(1); + } + +#ifndef DEBUG + /* Disconnect from the controlling terminal. */ + if (fork()) + exit(0); + for (i = 0; i < 10; i++) + if (i != s) + (void) close(i); + (void) open("/", O_RDONLY); + (void) dup2(0, 1); + (void) dup2(0, 2); + i = open("/dev/tty", O_RDWR); + if (i > 0) { + (void) ioctl(i, TIOCNOTTY, (char *) NULL); + (void) close(i); + } + +#endif + +#ifdef SIGCHLD + (void) signal(SIGCHLD, sigchild); +#else +#ifdef SIGCLD + (void) signal(SIGCLD, sigchild); +#endif +#endif + fp = fopen(Spiced_Log, "a"); + fprintf(fp, "\n-- new daemon, pid = %d, date = %s\n\n", + getpid(), datestring()); + (void) fclose(fp); + + /* Start (void) listening for requests. */ + (void) listen(s, 5); + for (;;) { + g = accept(s, (struct sockaddr *) &from, &len); + if (g < 0) { + if (errno != EINTR) { + fp = fopen(Spiced_Log, "a"); + fprintf(fp, "\n>>> accept: %s\n\n", + sys_errlist[errno]); + exit(1); + } + continue; + } + if (!fork()) { + (void) close(s); +#ifdef SIGCHLD + (void) signal(SIGCHLD, SIG_IGN); +#else +#ifdef SIGCLD + (void) signal(SIGCLD, SIG_IGN); +#endif +#endif + dostuff(g); + } + nrunning++; + (void) close(g); + } + } else { + /* All this is already done for us. */ + dostuff(0); + } +} + +void +dostuff(s) +{ + FILE *fp; + char *datestring(); + char buf[BUFSIZ], user[16], host[32], program[128]; + char *argv[3], *t; + int i, rc; +#ifdef HAS_INTWAITSTATUS + int stats; +#else + union wait stats; +#endif +#ifdef HAS_BSDRUSAGE + struct rusage ru; +#endif + + /* Should do some sort of verification */ + i = read(s, buf, BUFSIZ); + if (i < 0) { + perror("spiced: read"); + exit(1); + } + i = sscanf(buf, "%s %s %s", user, host, program); + if (i < 2) { + fprintf(stderr, "Error: bad init line: %s\n", buf); + exit(1); + } + if (i == 2) + (void) strcpy(program, tilde_expand(Spice_Path)); + + if (nrunning > maxjobs - 1) { + /* Too many people. */ + (void) write(s, "toomany", 8); + fp = fopen(Spiced_Log, "a"); + fprintf(fp, "%s: %s@%s: turned down - %d jobs now\n", + datestring(), user, host, nrunning); + (void) fclose(fp); + exit(0); + } + (void) write(s, "ok", 3); + + if ((i = fork()) == 0) { + (void) dup2(s, 0); + (void) dup2(s, 1); + (void) dup2(s, 2); + argv[0] = program; + argv[1] = "-S"; + argv[2] = NULL; + (void) execve(program, argv, environ); + perror(program); + exit(1); + } +#ifdef HAS_BSDRUSAGE + /* Assume BSDRUSAGE -> wait3( ) XXX */ + if (wait3(&stats, 0, &ru) != i) { + perror("wait"); + exit(1); + } +#else +#ifdef HAS_WAIT + wait(&stats); + rc = 0; + rc = WEXITSTATUS(stats); +#endif +#endif + + /* Write a log entry. */ +#ifdef HAS_BSDRUSAGE + (void) sprintf(buf, "%d:%d.%6d", ru.ru_utime.tv_sec / 60, + ru.ru_utime.tv_sec % 60, ru.ru_utime.tv_usec); + for (t = buf; *t; t++) + ; + for (t--; *t == '0'; *t-- = '\0') + ; +#else + (void) strcpy(buf, "unknown"); +#endif + fp = fopen(Spiced_Log, "a"); + fprintf(fp, "%s: %s@%s: %s - \n\texit %d, time %s\n", + datestring(), user, host, program, rc, + buf); + (void) fclose(fp); + exit(0); +} + +/* Don't care what happens to the child */ + +int +sigchild() +{ + int pid; + FILE *fp; + + pid = wait((union wait *) NULL); + if (pid == -1) { + fp = fopen(Spiced_Log, "a"); + fprintf(fp, "\n>>>spiced: wait: %s\n\n", sys_errlist[errno]); + (void) fclose(fp); + } else + nrunning--; + return; +} + +#else /* not HAS_BSDSOCKETS */ +main( ) +{ + fprintf(stderr, + "The program \"spiced\" is not available on this system.\n"); + exit(1); +} +#endif /* HAS_BSDSOCKETS */