|
|
1.1 root 1: /* ftam-ls.c - interactive initiator FTAM -- "ls" */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftam-ls.c,v 7.1 90/07/01 21:03:12 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/ftam2/RCS/ftam-ls.c,v 7.1 90/07/01 21:03:12 mrose Exp $
9: *
10: *
11: * $Log: ftam-ls.c,v $
12: * Revision 7.1 90/07/01 21:03:12 mrose
13: * pepsy
14: *
15: * Revision 7.0 89/11/23 21:54:21 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include <signal.h>
32: #include <stdio.h>
33: #include "FTAM-types.h"
34: #include "ftamuser.h"
35:
36: /* DATA */
37:
38: static int dashl;
39: static int didrecurse;
40: static int silent;
41:
42:
43: static long now;
44: static long longtimeago;
45:
46:
47: int toomany;
48:
49: int nfilent = 0;
50: struct filent *filents = NULL;
51:
52: int filcmp ();
53:
54:
55: #ifdef BRIDGE
56: FILE *fdopen();
57: #endif
58: static FILE *lsfp = stdout;
59:
60:
61: long time ();
62: char *ctime ();
63: FILE *popen ();
64:
65: /* */
66:
67: #ifndef BRIDGE
68: int f_fls (vec)
69: char **vec;
70: {
71: int doingpipe,
72: result;
73: SFP pstat;
74: char *cp,
75: *pp,
76: buffer[BUFSIZ];
77: FILE *fp;
78:
79: pp = vec[0];
80: if (*++vec == NULL) {
81: if (getline ("output to file/program: ", buffer) == NOTOK
82: || str2vec (buffer, vec) < 1)
83: return OK;
84: }
85:
86: cp = vec[0];
87: if (*cp == '|') {
88: if ((fp = popen (cp + 1, "w")) == NULL) {
89: advise (cp + 1, "unable to start");
90: return OK;
91: }
92:
93: doingpipe = 1;
94: pstat = signal (SIGPIPE, SIG_IGN);
95: }
96: else {
97: if ((cp = xglob1val (cp, 0)) == NULL)
98: return OK;
99:
100: if ((fp = fopen (cp, "w")) == NULL) {
101: advise (cp, "unable to write");
102: free (cp);
103: return OK;
104: }
105:
106: doingpipe = 0;
107: }
108: vec[0] = pp + 1;
109:
110: lsfp = fp;
111:
112: result = f_ls (vec);
113:
114: if (doingpipe) {
115: (void) pclose (fp);
116: (void) signal (SIGPIPE, pstat);
117: }
118: else {
119: free (cp);
120: (void) fclose (fp);
121: }
122:
123: lsfp = stdout;
124:
125: return result;
126: }
127: #endif
128:
129: /* */
130:
131: int f_ls (vec)
132: char **vec;
133: {
134: int invis,
135: multi,
136: result;
137: #ifdef BRIDGE
138: int fd;
139: #else
140: char buffer[BUFSIZ];
141: #endif
142:
143: if (dashl = strcmp (*vec, "dir") == 0) {
144: if (!(attrs & FATTR_STORAGE)) {
145: advise (NULLCP, "no support for storage attributes");
146: return OK;
147: }
148:
149: (void) time (&now);
150: longtimeago = now - 6L * 30L * 24L * 60L * 60L;
151: }
152:
153: if (*++vec == NULL) {
154: #ifdef BRIDGE
155: return NOTOK;
156: #else
157: switch (realstore) {
158: case RFS_UNIX:
159: *vec++ = ".";
160: *vec-- = NULL;
161: invis = !dashl;
162: break;
163:
164: default:
165: if (getline ("file: ", buffer) == NOTOK
166: || str2vec (buffer, vec) < 1)
167: return OK;
168: invis = 0;
169: break;
170: }
171: #endif
172: }
173: else
174: invis = 0;
175:
176: #ifdef BRIDGE
177: if ((fd = dataconn ("LIST")) == NOTOK
178: || (lsfp = fdopen (fd, "w")) == NULL) {
179: (void) sprintf (ftam_error, "out of memory");
180: if (fd != NOTOK) {
181: (void) close (fd);
182: return NOTOK;
183: }
184: return DONE;
185: }
186: #endif
187:
188: result = OK;
189: if (vec = xglob (vec, 1)) {
190: register char **gp;
191:
192: didrecurse = 0;
193: multi = vec[1] ? 1 : 0;
194:
195: for (gp = vec; *gp && !interrupted; gp++) {
196: result = ls (*gp, *gp, 1, gp == vec, gp[1] == NULL, invis, multi);
197:
198: if (ftamfd == NOTOK || result == NOTOK)
199: break;
200: }
201:
202: blkfree (vec);
203: }
204: #ifdef BRIDGE
205: (void) fclose (lsfp);
206: (void) close (fd);
207: #endif
208:
209: return result;
210: }
211:
212: /* */
213:
214: static int ls (file, entry, top, first, last, invis, multi)
215: char *file,
216: *entry;
217: int top,
218: first,
219: last,
220: invis,
221: multi;
222: {
223: int recurse;
224: long mtime;
225: char *s;
226: UTC ut;
227: struct FTAMgroup ftgs;
228: register struct FTAMgroup *ftg = &ftgs;
229: struct FTAMindication ftis;
230: register struct FTAMindication *fti = &ftis;
231: struct vfsmap *vf = &vfs[VFS_FDF];
232:
233: bzero ((char *) ftg, sizeof *ftg);
234: ftg -> ftg_flags |= FTG_BEGIN | FTG_END;
235: ftg -> ftg_threshold = 0;
236:
237: ftg -> ftg_flags |= FTG_SELECT;
238: {
239: register struct FTAMselect *ftse = &ftg -> ftg_select;
240: register struct FTAMattributes *fa = &ftse -> ftse_attrs;
241:
242: fa -> fa_present = FA_FILENAME;
243: fa -> fa_nfile = 0;
244: fa -> fa_files[fa -> fa_nfile++] = file;
245:
246: ftse -> ftse_access = FA_PERM_READATTR;
247: FCINIT (&ftse -> ftse_conctl);
248: }
249: ftg -> ftg_threshold++;
250:
251: ftg -> ftg_flags |= FTG_RDATTR;
252: {
253: register struct FTAMreadattr *ftra = &ftg -> ftg_readattr;
254:
255: ftra -> ftra_attrnames = FA_FILENAME | FA_CONTENTS;
256: if (dashl)
257: #ifdef DEBUG
258: ftra -> ftra_attrnames |= FA_STORAGE
259: | (attrs & FATTR_SECURITY ? FA_SECURITY : 0);
260: #else
261: ftra -> ftra_attrnames |= FA_ID_CREATE | FA_DATE_MODIFY
262: | FA_ACCOUNT | FA_FILESIZE;
263: #endif
264: }
265: ftg -> ftg_threshold++;
266:
267: ftg -> ftg_flags |= FTG_DESELECT;
268: ftg -> ftg_threshold++;
269:
270: if (FManageRequest (ftamfd, ftg, fti) == NOTOK) {
271: ftam_advise (&fti -> fti_abort, "F-MANAGE.REQUEST");
272: return NOTOK;
273: }
274:
275: ftg = &fti -> fti_group;
276:
277: if (ftg -> ftg_flags & FTG_SELECT) {
278: register struct FTAMselect *ftse = &ftg -> ftg_select;
279: register struct FTAMattributes *fa = &ftse -> ftse_attrs;
280:
281: if (multi && ftse -> ftse_state != FSTATE_SUCCESS)
282: printf ("%s\n", fa -> fa_files[0]);
283: ftam_diag (ftse -> ftse_diags, ftse -> ftse_ndiag, 1,
284: ftse -> ftse_action);
285: if (ftse -> ftse_state != FSTATE_SUCCESS)
286: goto you_lose;
287:
288: file = fa -> fa_files[0];
289: }
290:
291: recurse = 0;
292:
293: if (ftg -> ftg_flags & FTG_RDATTR) {
294: register struct FTAMreadattr *ftra = &ftg -> ftg_readattr;
295: register struct FTAMattributes *fa = &ftra -> ftra_attrs;
296:
297: ftam_diag (ftra -> ftra_diags, ftra -> ftra_ndiag, 1,
298: ftra -> ftra_action);
299: if (ftra -> ftra_action != FACTION_SUCCESS)
300: fa -> fa_present = 0;
301: fa -> fa_present &= ~fa -> fa_novalue;
302:
303: if (top
304: && (fa -> fa_present & FA_FILENAME)
305: && vf -> vf_oid
306: && (fa -> fa_present & FA_CONTENTS)
307: && oid_cmp (vf -> vf_oid, fa -> fa_contents) == 0) {
308: recurse++;
309: if (!didrecurse && !first)
310: #ifdef BRIDGE
311: fprintf (lsfp, "\r\n");
312: #else
313: fprintf (lsfp, "\n");
314: #endif
315: }
316: if (!invis)
317: invis = recurse && !multi;/* recurse depends on top */
318:
319: if (dashl && !invis && !recurse) {
320: s = (fa -> fa_present & FA_ID_CREATE) ? fa -> fa_id_create : NULL;
321: ut = (fa -> fa_present & FA_DATE_MODIFY) ? &fa -> fa_date_modify
322: : NULLUTC;
323:
324: if (fa -> fa_present & FA_CONTENTS) {
325: register struct vfsmap *uf;
326:
327: for (uf = vfs; uf -> vf_entry; uf++)
328: if (oid_cmp (uf -> vf_oid, fa -> fa_contents) == 0)
329: break;
330: fprintf (lsfp, "%c ", uf -> vf_entry ? uf -> vf_stat : ' ');
331: }
332: else
333: fprintf (lsfp, " ");
334: fprintf (lsfp, "%-8.8s %-8.8s %8d ", s ? s : "",
335: (fa -> fa_present & FA_ACCOUNT) ? fa -> fa_account : "",
336: (fa -> fa_present & FA_FILESIZE) ? fa -> fa_filesize : 0);
337: if (ut) {
338: mtime = gtime (ut2tm (ut));
339: s = ctime (&mtime);
340: if (mtime < longtimeago || mtime > now)
341: fprintf (lsfp, "%-7.7s %-4.4s ", s + 4, s + 20);
342: else
343: fprintf (lsfp, "%-12.12s ", s + 4);
344: }
345: else
346: fprintf (lsfp, " ");
347: }
348: if (!invis) {
349: char *dp;
350:
351: dp = top && (fa -> fa_present & FA_FILENAME) ? fa -> fa_files[0]
352: : entry;
353: #ifdef BRIDGE
354: fprintf (lsfp, "%s%s\r\n", dp, multi && recurse ? ":" : "");
355: #else
356: fprintf (lsfp, "%s%s\n", dp, multi && recurse ? ":" : "");
357: #endif
358: }
359: }
360:
361: if (ftg -> ftg_flags & FTG_DESELECT) {
362: register struct FTAMdeselect *ftde = &ftg -> ftg_deselect;
363:
364: ftam_diag (ftde -> ftde_diags, ftde -> ftde_ndiag, 1,
365: ftde -> ftde_action);
366: ftam_chrg (&ftde -> ftde_charges);
367: }
368:
369: if (recurse) {
370: struct FADUidentity faduids;
371: register struct FADUidentity *faduid = &faduids;
372:
373: faduid -> fa_type = FA_FIRSTLAST;
374: faduid -> fa_firstlast = FA_FIRST;
375:
376: (void) fdffnx (NOTOK, (struct PSAPdata *) 0, 0);
377: (void) getvf (file, NULLCP, faduid, vf, fdffnx);
378:
379: (void) fdfls (file);
380:
381: (void) fdffnx (NOTOK, (struct PSAPdata *) 0, 0);
382: didrecurse++;
383: }
384:
385: if (top && !last && didrecurse)
386: fprintf (lsfp, "\n");
387:
388: FTGFREE (ftg);
389: return OK;
390:
391: you_lose: ;
392: FTGFREE (ftg);
393: return NOTOK;
394: }
395:
396: /* */
397:
398: static int fdfls (file)
399: char *file;
400: {
401: register int i,
402: j,
403: w;
404: int columns,
405: width,
406: lines;
407: char *bp,
408: buffer[BUFSIZ];
409: register struct filent *fi,
410: **xi,
411: **yi;
412:
413: switch (realstore) {
414: case RFS_UNIX:
415: if (strcmp (file, ".")) {
416: #ifdef apollo
417: if (*file == '/')
418: (void) sprintf (bp = buffer, "%s", file);
419: else
420: #endif
421: (void) sprintf (bp = buffer, "%s/", file);
422: bp += strlen (bp);
423: i = bp - buffer;
424: for (xi = &filents; fi = *xi;)
425: if (strncmp (fi -> fi_name, buffer, i) == 0) {
426: fi -> fi_entry = fi -> fi_name + i;
427: if (!dashl && !silent && *fi -> fi_entry == '.') {
428: *xi = fi -> fi_next;
429: if (fi -> fi_name)
430: free (fi -> fi_name);
431: if (fi -> fi_oid)
432: oid_free (fi -> fi_oid);
433: free ((char *) fi);
434:
435: nfilent--;
436: }
437: else
438: xi = &fi -> fi_next;
439: }
440: }
441: else
442: bp = buffer;
443: break;
444:
445: default:
446: bp = buffer;
447: break;
448: }
449:
450: switch (nfilent) {
451: case 0:
452: break;
453:
454: case 1:
455: fi = filents;
456: if (dashl)
457: (void) ls (fi -> fi_name, fi -> fi_entry, 0, 1, 1, 0, 0);
458: else
459: #ifdef BRIDGE
460: fprintf (lsfp, "%s\r\n", fi -> fi_entry);
461: #else
462: fprintf (lsfp, "%s\n", fi -> fi_entry);
463: #endif
464: break;
465:
466: default:
467: xi = (struct filent **)
468: calloc ((unsigned) (nfilent + 1), sizeof *xi);
469: if (xi) {
470: for (fi = filents, yi = xi; fi; fi = fi -> fi_next)
471: *yi++ = fi;
472: qsort ((char *) xi, nfilent, sizeof *xi, filcmp);
473: }
474:
475: if (dashl) {
476: if (xi) {
477: for (filents = NULL, yi--; yi >= xi; yi--) {
478: fi = *yi;
479: fi -> fi_next = filents;
480: filents = fi;
481: }
482:
483: free ((char *) xi);
484: }
485:
486: for (fi = filents; fi; fi = fi -> fi_next)
487: (void) ls (fi -> fi_name, fi -> fi_entry, 0, fi == filents,
488: fi -> fi_next == NULL, 0, 1);
489: break;
490: }
491:
492: if (!xi) {
493: for (fi = filents; fi; fi = fi -> fi_next)
494: #ifdef BRIDGE
495: fprintf (lsfp, "%s\r\n", fi -> fi_entry);
496: #else
497: fprintf (lsfp, "%s\n", fi -> fi_entry);
498: #endif
499: break;
500: }
501:
502: width = 0;
503: for (yi = xi; fi = *yi; yi++)
504: if ((w = strlen (fi -> fi_entry)) > width)
505: width = w;
506: if (lsfp != stdout) {
507: columns = 1;
508: lines = nfilent;
509: }
510: else {
511: if ((columns = ncols (lsfp) / (width = (width + 8) & ~7)) == 0)
512: columns = 1;
513: lines = (nfilent + columns - 1) / columns;
514: }
515: for (i = 0; i < lines; i++)
516: for (j = 0; j < columns; j++) {
517: fi = xi[w = j * lines + i];
518: fprintf (lsfp, "%s", fi -> fi_entry);
519: if (w + lines >= nfilent) {
520: #ifdef BRIDGE
521: (void) fputc ('\r', lsfp);
522: (void) fputc ('\n', lsfp);
523: #else
524: (void) fputc ('\n', lsfp);
525: #endif
526: break;
527: }
528: for (w = strlen (fi -> fi_entry);
529: w < width;
530: w = (w + 8) & ~7)
531: (void) fputc ('\t', lsfp);
532: }
533: free ((char *) xi);
534: }
535:
536: return OK;
537: }
538:
539: /* */
540:
541: /* ARGSUSED */
542:
543: int fdffnx (fd, px, status)
544: int fd;
545: register struct PSAPdata *px;
546: int status;
547: {
548: register int i;
549: register PE pe,
550: *pep;
551: register struct filent *fi;
552:
553: if (px == NULL) {
554: register struct filent *gi;
555:
556: for (fi = filents; fi; fi = gi) {
557: gi = fi -> fi_next;
558: if (fi -> fi_name);
559: free (fi -> fi_name);
560: if (fi -> fi_oid)
561: oid_free (fi -> fi_oid);
562: free ((char *) fi);
563: }
564: filents = NULL, nfilent = toomany = 0;
565:
566: silent = status;
567: return OK;
568: }
569:
570: for (pep = px -> px_info, i = px -> px_ninfo - 1; i >= 0; pep++, i--) {
571: int result;
572: struct type_DOCS_NBS__9__Datatype1 *d9;
573: struct FTAMattributes fas;
574: register struct FTAMattributes *fa = &fas;
575: struct FTAMindication ftis;
576:
577: if ((pe = *pep) == NULLPE)
578: continue;
579:
580: d9 = NULL;
581: if (decode_DOCS_NBS__9__Datatype1 (pe, 1, NULLIP, NULLVP, &d9)
582: == NOTOK) {
583: if (silent)
584: globerr = PY_pepy;
585: else
586: advise (NULLCP, "%s", PY_pepy);
587:
588: if (d9)
589: free_DOCS_NBS__9__Datatype1 (d9);
590:
591: continue;
592: }
593:
594: if (debug)
595: WATCHP (DOCS_NBS__9__Datatype1, pe, 1);
596:
597: bzero ((char *) fa, sizeof *fa);
598: result = fdf_d2attrs (ftamfd, d9, fa, &ftis);
599:
600: free_DOCS_NBS__9__Datatype1 (d9);
601:
602: if (result == NOTOK) {
603: register struct FTAMabort *fta = &ftis.fti_abort;
604:
605: if (silent)
606: globerr = "unable to interpret datatype";
607: else
608: ftam_diag (fta -> fta_diags, fta -> fta_ndiag, fta -> fta_peer,
609: FACTION_PERM);
610: FAFREE (fa);
611:
612: continue;
613: }
614:
615: fi = (struct filent *) calloc (1, sizeof *fi);
616: if (fi == NULL) {
617: if (toomany == 0) {
618: if (silent)
619: globerr = "too many files, listing truncated";
620: else
621: advise (NULLCP, "too many files, listing truncated");
622: toomany++;
623: }
624:
625: FAFREE (fa);
626: break;
627: }
628:
629: if (!(fa -> fa_present & (FA_FILENAME | FA_CONTENTS))) {
630: if (silent)
631: globerr = "no filename/contents found in FDF entry";
632: else
633: advise (NULLCP, "no filename/contents found in FDF entry");
634:
635: FAFREE (fa);
636: continue;
637: }
638:
639: fi -> fi_name = fi -> fi_entry = fa -> fa_files[0];
640: fa -> fa_files[0] = NULLCP;
641: fi -> fi_oid = fa -> fa_contents;
642: fa -> fa_contents = NULLOID;
643: fi -> fi_next = filents;
644: filents = fi, nfilent++;
645:
646: FAFREE (fa);
647: }
648:
649: PXFREE (px);
650:
651: return status;
652: }
653:
654:
655: static int filcmp (a, b)
656: struct filent **a,
657: **b;
658: {
659: return strcmp ((*a) -> fi_entry, (*b) -> fi_entry);
660: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.