|
|
1.1 ! root 1: static char *rcsid = "$Header$"; ! 2: /* ! 3: * prmdir - remove a project directory ! 4: * ! 5: * Author: Peter J. Nicklin ! 6: */ ! 7: #include <sys/param.h> ! 8: #include <signal.h> ! 9: #include <stdio.h> ! 10: #include "getarg.h" ! 11: #include "macro.h" ! 12: #include "null.h" ! 13: #include "path.h" ! 14: #include "pdb.h" ! 15: #include "pld.h" ! 16: #include "slist.h" ! 17: #include "spms.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 *RMFLAG = ""; /* rm "-f" flag */ ! 24: char *PGN = "prmdir"; /* program name */ ! 25: int RECURSIVE = 0; /* remove project dirs recursively */ ! 26: int UNDEFINE = 0; /* remove proj dir definitions only */ ! 27: int WANT_TO_EXIT = 0; /* advisory exit flag */ ! 28: ! 29: main(argc, argv) ! 30: int argc; ! 31: char **argv; ! 32: { ! 33: extern int PPDEBUG; /* project pathname debug flag */ ! 34: char *getcwp(); /* get current working project */ ! 35: char *getwd(); /* get current working directory */ ! 36: int isfg(); /* is process in foreground? */ ! 37: int onintr(); /* process signals */ ! 38: int rmpdir(); /* remove a project directory */ ! 39: int rmtyp(); /* remove project dir type labels */ ! 40: int unpdir(); /* undefine project directory */ ! 41: int status = 0; /* exit status */ ! 42: int xppath(); /* expand project pathname */ ! 43: PATH pathbuf; /* pathname struct buffer */ ! 44: SLIST *pdirtyp; /* project directory type labels list */ ! 45: SLIST *slinit(); /* initialize singly-linked list */ ! 46: void typargtolist(); /* type labels -> pdirtyp list */ ! 47: ! 48: pdirtyp = slinit(); ! 49: { ! 50: register char *s; /* option pointer */ ! 51: while (--argc > 0 && **++argv == '-') ! 52: { ! 53: for (s = argv[0]+1; *s != '\0'; s++) ! 54: switch (*s) ! 55: { ! 56: case 'D': ! 57: PPDEBUG = YES; ! 58: break; ! 59: case 'T': ! 60: typargtolist(GETARG(s), pdirtyp); ! 61: if (*s == '\0') ! 62: status = 1; ! 63: goto endfor; ! 64: case 'f': ! 65: RMFLAG = "-f"; ! 66: break; ! 67: case 'r': ! 68: RECURSIVE++; ! 69: break; ! 70: case 'u': ! 71: UNDEFINE++; ! 72: break; ! 73: default: ! 74: warn("bad option -%c", *s); ! 75: status = 1; ! 76: goto endfor; ! 77: } ! 78: endfor: continue; ! 79: } ! 80: } ! 81: if (status == 1 || argc < 1) ! 82: fatal("usage: prmdir [-fru] [-T type[,type...]] pdirname ..."); ! 83: ! 84: if ((CWP = getcwp()) == NULL) ! 85: fatal("no project environment"); ! 86: if (getwd(CWD) == NULL) ! 87: fatal("can't find current working directory"); ! 88: if (isfg() == YES) ! 89: { ! 90: signal(SIGHUP, onintr); ! 91: signal(SIGINT, onintr); ! 92: signal(SIGQUIT, onintr); ! 93: } ! 94: ! 95: for (; argc > 0; ++argv, --argc) ! 96: { ! 97: if (xppath(*argv, &pathbuf) == -1) ! 98: { ! 99: patherr(*argv); ! 100: status = 1; ! 101: continue; ! 102: } ! 103: switch (pathbuf.p_mode & P_IFMT) ! 104: { ! 105: case P_IFPDIR: ! 106: if (SLNUM(pdirtyp) > 0) ! 107: status |= rmtyp(*argv, pdirtyp, &pathbuf); ! 108: else if (UNDEFINE) ! 109: status |= unpdir(&pathbuf); ! 110: else ! 111: status |= rmpdir(*argv, &pathbuf); ! 112: break; ! 113: case P_IFHOME: ! 114: case P_IFPROOT: ! 115: warn("%s is a project root directory", *argv); ! 116: status = 1; ! 117: break; ! 118: case P_IFNEW: ! 119: case P_IFREG: ! 120: warn("%s: no such project directory", *argv); ! 121: status = 1; ! 122: break; ! 123: } ! 124: if (WANT_TO_EXIT) ! 125: exit(1); ! 126: } ! 127: exit(status); ! 128: } ! 129: ! 130: ! 131: ! 132: /* ! 133: * onintr() resets interrupt, quit, and hangup signals, and sets a flag ! 134: * which advises the process to exit at the first opportunity. ! 135: */ ! 136: onintr() ! 137: { ! 138: signal(SIGINT, onintr); ! 139: signal(SIGQUIT, onintr); ! 140: signal(SIGHUP, onintr); ! 141: ! 142: WANT_TO_EXIT = 1; ! 143: } ! 144: ! 145: ! 146: ! 147: /* ! 148: * pbrmtyp() removes type labels from database buffer. ! 149: */ ! 150: void ! 151: pbrmtyp(ppathname, typlist) ! 152: char *ppathname; /* project pathname */ ! 153: SLIST *typlist; /* type labels list */ ! 154: { ! 155: char *pbgetstring(); /* get specified string field */ ! 156: char *pdtfind(); /* find type label in buffer */ ! 157: char *slget(); /* get next key from list */ ! 158: char *tp; /* pointer to type label */ ! 159: char typbuf[TYPBUFSIZE]; /* project directory types buffer */ ! 160: int pbaddstring(); /* add string field */ ! 161: int strlen(); /* string length */ ! 162: void slrewind(); /* rewind list */ ! 163: void pdtrm(); /* remove type label */ ! 164: ! 165: pbgetstring(PDIRTYPE, typbuf); ! 166: slrewind(typlist); ! 167: while ((tp = slget(typlist)) != NULL) ! 168: { ! 169: if (pdtfind(tp, typbuf) != NULL) ! 170: pdtrm(tp, typbuf); ! 171: else ! 172: warn("%s: \"%s\" type label not found", ppathname, tp); ! 173: } ! 174: pbaddstring(PDIRTYPE, typbuf); ! 175: } ! 176: ! 177: ! 178: ! 179: /* ! 180: * rmd() removes a project directory. rmd() returns the status of the rm ! 181: * command or 1 if the user decides not to remove a project directory. ! 182: */ ! 183: rmd(pathname) ! 184: char *pathname; /* full pathname of directory */ ! 185: { ! 186: char cmdbuf[PATHSIZE+9]; /* command buffer */ ! 187: char *sprintf(); /* print output to string */ ! 188: int status; /* return status */ ! 189: int yes(); /* is reply yes? */ ! 190: ! 191: if (RECURSIVE) ! 192: { ! 193: sprintf(cmdbuf, "rm %s -r %s", RMFLAG, pathname); ! 194: printf("%s? [yn](n): ", cmdbuf); ! 195: if (!yes()) ! 196: return(1); ! 197: status = system(cmdbuf); ! 198: status >>= NBBY; ! 199: status &= 0xff; ! 200: } ! 201: else { ! 202: status = RM_DIR(pathname); ! 203: } ! 204: return(status); ! 205: } ! 206: ! 207: ! 208: ! 209: /* ! 210: * rmpdir() removes a project directory. Returns 0 is successful, otherwise 1. ! 211: */ ! 212: rmpdir(ppathname, pb) ! 213: char *ppathname; /* project directory pathname */ ! 214: PATH *pb; /* pathname struct buffer */ ! 215: { ! 216: int _closepdb(); /* close database without updating */ ! 217: int closepdb(); /* close database */ ! 218: int errpdb(); /* print database error */ ! 219: int plen; /* length of regular pathname */ ! 220: int pputent(); /* write buffer to database */ ! 221: int status = 0; /* return status */ ! 222: int strlen(); /* string length */ ! 223: int strncmp(); /* compare n characters */ ! 224: PATH *pd; /* pathname struct pointer */ ! 225: PATH *readpld(); /* read project link directory entry */ ! 226: PDB *openpdb(); /* open database */ ! 227: PDB *pldp; /* project link directory stream */ ! 228: ! 229: plen = strlen(pb->p_path); ! 230: if (strncmp(pb->p_path, CWD, plen) == 0) ! 231: { ! 232: warn("can't remove %s from current directory", ppathname); ! 233: return(1); ! 234: } ! 235: if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL) ! 236: return(errpdb((PDB *) NULL)); ! 237: while ((pd = readpld(pldp)) != NULL) ! 238: if (EQUAL(pb->p_alias, pd->p_alias)) ! 239: continue; /* the directory itself */ ! 240: else if (strncmp(pb->p_path, pd->p_path, plen) == 0) ! 241: { /* nest project directories */ ! 242: if (pd->p_mode == P_IFPROOT) ! 243: { /* don't clobber projects */ ! 244: warn("can't remove %s because project %s exists", ! 245: ppathname, pd->p_path); ! 246: status = 1; ! 247: break; ! 248: } ! 249: } ! 250: else { ! 251: pputent(pldp); ! 252: } ! 253: if (status == 1) ! 254: _closepdb(pldp); ! 255: else { ! 256: if ((status = rmd(pb->p_path)) != 0) ! 257: _closepdb(pldp); ! 258: else ! 259: status = closepdb(pldp); ! 260: } ! 261: return(status); ! 262: } ! 263: ! 264: ! 265: ! 266: /* ! 267: * rmtyp() removes type labels from an existing project directory. ! 268: */ ! 269: rmtyp(ppathname, pdirtyp, pb) ! 270: char *ppathname; /* project directory pathname */ ! 271: SLIST *pdirtyp; /* project directory type labels list */ ! 272: PATH *pb; /* pathname struct buffer */ ! 273: { ! 274: char *pbfndkey(); /* find key */ ! 275: int closepdb(); /* close database */ ! 276: int errpdb(); /* print database error */ ! 277: int pgetent(); /* load next entry into buffer */ ! 278: int pputent(); /* write buffer to database */ ! 279: int status = 0; /* return status */ ! 280: PDB *openpdb(); /* open database */ ! 281: PDB *pldp; /* project link directory stream */ ! 282: void pbrmtyp(); /* remove type labels from buffer */ ! 283: ! 284: if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL) ! 285: return(errpdb((PDB *) NULL)); ! 286: while (pgetent(pldp) != EOF) ! 287: { ! 288: if (pbfndkey(pb->p_alias) != NULL) ! 289: pbrmtyp(ppathname, pdirtyp); ! 290: pputent(pldp); ! 291: } ! 292: status = closepdb(pldp); ! 293: return(status); ! 294: } ! 295: ! 296: ! 297: ! 298: /* ! 299: * typargtolist() prepends comma-separated type labels specified in typarg ! 300: * to typlist. ! 301: */ ! 302: void ! 303: typargtolist(typarg, typlist) ! 304: register char *typarg; /* type labels argument */ ! 305: SLIST *typlist; /* type labels list */ ! 306: { ! 307: register char *t; /* type label argument pointer */ ! 308: char *slprepend(); /* prepend singly-linked list key */ ! 309: ! 310: for (t = typarg; *t != '\0'; t++) ! 311: continue; ! 312: for (; t >= typarg; t--) ! 313: if (t[0] == ',') ! 314: { ! 315: if (t[1] != '\0') ! 316: slprepend(t+1, typlist); ! 317: t[0] = '\0'; ! 318: } ! 319: slprepend(typarg, typlist); ! 320: } ! 321: ! 322: ! 323: ! 324: /* ! 325: * unpdir() undefines a project directory. Returns 0 is successful, otherwise 1. ! 326: */ ! 327: unpdir(pb) ! 328: PATH *pb; /* pathname struct buffer */ ! 329: { ! 330: int closepdb(); /* close database */ ! 331: int errpdb(); /* print database error */ ! 332: int pputent(); /* write buffer to database */ ! 333: PATH *pd; /* pathname struct pointer */ ! 334: PATH *readpld(); /* read project link directory entry */ ! 335: PDB *openpdb(); /* open database */ ! 336: PDB *pldp; /* project link directory stream */ ! 337: ! 338: if ((pldp = openpdb(PLDNAME, pb->p_project, "rw")) == NULL) ! 339: return(errpdb((PDB *) NULL)); ! 340: while ((pd = readpld(pldp)) != NULL) ! 341: if (EQUAL(pb->p_alias, pd->p_alias)) ! 342: continue; ! 343: else ! 344: pputent(pldp); ! 345: return(closepdb(pldp)); ! 346: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.