|
|
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.