|
|
BSD 4.3
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSD/contrib/spms/src/bin/prmdir/prmdir.c,v 1.1.1.1 2018/04/24 16:12:55 root Exp $";
/*
* prmdir - remove a project directory
*
* Author: Peter J. Nicklin
*/
#include <sys/param.h>
#include <signal.h>
#include <stdio.h>
#include "getarg.h"
#include "macro.h"
#include "null.h"
#include "path.h"
#include "pdb.h"
#include "pld.h"
#include "slist.h"
#include "spms.h"
#include "system.h"
#include "yesno.h"
char CWD[PATHSIZE]; /* current working directory */
char *CWP; /* current working project */
char *RMFLAG = ""; /* rm "-f" flag */
char *PGN = "prmdir"; /* program name */
int RECURSIVE = 0; /* remove project dirs recursively */
int UNDEFINE = 0; /* remove proj dir definitions only */
int WANT_TO_EXIT = 0; /* advisory exit flag */
main(argc, argv)
int argc;
char **argv;
{
extern int PPDEBUG; /* project pathname debug flag */
char *getcwp(); /* get current working project */
char *getwd(); /* get current working directory */
int isfg(); /* is process in foreground? */
int onintr(); /* process signals */
int rmpdir(); /* remove a project directory */
int rmtyp(); /* remove project dir type labels */
int unpdir(); /* undefine project directory */
int status = 0; /* exit status */
int xppath(); /* expand project pathname */
PATH pathbuf; /* pathname struct buffer */
SLIST *pdirtyp; /* project directory type labels list */
SLIST *slinit(); /* initialize singly-linked list */
void typargtolist(); /* type labels -> pdirtyp list */
pdirtyp = slinit();
{
register char *s; /* option pointer */
while (--argc > 0 && **++argv == '-')
{
for (s = argv[0]+1; *s != '\0'; s++)
switch (*s)
{
case 'D':
PPDEBUG = YES;
break;
case 'T':
typargtolist(GETARG(s), pdirtyp);
if (*s == '\0')
status = 1;
goto endfor;
case 'f':
RMFLAG = "-f";
break;
case 'r':
RECURSIVE++;
break;
case 'u':
UNDEFINE++;
break;
default:
warn("bad option -%c", *s);
status = 1;
goto endfor;
}
endfor: continue;
}
}
if (status == 1 || argc < 1)
fatal("usage: prmdir [-fru] [-T type[,type...]] pdirname ...");
if ((CWP = getcwp()) == NULL)
fatal("no project environment");
if (getwd(CWD) == NULL)
fatal("can't find current working directory");
if (isfg() == YES)
{
signal(SIGHUP, onintr);
signal(SIGINT, onintr);
signal(SIGQUIT, onintr);
}
for (; argc > 0; ++argv, --argc)
{
if (xppath(*argv, &pathbuf) == -1)
{
patherr(*argv);
status = 1;
continue;
}
switch (pathbuf.p_mode & P_IFMT)
{
case P_IFPDIR:
if (SLNUM(pdirtyp) > 0)
status |= rmtyp(*argv, pdirtyp, &pathbuf);
else if (UNDEFINE)
status |= unpdir(&pathbuf);
else
status |= rmpdir(*argv, &pathbuf);
break;
case P_IFHOME:
case P_IFPROOT:
warn("%s is a project root directory", *argv);
status = 1;
break;
case P_IFNEW:
case P_IFREG:
warn("%s: no such project directory", *argv);
status = 1;
break;
}
if (WANT_TO_EXIT)
exit(1);
}
exit(status);
}
/*
* 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;
}
/*
* pbrmtyp() removes type labels from database buffer.
*/
void
pbrmtyp(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 *slget(); /* get next key from list */
char *tp; /* pointer to type label */
char typbuf[TYPBUFSIZE]; /* project directory types buffer */
int pbaddstring(); /* add string field */
int strlen(); /* string length */
void slrewind(); /* rewind list */
void pdtrm(); /* remove type label */
pbgetstring(PDIRTYPE, typbuf);
slrewind(typlist);
while ((tp = slget(typlist)) != NULL)
{
if (pdtfind(tp, typbuf) != NULL)
pdtrm(tp, typbuf);
else
warn("%s: \"%s\" type label not found", ppathname, tp);
}
pbaddstring(PDIRTYPE, typbuf);
}
/*
* rmd() removes a project directory. rmd() returns the status of the rm
* command or 1 if the user decides not to remove a project directory.
*/
rmd(pathname)
char *pathname; /* full pathname of directory */
{
char cmdbuf[PATHSIZE+9]; /* command buffer */
char *sprintf(); /* print output to string */
int status; /* return status */
int yes(); /* is reply yes? */
if (RECURSIVE)
{
sprintf(cmdbuf, "rm %s -r %s", RMFLAG, pathname);
printf("%s? [yn](n): ", cmdbuf);
if (!yes())
return(1);
status = system(cmdbuf);
status >>= NBBY;
status &= 0xff;
}
else {
status = RM_DIR(pathname);
}
return(status);
}
/*
* rmpdir() removes a project directory. Returns 0 is successful, otherwise 1.
*/
rmpdir(ppathname, pb)
char *ppathname; /* project directory pathname */
PATH *pb; /* pathname struct buffer */
{
int _closepdb(); /* close database without updating */
int closepdb(); /* close database */
int errpdb(); /* print database error */
int plen; /* length of regular pathname */
int pputent(); /* write buffer to database */
int status = 0; /* return status */
int strlen(); /* string length */
int strncmp(); /* compare n characters */
PATH *pd; /* pathname struct pointer */
PATH *readpld(); /* read project link directory entry */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
plen = strlen(pb->p_path);
if (strncmp(pb->p_path, CWD, plen) == 0)
{
warn("can't remove %s from current directory", ppathname);
return(1);
}
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while ((pd = readpld(pldp)) != NULL)
if (EQUAL(pb->p_alias, pd->p_alias))
continue; /* the directory itself */
else if (strncmp(pb->p_path, pd->p_path, plen) == 0)
{ /* nest project directories */
if (pd->p_mode == P_IFPROOT)
{ /* don't clobber projects */
warn("can't remove %s because project %s exists",
ppathname, pd->p_path);
status = 1;
break;
}
}
else {
pputent(pldp);
}
if (status == 1)
_closepdb(pldp);
else {
if ((status = rmd(pb->p_path)) != 0)
_closepdb(pldp);
else
status = closepdb(pldp);
}
return(status);
}
/*
* rmtyp() removes type labels from an existing project directory.
*/
rmtyp(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 */
int status = 0; /* return status */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
void pbrmtyp(); /* remove type labels from buffer */
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while (pgetent(pldp) != EOF)
{
if (pbfndkey(pb->p_alias) != NULL)
pbrmtyp(ppathname, pdirtyp);
pputent(pldp);
}
status = closepdb(pldp);
return(status);
}
/*
* typargtolist() prepends comma-separated type labels specified in typarg
* to typlist.
*/
void
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 */
for (t = typarg; *t != '\0'; t++)
continue;
for (; t >= typarg; t--)
if (t[0] == ',')
{
if (t[1] != '\0')
slprepend(t+1, typlist);
t[0] = '\0';
}
slprepend(typarg, typlist);
}
/*
* unpdir() undefines a project directory. Returns 0 is successful, otherwise 1.
*/
unpdir(pb)
PATH *pb; /* pathname struct buffer */
{
int closepdb(); /* close database */
int errpdb(); /* print database error */
int pputent(); /* write buffer to database */
PATH *pd; /* pathname struct pointer */
PATH *readpld(); /* read project link directory entry */
PDB *openpdb(); /* open database */
PDB *pldp; /* project link directory stream */
if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL)
return(errpdb((PDB *) NULL));
while ((pd = readpld(pldp)) != NULL)
if (EQUAL(pb->p_alias, pd->p_alias))
continue;
else
pputent(pldp);
return(closepdb(pldp));
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.