00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <signal.h>
00005 #include <unistd.h>
00006 #include <sys/wait.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <fcntl.h>
00010
00011 #define TRUE 1
00012 #define FALSE 0
00013 #define lowbyte(w) ((w) & 0377)
00014 #define highbyte(w) lowbyte((w) >>8)
00015
00016 typedef short BOOLEAN;
00017
00018 #define MAXVAR 50
00019
00020 static struct varslot {
00021 char *name;
00022 char *val;
00023 BOOLEAN exported;
00024 }sym[MAXVAR];
00025
00026 extern char **environ;
00027
00028 char *malloc(), *realloc();
00029
00030 static BOOLEAN assign(char **p, char *s)
00031 {
00032 int size;
00033
00034 size = strlen(s) +1;
00035 if (*p == NULL) {
00036 if(( *p = malloc(size)) == NULL)
00037 return(FALSE);
00038 }
00039 else if (( *p = realloc(*p, size)) == NULL)
00040 return(FALSE);
00041 strcpy (*p, s);
00042 return(TRUE);
00043 }
00044
00045
00046 BOOLEAN EVexport(char *name)
00047 {
00048 struct varslot *v;
00049 static struct varslot *find( );
00050
00051 if ( (v=find(name) ) == NULL)
00052 return(FALSE);
00053 if (v->name == NULL)
00054 if(!assign(&v->name, name) ||!assign(&v->val, ""))
00055 return(FALSE);
00056 v->exported = TRUE;
00057 return(TRUE);
00058 }
00059
00060
00061 static struct varslot *find(char *name)
00062 {
00063
00064 int i;
00065 struct varslot *v;
00066
00067 v = NULL;
00068 for(i=0;i<MAXVAR;i++)
00069 if( sym[i].name == NULL){
00070 if ( v == NULL) v = &sym[i];
00071 }
00072 else if (strcmp(sym[i].name, name) == 0){
00073 v = &sym[i];
00074 break;
00075 }
00076 return(v);
00077 }
00078
00079 BOOLEAN EVset(char *name, char *val)
00080 {
00081 struct varslot *v;
00082
00083 if (( v=find(name)) == NULL)
00084 return(FALSE);
00085 return(assign(&v ->name, name)&& assign(&v->val, val));
00086 }
00087
00088
00089 BOOLEAN EVinit()
00090 {
00091 int i ,namelen;
00092 char name[100];
00093
00094 for (i=0; environ[i] != NULL; i++){
00095 namelen = strcspn(environ[i] ,"=");
00096 strncpy(name,environ[i],namelen);
00097 name[namelen ]='\0';
00098 if (!EVset (name,&environ[i][namelen +1])|| !EVexport (name))
00099 return(FALSE);
00100 }
00101 return(TRUE);
00102 }
00103
00104
00105 char *EVget(char *name)
00106 {
00107 struct varslot *v;
00108
00109 if (( v=find(name) ) == NULL || v->name ==NULL)
00110 return(NULL);
00111 return( v->val);
00112 }
00113
00114 void fatal(char *msg)
00115 {
00116 fprintf(stderr, "ERROR:%s\n", msg);
00117 exit(1);
00118 }
00119
00120 void syserr (char *msg)
00121 {
00122 extern int errno, sys_nerr;
00123 extern char *sys_errlist[];
00124
00125 fprintf(stderr, "ERROR: %s (%d", msg,errno);
00126 if ( errno > 0 && errno < sys_nerr )
00127 fprintf(stderr, ";%s)\n",sys_errlist[errno]);
00128 else
00129 fprintf(stderr, ")\n");
00130 exit(1);
00131 }
00132
00133
00134 BOOLEAN EVupdate()
00135 {
00136 int i, envi, nvlen;
00137 struct varslot *v;
00138 static BOOLEAN updated = FALSE;
00139
00140 if ( !updated)
00141 if((environ = (char **)malloc((MAXVAR +1) *sizeof(char *)))
00142 == NULL)
00143 return(FALSE);
00144 envi =0;
00145 for(i=0; i<MAXVAR;i++){
00146 v = &sym[i];
00147 if (v->name ==NULL || !v->exported)
00148 continue;
00149 nvlen = strlen(v->name) + strlen(v->val) +2;
00150 if(!updated){
00151 if ((environ[envi] = malloc(nvlen)) ==NULL)
00152 return(FALSE);
00153 }
00154 else if( (environ[envi] = realloc(environ[envi],nvlen)) ==NULL)
00155 return(FALSE);
00156 sprintf(environ[envi], "%s=%s", v->name, v->val);
00157 envi++;
00158 }
00159 environ[envi] = NULL;
00160 updated = TRUE;
00161 return(TRUE);
00162 }
00163
00164
00165
00166 void EVprint()
00167 {
00168 int i;
00169
00170 for(i=0;i<MAXVAR;i++)
00171 if(sym[i].name !=NULL)
00172 printf("%3s %s=%s\n", sym[i].exported?"[E]":"",
00173 sym[i].name, sym[i].val);
00174 }
00175
00176 void asg(int argc,char *argv[])
00177 {
00178
00179 char *name, *val, *strtok();
00180
00181 if (argc != 1)
00182 printf("Extra args\n");
00183 else{
00184 name = strtok(argv[0], "=");
00185 val = strtok(NULL, "\1");
00186 if (!EVset(name, val))
00187 printf("Cannot assign\n");
00188 }
00189 }
00190
00191 void set (int argc,char *argv[] )
00192 {
00193 if( argc!=1)
00194 printf("Extra args\n");
00195 else
00196 EVprint();
00197 }
00198
00199
00200 void export(int argc,char *argv[])
00201 {
00202 int i;
00203
00204 if (argc ==1){
00205 set(argc, argv);
00206 return;
00207 }
00208 for(i=1; i<argc;i++)
00209 if(!EVexport (argv[i])) {
00210 printf("Cannot export %s\n", argv[i]);
00211 return;
00212 }
00213 }
00214
00215
00216 void statusprt (int pid,int status)
00217 {
00218 int code;
00219 static char *sigmsg[] = {
00220 "",
00221 "Hangup",
00222 "Interrupt",
00223 "Quit",
00224 "Illegal instruction",
00225 "Trace trap",
00226 "IOT instruction",
00227 "EMT instruction",
00228 "Floating point exception",
00229 "Kill",
00230 "Bus error",
00231 "Segmentation violation",
00232 "Bad arg to system call",
00233 "Write on pipe",
00234 "Alarm clock",
00235 "Terminate signal",
00236 "User signal 1",
00237 "User signal 2",
00238 "Death of child",
00239 "Power fail",
00240 };
00241
00242 if (status != 0 && pid != 0)
00243 printf("Process %d :", pid);
00244 if (lowbyte(status) == 0){
00245 if (( code = highbyte (status)) !=0)
00246 printf("Exit code %d\n", code);
00247 }
00248 else{
00249 if((code = status & 00177) <=MAXSIG)
00250 printf("%s", sigmsg[code]);
00251 else
00252 printf("Signal #%d", code);
00253 if (( status & 0200) == 0200)
00254 printf("-core dumped");
00255 printf("\n");
00256 }
00257 }
00258
00259
00260 static void (*entryint)(), (*entryquit)();
00261
00262 void ignoresig()
00263 {
00264 static BOOLEAN first = TRUE;
00265
00266 if(first) {
00267 first = FALSE;
00268 entryint = signal(SIGINT, SIG_IGN);
00269 entryquit = signal(SIGQUIT, SIG_IGN);
00270 if( entryint == SIG_ERR || entryquit == SIG_ERR )
00271 syserr("signal");
00272 }
00273
00274 else if (signal(SIGINT, SIG_IGN) == SIG_ERR ||
00275 signal(SIGQUIT, SIG_IGN) == SIG_ERR)
00276 syserr("signal");
00277 }
00278
00279 void entrysig()
00280 {
00281 if(signal (SIGINT, entryint) == SIG_ERR ||
00282 signal(SIGQUIT, entryquit) == SIG_ERR)
00283 syserr("signal");
00284 }
00285
00286 void catchsigs ()
00287 {
00288 void cleanup();
00289 static void setsig( );
00290
00291 setsig(SIGHUP, cleanup);
00292 setsig(SIGINT, cleanup);
00293 setsig(SIGQUIT,cleanup);
00294 setsig(SIGTERM,cleanup);
00295 }
00296
00297 static void setsig(sig, fcn)
00298 int sig;
00299 void (*fcn)();
00300 {
00301 if(signal(sig, SIG_IGN) == SIG_ERR) syserr("signal");
00302 else if(signal(sig,SIG_IGN)== SIG_IGN) return;
00303 else if(signal(sig,SIG_IGN)== SIG_DFL){
00304 if( signal(sig, fcn)==SIG_ERR)syserr("signal");
00305 }
00306 else
00307 fatal("signal already caught!");
00308
00309 }
00310
00311 void cleanup(int sig)
00312 {
00313
00314 if( signal(sig, SIG_IGN) == SIG_ERR)
00315 syserr("signal");
00316
00317 switch (sig) {
00318 case SIGHUP:
00319 fprintf(stderr, "Hangup.\n");
00320 break;
00321 case SIGINT:
00322 fprintf(stderr, "Interrupt.\n");
00323 break;
00324 case SIGQUIT:
00325 fprintf(stderr, "Quit.\n");
00326 }
00327 exit(1);
00328 }
00329
00330 typedef enum { T_WORD, T_BAR,T_AMP, T_SEMI, T_GT, T_GTGT, T_LT,
00331 T_NL, T_EOF } TOKEN;
00332 static TOKEN gettoken (char *word)
00333 {
00334 enum { NEUTRAL, GTGT ,INQUOTE, INWORD } state = NEUTRAL;
00335 int c;
00336 char *w;
00337
00338 w = word;
00339 while (( c=getchar ())!=EOF){
00340 switch (state) {
00341 case NEUTRAL:
00342 switch (c){
00343 case ';':
00344 return(T_SEMI);
00345 case '&':
00346 return(T_AMP);
00347 case '|':
00348 return(T_BAR);
00349 case '<':
00350 return(T_LT);
00351 case '\n':
00352 return(T_NL);
00353 case ' ':
00354 case '\t':
00355 continue;
00356 case '>':
00357 state=GTGT;
00358 continue;
00359 case '"':
00360 state=INQUOTE;
00361 continue;
00362 default:
00363 state=INWORD;
00364 *w++=c;
00365 continue;
00366 }
00367 case GTGT:
00368 if (c== '>')
00369 return(T_GTGT);
00370 ungetc(c, stdin);
00371 return(T_GT);
00372 case INQUOTE:
00373 switch (c){
00374 case '\\':
00375 *w++=getchar();
00376 continue;
00377 case '"':
00378 *w = '\0';
00379 return(T_WORD);
00380 default:
00381 *w++=c;
00382 continue;
00383 }
00384 case INWORD:
00385 switch (c){
00386 case '\\':
00387 case '&':
00388 case '|':
00389 case '<':
00390 case '>':
00391 case '\n':
00392 case ' ':
00393 case '\t':
00394 ungetc(c,stdin);
00395 *w='\0';
00396 return (T_WORD);
00397 default:
00398 *w++ =c;
00399 continue;
00400 }
00401 }
00402 }
00403 return (T_EOF);
00404 }