1: /* $Header: util.c,v 4.3.1.2 85/05/15 14:44:27 lwall Exp $
   2:  *
   3:  * $Log:	util.c,v $
   4:  * Revision 4.3.1.2  85/05/15  14:44:27  lwall
   5:  * Last arg of execl changed from 0 to Nullch [(char*)0].
   6:  *
   7:  * Revision 4.3.1.1  85/05/10  11:41:30  lwall
   8:  * Branch for patches.
   9:  *
  10:  * Revision 4.3  85/05/01  11:51:44  lwall
  11:  * Baseline for release with 4.3bsd.
  12:  *
  13:  */
  14: 
  15: #include "EXTERN.h"
  16: #include "common.h"
  17: #include "final.h"
  18: #include "ndir.h"
  19: #include "INTERN.h"
  20: #include "util.h"
  21: 
  22: void
  23: util_init()
  24: {
  25:     ;
  26: }
  27: 
  28: /* fork and exec a shell command */
  29: 
  30: int
  31: doshell(shl,s)
  32: char *s, *shl;
  33: {
  34:     int status, pid, w;
  35:     register int (*istat)(), (*qstat)();
  36:     int (*signal())();
  37:     char *shell;
  38: 
  39: #ifdef SIGTSTP
  40:     sigset(SIGTSTP,SIG_DFL);
  41:     sigset(SIGCONT,SIG_DFL);
  42: #endif
  43:     if (shl != Nullch)
  44:     shell = shl;
  45:     else if ((shell = getenv("SHELL")) == Nullch || !*shell)
  46:     shell = PREFSHELL;
  47:     if ((pid = vfork()) == 0) {
  48: #ifdef SERVER
  49:         int i;
  50: 
  51:     /* This is necessary to keep bourne shell from puking */
  52: 
  53:         for (i = 3; i < 10; ++i)
  54:                 (void) close(i);
  55: #endif SERVER
  56: 
  57:     if (*s)
  58:         execl(shell, shell, "-c", s, Nullch);
  59:     else
  60:         execl(shell, shell, Nullch, Nullch, Nullch);
  61:     _exit(127);
  62:     }
  63: #ifndef lint
  64:     istat = signal(SIGINT, SIG_IGN);
  65:     qstat = signal(SIGQUIT, SIG_IGN);
  66: #else
  67:     istat = Null(int (*)());
  68:     qstat = Null(int (*)());
  69: #endif lint
  70:     waiting = TRUE;
  71:     while ((w = wait(&status)) != pid && w != -1)
  72:     ;
  73:     if (w == -1)
  74:     status = -1;
  75:     waiting = FALSE;
  76:     signal(SIGINT, istat);
  77:     signal(SIGQUIT, qstat);
  78: #ifdef SIGTSTP
  79:     sigset(SIGTSTP,stop_catcher);
  80:     sigset(SIGCONT,cont_catcher);
  81: #endif
  82:     return status;
  83: }
  84: 
  85: static char nomem[] = "rn: out of memory!\n";
  86: 
  87: /* paranoid version of malloc */
  88: 
  89: char *
  90: safemalloc(size)
  91: MEM_SIZE size;
  92: {
  93:     char *ptr;
  94:     char *malloc();
  95: 
  96:     ptr = malloc(size?size:1);  /* malloc(0) is NASTY on our system */
  97:     if (ptr != Nullch)
  98:     return ptr;
  99:     else {
 100:     fputs(nomem,stdout) FLUSH;
 101:     sig_catcher(0);
 102:     }
 103:     /*NOTREACHED*/
 104: }
 105: 
 106: /* paranoid version of realloc */
 107: 
 108: char *
 109: saferealloc(where,size)
 110: char *where;
 111: MEM_SIZE size;
 112: {
 113:     char *ptr;
 114:     char *realloc();
 115: 
 116:     ptr = realloc(where,size?size:1);   /* realloc(0) is NASTY on our system */
 117:     if (ptr != Nullch)
 118:     return ptr;
 119:     else {
 120:     fputs(nomem,stdout) FLUSH;
 121:     sig_catcher(0);
 122:     }
 123:     /*NOTREACHED*/
 124: }
 125: 
 126: /* safe version of string copy */
 127: 
 128: char *
 129: safecpy(to,from,len)
 130: char *to;
 131: register char *from;
 132: register int len;
 133: {
 134:     register char *dest = to;
 135: 
 136:     if (from != Nullch)
 137:     for (len--; len && (*dest++ = *from++); len--) ;
 138:     *dest = '\0';
 139:     return to;
 140: }
 141: 
 142: /* safe version of string concatenate, with \n deletion and space padding */
 143: 
 144: char *
 145: safecat(to,from,len)
 146: char *to;
 147: register char *from;
 148: register int len;
 149: {
 150:     register char *dest = to;
 151: 
 152:     len--;              /* leave room for null */
 153:     if (*dest) {
 154:     while (len && *dest++) len--;
 155:     if (len) {
 156:         len--;
 157:         *(dest-1) = ' ';
 158:     }
 159:     }
 160:     if (from != Nullch)
 161:     while (len && (*dest++ = *from++)) len--;
 162:     if (len)
 163:     dest--;
 164:     if (*(dest-1) == '\n')
 165:     dest--;
 166:     *dest = '\0';
 167:     return to;
 168: }
 169: 
 170: /* copy a string up to some (non-backslashed) delimiter, if any */
 171: 
 172: char *
 173: cpytill(to,from,delim)
 174: register char *to, *from;
 175: register int delim;
 176: {
 177:     for (; *from; from++,to++) {
 178:     if (*from == '\\' && from[1] == delim)
 179:         from++;
 180:     else if (*from == delim)
 181:         break;
 182:     *to = *from;
 183:     }
 184:     *to = '\0';
 185:     return from;
 186: }
 187: 
 188: /* return ptr to little string in big string, NULL if not found */
 189: 
 190: char *
 191: instr(big, little)
 192: char *big, *little;
 193: 
 194: {
 195:     register char *t, *s, *x;
 196: 
 197:     for (t = big; *t; t++) {
 198:     for (x=t,s=little; *s; x++,s++) {
 199:         if (!*x)
 200:         return Nullch;
 201:         if (*s != *x)
 202:         break;
 203:     }
 204:     if (!*s)
 205:         return t;
 206:     }
 207:     return Nullch;
 208: }
 209: 
 210: /* effective access */
 211: 
 212: #ifdef SETUIDGID
 213: int
 214: eaccess(filename, mod)
 215: char *filename;
 216: int mod;
 217: {
 218:     int protection, euid;
 219: 
 220:     mod &= 7;               /* remove extraneous garbage */
 221:     if (stat(filename, &filestat) < 0)
 222:     return -1;
 223:     euid = geteuid();
 224:     if (euid == ROOTID)
 225:     return 0;
 226:     protection = 7 & (filestat.st_mode >>
 227:       (filestat.st_uid == euid ? 6 :
 228:         (filestat.st_gid == getegid() ? 3 : 0)
 229:       ));
 230:     if ((mod & protection) == mod)
 231:     return 0;
 232:     errno = EACCES;
 233:     return -1;
 234: }
 235: #endif
 236: 
 237: /*
 238:  * Get working directory
 239:  */
 240: 
 241: #ifdef GETWD
 242: #define dot "."
 243: #define dotdot  ".."
 244: 
 245: static  char    *name;
 246: 
 247: static  DIR *dirp;
 248: static  int off;
 249: static  struct  stat    d, dd;
 250: static  struct  direct  *dir;
 251: 
 252: char *
 253: getwd(np)
 254: char *np;
 255: {
 256:     long rdev, rino;
 257: 
 258:     *np++ = '/';
 259:     *np = 0;
 260:     name = np;
 261:     off = -1;
 262:     stat("/", &d);
 263:     rdev = d.st_dev;
 264:     rino = d.st_ino;
 265:     for (;;) {
 266:         stat(dot, &d);
 267:         if (d.st_ino==rino && d.st_dev==rdev)
 268:             goto done;
 269:         if ((dirp = opendir(dotdot)) == Null(DIR *))
 270:             prexit("getwd: cannot open ..\n");
 271:         stat(dotdot, &dd);
 272:         chdir(dotdot);
 273:         if(d.st_dev == dd.st_dev) {
 274:             if(d.st_ino == dd.st_ino)
 275:                 goto done;
 276:             do
 277:                 if ((dir = readdir(dirp)) == Null(struct direct *))
 278:                     prexit("getwd: read error in ..\n");
 279:             while (dir->d_ino != d.st_ino);
 280:         }
 281:         else do {
 282:                 if ((dir = readdir(dirp)) == Null(struct direct *))
 283:                     prexit("getwd: read error in ..\n");
 284:                 stat(dir->d_name, &dd);
 285:             } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
 286:         cat();
 287:         closedir(dirp);
 288:     }
 289: done:
 290:     name--;
 291:     if (chdir(name) < 0) {
 292:         printf("getwd: can't cd back to %s\n",name) FLUSH;
 293:         sig_catcher(0);
 294:     }
 295:     return (name);
 296: }
 297: 
 298: void
 299: cat()
 300: {
 301:     register i, j;
 302: 
 303:     i = -1;
 304:     while (dir->d_name[++i] != 0);
 305:     if ((off+i+2) > 1024-1)
 306:         return;
 307:     for(j=off+1; j>=0; --j)
 308:         name[j+i+1] = name[j];
 309:     if (off >= 0)
 310:         name[i] = '/';
 311:     off=i+off+1;
 312:     name[off] = 0;
 313:     for(--i; i>=0; --i)
 314:         name[i] = dir->d_name[i];
 315: }
 316: 
 317: void
 318: prexit(cp)
 319: char *cp;
 320: {
 321:     write(2, cp, strlen(cp));
 322:     sig_catcher(0);
 323: }
 324: #else
 325: char *
 326: getwd(np)           /* shorter but slower */
 327: char *np;
 328: {
 329:     FILE *popen();
 330:     FILE *pipefp = popen("/bin/pwd","r");
 331: 
 332:     if (pipefd == Nullfp) {
 333:     printf("Can't run /bin/pwd\n") FLUSH;
 334:     finalize(1);
 335:     }
 336:     fgets(np,512,pipefp);
 337:     np[strlen(np)-1] = '\0';    /* wipe out newline */
 338:     pclose(pipefp);
 339:     return np;
 340: }
 341: #endif
 342: 
 343: /* just like fgets but will make bigger buffer as necessary */
 344: 
 345: char *
 346: get_a_line(original_buffer,buffer_length,fp)
 347: char *original_buffer;
 348: register int buffer_length;
 349: FILE *fp;
 350: {
 351:     register int bufix = 0;
 352:     register int nextch;
 353:     register char *some_buffer_or_other = original_buffer;
 354: 
 355:     do {
 356:     if (bufix >= buffer_length) {
 357:         buffer_length *= 2;
 358:         if (some_buffer_or_other == original_buffer) {
 359:                     /* currently static? */
 360:         some_buffer_or_other = safemalloc((MEM_SIZE)buffer_length+1);
 361:         strncpy(some_buffer_or_other,original_buffer,buffer_length/2);
 362:                     /* so we must copy it */
 363:         }
 364:         else {          /* just grow in place, if possible */
 365:         some_buffer_or_other = saferealloc(some_buffer_or_other,
 366:             (MEM_SIZE)buffer_length+1);
 367:         }
 368:     }
 369:     if ((nextch = getc(fp)) == EOF)
 370:         return Nullch;
 371:     some_buffer_or_other[bufix++] = (char) nextch;
 372:     } while (nextch && nextch != '\n');
 373:     some_buffer_or_other[bufix] = '\0';
 374:     len_last_line_got = bufix;
 375:     return some_buffer_or_other;
 376: }
 377: 
 378: /* copy a string to a safe spot */
 379: 
 380: char *
 381: savestr(str)
 382: char *str;
 383: {
 384:     register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
 385: 
 386:     strcpy(newaddr,str);
 387:     return newaddr;
 388: }
 389: 
 390: int
 391: makedir(dirname,nametype)
 392: register char *dirname;
 393: int nametype;
 394: {
 395: #ifdef MAKEDIR
 396:     register char *end;
 397:     register char *s;
 398:     char tmpbuf[1024];
 399:     register char *tbptr = tmpbuf+5;
 400: 
 401:     for (end = dirname; *end; end++) ;  /* find the end */
 402:     if (nametype == MD_FILE) {      /* not to create last component? */
 403:     for (--end; end != dirname && *end != '/'; --end) ;
 404:     if (*end != '/')
 405:         return 0;           /* nothing to make */
 406:     *end = '\0';            /* isolate file name */
 407:     }
 408:     strcpy(tmpbuf,"mkdir");
 409: 
 410:     s = end;
 411:     for (;;) {
 412:     if (stat(dirname,&filestat) >= 0) {
 413:                     /* does this much exist? */
 414:         *s = '/';           /* mark this as existing */
 415:         break;
 416:     }
 417:     s = rindex(dirname,'/');    /* shorten name */
 418:     if (!s)             /* relative path! */
 419:         break;          /* hope they know what they are doing */
 420:     *s = '\0';          /* mark as not existing */
 421:     }
 422: 
 423:     for (s=dirname; s <= end; s++) {    /* this is grody but efficient */
 424:     if (!*s) {          /* something to make? */
 425:         sprintf(tbptr," %s",dirname);
 426:         tbptr += strlen(tbptr); /* make it, sort of */
 427:         *s = '/';           /* mark it made */
 428:     }
 429:     }
 430:     if (nametype == MD_DIR)     /* don't need final slash unless */
 431:     *end = '\0';            /*  a filename follows the dir name */
 432: 
 433:     return (tbptr==tmpbuf+5 ? 0 : doshell(sh,tmpbuf));
 434:                     /* exercise our faith */
 435: #else
 436:     sprintf(cmd_buf,"%s %s %d", filexp(DIRMAKER), dirname, nametype);
 437:     return doshell(sh,cmd_buf);
 438: #endif
 439: }
 440: 
 441: #ifdef SETENV
 442: static bool firstsetenv = TRUE;
 443: extern char **environ;
 444: 
 445: void
 446: setenv(nam,val)
 447: char *nam, *val;
 448: {
 449:     register int i=envix(nam);      /* where does it go? */
 450: 
 451:     if (!environ[i]) {          /* does not exist yet */
 452:     if (firstsetenv) {      /* need we copy environment? */
 453:         int j;
 454: #ifndef lint
 455:         char **tmpenv = (char**)    /* point our wand at memory */
 456:         safemalloc((MEM_SIZE) (i+2) * sizeof(char*));
 457: #else
 458:         char **tmpenv = Null(char **);
 459: #endif lint
 460: 
 461:         firstsetenv = FALSE;
 462:         for (j=0; j<i; j++)     /* copy environment */
 463:         tmpenv[j] = environ[j];
 464:         environ = tmpenv;       /* tell exec where it is now */
 465:     }
 466: #ifndef lint
 467:     else
 468:         environ = (char**) saferealloc((char*) environ,
 469:         (MEM_SIZE) (i+2) * sizeof(char*));
 470:                     /* just expand it a bit */
 471: #endif lint
 472:     environ[i+1] = Nullch;  /* make sure it's null terminated */
 473:     }
 474:     environ[i] = safemalloc((MEM_SIZE) strlen(nam) + strlen(val) + 2);
 475:                     /* this may or may not be in */
 476:                     /* the old environ structure */
 477:     sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
 478: }
 479: 
 480: int
 481: envix(nam)
 482: char *nam;
 483: {
 484:     register int i, len = strlen(nam);
 485: 
 486:     for (i = 0; environ[i]; i++) {
 487:     if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
 488:         break;          /* strnEQ must come first to avoid */
 489:     }                   /* potential SEGV's */
 490:     return i;
 491: }
 492: #endif
 493: 
 494: void
 495: notincl(feature)
 496: char *feature;
 497: {
 498:     printf("\nNo room for feature \"%s\" on this machine.\n",feature) FLUSH;
 499: }
 500: 
 501: char *
 502: getval(nam,def)
 503: char *nam,*def;
 504: {
 505:     char *val;
 506: 
 507:     if ((val = getenv(nam)) == Nullch || !*val)
 508:     val = def;
 509:     return val;
 510: }
 511: 
 512: /* grow a static string to at least a certain length */
 513: 
 514: void
 515: growstr(strptr,curlen,newlen)
 516: char **strptr;
 517: int *curlen;
 518: int newlen;
 519: {
 520:     if (newlen > *curlen) {     /* need more room? */
 521:     if (*curlen)
 522:         *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
 523:     else
 524:         *strptr = safemalloc((MEM_SIZE)newlen);
 525:     *curlen = newlen;
 526:     }
 527: }
 528: 
 529: void
 530: setdef(buffer,dflt)
 531: char *buffer,*dflt;
 532: {
 533: #ifdef STRICTCR
 534:     if (*buffer == ' ')
 535: #else
 536:     if (*buffer == ' ' || *buffer == '\n')
 537: #endif
 538:     {
 539:     if (*dflt == '^' && isupper(dflt[1]))
 540:         *buffer = Ctl(dflt[1]);
 541:     else
 542:         *buffer = *dflt;
 543:     }
 544: }

Defined functions

cat defined in line 298; used 2 times
eaccess defined in line 213; used 1 times
envix defined in line 480; used 2 times
get_a_line defined in line 345; used 2 times
getwd defined in line 325; used 5 times
growstr defined in line 514; used 5 times
makedir defined in line 390; used 7 times
prexit defined in line 317; used 4 times
safecat defined in line 144; used 4 times
setenv defined in line 445; used 5 times
util_init defined in line 22; used 2 times

Defined variables

d defined in line 249; used 11 times
dd defined in line 249; used 6 times
dir defined in line 250; used 6 times
dirp defined in line 247; used 4 times
name defined in line 245; used 10 times
nomem defined in line 85; used 2 times
off defined in line 248; used 7 times

Defined macros

dot defined in line 242; used 1 times
dotdot defined in line 243; used 3 times
Last modified: 1987-03-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4355
Valid CSS Valid XHTML 1.0 Strict