#define DCT_VERSION "dct version 1.2c 10 Dec 2004" /* 10 Dec 2004. v 1.2c WJS */ /* Bug fix: incorrect strdupl call */ /* [Begin 1.2c] */ /* 25 Aug 2004. v 1.2b WJS */ /* serv had its own putenv. Recode dct to use the system one */ /* Not checking return value yet - that's a job for dct v 2.0 */ /* Put MAX_SERV_DCT_BUF (formerly MAX_BUF) in core.h so serv & */ /* dct can be coordinated */ /* Standardize version stuff */ /* [Begin 1.2b] */ /* 11 Feb 2004. v 1.2a WJS */ /* Declare putenv to avoid diagnostic. #include stdlib since man */ /* page says it "goes with" putenv - don't know why. */ /* Remove declaration for getenv since it's unused */ /* [Begin 1.2a] */ /* 17 Jan 2004. v 1.2 WJS */ /* Divider between obj defn and env vars was 1st blank in obj defn */ /* Arrange things not to count blanks between parens */ /* Put a void type on mergeparams (this mod made on synthesis' */ /* version 6 Nov 2000 by Chris Hammond) */ /* [Begin 1.2] */ #include "core.h" /* #define OBJECT_ROOT "/d3/glenn/jg/objects" #define METHOD_ROOT "/d3/glenn/jg/methods/" #define DEBUG */ int putenv(); char *strdupl(); /* from utils.c */ /************************************************************************/ char *dct_return_vers() /* Routine exists mostly to force .h file version string into this */ /* module, but we could call it if we want. Note string must not be */ /* global or we'll have conflicts if another routine similarly */ /* includes the version string */ { static char version[] = DCT_VERSION"/"COREH_VERSION; return version; } /* ==================== search sequence: ============= //machine path/tail - tail in path/.objects [local] /jgpath/tail - tail in OBJECT_ROOT/jgpath/.objects /jgpath/tail - tail in OBJECT_ROOT/jgpath/.remoteobjects path/exec - executeable program METHOD_ROOT/path/exec [local || dctcount<8 (not first pass)] path/datafile - use def method on local file [local] ===================================================== */ int scandct(s,t) char *s,*t; { FILE *fdic; char tdic[MAX_SERV_DCT_BUF],dctname[MAX_SERV_DCT_BUF],*sp; int nok,nb,l; /* Next comment based on the idea that putenv does NOT make a copy */ /* of its argument [from man putenv on talia.whoi.edu, a linux box */ /* "Thus, it is an error is to call putenv() with an auto- */ /* matic variable as the argument, then return from the call- */ /* ing function while string is still part of the environment."] */ /* Next is a volatile pointer that is set to dynamically allocated */ /* memory. Thus, the pointer will be lost upon function return, */ /* and the memory cannot be freed. This is OK, since idea is to */ /* have this memory survive exit from scandct so env vars will be */ /* "present" when/if calling program needs them. Cannot use a */ /* static buffer here in case scandct is called more than once */ char *list_of_env_vars; #ifdef DEBUG printf("Searching >%s< for >%s<\n",s,t); #endif sp=strrchr(t,'/'); if(sp){ *(sp++)=0; strcpy(dctname,t); strcat(dctname,"/"); strcat(dctname,s); } else { strcpy(dctname,s); sp=t; }; strcat(sp,"="); #ifdef DEBUG printf("Open >%s< and look for >%s<\n",dctname,sp); #endif fdic=fopen(dctname,"r"); if(fdic==NULL)return 0; nok=1; while (!feof(fdic) && nok) { fgets(tdic,MAX_SERV_DCT_BUF-1,fdic); if (strstr(tdic,sp)==tdic) nok=0; }; fclose(fdic); if (nok) return 0; strcpy(t,strchr(tdic,'=')+1); l=strlen(t); if (t[l-1] == '\n') t[--l] = '\0'; nb=0; for(sp=t; sptmp) if(*(k-1) == ')') *(k-1)=','; j=req-1; reqproj=0; nb=0; i=1; while(*(++j)){ *(k++)= *j; switch(*j){ case '(':nb++;break; case ')':nb--;break; case '<': case '>': case '=':i=0;break; case ',':if(nb==0 && i==1)reqproj=1; i=1; break; }; }; *k=0; if(reqproj || dctopt) { while(j=strstr(tmp,",,"))strcpy(j,j+1); strcpy(req,tmp); *dct=0; return; }; j=dct; nb=0; while(*(++j)){ switch(*j){ case '[':nb++;break; case ']':nb--;break; default:if(nb) *(k++) = *j;break; }; }; if(k>tmp) { if(*(k-1) == ',') *(k-1)=0; else *k=0; while(j=strstr(tmp,",,"))strcpy(j,j+1); strcpy(req,tmp); } else *req=0; *dct=0; return; } int dctsearch(obj,method,params,localflag) char *obj,*method,*params; int localflag; { char pathreq[MAX_SERV_DCT_BUF]; char metreq[MAX_SERV_DCT_BUF]; char parreq[MAX_SERV_DCT_BUF]; char tmp[MAX_SERV_DCT_BUF]; char *j; int dctcount; int dctnfound; COPY_INTO_FIXED_LEN_BUFFER(pathreq,obj,"dct: copying object string"); COPY_INTO_FIXED_LEN_BUFFER(parreq,params,"dct: copying parameter string"); *method=0; *params=0; dctcount=8; while(dctcount){ dctnfound=1; /* //machine ... */ #ifdef DEBUG printf("test // ... %s**%s\n",pathreq,parreq); #endif if(strstr(pathreq,"//")==pathreq){ strcpy(method,pathreq); strcpy(params,parreq); return 1; }; /* check for object dictionary */ if(localflag){ strcpy(tmp,pathreq); #ifdef DEBUG printf("test local obj... %s**%s\n",tmp,parreq); #endif if(scandct(".objects",tmp)){ j=strchr(tmp,'('); if(j)mergeparams(parreq,j); if(strstr(tmp,"//")==tmp){ strcpy(method,tmp); strcpy(params,parreq); return 1; }; strcpy(pathreq,tmp); dctnfound=0; }; }; /* check system .objects dictionary */ if(dctnfound && *pathreq == '/'){ strcpy(tmp,OBJECT_ROOT); if(*pathreq){ strcat(tmp,"/"); strcat(tmp,pathreq); }; #ifdef DEBUG printf("test sys local ... %s**%s\n",tmp,parreq); #endif if(scandct(".objects",tmp)){ j=strchr(tmp,'('); if(j)mergeparams(parreq,j); if(strstr(tmp,"//")==tmp){ strcpy(method,tmp); strcpy(params,parreq); return 1; }; strcpy(pathreq,tmp); dctnfound=0; }; }; /* check system .remoteobjects dictionary */ if(dctnfound && *pathreq == '/'){ strcpy(tmp,OBJECT_ROOT); if(*pathreq){ strcat(tmp,"/"); strcat(tmp,pathreq); }; #ifdef DEBUG printf("test sys global ... %s**%s\n",tmp,parreq); #endif if(scandct(".remoteobjects",tmp)){ j=strchr(tmp,'('); if(j)mergeparams(parreq,j); if(strstr(method,"//")==method){ strcpy(method,tmp); strcpy(params,parreq); return 1; }; strcpy(pathreq,tmp); dctnfound=0; }; }; /* check for system method */ if(dctnfound && (localflag || dctcount<8)){ strcpy(tmp,METHOD_ROOT); strcat(tmp,pathreq); #ifdef DEBUG printf("test sys meth ... %s**%s\n",tmp,parreq); #endif if(access(tmp,X_OK)==0){ strcpy(method,tmp); strcpy(params,parreq); return 1; }; }; /* local file - use default method */ if(dctnfound && localflag){ #ifdef DEBUG printf("test def file ... %s**\n",pathreq); #endif if(access(pathreq,R_OK)==0){ strcpy(tmp,"("); strcat(tmp,pathreq); strcat(tmp,")"); mergeparams(parreq,tmp); strcpy(pathreq,"def"); dctnfound=0; }; }; /* error */ if(dctnfound){ strcpy(method,"Cannot be found in dictionary:"); return 0; }; dctcount--; }; strcpy(method,"Too many iterations in dictionary - check for loops:"); return 0; } /* main(argc,argv) int argc; char *argv[]; { char met[1024],par[1024]; int i; if(dctsearch(argv[1],met,par,1)) printf("dctsearch = %s**%s\n",met,par); else printf("Not found\n"); } */