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