|
|
1.1 root 1: static char *rcsid = "$Header$";
2: /*
3: * ppd - list project directories
4: *
5: * Author: Peter J. Nicklin
6: */
7: #include <stdio.h>
8: #include "getarg.h"
9: #include "macro.h"
10: #include "null.h"
11: #include "path.h"
12: #include "pdb.h"
13: #include "pdtyp.h"
14: #include "pld.h"
15: #include "slslist.h"
16: #include "spms.h"
17: #include "yesno.h"
18:
19: #define MAXLINE 80 /* maximum output line size */
20: #define TABSIZE 8 /* default tab width */
21: #define MINIMUM_GAP 2 /* minimum space between items */
22:
23: /*
24: * Information request definitions
25: */
26: #define ABSOLUTE_PATH_INFO 1 /* list absolute pathnames */
27: #define ALIAS_INFO 2 /* list aliases + absolute pathnames */
28: #define DESCRIPTION_INFO 3 /* list directory descriptions */
29: #define REGULAR_INFO 4 /* list project directory aliases */
30: #define TYPE_LABEL_INFO 5 /* list type labels */
31:
32: char *PGN = "ppd"; /* program name */
33: int INFORMATION = REGULAR_INFO; /* type of information to be printed */
34: int LIST_ALL_ENTRIES = NO; /* print "..." && "...." ? */
35: int LIST_PLD_CONTENTS = YES; /* list project link dir contents */
36: int MARK_PROJECT_ROOT = 0; /* append project root dirs with `^' */
37: int ONE_ENTRY_PER_LINE = 0; /* print 1 project directory/line */
38: int PRINT_HEADING = YES; /* print headings for projects */
39: int RECURSIVE = 0; /* recursively print projects */
40: PDTYP PDIRTYP; /* project directory type labels list */
41:
42: main(argc, argv)
43: int argc;
44: char **argv;
45: {
46: extern int PPDEBUG; /* project pathname debug flag */
47: char *cwp; /* current working project */
48: char *getcwp(); /* get current working project */
49: char *slsappend(); /* append key+string */
50: int pdtolist(); /* add project directories to pdlist */
51: int pdtparse(); /* parse boolean type label expr */
52: int qsort(); /* quicker sort */
53: int readpath(); /* read project or regular pathname */
54: int status = 0; /* exit status */
55: int strpcmp(); /* compare pointed-to strings */
56: PATH pathbuf; /* pathname struct buffer */
57: SLSBLK *pblk; /* project list block */
58: SLSLIST *pdlist; /* project directory list */
59: SLSLIST *plist; /* project list */
60: SLSLIST *slsinit(); /* initialize key+string list */
61: void printlist(); /* print project directory list */
62: void slsrm(); /* remove key+string list */
63:
64: {
65: register char *s; /* option pointer */
66: while (--argc > 0 && **++argv == '-')
67: {
68: for (s = argv[0]+1; *s != '\0'; s++)
69: switch (*s)
70: {
71: case '1':
72: ONE_ENTRY_PER_LINE++;
73: break;
74: case 'D':
75: PPDEBUG = YES;
76: break;
77: case 'T':
78: if (pdtparse(GETARG(s), &PDIRTYP) == NO)
79: status = 1;
80: goto endfor;
81: case 'a':
82: LIST_ALL_ENTRIES = YES;
83: break;
84: case 'd':
85: INFORMATION = DESCRIPTION_INFO;
86: ONE_ENTRY_PER_LINE++;
87: break;
88: case 'l':
89: INFORMATION = ABSOLUTE_PATH_INFO;
90: ONE_ENTRY_PER_LINE++;
91: break;
92: case 'm':
93: MARK_PROJECT_ROOT++;
94: break;
95: case 'n':
96: INFORMATION = ALIAS_INFO;
97: ONE_ENTRY_PER_LINE++;
98: break;
99: case 'p':
100: LIST_PLD_CONTENTS = NO;
101: break;
102: case 'q':
103: PRINT_HEADING = NO;
104: break;
105: case 'r':
106: RECURSIVE++;
107: break;
108: case 't':
109: INFORMATION = TYPE_LABEL_INFO;
110: ONE_ENTRY_PER_LINE++;
111: break;
112: default:
113: warn("bad option -%c", *s);
114: status = 1;
115: goto endfor;
116: }
117: endfor: continue;
118: }
119: }
120: if (status == 1)
121: fatal("usage: ppd [-1adlmnpqrt] [-T typexpr] [pdirname ...]");
122:
123: if (argc < 1)
124: {
125: if ((cwp = getcwp()) == NULL)
126: fatal("no project environment");
127: status |= listproject("", cwp);
128: exit(status);
129: }
130:
131: pdlist = slsinit();
132: plist = slsinit();
133: qsort((char *) argv, argc, sizeof(char *), strpcmp);
134: for (; argc > 0; argc--, argv++)
135: if (readpath(*argv, &pathbuf) == -1)
136: {
137: patherr(*argv);
138: status = 1;
139: }
140: else switch (pathbuf.p_mode & P_IFMT)
141: {
142: case P_IFNEW:
143: case P_IFREG:
144: warn("%s: no such project or project directory", *argv);
145: status = 1;
146: break;
147: case P_IFHOME:
148: case P_IFPROOT:
149: if (LIST_PLD_CONTENTS == YES)
150: {
151: if (slsappend(*argv, pathbuf.p_path,
152: plist) == NULL)
153: exit(1);
154: }
155: else {
156: status |= pdtolist(*argv, &pathbuf, pdlist);
157: }
158: break;
159: case P_IFPDIR:
160: status |= pdtolist(*argv, &pathbuf, pdlist);
161: break;
162: }
163:
164: /* don't bother to print heading if single project request */
165: if (RECURSIVE == 0 && SLSNUM(pdlist) == 0 && SLSNUM(plist) == 1)
166: PRINT_HEADING = NO;
167:
168: /* print discrete project directories */
169: printlist("", pdlist);
170: slsrm(CNULL, pdlist);
171:
172: /* print projects */
173: for (pblk = plist->head; pblk != NULL; pblk = pblk->next)
174: status |= listproject(pblk->key, pblk->string);
175: exit(status);
176: }
177:
178:
179:
180: /*
181: * getpdesc() gets a project description. Returns constant 1 if error,
182: * otherwise 0.
183: */
184: getpdesc(desc, pathname)
185: char *desc; /* description receiving buffer */
186: char *pathname; /* project link directory pathname */
187: {
188: char *pbgetstring(); /* get specified string field */
189: int closepdb(); /* close database */
190: int errpdb(); /* print database error message */
191: int pfndent(); /* find and load database entry */
192: PDB *pldp; /* project link directory stream */
193: PDB *openpdb(); /* open database */
194:
195: *desc = '\0';
196: if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
197: return(errpdb((PDB *) NULL));
198: if (pfndent(CURPROJECT, pldp) == YES)
199: pbgetstring(PDIRDESC, desc);
200: return(closepdb(pldp));
201: }
202:
203:
204:
205: /*
206: * getptype() gets project root directory types. Returns constant 1 if error,
207: * otherwise 0.
208: */
209: getptype(type, pathname)
210: char *type; /* type receiving buffer */
211: char *pathname; /* project link directory pathname */
212: {
213: char *pbgetstring(); /* get specified string field */
214: int closepdb(); /* close database */
215: int errpdb(); /* print database error message */
216: int pfndent(); /* find and load database entry */
217: PDB *pldp; /* project link directory stream */
218: PDB *openpdb(); /* open database */
219:
220: *type = '\0';
221: if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
222: return(errpdb((PDB *) NULL));
223: if (pfndent(CURPROJECT, pldp) == YES)
224: pbgetstring(PDIRTYPE, type);
225: return(closepdb(pldp));
226: }
227:
228:
229:
230: /*
231: * ksprint() prints a list of key+string pairs (one pair per line).
232: */
233: void
234: ksprint(colwidth, pdlist)
235: int colwidth; /* maximum column width */
236: SLSLIST *pdlist; /* project directory list */
237: {
238: register char *kp; /* key pointer */
239: register char *tp; /* type label pointer */
240: register int cw; /* column width */
241: SLSBLK *curblk; /* current list block */
242:
243: for (curblk = pdlist->head; curblk != NULL; curblk = curblk->next)
244: {
245: for (cw=colwidth, kp=curblk->key; *kp != '\0' && cw-- > 0; kp++)
246: putchar(*kp);
247: if (cw > 0 && *curblk->string != '\0')
248: for(; cw > 0; cw -= TABSIZE)
249: putchar('\t');
250: if (INFORMATION == TYPE_LABEL_INFO)
251: {
252: for (tp = curblk->string; *tp != '\0'; tp++)
253: if (*tp == _PDTSC)
254: {
255: putchar(',');
256: putchar(' ');
257: }
258: else {
259: putchar(*tp);
260: }
261: putchar('\n');
262: }
263: else {
264: puts(curblk->string);
265: }
266: }
267: }
268:
269:
270:
271: /*
272: * listproject() lists a project link directory.
273: */
274: listproject(ppathname, pathname)
275: char *ppathname; /* project pathname */
276: char *pathname; /* regular pathname */
277: {
278: register char *alias; /* alias buffer pointer */
279: register char *path; /* path buffer pointer */
280: char aliasbuf[ALIASSIZE+1]; /* alias marking buffer */
281: char descbuf[DIRDESCSIZE]; /* project root directory description */
282: char *kp; /* key pointer */
283: char pathbuf[PATHSIZE+1]; /* regular pathname marking buffer */
284: char ppathbuf[PPATHSIZE]; /* project path concatenation buffer */
285: char *ppathcat(); /* project pathname concatenation */
286: char *slsappend(); /* append key+string */
287: char *strcat(); /* string concatenation */
288: char *strcpy(); /* string copy */
289: char typebuf[TYPBUFSIZE]; /* project root directory types */
290: int closepdb(); /* close database */
291: int errpdb(); /* print database error message */
292: int getpdesc(); /* get project description */
293: int getptype(); /* get project root directory types */
294: int pdtmatch(); /* match project dir type label expr */
295: int slssort(); /* sort key+string list */
296: int status = 0; /* return status */
297: int strcmp(); /* string comparison */
298: PATH *pd; /* pathname struct pointer */
299: PATH *readpld(); /* read project link directory entry */
300: PDB *openpdb(); /* open database */
301: PDB *pldp; /* project link directory stream */
302: SLSBLK *pblk; /* project list block */
303: SLSLIST *pdlist; /* project directory list */
304: SLSLIST *plist; /* project list */
305: SLSLIST *slsinit(); /* initialize key+string list */
306: void printlist(); /* print project directory list */
307: void slsrm(); /* remove key+string list */
308:
309: pdlist = slsinit();
310: plist = slsinit();
311:
312: /* read PLDNAME project link directory */
313: if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
314: return(errpdb((PDB *) NULL));
315: while ((pd = readpld(pldp)) != NULL)
316: {
317: alias = pd->p_alias;
318: path = pd->p_path;
319: if (EQUAL(alias, PARENTPROJECT))
320: {
321: if (LIST_ALL_ENTRIES == NO)
322: continue;
323: }
324: else if (EQUAL(alias, CURPROJECT))
325: {
326: if (PDIRTYP.pfxsize == 0 && LIST_ALL_ENTRIES == NO)
327: continue;
328: }
329: else if (RECURSIVE && pd->p_mode == P_IFPROOT)
330: if (slsappend(alias, path, plist) == NULL)
331: exit(1);
332:
333: if (PDIRTYP.pfxsize != 0 && pdtmatch(&PDIRTYP,pd->p_type) == NO)
334: continue;
335:
336: if (MARK_PROJECT_ROOT)
337: if (pd->p_mode == P_IFPROOT)
338: if (INFORMATION == ABSOLUTE_PATH_INFO)
339: {
340: path = strcpy(pathbuf, path);
341: strcat(path, ROOTPROJECT);
342: }
343: else {
344: alias = strcpy(aliasbuf, alias);
345: strcat(alias, ROOTPROJECT);
346: }
347:
348: switch (INFORMATION)
349: {
350: case REGULAR_INFO:
351: kp = slsappend(alias, "", pdlist);
352: break;
353: case ABSOLUTE_PATH_INFO:
354: kp = slsappend(path, "", pdlist);
355: break;
356: case ALIAS_INFO:
357: kp = slsappend(alias, path, pdlist);
358: break;
359: case TYPE_LABEL_INFO:
360: if (pd->p_mode == P_IFPDIR)
361: {
362: kp=slsappend(alias, pd->p_type, pdlist);
363: }
364: else {
365: status |= getptype(typebuf, path);
366: kp=slsappend(alias, typebuf, pdlist);
367: }
368: break;
369: case DESCRIPTION_INFO:
370: if (pd->p_mode == P_IFPDIR)
371: {
372: kp=slsappend(alias, pd->p_desc, pdlist);
373: }
374: else {
375: status |= getpdesc(descbuf, path);
376: kp=slsappend(alias, descbuf, pdlist);
377: }
378: break;
379: }
380: if (kp == NULL)
381: exit(1);
382: }
383: status |= closepdb(pldp);
384:
385: /* sort and print project directories */
386: if (slssort(strcmp, pdlist) == NO)
387: exit(1);
388: printlist(ppathname, pdlist);
389: slsrm(CNULL, pdlist);
390:
391: /* if RECURSIVE, list subprojects */
392: if (RECURSIVE)
393: {
394: if (slssort(strcmp, plist) == NO)
395: exit(1);
396: for (pblk = plist->head; pblk != NULL; pblk = pblk->next)
397: {
398: ppathcat(ppathbuf, ppathname, pblk->key);
399: status |= listproject(ppathbuf, pblk->string);
400: }
401: }
402: slsrm(CNULL, plist);
403:
404: return(status);
405: }
406:
407:
408:
409: /*
410: * pdtolist() adds project (root) directories to pdlist. Returns
411: * constant 1 if error, otherwise 0.
412: */
413: pdtolist(ppathname, pb, pdlist)
414: char *ppathname; /* project pathname */
415: PATH *pb; /* pathname struct buffer */
416: SLSLIST *pdlist; /* project directory list */
417: {
418: char *kp; /* key pointer */
419: char *slsappend(); /* append key+string */
420: char *strcat(); /* string concatenation */
421: int status = 0; /* return status */
422: unsigned long pathtyp; /* type of pathname */
423:
424: pathtyp = pb->p_mode & P_IFMT;
425:
426: if (MARK_PROJECT_ROOT)
427: if (pathtyp == P_IFHOME || pathtyp == P_IFPROOT)
428: if (INFORMATION == ABSOLUTE_PATH_INFO)
429: strcat(pb->p_path, ROOTPROJECT);
430: else
431: strcat(ppathname, ROOTPROJECT);
432: switch (INFORMATION)
433: {
434: case REGULAR_INFO:
435: kp = slsappend(ppathname, "", pdlist);
436: break;
437: case ABSOLUTE_PATH_INFO:
438: kp = slsappend(pb->p_path, "", pdlist);
439: break;
440: case ALIAS_INFO:
441: kp = slsappend(ppathname, pb->p_path, pdlist);
442: break;
443: case TYPE_LABEL_INFO:
444: kp = slsappend(ppathname, pb->p_type, pdlist);
445: break;
446: case DESCRIPTION_INFO:
447: kp = slsappend(ppathname, pb->p_desc, pdlist);
448: break;
449: }
450: if (kp == NULL)
451: exit(1);
452: return(status);
453: }
454:
455:
456:
457: /*
458: * printlist() prints out a list of project directories.
459: */
460: void
461: printlist(ppathname, pdlist)
462: char *ppathname; /* project pathname */
463: SLSLIST *pdlist; /* project directory list */
464: {
465: static int have_printed; /* has printing already been done? */
466: int colwidth; /* maximum column width */
467: int ncol; /* number of columns */
468: void ksprint(); /* print list of key+string pairs */
469: void slsprint(); /* print key+string list (key only) */
470:
471: colwidth = pdlist->maxkey + MINIMUM_GAP;
472: if (colwidth % TABSIZE) colwidth = TABSIZE * (colwidth/TABSIZE + 1);
473:
474: if (*ppathname != '\0' && PRINT_HEADING == YES)
475: printf((have_printed) ? "\n%s:\n" : "%s:\n", ppathname);
476:
477: if (INFORMATION == REGULAR_INFO || INFORMATION == ABSOLUTE_PATH_INFO)
478: if (ONE_ENTRY_PER_LINE)
479: slsprint(1, colwidth, YES, stdout, pdlist);
480: else {
481: ncol = MAXLINE / colwidth;
482: slsprint(ncol, colwidth, YES, stdout, pdlist);
483: }
484: else
485: ksprint(colwidth, pdlist);
486:
487: if (SLSNUM(pdlist) > 0)
488: have_printed = 1;
489: }
490:
491:
492:
493: /*
494: * strpcmp() compares strings stored in a pointer array. Returns whatever
495: * strcmp() returns.
496: */
497: strpcmp(p1, p2)
498: char **p1, **p2; /* string pointers */
499: {
500: int strcmp(); /* string comparison */
501:
502: return(strcmp(*p1, *p2));
503: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.