Annotation of 43BSD/contrib/spms/src/bin/pmkdir/pmkdir.c, revision 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.