|
|
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 = 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.