Annotation of 43BSD/contrib/spms/src/bin/pmkdir/pmkdir.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.