BSD 4_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 26 Jun 1983 08:53:32 +0000 (00:53 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sun, 26 Jun 1983 08:53:32 +0000 (00:53 -0800)
Work on file usr/src/new/new/spms/src/bin/prmdir/prmdir.c

Synthesized-from: CSRG/cd1/4.2

usr/src/new/new/spms/src/bin/prmdir/prmdir.c [new file with mode: 0644]

diff --git a/usr/src/new/new/spms/src/bin/prmdir/prmdir.c b/usr/src/new/new/spms/src/bin/prmdir/prmdir.c
new file mode 100644 (file)
index 0000000..b8908e8
--- /dev/null
@@ -0,0 +1,346 @@
+static char *rcsid = "$Header$";
+/*
+ * 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));
+}