|
|
1.1 ! root 1: #include <sys/types.h> ! 2: #include <sys/stat.h> ! 3: #include <errno.h> ! 4: ! 5: extern int errno; ! 6: ! 7: #define U_MODE (xstat.st_mode >> 6) & 7) ! 8: #define G_MODE (xstat.st_mode >> 3) & 7) ! 9: #define O_MODE (xstat.st_mode & 7) ! 10: ! 11: static char * ! 12: dir(path) ! 13: char *path; ! 14: { ! 15: static char base[128]; ! 16: char *p; ! 17: char *strrchr(); ! 18: ! 19: strncpy(base, path, sizeof(base)-1); ! 20: base[sizeof(base)-1] = '\0'; ! 21: p = strrchr(base, '/'); ! 22: if (p==0) ! 23: return "."; ! 24: *p = '\0'; ! 25: return base; ! 26: } ! 27: ! 28: access2(name, mode, uid, gid) ! 29: char *name; ! 30: { ! 31: struct stat xstat; ! 32: ! 33: if (-1 == stat(name, &xstat)) { ! 34: if (!(mode&2) || -1==stat(dir(name), &xstat)) { ! 35: perror("stat"); ! 36: return -1; ! 37: } ! 38: ! 39: /* check ability to create file */ ! 40: if (xstat.st_uid == uid && (U_MODE & 2) ! 41: return 0; ! 42: if (xstat.st_gid == gid && (G_MODE & 2) ! 43: return 0; ! 44: if (xstat.st_uid != uid && xstat.st_gid != gid && O_MODE & 2) ! 45: return 0; ! 46: errno = EACCES; ! 47: return -1; ! 48: } ! 49: ! 50: if (xstat.st_uid == uid && (U_MODE & mode) ! 51: return 0; ! 52: if (xstat.st_gid == gid && (G_MODE & mode) ! 53: return 0; ! 54: if (xstat.st_uid != uid && xstat.st_gid != gid && O_MODE & mode) ! 55: return 0; ! 56: errno = EACCES; ! 57: return -1; ! 58: } ! 59: ! 60: mkdir(f, mode) ! 61: char *f; ! 62: { ! 63: int status, i, mode; ! 64: struct stat st; ! 65: ! 66: if (!stat(f, &st)) ! 67: return(-1); ! 68: while((i=fork()) == -1) ! 69: sleep(3); ! 70: if(i) { ! 71: wait(&status); ! 72: return(stat(f, &st)); ! 73: } ! 74: execl("/bin/mkdir", "mkdir", f, 0); ! 75: exit(1); ! 76: } ! 77: ! 78: rmdir(f) ! 79: char *f; ! 80: { ! 81: int status, i; ! 82: struct stat st; ! 83: ! 84: if (-1 == stat(f, &st)) ! 85: return(-1); ! 86: while((i=fork()) == -1) ! 87: sleep(3); ! 88: if(i) { ! 89: wait(&status); ! 90: if (stat(f, &st) == -1) ! 91: return(0); ! 92: return(-1); ! 93: ! 94: } ! 95: execl("/bin/rmdir", "rmdir", f, 0); ! 96: exit(1); ! 97: } ! 98: ! 99: /* ! 100: * C-shell glob for random programs. ! 101: */ ! 102: ! 103: #include <ndir.h> ! 104: #include <stdio.h> ! 105: #include <pwd.h> ! 106: ! 107: #define QUOTE 0200 ! 108: #define TRIM 0177 ! 109: #define eq(a,b) (strcmp(a, b)==0) ! 110: #define GAVSIZ (NCARGS/6) ! 111: #define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR) ! 112: ! 113: static char **gargv; /* Pointer to the (stack) arglist */ ! 114: static short gargc; /* Number args in gargv */ ! 115: static short gnleft; ! 116: static short gflag; ! 117: static int tglob(); ! 118: char **glob(); ! 119: char *globerr; ! 120: char *home; ! 121: struct passwd *getpwnam(); ! 122: extern int errno; ! 123: static char *strspl(), **copyblk(), *strend(); ! 124: char *malloc(), *strcpy(), *strcat(); ! 125: ! 126: static int globcnt; ! 127: ! 128: char *globchars = "`{[*?"; ! 129: ! 130: static char *gpath, *gpathp, *lastgpathp; ! 131: static int globbed; ! 132: static char *entp; ! 133: static char **sortbas; ! 134: ! 135: char ** ! 136: glob(v) ! 137: register char *v; ! 138: { ! 139: char agpath[BUFSIZ]; ! 140: char *agargv[GAVSIZ]; ! 141: char *vv[2]; ! 142: vv[0] = v; ! 143: vv[1] = 0; ! 144: gflag = 0; ! 145: rscan(vv, tglob); ! 146: if (gflag == 0) ! 147: return (copyblk(vv)); ! 148: ! 149: globerr = 0; ! 150: gpath = agpath; gpathp = gpath; *gpathp = 0; ! 151: lastgpathp = &gpath[sizeof agpath - 2]; ! 152: ginit(agargv); globcnt = 0; ! 153: collect(v); ! 154: if (globcnt == 0 && (gflag&1)) { ! 155: blkfree(gargv), gargv = 0; ! 156: return (0); ! 157: } else ! 158: return (gargv = copyblk(gargv)); ! 159: } ! 160: ! 161: static ! 162: ginit(agargv) ! 163: char **agargv; ! 164: { ! 165: ! 166: agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0; ! 167: gnleft = NCARGS - 4; ! 168: } ! 169: ! 170: static ! 171: collect(as) ! 172: register char *as; ! 173: { ! 174: if (eq(as, "{") || eq(as, "{}")) { ! 175: Gcat(as, ""); ! 176: sort(); ! 177: } else ! 178: acollect(as); ! 179: } ! 180: ! 181: static ! 182: acollect(as) ! 183: register char *as; ! 184: { ! 185: register int ogargc = gargc; ! 186: ! 187: gpathp = gpath; *gpathp = 0; globbed = 0; ! 188: expand(as); ! 189: if (gargc != ogargc) ! 190: sort(); ! 191: } ! 192: ! 193: static ! 194: sort() ! 195: { ! 196: register char **p1, **p2, *c; ! 197: char **Gvp = &gargv[gargc]; ! 198: ! 199: p1 = sortbas; ! 200: while (p1 < Gvp-1) { ! 201: p2 = p1; ! 202: while (++p2 < Gvp) ! 203: if (strcmp(*p1, *p2) > 0) ! 204: c = *p1, *p1 = *p2, *p2 = c; ! 205: p1++; ! 206: } ! 207: sortbas = Gvp; ! 208: } ! 209: ! 210: static ! 211: expand(as) ! 212: char *as; ! 213: { ! 214: register char *cs; ! 215: register char *sgpathp, *oldcs; ! 216: struct stat stb; ! 217: ! 218: sgpathp = gpathp; ! 219: cs = as; ! 220: if (*cs == '~' && gpathp == gpath) { ! 221: addpath('~'); ! 222: for (cs++; letter(*cs) || digit(*cs) || *cs == '-';) ! 223: addpath(*cs++); ! 224: if (!*cs || *cs == '/') { ! 225: if (gpathp != gpath + 1) { ! 226: *gpathp = 0; ! 227: if (gethdir(gpath + 1)) ! 228: globerr = "Unknown user name after ~"; ! 229: strcpy(gpath, gpath + 1); ! 230: } else ! 231: strcpy(gpath, home); ! 232: gpathp = strend(gpath); ! 233: } ! 234: } ! 235: while (!any(*cs, globchars)) { ! 236: if (*cs == 0) { ! 237: if (!globbed) ! 238: Gcat(gpath, ""); ! 239: else if (stat(gpath, &stb) >= 0) { ! 240: Gcat(gpath, ""); ! 241: globcnt++; ! 242: } ! 243: goto endit; ! 244: } ! 245: addpath(*cs++); ! 246: } ! 247: oldcs = cs; ! 248: while (cs > as && *cs != '/') ! 249: cs--, gpathp--; ! 250: if (*cs == '/') ! 251: cs++, gpathp++; ! 252: *gpathp = 0; ! 253: if (*oldcs == '{') { ! 254: execbrc(cs, ((char *)0)); ! 255: return; ! 256: } ! 257: matchdir(cs); ! 258: endit: ! 259: gpathp = sgpathp; ! 260: *gpathp = 0; ! 261: } ! 262: ! 263: static ! 264: matchdir(pattern) ! 265: char *pattern; ! 266: { ! 267: struct stat stb; ! 268: register struct direct *dp; ! 269: DIR *dirp; ! 270: register int cnt; ! 271: ! 272: dirp = opendir(gpath); ! 273: if (dirp == NULL) { ! 274: if (globbed) ! 275: return; ! 276: goto patherr2; ! 277: } ! 278: if (fstat(dirp->dd_fd, &stb) < 0) ! 279: goto patherr1; ! 280: if (!isdir(stb)) { ! 281: errno = ENOTDIR; ! 282: goto patherr1; ! 283: } ! 284: while ((dp = readdir(dirp)) != NULL) { ! 285: if (dp->d_ino == 0) ! 286: continue; ! 287: if (match(dp->d_name, pattern)) { ! 288: Gcat(gpath, dp->d_name); ! 289: globcnt++; ! 290: } ! 291: } ! 292: closedir(dirp); ! 293: return; ! 294: ! 295: patherr1: ! 296: closedir(dirp); ! 297: patherr2: ! 298: globerr = "Bad directory components"; ! 299: } ! 300: ! 301: static ! 302: execbrc(p, s) ! 303: char *p, *s; ! 304: { ! 305: char restbuf[BUFSIZ + 2]; ! 306: register char *pe, *pm, *pl; ! 307: int brclev = 0; ! 308: char *lm, savec, *sgpathp; ! 309: ! 310: for (lm = restbuf; *p != '{'; *lm++ = *p++) ! 311: continue; ! 312: for (pe = ++p; *pe; pe++) ! 313: switch (*pe) { ! 314: ! 315: case '{': ! 316: brclev++; ! 317: continue; ! 318: ! 319: case '}': ! 320: if (brclev == 0) ! 321: goto pend; ! 322: brclev--; ! 323: continue; ! 324: ! 325: case '[': ! 326: for (pe++; *pe && *pe != ']'; pe++) ! 327: continue; ! 328: continue; ! 329: } ! 330: pend: ! 331: brclev = 0; ! 332: for (pl = pm = p; pm <= pe; pm++) ! 333: switch (*pm & (QUOTE|TRIM)) { ! 334: ! 335: case '{': ! 336: brclev++; ! 337: continue; ! 338: ! 339: case '}': ! 340: if (brclev) { ! 341: brclev--; ! 342: continue; ! 343: } ! 344: goto doit; ! 345: ! 346: case ','|QUOTE: ! 347: case ',': ! 348: if (brclev) ! 349: continue; ! 350: doit: ! 351: savec = *pm; ! 352: *pm = 0; ! 353: strcpy(lm, pl); ! 354: strcat(restbuf, pe + 1); ! 355: *pm = savec; ! 356: if (s == 0) { ! 357: sgpathp = gpathp; ! 358: expand(restbuf); ! 359: gpathp = sgpathp; ! 360: *gpathp = 0; ! 361: } else if (amatch(s, restbuf)) ! 362: return (1); ! 363: sort(); ! 364: pl = pm + 1; ! 365: if (brclev) ! 366: return (0); ! 367: continue; ! 368: ! 369: case '[': ! 370: for (pm++; *pm && *pm != ']'; pm++) ! 371: continue; ! 372: if (!*pm) ! 373: pm--; ! 374: continue; ! 375: } ! 376: if (brclev) ! 377: goto doit; ! 378: return (0); ! 379: } ! 380: ! 381: static ! 382: match(s, p) ! 383: char *s, *p; ! 384: { ! 385: register int c; ! 386: register char *sentp; ! 387: char sglobbed = globbed; ! 388: ! 389: if (*s == '.' && *p != '.') ! 390: return (0); ! 391: sentp = entp; ! 392: entp = s; ! 393: c = amatch(s, p); ! 394: entp = sentp; ! 395: globbed = sglobbed; ! 396: return (c); ! 397: } ! 398: ! 399: static ! 400: amatch(s, p) ! 401: register char *s, *p; ! 402: { ! 403: register int scc; ! 404: int ok, lc; ! 405: char *sgpathp; ! 406: struct stat stb; ! 407: int c, cc; ! 408: ! 409: globbed = 1; ! 410: for (;;) { ! 411: scc = *s++ & TRIM; ! 412: switch (c = *p++) { ! 413: ! 414: case '{': ! 415: return (execbrc(p - 1, s - 1)); ! 416: ! 417: case '[': ! 418: ok = 0; ! 419: lc = 077777; ! 420: while (cc = *p++) { ! 421: if (cc == ']') { ! 422: if (ok) ! 423: break; ! 424: return (0); ! 425: } ! 426: if (cc == '-') { ! 427: if (lc <= scc && scc <= *p++) ! 428: ok++; ! 429: } else ! 430: if (scc == (lc = cc)) ! 431: ok++; ! 432: } ! 433: if (cc == 0) ! 434: if (ok) ! 435: p--; ! 436: else ! 437: return 0; ! 438: continue; ! 439: ! 440: case '*': ! 441: if (!*p) ! 442: return (1); ! 443: if (*p == '/') { ! 444: p++; ! 445: goto slash; ! 446: } ! 447: s--; ! 448: do { ! 449: if (amatch(s, p)) ! 450: return (1); ! 451: } while (*s++); ! 452: return (0); ! 453: ! 454: case 0: ! 455: return (scc == 0); ! 456: ! 457: default: ! 458: if (c != scc) ! 459: return (0); ! 460: continue; ! 461: ! 462: case '?': ! 463: if (scc == 0) ! 464: return (0); ! 465: continue; ! 466: ! 467: case '/': ! 468: if (scc) ! 469: return (0); ! 470: slash: ! 471: s = entp; ! 472: sgpathp = gpathp; ! 473: while (*s) ! 474: addpath(*s++); ! 475: addpath('/'); ! 476: if (stat(gpath, &stb) == 0 && isdir(stb)) ! 477: if (*p == 0) { ! 478: Gcat(gpath, ""); ! 479: globcnt++; ! 480: } else ! 481: expand(p); ! 482: gpathp = sgpathp; ! 483: *gpathp = 0; ! 484: return (0); ! 485: } ! 486: } ! 487: } ! 488: ! 489: static ! 490: Gmatch(s, p) ! 491: register char *s, *p; ! 492: { ! 493: register int scc; ! 494: int ok, lc; ! 495: int c, cc; ! 496: ! 497: for (;;) { ! 498: scc = *s++ & TRIM; ! 499: switch (c = *p++) { ! 500: ! 501: case '[': ! 502: ok = 0; ! 503: lc = 077777; ! 504: while (cc = *p++) { ! 505: if (cc == ']') { ! 506: if (ok) ! 507: break; ! 508: return (0); ! 509: } ! 510: if (cc == '-') { ! 511: if (lc <= scc && scc <= *p++) ! 512: ok++; ! 513: } else ! 514: if (scc == (lc = cc)) ! 515: ok++; ! 516: } ! 517: if (cc == 0) ! 518: if (ok) ! 519: p--; ! 520: else ! 521: return 0; ! 522: continue; ! 523: ! 524: case '*': ! 525: if (!*p) ! 526: return (1); ! 527: for (s--; *s; s++) ! 528: if (Gmatch(s, p)) ! 529: return (1); ! 530: return (0); ! 531: ! 532: case 0: ! 533: return (scc == 0); ! 534: ! 535: default: ! 536: if ((c & TRIM) != scc) ! 537: return (0); ! 538: continue; ! 539: ! 540: case '?': ! 541: if (scc == 0) ! 542: return (0); ! 543: continue; ! 544: ! 545: } ! 546: } ! 547: } ! 548: ! 549: static ! 550: Gcat(s1, s2) ! 551: register char *s1, *s2; ! 552: { ! 553: register int len = strlen(s1) + strlen(s2) + 1; ! 554: ! 555: if (len >= gnleft || gargc >= GAVSIZ - 1) ! 556: globerr = "Arguments too long"; ! 557: else { ! 558: gargc++; ! 559: gnleft -= len; ! 560: gargv[gargc] = 0; ! 561: gargv[gargc - 1] = strspl(s1, s2); ! 562: } ! 563: } ! 564: ! 565: static ! 566: addpath(c) ! 567: char c; ! 568: { ! 569: ! 570: if (gpathp >= lastgpathp) ! 571: globerr = "Pathname too long"; ! 572: else { ! 573: *gpathp++ = c; ! 574: *gpathp = 0; ! 575: } ! 576: } ! 577: ! 578: static ! 579: rscan(t, f) ! 580: register char **t; ! 581: int (*f)(); ! 582: { ! 583: register char *p, c; ! 584: ! 585: while (p = *t++) { ! 586: if (f == tglob) ! 587: if (*p == '~') ! 588: gflag |= 2; ! 589: else if (eq(p, "{") || eq(p, "{}")) ! 590: continue; ! 591: while (c = *p++) ! 592: (*f)(c); ! 593: } ! 594: } ! 595: ! 596: static ! 597: scan(t, f) ! 598: register char **t; ! 599: int (*f)(); ! 600: { ! 601: register char *p, c; ! 602: ! 603: while (p = *t++) ! 604: while (c = *p) ! 605: *p++ = (*f)(c); ! 606: } ! 607: ! 608: static ! 609: tglob(c) ! 610: register char c; ! 611: { ! 612: ! 613: if (any(c, globchars)) ! 614: gflag |= c == '{' ? 2 : 1; ! 615: return (c); ! 616: } ! 617: ! 618: static ! 619: trim(c) ! 620: char c; ! 621: { ! 622: ! 623: return (c & TRIM); ! 624: } ! 625: ! 626: ! 627: letter(c) ! 628: register char c; ! 629: { ! 630: ! 631: return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); ! 632: } ! 633: ! 634: digit(c) ! 635: register char c; ! 636: { ! 637: ! 638: return (c >= '0' && c <= '9'); ! 639: } ! 640: ! 641: any(c, s) ! 642: register int c; ! 643: register char *s; ! 644: { ! 645: ! 646: while (*s) ! 647: if (*s++ == c) ! 648: return(1); ! 649: return(0); ! 650: } ! 651: blklen(av) ! 652: register char **av; ! 653: { ! 654: register int i = 0; ! 655: ! 656: while (*av++) ! 657: i++; ! 658: return (i); ! 659: } ! 660: ! 661: char ** ! 662: blkcpy(oav, bv) ! 663: char **oav; ! 664: register char **bv; ! 665: { ! 666: register char **av = oav; ! 667: ! 668: while (*av++ = *bv++) ! 669: continue; ! 670: return (oav); ! 671: } ! 672: ! 673: blkfree(av0) ! 674: char **av0; ! 675: { ! 676: register char **av = av0; ! 677: ! 678: while (*av) ! 679: free(*av++); ! 680: free((char *)av0); ! 681: } ! 682: ! 683: static ! 684: char * ! 685: strspl(cp, dp) ! 686: register char *cp, *dp; ! 687: { ! 688: register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1)); ! 689: ! 690: if (ep == (char *)0) ! 691: fatal("Out of memory"); ! 692: strcpy(ep, cp); ! 693: strcat(ep, dp); ! 694: return (ep); ! 695: } ! 696: ! 697: static ! 698: char ** ! 699: copyblk(v) ! 700: register char **v; ! 701: { ! 702: register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) * ! 703: sizeof(char **))); ! 704: if (nv == (char **)0) ! 705: fatal("Out of memory"); ! 706: ! 707: return (blkcpy(nv, v)); ! 708: } ! 709: ! 710: static ! 711: char * ! 712: strend(cp) ! 713: register char *cp; ! 714: { ! 715: ! 716: while (*cp) ! 717: cp++; ! 718: return (cp); ! 719: } ! 720: /* ! 721: * Extract a home directory from the password file ! 722: * The argument points to a buffer where the name of the ! 723: * user whose home directory is sought is currently. ! 724: * We write the home directory of the user back there. ! 725: */ ! 726: gethdir(home) ! 727: char *home; ! 728: { ! 729: register struct passwd *pp = getpwnam(home); ! 730: ! 731: if (pp == 0) ! 732: return (1); ! 733: strcpy(home, pp->pw_dir); ! 734: return (0); ! 735: } ! 736: ! 737: char version[] = "Version 4.7 Mon Sep 23 21:57:45 EDT 1985";
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.