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