|
|
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.