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

Defined functions

cat defined in line 289; used 2 times
eaccess defined in line 204; used 1 times
envix defined in line 471; used 2 times
get_a_line defined in line 336; used 2 times
getwd defined in line 316; used 5 times
growstr defined in line 505; used 5 times
makedir defined in line 381; used 7 times
prexit defined in line 308; used 4 times
safecat defined in line 135; used 4 times
setenv defined in line 436; used 5 times
util_init defined in line 22; used 2 times

Defined variables

d defined in line 240; used 11 times
dd defined in line 240; used 6 times
dir defined in line 241; used 6 times
dirp defined in line 238; used 4 times
name defined in line 236; used 10 times
nomem defined in line 76; used 2 times
off defined in line 239; used 7 times

Defined macros

dot defined in line 233; used 1 times
dotdot defined in line 234; used 3 times
Last modified: 1985-06-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2000
Valid CSS Valid XHTML 1.0 Strict