1: static char *rcsid = "$Header$";
   2: /*
   3:  * pmkdir - make a project 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 "system.h"
  19: #include "yesno.h"
  20: 
  21: char CWD[PATHSIZE];         /* current working directory */
  22: char *CWP;              /* current working project */
  23: char *PGN = "pmkdir";           /* program name */
  24: int WANT_TO_EXIT = 0;           /* advisory exit flag */
  25: 
  26: main(argc, argv)
  27:     int argc;
  28:     char **argv;
  29: {
  30:     extern int PPDEBUG;     /* project pathname debug flag */
  31:     char *alias = NULL;     /* alternative project directory name */
  32:     char *getcwp();         /* get current working project */
  33:     char *getwd();          /* get current working directory */
  34:     int addtyp();           /* make project directory type labels */
  35:     int chalias();          /* change project directory alias */
  36:     int chdesc();           /* change project directory descrip */
  37:     int isfg();         /* is process in foreground? */
  38:     int minusdflag = YES;       /* project directory description flag */
  39:     int mkpdir();           /* make a project directory */
  40:     int mustexist = 0;      /* existing directories flag */
  41:     int onintr();           /* process signals */
  42:     int plusdflag = NO;     /* project directory description flag */
  43:     int status = 0;         /* exit status */
  44:     int typargtolist();     /* type labels -> pdirtyp list */
  45:     int xppath();           /* expand project pathname */
  46:     PATH pathbuf;           /* pathname struct buffer */
  47:     SLIST *pdirtyp;         /* project directory type labels list */
  48:     SLIST *slinit();        /* initialize singly-linked list */
  49: 
  50:     pdirtyp = slinit();
  51:     {
  52:     register char *s;       /* option pointer */
  53:     while (--argc > 0 && (**++argv == '-' || **argv == '+'))
  54:         {
  55:         if (**argv == '-')
  56:             {
  57:             for (s = argv[0]+1; *s != '\0'; s++)
  58:                 switch (*s)
  59:                     {
  60:                     case 'D':
  61:                         PPDEBUG = YES;
  62:                         break;
  63:                     case 'N':
  64:                         alias = GETARG(s);
  65:                         if (*alias == '\0')
  66:                             status = 1;
  67:                         goto endif;
  68:                     case 'T':
  69:                         if (typargtolist(GETARG(s),pdirtyp)==NO)
  70:                             status = 1;
  71:                         else if (*s == '\0')
  72:                             status = 1;
  73:                         goto endif;
  74:                     case 'd':
  75:                         minusdflag = NO;
  76:                         break;
  77:                     default:
  78:                         warn("bad option -%c", *s);
  79:                         status = 1;
  80:                         goto endif;
  81:                     }
  82:             }
  83:         else    {
  84:             mustexist = 1;
  85:             for (s = argv[0]+1; *s != '\0'; s++)
  86:                 switch (*s)
  87:                     {
  88:                     case 'N':
  89:                         alias = GETARG(s);
  90:                         if (*alias == '\0')
  91:                             status = 1;
  92:                         goto endif;
  93:                     case 'T':
  94:                         if (typargtolist(GETARG(s),pdirtyp)==NO)
  95:                             status = 1;
  96:                         else if (*s == '\0')
  97:                             status = 1;
  98:                         goto endif;
  99:                     case 'd':
 100:                         plusdflag = YES;
 101:                         break;
 102:                     default:
 103:                         warn("bad option +%c", *s);
 104:                         status = 1;
 105:                         goto endif;
 106:                     }
 107:             }
 108:         endif: continue;
 109:         }
 110:     if (status == 1 || argc < 1)
 111:         fatal("usage: pmkdir [{+-}d] [{+-}N alias] %s",
 112:               "[{+-}T type[,type...]]\n        pdirname ...");
 113:     }
 114: 
 115:     if ((CWP = getcwp()) == NULL)
 116:         fatal("no project environment");
 117:     if (getwd(CWD) == NULL)
 118:         fatal("can't find current working directory");
 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 (mustexist)
 135:             switch (pathbuf.p_mode & P_IFMT)
 136:                 {
 137:                 case P_IFPDIR:
 138:                     if (SLNUM(pdirtyp) > 0)
 139:                         status |= addtyp(*argv, pdirtyp,
 140:                               &pathbuf);
 141:                     if (plusdflag == YES)
 142:                         status |= chdesc(*argv, &pathbuf);
 143:                     if (alias != NULL)
 144:                         status |= chalias(*argv, alias,
 145:                               &pathbuf);
 146:                     break;
 147:                 case P_IFNEW:
 148:                 case P_IFREG:
 149:                     warn("%s: no such project directory", *argv);
 150:                     status = 1;
 151:                     break;
 152:                 case P_IFHOME:
 153:                 case P_IFPROOT:
 154:                     warn("%s is a project root directory", *argv);
 155:                     status = 1;
 156:                     break;
 157:                 }
 158:         else
 159:             status |= mkpdir(*argv, alias, pdirtyp, minusdflag, &pathbuf);
 160:         if (WANT_TO_EXIT)
 161:             exit(1);
 162:         }
 163:     exit(status);
 164: }
 165: 
 166: 
 167: 
 168: /*
 169:  * addtyp() adds type labels to an existing project directory.
 170:  */
 171: addtyp(ppathname, pdirtyp, pb)
 172:     char *ppathname;        /* project directory pathname */
 173:     SLIST *pdirtyp;         /* project directory type labels list */
 174:     PATH *pb;           /* pathname struct buffer */
 175: {
 176:     char *pbfndkey();       /* find key */
 177:     int closepdb();         /* close database */
 178:     int errpdb();           /* print database error */
 179:     int pgetent();          /* load next entry into buffer */
 180:     int pputent();          /* write buffer to database */
 181:     PDB *openpdb();         /* open database */
 182:     PDB *pldp;          /* project link directory stream */
 183:     void pbaddtyp();        /* add type labels to buffer */
 184: 
 185:     if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
 186:         return(errpdb((PDB *) NULL));
 187:     while (pgetent(pldp) != EOF)
 188:         {
 189:         if (pbfndkey(pb->p_alias) != NULL)
 190:             pbaddtyp(ppathname, pdirtyp);
 191:         pputent(pldp);
 192:         }
 193:     return(closepdb(pldp));
 194: }
 195: 
 196: 
 197: 
 198: /*
 199:  * badtyp() prints a bad format type label message.
 200:  */
 201: void
 202: badtyp(type)
 203:     char *type;         /* type label */
 204: {
 205:     warn("\"%s\" type label is badly formatted", type);
 206: }
 207: 
 208: 
 209: 
 210: /*
 211:  * chalias() changes an existing project directory alias.
 212:  */
 213: chalias(ppathname, newalias, pb)
 214:     char *ppathname;        /* project directory pathname */
 215:     char *newalias;         /* new project directory alias */
 216:     PATH *pb;           /* pathname struct buffer */
 217: {
 218:     char *pbfndkey();       /* find key */
 219:     int _closepdb();        /* close database without updating */
 220:     int closepdb();         /* close database */
 221:     int errpdb();           /* print database error */
 222:     int pbchgkey();         /* change existing key */
 223:     int pgetent();          /* load next entry into buffer */
 224:     int pputent();          /* write buffer to database */
 225:     PDB *openpdb();         /* open database */
 226:     PDB *pldp;          /* project link directory stream */
 227: 
 228:     if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
 229:         return(errpdb((PDB *) NULL));
 230:     while (pgetent(pldp) != EOF)
 231:         {
 232:         if (pbfndkey(newalias) != NULL)
 233:             {
 234:             warn("%s: %s exists", ppathname, newalias);
 235:             _closepdb(pldp);
 236:             return(1);
 237:             }
 238:         pbchgkey(pb->p_alias, newalias);
 239:         pputent(pldp);
 240:         }
 241:     return(closepdb(pldp));
 242: }
 243: 
 244: 
 245: 
 246: /*
 247:  * chdesc() changes an existing project directory description.
 248:  */
 249: chdesc(ppathname, pb)
 250:     char *ppathname;        /* project directory pathname */
 251:     PATH *pb;           /* pathname struct buffer */
 252: {
 253:     char *pbfndkey();       /* find key */
 254:     int closepdb();         /* close database */
 255:     int errpdb();           /* print database error */
 256:     int pgetent();          /* load next entry into buffer */
 257:     int pputent();          /* write buffer to database */
 258:     PDB *openpdb();         /* open database */
 259:     PDB *pldp;          /* project link directory stream */
 260:     void pbadddesc();       /* add project directory description */
 261: 
 262:     if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
 263:         return(errpdb((PDB *) NULL));
 264:     while (pgetent(pldp) != EOF)
 265:         {
 266:         if (pbfndkey(pb->p_alias) != NULL)
 267:             pbadddesc(ppathname);
 268:         pputent(pldp);
 269:         }
 270:     return(closepdb(pldp));
 271: }
 272: 
 273: 
 274: 
 275: /*
 276:  * mkpdir() makes a project directory.
 277:  */
 278: mkpdir(ppathname, alias, pdirtyp, dflag, pb)
 279:     char *ppathname;        /* project directory pathname */
 280:     char *alias;            /* alternative project directory name */
 281:     int dflag;          /* project directory description flag */
 282:     SLIST *pdirtyp;         /* project directory type labels list */
 283:     PATH *pb;           /* pathname struct buffer */
 284: {
 285:     char apathname[PATHSIZE];   /* absolute regular pathname */
 286:     char *mkalias();        /* construct alias from pathname */
 287:     char *optpath();        /* optimize pathname */
 288:     char *pathcat();        /* pathname concatenation */
 289:     char *pbfndkey();       /* find database key */
 290:     char *rdp;          /* relative project directory path */
 291:     char rpathname[PATHSIZE];   /* project root directory pathname */
 292:     char *strcpy();         /* string copy */
 293:     char *xorpath();        /* remove subpathname */
 294:     int _closepdb();        /* close database without updating */
 295:     int closepdb();         /* close database */
 296:     int errpdb();           /* print database error message */
 297:     int pbaddkey();         /* add key */
 298:     int pbaddstring();      /* add string field */
 299:     int pgetent();          /* load next entry into buffer */
 300:     int pputent();          /* write buffer to database */
 301:     PDB *openpdb();         /* open database */
 302:     PDB *pldp;          /* project link directory stream */
 303:     void pbadddesc();       /* add project directory description */
 304:     void pbaddtyp();        /* add type labels to buffer */
 305:     void pbclear();         /* clear buffer */
 306: 
 307:     switch (pb->p_mode & P_IFMT)
 308:         {
 309:         case P_IFNEW:
 310:         case P_IFREG:
 311:             break;
 312:         case P_IFPDIR:
 313:         case P_IFHOME:
 314:         case P_IFPROOT:
 315:             warn("%s exists", ppathname);
 316:             return(1);
 317:         }
 318: 
 319:     /* create pathname relative to project root directory */
 320:     strcpy(rpathname, pb->p_project);
 321:     if (*pb->p_path == _RDIRC)
 322:         {
 323:         rdp = xorpath(rpathname, pb->p_path);
 324:         }
 325:     else    {
 326:         optpath(pathcat(apathname, CWD, pb->p_path));
 327:         rdp = xorpath(rpathname, apathname);
 328:         }
 329: 
 330:     /* open project link directory */
 331:     if ((pldp = openpdb(PLDNAME, rpathname, "rw")) == NULL)
 332:         return(errpdb((PDB *) NULL));
 333: 
 334:     /*
 335: 	 * check for existing aliases while preparing project link
 336: 	 * directory for new entry.
 337: 	 */
 338:     if (alias == NULL)
 339:         if (EQUAL(pb->p_alias, CURDIR) || EQUAL(pb->p_alias, PARENTDIR))
 340:             alias = mkalias(rdp);
 341:         else
 342:             alias = pb->p_alias;
 343:     while (pgetent(pldp) != EOF)
 344:         {
 345:         if (pbfndkey(alias) != NULL)
 346:             {
 347:             warn("%s: %s exists", ppathname, alias);
 348:             _closepdb(pldp);
 349:             return(1);
 350:             }
 351:         pputent(pldp);
 352:         }
 353: 
 354:     /* make the directory if non-existent */
 355:     if ((pb->p_mode & P_IFMT) == P_IFREG)
 356:         {
 357:         if ((pb->p_mode & S_IFMT) != S_IFDIR)
 358:             {
 359:             warn("%s: not a directory", ppathname);
 360:             _closepdb(pldp);
 361:             return(1);
 362:             }
 363:         }
 364:     else if (MK_DIR(pb->p_path) != 0)
 365:         {
 366:         _closepdb(pldp);
 367:         return(1);
 368:         }
 369: 
 370:     /* update database */
 371:     pbclear();
 372:     pbaddkey(alias);
 373:     pbaddstring(PDIRPATH, rdp);
 374:     pbaddtyp(ppathname, pdirtyp);
 375:     if (dflag == YES)
 376:         pbadddesc(ppathname);
 377:     else
 378:         pbaddstring(PDIRDESC, "");
 379:     pputent(pldp);
 380:     return(closepdb(pldp));
 381: }
 382: 
 383: 
 384: 
 385: /*
 386:  * onintr() resets interrupt, quit, and hangup signals, and sets a flag
 387:  * which advises the process to exit at the first opportunity.
 388:  */
 389: onintr()
 390: {
 391:     signal(SIGINT, onintr);
 392:     signal(SIGQUIT, onintr);
 393:     signal(SIGHUP, onintr);
 394: 
 395:     WANT_TO_EXIT = 1;
 396: }
 397: 
 398: 
 399: 
 400: /*
 401:  * pbadddesc() fetchs a project directory description from stdin and
 402:  * adds to database buffer.
 403:  */
 404: void
 405: pbadddesc(ppathname)
 406:     char *ppathname;        /* project directory pathname */
 407: {
 408:     char dirdesc[DIRDESCSIZE];  /* project directory description */
 409:     char *gets();           /* get a line from stdin */
 410:     int pbaddstring();      /* add string field */
 411: 
 412:     printf("%s: description? (1 line): ", ppathname);
 413:     gets(dirdesc);
 414:     pbaddstring(PDIRDESC, dirdesc);
 415: }
 416: 
 417: 
 418: 
 419: /*
 420:  * pbaddtyp() adds type labels to database buffer.
 421:  */
 422: void
 423: pbaddtyp(ppathname, typlist)
 424:     char *ppathname;        /* project pathname */
 425:     SLIST *typlist;         /* type labels list */
 426: {
 427:     char *pbgetstring();        /* get specified string field */
 428:     char *pdtfind();        /* find type label in buffer */
 429:     char *pfxcpy();         /* copy string prefix */
 430:     char *slget();          /* get next key from list */
 431:     char *tp;           /* pointer to type label */
 432:     char type[TYPESIZE];        /* type label buffer */
 433:     char typbuf[TYPBUFSIZE];    /* project directory types buffer */
 434:     int pbaddstring();      /* add string field */
 435:     void pdtinsert();       /* insert type label */
 436:     void slrewind();        /* rewind list */
 437: 
 438:     pbgetstring(PDIRTYPE, typbuf);
 439:     slrewind(typlist);
 440:     while ((tp = slget(typlist)) != NULL)
 441:         {
 442:         if (pdtfind(pfxcpy(type, tp), typbuf) == NULL)
 443:             pdtinsert(tp, typbuf);
 444:         else
 445:             warn("%s: \"%s\" type label exists", ppathname, type);
 446:         }
 447:     pbaddstring(PDIRTYPE, typbuf);
 448: }
 449: 
 450: 
 451: 
 452: /*
 453:  * typargtolist() prepends comma-separated type labels specified in typarg
 454:  * to typlist. Returns NO if type labels are badly formatted, otherwise
 455:  * YES.
 456:  */
 457: typargtolist(typarg, typlist)
 458:     register char *typarg;      /* type labels argument */
 459:     SLIST *typlist;         /* type labels list */
 460: {
 461:     register char *t;       /* type label argument pointer */
 462:     char *slprepend();      /* prepend singly-linked list key */
 463:     int ispdt();            /* is project dir type label legal? */
 464:     int status = YES;       /* return status */
 465:     void badtyp();          /* print bad type label message */
 466: 
 467:     for (t = typarg; *t != '\0'; t++)
 468:         continue;
 469:     for (; t >= typarg; t--)
 470:         if (t[0] == ',')
 471:             {
 472:             if (t[1] != '\0')
 473:                 if (ispdt(t+1))
 474:                     slprepend(t+1, typlist);
 475:                 else    {
 476:                     badtyp(t+1);
 477:                     status = NO;
 478:                     }
 479:             t[0] = '\0';
 480:             }
 481:     if (ispdt(typarg))
 482:         slprepend(typarg, typlist);
 483:     else    {
 484:         badtyp(typarg);
 485:         status = NO;
 486:         }
 487:     return(status);
 488: }

Defined functions

addtyp defined in line 171; used 2 times
badtyp defined in line 201; used 3 times
chalias defined in line 213; used 2 times
chdesc defined in line 249; used 2 times
main defined in line 26; never used
mkpdir defined in line 278; used 2 times
onintr defined in line 389; used 7 times
pbadddesc defined in line 404; used 4 times
pbaddtyp defined in line 422; used 4 times
typargtolist defined in line 457; used 3 times

Defined variables

CWD defined in line 21; used 2 times
CWP defined in line 22; used 1 times
PGN defined in line 23; never used
WANT_TO_EXIT defined in line 24; 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: 2194
Valid CSS Valid XHTML 1.0 Strict