/* $OpenXM: OpenXM/src/kan96xx/Kan/shell.c,v 1.5 2003/12/04 05:27:19 takayama Exp $ */ #include #include #include #include #include #include #include #include "datatype.h" #include "stackm.h" #include "extern.h" #include "extern2.h" #include #include "plugin.h" #include "kclass.h" #include #include "ox_pathfinder.h" static struct object KoxShell_test1(struct object ob); static struct object oxsExecuteBlocked(struct object ob); static struct object oxsSetenv(struct object ob); static char *oxsIsURI(char *s); static char *oxsURIgetVarName(char *s); static char *oxsURIgetExtension(char *s); static char *oxsURIgetFileName(char *s); static char *oxsRemoveOpt(char *s); static char *oxsGetOpt(char *s); static char *oxsVarToFile(char *v,char *extension,char *comamnd,int tmp); static int oxsFileToVar(char *v,char *fname); static char **oxsBuildArgv(struct object ob); static char **oxsBuildArgvRedirect(char **argv); static struct object testmain(struct object ob); #define mymalloc(n) sGC_malloc(n) #define nomemory(n) errorKan1("%s\n","No more memory in shell.c"); #define MAXFILES 256 static char *AfterReadFile[MAXFILES]; static char *AfterSetVar[MAXFILES]; static int AfterPt=0; static char *AfterDeleteFile[MAXFILES]; static int AfterD=0; static int KeepTmpFiles = 1; extern int OX_P_stdin; extern int OX_P_stdout; extern int OX_P_stderr; struct object KoxShell(struct object ob) { return KoxShell_test1(ob); } /* A temporary help system */ void KoxShellHelp(char *key,FILE *fp) { char *keys[]={"command","export","which","redirect","@@@@gatekeeper"}; int i; #define HSIZE 20 char *s[HSIZE]; if (key == NULL) { fprintf(fp,"\n"); for (i=0; strcmp(keys[i],"@@@@gatekeeper") != 0; i++) { fprintf(fp,"%s\n",keys[i]); KoxShellHelp(keys[i],fp); fprintf(fp,"\n",keys[i]); } return; } for (i=0; i> or << which command-name path >>"); } return(rob); }else if (strcmp(cmd,"export")==0) { rob=oxsSetenv(ob); }else{ rob = oxsExecuteBlocked(ob); } return(rob); } /* Functions for ox_shell */ struct object KoxWhich(struct object cmdo,struct object patho) { struct object rob; char *sss; rob = NullObject; if (cmdo.tag != Sdollar) errorKan1("%s\n","KoxWhich(str-obj,str-obj)"); if (patho.tag == Sdollar) { sss=oxWhich(KopString(cmdo),KopString(patho)); if (sss != NULL) rob=KpoString(sss); else{ sss=getCommandPath(KopString(cmdo)); if (sss != NULL) rob=KpoString(sss); } }else{ sss=getCommandPath(KopString(cmdo)); if (sss != NULL) rob=KpoString(sss); } return(rob); } /* Example. [(export) (PATH) (=) (/usr/new/bin:$PATH)] */ static struct object oxsSetenv(struct object ob) { struct object rob; int i,n; char *envp; char *new; int r; rob = NullObject; if (ob.tag != Sarray) errorKan1("%s\n","oxsSetenv requires an array of srings."); n = getoaSize(ob); if ((n != 4) && (n != 3)) errorKan1("%s\n","oxsSetenv requires an array of srings. Length must be 3 or 4."); for (i=0; i stringIn s="stringInOut://abc.poly" ==> stringInOut */ char *oxsIsURI(char *s) { int n,i,j; char *u; if (s == NULL) return((char *)NULL); s = oxsRemoveOpt(s); n = strlen(s); for (i=0; i abc s="stringInOut://abc.poly" ==> abc s="stringInOut://abc" ==> abc */ char *oxsURIgetVarName(char *s) { int n,i,j; char *u; if (s == NULL) return((char *)NULL); s = oxsRemoveOpt(s); n = strlen(s); for (i=0; i poly s="stringInOut://abc.poly" ==> poly s="stringInOut://abc" ==> NULL */ char *oxsURIgetExtension(char *s) { int n,i,j,k; char *u; if (s == NULL) return((char *)NULL); s = oxsRemoveOpt(s); n = strlen(s); for (i=0; i limit - 10) { sold = s; limit *= 2; s = (char *)mymalloc(limit); if (s == NULL) errorKan1("%s\n","No more memory in oxsFileToVar()."); strcpy(s,sold); } i++; } fclose(fp); KputUserDictionary(v,KpoString(s)); return(0); } static char **oxsBuildArgv(struct object ob) { int n,i; char **argv; char *s; char *type; char *ext, *v; int usetmp=1; int win=0; struct object ocmd; /* bug: win variable must be properly set on windows native. */ if (ob.tag != Sarray) errorKan1("%s\n","oxsBuildArgv() requires an array as an argument."); n = getoaSize(ob); for (i=0; i= MAXFILES) { AfterPt=0; errorKan1("%s\n","oxsBuildArgv(), Too may files to open."); } }else if (strcmp(type,"stringOut") == 0) { argv[i] = generateTMPfileName2(v,ext,usetmp,win); AfterDeleteFile[AfterD++] = argv[i]; AfterReadFile[AfterPt] = argv[i]; AfterSetVar[AfterPt] = v; AfterPt++; if (AfterPt >= MAXFILES) { AfterPt=0; errorKan1("%s\n","oxsBuildArgv(), Too may files to open."); } }else { errorKan1("%s\n","This URI type has not yet been implemented."); } if (AfterD >= MAXFILES) { AfterD=0; errorKan1("%s\n","oxsBuildArgv(), Too may files to open."); } } } return(argv); } static struct object oxsExecuteBlocked(struct object ob) { int r,i,n; char **argv; argv = oxsBuildArgv(ob); argv = oxsBuildArgvRedirect(argv); r=oxForkExecBlocked(argv); /* bug: what happen when NoX? */ /* if (1) { for (i=0; argv[i] != NULL; i++) { fprintf(stderr,"argv[%d]=%s\n",i,argv[i]); } errorKan1("%s\n","ForkExecBlocked failed."); } */ if (AfterPt > 0) { for (i=0; i< AfterPt; i++) { oxsFileToVar(AfterSetVar[i],AfterReadFile[i]); } } AfterPt = 0; if (AfterD > 0) { for (i=0; i< AfterD; i++) { if (!KeepTmpFiles) { oxDeleteFile(AfterDeleteFile[i]); } } } AfterD = 0; return(KpoInteger(r)); } static char **oxsBuildArgvRedirect(char **argv) { char **newargv; int n,i,j; FILE *fp; char *fname; n = 0; while (argv[n] != NULL) n++; newargv = (char **) mymalloc(sizeof(char *)*(n+1)); for (i=0; i<=n; i++) newargv[i]=(char *)NULL; j=0; /* bug: Critical area, do not make an interruption. */ for (i=0; i")==0) { fname = argv[i+1]; fp == NULL; if (fname != NULL) { fp = fopen(fname,"w"); } if (fp == NULL) { oxResetRedirect(); errorKan1("%s\n","oxsBuildArgvRedirect, cannot open the output file.\n"); } fclose(fp); /* touch */ OX_P_stdout = open(fname,O_WRONLY); i++; }else if (strcmp(argv[i],"2>") == 0) { fname = argv[i+1]; fp == NULL; if (fname != NULL) { fp = fopen(fname,"w"); } if (fp == NULL) { oxResetRedirect(); errorKan1("%s\n","oxsBuildArgvRedirect, cannot open the output (stderr) file.\n"); } fclose(fp); /* touch */ OX_P_stderr = open(fname,O_WRONLY); i++; }else{ newargv[j++] = argv[i]; } } return( newargv ); }