|
|
BSD 4.3
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSD/contrib/spms/src/bin/pmkdir/pmkdir.c,v 1.1.1.1 2018/04/24 16:12:55 root Exp $";
/*
* pmkdir - make a project directory
*
* Author: Peter J. Nicklin
*/
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "getarg.h"
#include "macro.h"
#include "null.h"
#include "path.h"
#include "pdb.h"
#include "pld.h"
#include "slist.h"
#include "system.h"
#include "yesno.h"
char CWD[PATHSIZE]; /* current working directory */
char *CWP; /* current working project */
char *PGN = "pmkdir"; /* program name */
int WANT_TO_EXIT = 0; /* advisory exit flag */
main(argc, argv)
int argc;
char **argv;
{
extern int PPDEBUG; /* project pathname debug flag */
char *alias = NULL; /* alternative project directory name */
char *getcwp(); /* get current working project */
char *getwd(); /* get current working directory */
int addtyp(); /* make project directory type labels */
int chalias(); /* change project directory alias */
int chdesc(); /* change project directory descrip */
int isfg(); /* is process in foreground? */
int minusdflag = YES; /* project directory description flag */
int mkpdir(); /* make a project directory */
int mustexist = 0; /* existing directories flag */
int onintr(); /* process signals */
int plusdflag = NO; /* project directory description flag */
int status = 0; /* exit status */
int typargtolist(); /* type labels -> pdirtyp list */
int xppath(); /* expand project pathname */
PATH pathbuf; /* pathname struct buffer */
SLIST *pdirtyp; /* project directory type labels list */
SLIST *slinit(); /* initialize singly-linked list */
pdirtyp = slinit();
{
register char *s; /* option pointer */
while (--argc > 0 && (**++argv == '-' || **argv == '+'))
{
if (**argv == '-')
{
for (s = argv[0]+1; *s != '\0'; s++)
switch (*s)
{
case 'D':
PPDEBUG = YES;
break;
case 'N':
alias = GETARG(s);
if (*alias == '\0')
status = 1;
goto endif;
case 'T':
if (typargtolist(GETARG(s),pdirtyp)==NO)
status = 1;
else if (*s == '\0')
status = 1;
goto endif;
case 'd':
minusdflag = NO;
break;
default:
warn("bad option -%c", *s);
status = 1;
goto endif;
}
}
else {
mustexist = 1;
for (s = argv[0]+1; *s != '\0'; s++)
switch (*s)
{
case 'N':
alias = GETARG(s);
if (*alias == '\0')
status = 1;
goto endif;
case 'T':
if (typargtolist(GETARG(s),pdirtyp)==NO)
status = 1;
else if (*s == '\0')
status = 1;
goto endif;
case 'd':
plusdflag = YES;
break;
default:
warn("bad option +%c", *s);
status = 1;
goto endif;
}
}
endif: continue;
}
if (status == 1 || argc < 1)
fatal("usage: pmkdir [{+-}d] [{+-}N alias] %s",
"[{+-}T type[,type...]]\n pdirname ...");
}
if ((CWP = getcwp()) == NULL)
fatal("no project environment");
if (getwd(CWD) == NULL)
fatal("can't find current working directory");
if (isfg() == YES)
{
signal(SIGINT, onintr);
signal(SIGQUIT, onintr);
signal(SIGHUP, onintr);
}
for (; argc > 0; ++argv, --argc)
{
if (xppath(*argv, &pathbuf) == -1)
{
patherr(*argv);
status = 1;
continue;
}
if (mustexist)
switch (pathbuf.p_mode & P_IFMT)
{
case P_IFPDIR:
if (SLNUM(pdirtyp) > 0)
status |= addtyp(*argv, pdirtyp,
&pathbuf);
if (plusdflag == YES)
status |= chdesc(*argv, &pathbuf);
if (alias != NULL)
status |= chalias(*argv, alias,
&pathbuf);
break;
case P_IFNEW:
case P_IFREG:
warn("%s: no such project directory", *argv);
status = 1;
break;
case P_IFHOME:
case P_IFPROOT:
warn("%s is a project root directory", *argv);
status = 1;
break;
}
else
status |= mkpdir(*argv, alias, pdirtyp, minusdflag, &pathbuf);
if (WANT_TO_EXIT)
exit(1);
}
exit(status);
}
/*
* addtyp() adds type labels to an existing project directory.
*/
addtyp(ppathname, pdirtyp, pb)
char *ppathname; /* project directory pathname */
SLIST *pdirtyp; /* project directory type labels list */
PATH *pb; /* pathname struct buffer */
{
char *pbfndkey(); /* find key */
int closepdb(); /* close database */
int errpdb(); /* print database error */
int pgetent(); /* load next entry into buffer */
int pputent(); /* write buffer to database */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
void pbaddtyp(); /* add type labels to buffer */
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while (pgetent(pldp) != EOF)
{
if (pbfndkey(pb->p_alias) != NULL)
pbaddtyp(ppathname, pdirtyp);
pputent(pldp);
}
return(closepdb(pldp));
}
/*
* badtyp() prints a bad format type label message.
*/
void
badtyp(type)
char *type; /* type label */
{
warn("\"%s\" type label is badly formatted", type);
}
/*
* chalias() changes an existing project directory alias.
*/
chalias(ppathname, newalias, pb)
char *ppathname; /* project directory pathname */
char *newalias; /* new project directory alias */
PATH *pb; /* pathname struct buffer */
{
char *pbfndkey(); /* find key */
int _closepdb(); /* close database without updating */
int closepdb(); /* close database */
int errpdb(); /* print database error */
int pbchgkey(); /* change existing key */
int pgetent(); /* load next entry into buffer */
int pputent(); /* write buffer to database */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while (pgetent(pldp) != EOF)
{
if (pbfndkey(newalias) != NULL)
{
warn("%s: %s exists", ppathname, newalias);
_closepdb(pldp);
return(1);
}
pbchgkey(pb->p_alias, newalias);
pputent(pldp);
}
return(closepdb(pldp));
}
/*
* chdesc() changes an existing project directory description.
*/
chdesc(ppathname, pb)
char *ppathname; /* project directory pathname */
PATH *pb; /* pathname struct buffer */
{
char *pbfndkey(); /* find key */
int closepdb(); /* close database */
int errpdb(); /* print database error */
int pgetent(); /* load next entry into buffer */
int pputent(); /* write buffer to database */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
void pbadddesc(); /* add project directory description */
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while (pgetent(pldp) != EOF)
{
if (pbfndkey(pb->p_alias) != NULL)
pbadddesc(ppathname);
pputent(pldp);
}
return(closepdb(pldp));
}
/*
* mkpdir() makes a project directory.
*/
mkpdir(ppathname, alias, pdirtyp, dflag, pb)
char *ppathname; /* project directory pathname */
char *alias; /* alternative project directory name */
int dflag; /* project directory description flag */
SLIST *pdirtyp; /* project directory type labels list */
PATH *pb; /* pathname struct buffer */
{
char apathname[PATHSIZE]; /* absolute regular pathname */
char *mkalias(); /* construct alias from pathname */
char *optpath(); /* optimize pathname */
char *pathcat(); /* pathname concatenation */
char *pbfndkey(); /* find database key */
char *rdp; /* relative project directory path */
char rpathname[PATHSIZE]; /* project root directory pathname */
char *strcpy(); /* string copy */
char *xorpath(); /* remove subpathname */
int _closepdb(); /* close database without updating */
int closepdb(); /* close database */
int errpdb(); /* print database error message */
int pbaddkey(); /* add key */
int pbaddstring(); /* add string field */
int pgetent(); /* load next entry into buffer */
int pputent(); /* write buffer to database */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
void pbadddesc(); /* add project directory description */
void pbaddtyp(); /* add type labels to buffer */
void pbclear(); /* clear buffer */
switch (pb->p_mode & P_IFMT)
{
case P_IFNEW:
case P_IFREG:
break;
case P_IFPDIR:
case P_IFHOME:
case P_IFPROOT:
warn("%s exists", ppathname);
return(1);
}
/* create pathname relative to project root directory */
strcpy(rpathname, pb->p_project);
if (*pb->p_path == _RDIRC)
{
rdp = xorpath(rpathname, pb->p_path);
}
else {
optpath(pathcat(apathname, CWD, pb->p_path));
rdp = xorpath(rpathname, apathname);
}
/* open project link directory */
if ((pldp = openpdb(PLDNAME, rpathname, "rw")) == NULL)
return(errpdb((PDB *) NULL));
/*
* check for existing aliases while preparing project link
* directory for new entry.
*/
if (alias == NULL)
if (EQUAL(pb->p_alias, CURDIR) || EQUAL(pb->p_alias, PARENTDIR))
alias = mkalias(rdp);
else
alias = pb->p_alias;
while (pgetent(pldp) != EOF)
{
if (pbfndkey(alias) != NULL)
{
warn("%s: %s exists", ppathname, alias);
_closepdb(pldp);
return(1);
}
pputent(pldp);
}
/* make the directory if non-existent */
if ((pb->p_mode & P_IFMT) == P_IFREG)
{
if ((pb->p_mode & S_IFMT) != S_IFDIR)
{
warn("%s: not a directory", ppathname);
_closepdb(pldp);
return(1);
}
}
else if (MK_DIR(pb->p_path) != 0)
{
_closepdb(pldp);
return(1);
}
/* update database */
pbclear();
pbaddkey(alias);
pbaddstring(PDIRPATH, rdp);
pbaddtyp(ppathname, pdirtyp);
if (dflag == YES)
pbadddesc(ppathname);
else
pbaddstring(PDIRDESC, "");
pputent(pldp);
return(closepdb(pldp));
}
/*
* onintr() resets interrupt, quit, and hangup signals, and sets a flag
* which advises the process to exit at the first opportunity.
*/
onintr()
{
signal(SIGINT, onintr);
signal(SIGQUIT, onintr);
signal(SIGHUP, onintr);
WANT_TO_EXIT = 1;
}
/*
* pbadddesc() fetchs a project directory description from stdin and
* adds to database buffer.
*/
void
pbadddesc(ppathname)
char *ppathname; /* project directory pathname */
{
char dirdesc[DIRDESCSIZE]; /* project directory description */
char *gets(); /* get a line from stdin */
int pbaddstring(); /* add string field */
printf("%s: description? (1 line): ", ppathname);
gets(dirdesc);
pbaddstring(PDIRDESC, dirdesc);
}
/*
* pbaddtyp() adds type labels to database buffer.
*/
void
pbaddtyp(ppathname, typlist)
char *ppathname; /* project pathname */
SLIST *typlist; /* type labels list */
{
char *pbgetstring(); /* get specified string field */
char *pdtfind(); /* find type label in buffer */
char *pfxcpy(); /* copy string prefix */
char *slget(); /* get next key from list */
char *tp; /* pointer to type label */
char type[TYPESIZE]; /* type label buffer */
char typbuf[TYPBUFSIZE]; /* project directory types buffer */
int pbaddstring(); /* add string field */
void pdtinsert(); /* insert type label */
void slrewind(); /* rewind list */
pbgetstring(PDIRTYPE, typbuf);
slrewind(typlist);
while ((tp = slget(typlist)) != NULL)
{
if (pdtfind(pfxcpy(type, tp), typbuf) == NULL)
pdtinsert(tp, typbuf);
else
warn("%s: \"%s\" type label exists", ppathname, type);
}
pbaddstring(PDIRTYPE, typbuf);
}
/*
* typargtolist() prepends comma-separated type labels specified in typarg
* to typlist. Returns NO if type labels are badly formatted, otherwise
* YES.
*/
typargtolist(typarg, typlist)
register char *typarg; /* type labels argument */
SLIST *typlist; /* type labels list */
{
register char *t; /* type label argument pointer */
char *slprepend(); /* prepend singly-linked list key */
int ispdt(); /* is project dir type label legal? */
int status = YES; /* return status */
void badtyp(); /* print bad type label message */
for (t = typarg; *t != '\0'; t++)
continue;
for (; t >= typarg; t--)
if (t[0] == ',')
{
if (t[1] != '\0')
if (ispdt(t+1))
slprepend(t+1, typlist);
else {
badtyp(t+1);
status = NO;
}
t[0] = '\0';
}
if (ispdt(typarg))
slprepend(typarg, typlist);
else {
badtyp(typarg);
status = NO;
}
return(status);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.