1: static char *rcsid = "$Header";
   2: /*
   3:  * mkproject - make a project root directory
   4:  *
   5:  * Author: Peter J. Nicklin
   6:  */
   7: #include <signal.h>
   8: #include <stdio.h>
   9: #include <sys/types.h>
  10: #include <sys/stat.h>
  11: #include "getarg.h"
  12: #include "macro.h"
  13: #include "null.h"
  14: #include "path.h"
  15: #include "pdb.h"
  16: #include "pld.h"
  17: #include "slist.h"
  18: #include "spms.h"
  19: #include "system.h"
  20: #include "yesno.h"
  21: 
  22: char CWD[PATHSIZE];         /* current working directory */
  23: char *CWP;              /* current working project */
  24: char *PGN = "mkproject";        /* program name */
  25: int WANT_TO_EXIT = 0;           /* advisory exit flag */
  26: 
  27: main(argc, argv)
  28:     int argc;
  29:     char **argv;
  30: {
  31:     extern int PPDEBUG;     /* project pathname debug flag */
  32:     char *alias = NULL;     /* alternative project directory name */
  33:     char *getcwp();         /* get current working project */
  34:     char *getwd();          /* get current working directory */
  35:     int addtyp();           /* make project directory type labels */
  36:     int chalias();          /* change project directory alias */
  37:     int chdesc();           /* change project directory descrip */
  38:     int isfg();         /* is process in foreground? */
  39:     int minusdflag = YES;       /* project directory description flag */
  40:     int mkproject();        /* make a project root directory */
  41:     int mustexist = 0;      /* existing directories flag */
  42:     int plusdflag = NO;     /* project directory description flag */
  43:     int typargtolist();     /* type labels -> pdirtyp list */
  44:     int xppath();           /* expand project pathname */
  45:     PATH pathbuf;           /* pathname struct buffer */
  46:     SLIST *pdirtyp;         /* project directory type labels list */
  47:     SLIST *slinit();        /* initialize singly-linked list */
  48:     int onintr();           /* process signals */
  49:     int status = 0;         /* exit status */
  50: 
  51:     pdirtyp = slinit();
  52:     {
  53:     register char *s;       /* option pointer */
  54:     while (--argc > 0 && (**++argv == '-' || **argv == '+'))
  55:         {
  56:         if (**argv == '-')
  57:             {
  58:             for (s = argv[0]+1; *s != '\0'; s++)
  59:                 switch (*s)
  60:                     {
  61:                     case 'D':
  62:                         PPDEBUG = YES;
  63:                         break;
  64:                     case 'N':
  65:                         alias = GETARG(s);
  66:                         if (*alias == '\0')
  67:                             status = 1;
  68:                         goto endif;
  69:                     case 'T':
  70:                         if (typargtolist(GETARG(s),pdirtyp)==NO)
  71:                             status = 1;
  72:                         else if (*s == '\0')
  73:                             status = 1;
  74:                         goto endif;
  75:                     case 'd':
  76:                         minusdflag = NO;
  77:                         break;
  78:                     default:
  79:                         warn("bad option -%c", *s);
  80:                         status = 1;
  81:                         goto endif;
  82:                     }
  83:             }
  84:         else    {
  85:             mustexist = 1;
  86:             for (s = argv[0]+1; *s != '\0'; s++)
  87:                 switch (*s)
  88:                     {
  89:                     case 'N':
  90:                         alias = GETARG(s);
  91:                         if (*alias == '\0')
  92:                             status = 1;
  93:                         goto endif;
  94:                     case 'T':
  95:                         if (typargtolist(GETARG(s),pdirtyp)==NO)
  96:                             status = 1;
  97:                         else if (*s == '\0')
  98:                             status = 1;
  99:                         goto endif;
 100:                     case 'd':
 101:                         plusdflag = YES;
 102:                         break;
 103:                     default:
 104:                         warn("bad option +%c", *s);
 105:                         status = 1;
 106:                         goto endif;
 107:                     }
 108:             }
 109:         endif: continue;
 110:         }
 111:     if (status == 1 || argc < 1)
 112:         fatal("usage: mkproject [{+-}d] [{+-}N alias] %s",
 113:               "[{+-}T type[,type...]]\n           projectname ...");
 114:     }
 115: 
 116:     if (getwd(CWD) == NULL)
 117:         fatal("can't find current working directory");
 118:     CWP = getcwp();
 119:     if (isfg() == YES)
 120:         {
 121:         signal(SIGINT, onintr);
 122:         signal(SIGQUIT, onintr);
 123:         signal(SIGHUP, onintr);
 124:         }
 125: 
 126:     for (; argc > 0; argv++, argc--)
 127:         {
 128:         if (xppath(*argv, &pathbuf) == -1)
 129:             {
 130:             patherr(*argv);
 131:             status = 1;
 132:             continue;
 133:             }
 134:         if (CWP == NULL && (pathbuf.p_mode&P_IFMT) != P_IFHOME)
 135:             fatal("no project environment");
 136:         if (mustexist)
 137:             switch (pathbuf.p_mode & P_IFMT)
 138:                 {
 139:                 case P_IFHOME:
 140:                 case P_IFPROOT:
 141:                     if (SLNUM(pdirtyp) > 0)
 142:                         status |= addtyp(*argv, pdirtyp,
 143:                               &pathbuf);
 144:                     if (plusdflag == YES)
 145:                         status |= chdesc(*argv, &pathbuf);
 146:                     if (alias != NULL)
 147:                         status |= chalias(*argv, alias,
 148:                                &pathbuf);
 149:                     break;
 150:                 case P_IFPDIR:
 151:                     warn("%s is a project directory", *argv);
 152:                     status = 1;
 153:                     break;
 154:                 case P_IFNEW:
 155:                 case P_IFREG:
 156:                     warn("%s: no such project", *argv);
 157:                     status = 1;
 158:                     break;
 159:                 }
 160:         else    {
 161:             status |= mkproject(*argv, alias, pdirtyp, minusdflag, &pathbuf);
 162:             }
 163:         if (WANT_TO_EXIT)
 164:             exit(1);
 165:         }
 166:     exit(status);
 167: }
 168: 
 169: 
 170: 
 171: /*
 172:  * addtyp() adds type labels to an existing project directory.
 173:  */
 174: addtyp(ppathname, pdirtyp, pb)
 175:     char *ppathname;        /* project directory pathname */
 176:     SLIST *pdirtyp;         /* project directory type labels list */
 177:     PATH *pb;           /* pathname struct buffer */
 178: {
 179:     char *pbfndkey();       /* find key */
 180:     int closepdb();         /* close database */
 181:     int errpdb();           /* print database error */
 182:     int pgetent();          /* load next entry into buffer */
 183:     int pputent();          /* write buffer to database */
 184:     PDB *openpdb();         /* open database */
 185:     PDB *pldp;          /* project link directory stream */
 186:     void pbaddtyp();        /* add type labels to buffer */
 187: 
 188:     if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
 189:         return(errpdb((PDB *) NULL));
 190:     while (pgetent(pldp) != EOF)
 191:         {
 192:         if (pbfndkey(CURPROJECT) != NULL)
 193:             pbaddtyp(ppathname, pdirtyp);
 194:         pputent(pldp);
 195:         }
 196:     return(closepdb(pldp));
 197: }
 198: 
 199: 
 200: 
 201: /*
 202:  * badtyp() prints a bad format type label message.
 203:  */
 204: void
 205: badtyp(type)
 206:     char *type;         /* type label */
 207: {
 208:     warn("\"%s\" type label is badly formatted", type);
 209: }
 210: 
 211: 
 212: 
 213: /*
 214:  * chalias() changes an existing project directory alias.
 215:  */
 216: chalias(ppathname, newalias, pb)
 217:     char *ppathname;        /* project directory pathname */
 218:     char *newalias;         /* new project directory alias */
 219:     PATH *pb;           /* pathname struct buffer */
 220: {
 221:     char *pbfndkey();       /* find key */
 222:     char *ppathcat();       /* project pathname concatenation */
 223:     char pppathname[PPATHSIZE]; /* parent project pathname */
 224:     int _closepdb();        /* close database without updating */
 225:     int closepdb();         /* close database */
 226:     int errpdb();           /* print database error */
 227:     int pbchgkey();         /* change existing key */
 228:     int pgetent();          /* load next entry into buffer */
 229:     int pputent();          /* write buffer to database */
 230:     int xppath();           /* expand project pathname */
 231:     PATH ppathbuf;          /* parent pathname struct buffer */
 232:     PDB *openpdb();         /* open database */
 233:     PDB *pldp;          /* project link directory stream */
 234: 
 235:     ppathcat(pppathname, ppathname, PARENTPROJECT);
 236:     xppath(pppathname, &ppathbuf);
 237:     if ((pldp = openpdb(PLDNAME, ppathbuf.p_path, "rw")) == NULL)
 238:         return(errpdb((PDB *) NULL));
 239:     while (pgetent(pldp) != EOF)
 240:         {
 241:         if (pbfndkey(newalias) != NULL)
 242:             {
 243:             warn("%s: %s exists", ppathname, newalias);
 244:             _closepdb(pldp);
 245:             return(1);
 246:             }
 247:         pbchgkey(pb->p_alias, newalias);
 248:         pputent(pldp);
 249:         }
 250:     return(closepdb(pldp));
 251: }
 252: 
 253: 
 254: 
 255: /*
 256:  * chdesc() changes an existing project directory description.
 257:  */
 258: chdesc(ppathname, pb)
 259:     char *ppathname;        /* project directory pathname */
 260:     PATH *pb;           /* pathname struct buffer */
 261: {
 262:     char *pbfndkey();       /* find key */
 263:     int closepdb();         /* close database */
 264:     int errpdb();           /* print database error */
 265:     int pgetent();          /* load next entry into buffer */
 266:     int pputent();          /* write buffer to database */
 267:     PDB *openpdb();         /* open database */
 268:     PDB *pldp;          /* project link directory stream */
 269:     void pbadddesc();       /* add project directory description */
 270: 
 271:     if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
 272:         return(errpdb((PDB *) NULL));
 273:     while (pgetent(pldp) != EOF)
 274:         {
 275:         if (pbfndkey(CURPROJECT) != NULL)
 276:             pbadddesc(ppathname);
 277:         pputent(pldp);
 278:         }
 279:     return(closepdb(pldp));
 280: }
 281: 
 282: 
 283: 
 284: /*
 285:  * mkpld() creates a project link directory. If PLDNAME already exists,
 286:  * the database is altered accordingly.
 287:  */
 288: mkpld(pathname, ppathname, ptp, pdirtyp, dflag)
 289:     char *pathname;         /* project root directory pathname */
 290:     char *ppathname;        /* project directory pathname */
 291:     char *ptp;          /* path to parent project */
 292:     SLIST *pdirtyp;         /* project directory type labels list */
 293:     int dflag;          /* project directory description flag */
 294: {
 295:     char *pathcat();        /* pathname concatenation */
 296:     char *pbfndkey();       /* find key */
 297:     char pldpath[PATHSIZE];     /* project link directory pathname */
 298:     int closepdb();         /* close database */
 299:     int errpdb();           /* print database error message */
 300:     int pbaddflag();        /* add flag field */
 301:     int pbaddkey();         /* add key */
 302:     int pbaddstring();      /* add string field */
 303:     int pgetent();          /* load database entry into buffer */
 304:     int pputent();          /* write buffer to database */
 305:     PDB *openpdb();         /* open database */
 306:     PDB *pldp;          /* project link directory stream */
 307:     void pbclear();         /* clear buffer */
 308:     void resetpdb();        /* reset current database pointer */
 309:     void pbadddesc();       /* add project directory description */
 310:     void pbaddtyp();        /* add type labels to buffer */
 311: 
 312:     if (FILEXIST(pathcat(pldpath, pathname, PLDNAME)))
 313:         {
 314:         if ((pldp = openpdb(PLDNAME, pathname, "rw")) == NULL)
 315:             return(errpdb((PDB *) NULL));
 316:         while (pgetent(pldp) != EOF)
 317:             {
 318:             if (pbfndkey(CURPROJECT) != NULL)
 319:                 {
 320:                 pbaddtyp(ppathname, pdirtyp);
 321:                 if (dflag == YES)
 322:                     pbadddesc(ppathname);
 323:                 }
 324:             else if (pbfndkey(PARENTPROJECT) != NULL)
 325:                 pbaddstring(PDIRPATH, ptp);
 326:             pputent(pldp);
 327:             }
 328:         }
 329:     else    {
 330:         if ((pldp = openpdb(PLDNAME, pathname, "w")) == NULL)
 331:             return(errpdb((PDB *) NULL));
 332: 
 333:         /* create current project entry */
 334:         resetpdb(pldp);
 335:         pbclear();
 336:         pbaddkey(CURPROJECT);
 337:         pbaddflag(PROOTDIR);
 338:         pbaddstring(PDIRPATH, CURDIR);
 339:         pbaddtyp(ppathname, pdirtyp);
 340:         if (dflag == YES)
 341:             pbadddesc(ppathname);
 342:         else
 343:             pbaddstring(PDIRDESC, "");
 344:         pputent(pldp);
 345: 
 346:         /* create parent project entry */
 347:         pbclear();
 348:         pbaddkey(PARENTPROJECT);
 349:         pbaddflag(PROOTDIR);
 350:         pbaddstring(PDIRPATH, ptp);
 351:         pputent(pldp);
 352:         }
 353:     return(closepdb(pldp));
 354: }
 355: 
 356: 
 357: 
 358: /*
 359:  * mkproject() makes a project root directory.
 360:  */
 361: mkproject(ppathname, alias, pdirtyp, dflag, pb)
 362:     char *ppathname;        /* project root directory pathname */
 363:     char *alias;            /* alternative project directory name */
 364:     int dflag;          /* project directory description flag */
 365:     SLIST *pdirtyp;         /* project directory type labels list */
 366:     PATH *pb;           /* pathname struct buffer */
 367: {
 368:     char apathname[PATHSIZE];   /* absolute regular pathname */
 369:     char *mkalias();        /* construct alias from pathname */
 370:     char *mkptp();          /* make path to parent project */
 371:     char *optpath();        /* optimize pathname */
 372:     char *pathcat();        /* pathname concatenation */
 373:     char *pbfndkey();       /* find database key */
 374:     char *rdp;          /* relative project directory path */
 375:     char rpathname[PATHSIZE];   /* project root directory pathname */
 376:     char *strcpy();         /* string copy */
 377:     char *xorpath();        /* remove subpathname */
 378:     int _closepdb();        /* close database without updating */
 379:     int closepdb();         /* close database */
 380:     int errpdb();           /* print database error message */
 381:     int mkpld();            /* make project link directory */
 382:     int mkrootproject();        /* make root project root directory */
 383:     int pbaddflag();        /* add flag field */
 384:     int pbaddkey();         /* add key */
 385:     int pbaddstring();      /* add string field */
 386:     int pgetent();          /* load next entry into buffer */
 387:     int pputent();          /* write buffer to database */
 388:     PDB *openpdb();         /* open database */
 389:     PDB *pldp;          /* project link directory stream */
 390:     void pbadddesc();       /* add project directory description */
 391:     void pbclear();         /* clear buffer */
 392: 
 393:     switch (pb->p_mode & P_IFMT)
 394:         {
 395:         case P_IFNEW:
 396:         case P_IFREG:
 397:             break;
 398:         case P_IFHOME:
 399:             return(mkrootproject(ppathname, pdirtyp, dflag, pb));
 400:         case P_IFPDIR:
 401:         case P_IFPROOT:
 402:             warn("%s exists", ppathname);
 403:             return(1);
 404:         }
 405: 
 406:     /* create pathname relative to project root directory */
 407:     strcpy(rpathname, pb->p_project);
 408:     if (*pb->p_path == _RDIRC)
 409:         {
 410:         rdp = xorpath(rpathname, pb->p_path);
 411:         }
 412:     else    {
 413:         optpath(pathcat(apathname, CWD, pb->p_path));
 414:         rdp = xorpath(rpathname, apathname);
 415:         }
 416: 
 417:     /* open project link directory */
 418:     if ((pldp = openpdb(PLDNAME, rpathname, "rw")) == NULL)
 419:         return(errpdb((PDB *) NULL));
 420: 
 421:     /*
 422: 	 * check for existing aliases while preparing project link
 423: 	 * directory for new entry
 424: 	 */
 425:     if (alias == NULL)
 426:         if (EQUAL(pb->p_alias, CURDIR) || EQUAL(pb->p_alias, PARENTDIR))
 427:             alias = mkalias(rdp);
 428:         else
 429:             alias = pb->p_alias;
 430:     while (pgetent(pldp) != EOF)
 431:         {
 432:         if (pbfndkey(alias) != NULL)
 433:             {
 434:             warn("%s: %s exists", ppathname, alias);
 435:             _closepdb(pldp);
 436:             return(1);
 437:             }
 438:         pputent(pldp);
 439:         }
 440: 
 441:     /* make the directory if non-existent */
 442:     if ((pb->p_mode & P_IFMT) == P_IFREG)
 443:         {
 444:         if ((pb->p_mode & S_IFMT) != S_IFDIR)
 445:             {
 446:             warn("%s: not a directory", ppathname);
 447:             _closepdb(pldp);
 448:             return(1);
 449:             }
 450:         }
 451:     else if (MK_DIR(pb->p_path) != 0)
 452:         {
 453:         _closepdb(pldp);
 454:         return(1);
 455:         }
 456: 
 457:     /* update database */
 458:     pbclear();
 459:     pbaddkey(alias);
 460:     pbaddflag(PROOTDIR);
 461:     pbaddstring(PDIRPATH, rdp);
 462:     pputent(pldp);
 463:     if (mkpld(pb->p_path, ppathname, mkptp(rpathname, rdp), pdirtyp, dflag) != 0)
 464:         {
 465:         _closepdb(pldp);
 466:         return(1);
 467:         }
 468:     return(closepdb(pldp));
 469: }
 470: 
 471: 
 472: 
 473: /*
 474:  * mkptp() returns a pathname to the parent project root directory.
 475:  * It attempts to create a relative pathname if possible, otherwise
 476:  * the parent root directory pathname is used.
 477:  */
 478: char *
 479: mkptp(rpathname, rdp)
 480:     char *rpathname;        /* parent project root directory */
 481:     register char *rdp;     /* pathname to project being created */
 482: {
 483:     register char *rp;      /* parent project root directory ptr */
 484:     char *strpcpy();        /* string copy and update pointer */
 485: 
 486:     if (*rdp == _RDIRC)
 487:         return(rpathname);
 488:     for(rp = rpathname; *rdp != '\0'; rdp++)
 489:         if (*rdp == _PSC)
 490:             rp = strpcpy(strpcpy(rp, PARENTDIR), PATHSEP);
 491:     rp = strpcpy(rp, PARENTDIR);
 492:     return(rpathname);
 493: }
 494: 
 495: 
 496: 
 497: /*
 498:  * mkrootproject creates a project link directory in the user's home
 499:  * directory. Returns zero if successful, otherwise 1.
 500:  */
 501: mkrootproject(ppathname, pdirtyp, dflag, pb)
 502:     char *ppathname;        /* project pathname */
 503:     SLIST *pdirtyp;         /* project directory type labels list */
 504:     int dflag;          /* project directory description flag */
 505:     PATH *pb;           /* pathname struct buffer */
 506: {
 507:     char *pathcat();        /* pathname concatenation */
 508:     char pldpath[PATHSIZE];     /* project link directory pathname */
 509:     int mkpld();            /* make a project link directory */
 510: 
 511:     if (FILEXIST(pathcat(pldpath, pb->p_path, PLDNAME)))
 512:         {
 513:         warn("%s exists", ppathname);
 514:         return(1);
 515:         }
 516:     return(mkpld(pb->p_path, ROOTPROJECT, CURDIR, pdirtyp, dflag));
 517: }
 518: 
 519: 
 520: 
 521: /*
 522:  * onintr() resets interrupt, quit, and hangup signals, and sets a flag
 523:  * which advises the process to exit at the first opportunity.
 524:  */
 525: onintr()
 526: {
 527:     signal(SIGINT, onintr);
 528:     signal(SIGQUIT, onintr);
 529:     signal(SIGHUP, onintr);
 530: 
 531:     WANT_TO_EXIT = 1;
 532: }
 533: 
 534: 
 535: 
 536: /*
 537:  * pbadddesc() fetchs a project directory description from stdin and
 538:  * adds to database buffer.
 539:  */
 540: void
 541: pbadddesc(ppathname)
 542:     char *ppathname;        /* project directory pathname */
 543: {
 544:     char dirdesc[DIRDESCSIZE];  /* project directory description */
 545:     char *gets();           /* get a line from stdin */
 546:     int pbaddstring();      /* add string field */
 547: 
 548:     printf("%s: description? (1 line): ", ppathname);
 549:     gets(dirdesc);
 550:     pbaddstring(PDIRDESC, dirdesc);
 551: }
 552: 
 553: 
 554: 
 555: 
 556: /*
 557:  * pbaddtyp() adds type labels to database buffer.
 558:  */
 559: void
 560: pbaddtyp(ppathname, typlist)
 561:     char *ppathname;        /* project pathname */
 562:     SLIST *typlist;         /* type labels list */
 563: {
 564:     char *pbgetstring();        /* get specified string field */
 565:     char *pdtfind();        /* find type label in buffer */
 566:     char *pfxcpy();         /* copy string prefix */
 567:     char *slget();          /* get next key from list */
 568:     char *tp;           /* pointer to type label */
 569:     char type[TYPESIZE];        /* type label buffer */
 570:     char typbuf[TYPBUFSIZE];    /* project directory types buffer */
 571:     int pbaddstring();      /* add string field */
 572:     void pdtinsert();       /* insert type label */
 573:     void slrewind();        /* rewind list */
 574: 
 575:     pbgetstring(PDIRTYPE, typbuf);
 576:     slrewind(typlist);
 577:     while ((tp = slget(typlist)) != NULL)
 578:         {
 579:         if (pdtfind(pfxcpy(type, tp), typbuf) == NULL)
 580:             pdtinsert(tp, typbuf);
 581:         else
 582:             warn("%s: \"%s\" type label exists", ppathname, type);
 583:         }
 584:     pbaddstring(PDIRTYPE, typbuf);
 585: }
 586: 
 587: 
 588: 
 589: /*
 590:  * typargtolist() prepends comma-separated type labels specified in typarg
 591:  * to typlist. Returns NO if type labels are badly formatted, otherwise
 592:  * YES.
 593:  */
 594: typargtolist(typarg, typlist)
 595:     register char *typarg;      /* type labels argument */
 596:     SLIST *typlist;         /* type labels list */
 597: {
 598:     register char *t;       /* type label argument pointer */
 599:     char *slprepend();      /* prepend singly-linked list key */
 600:     int ispdt();            /* is project dir type label legal? */
 601:     int status = YES;       /* return status */
 602:     void badtyp();          /* print bad type label message */
 603: 
 604:     for (t = typarg; *t != '\0'; t++)
 605:         continue;
 606:     for (; t >= typarg; t--)
 607:         if (t[0] == ',')
 608:             {
 609:             if (t[1] != '\0')
 610:                 if (ispdt(t+1))
 611:                     slprepend(t+1, typlist);
 612:                 else    {
 613:                     badtyp(t+1);
 614:                     status = NO;
 615:                     }
 616:             t[0] = '\0';
 617:             }
 618:     if (ispdt(typarg))
 619:         slprepend(typarg, typlist);
 620:     else    {
 621:         badtyp(typarg);
 622:         status = NO;
 623:         }
 624:     return(status);
 625: }

Defined functions

addtyp defined in line 174; used 2 times
badtyp defined in line 204; used 3 times
chalias defined in line 216; used 2 times
chdesc defined in line 258; used 2 times
main defined in line 27; never used
mkpld defined in line 288; used 4 times
mkproject defined in line 361; used 2 times
mkptp defined in line 478; used 2 times
mkrootproject defined in line 501; used 2 times
onintr defined in line 525; used 7 times
pbadddesc defined in line 540; used 6 times
pbaddtyp defined in line 559; used 5 times
typargtolist defined in line 594; used 3 times

Defined variables

CWD defined in line 22; used 2 times
CWP defined in line 23; used 2 times
PGN defined in line 24; never used
WANT_TO_EXIT defined in line 25; used 2 times
rcsid defined in line 1; never used
Last modified: 1985-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1926
Valid CSS Valid XHTML 1.0 Strict