|
|
1.1 root 1: # include <stdio.h>
2: # include <ingres.h>
3: # include <aux.h>
4: # include <lock.h>
5: # include <pv.h>
6: # include <sccs.h>
7: # include <opsys.h>
8: # include <sys/dir.h>
9:
10: SCCSID(@(#)purge.c 8.3 1/31/86)
11:
12: /*
13: ** PURGE DATABASE
14: **
15: ** This stand-alone routine cleans up a database. This includes:
16: **
17: ** - Destroy temporary relations, i.e., relations with names
18: ** beginning with "_SYS".
19: ** - Destroy expired relations
20: ** - Clean out junk files, such as core, etc.
21: ** - As a suggested future expansion, reformat relations which
22: ** have many overflow pages, or heaps with lots of old
23: ** deleted tuples, etc.
24: **
25: ** It may be called by the ingres superuser or by the dba of
26: ** a database. There are two modes. The first is where databases
27: ** to be purged are explicitly named. If none are named, then
28: ** all databases owned by the particular user (or all databases
29: ** if the INGRES superuser) are purged.
30: **
31: ** Flags:
32: ** -p enable the purge feature, i.e., clean out expired
33: ** relations as well as temporary relations.
34: ** -s attempt to run in superuser mode. The user must be
35: ** login "ingres" for this to succeed.
36: ** -a ask the user before each database.
37: ** -f clean out rather than report junk files.
38: **
39: ** (8/2/82 peter@lbl-unix)
40: ** allow dba to destroy user relations by suitable manipulation
41: ** of Usercode
42: ** added ExitFn = nullfn() to avoid untimely aborts on syserrs.
43: ** (5/13/83 peter@lbl-csam)
44: ** folded in new directory rootines for 4.1c-bsd
45: */
46:
47:
48: char All;
49: char Superuser;
50: char Ask;
51: char Purge;
52: char Clean;
53: extern int Wait_action;
54: extern int Status;
55: extern char *Usercode;
56: long Today;
57: short tTdbu[100];
58: extern int (*ExitFn)();
59:
60: main(argc, argv)
61: int argc;
62: char *argv[];
63: {
64: register char *db;
65: register int i;
66: char fake[256];
67: extern char *getnxtdb();
68: extern int null_fn();
69:
70: argv[argc] = NULL;
71: # ifdef xTTR1
72: tTrace(argv, 'T', tTdbu, 100);
73: # endif
74:
75: /* set up arguments and operating modes */
76: initialize(argc, argv);
77: time(&Today);
78: # ifdef xTTR2
79: tTfp(10, 2, "Usercode: %.2s\n", Usercode);
80: # endif
81:
82: /* Assign ExitFn so syserr (e.g. from destroy) does not cause aborts */
83: ExitFn = null_fn;
84:
85: while (db = getnxtdb())
86: {
87: purgedb(db);
88: }
89: printf("\npurge completed\n");
90: }
91:
92:
93: rubproc()
94: {
95: unldb();
96: exit(-1);
97: }
98:
99:
100:
101: /*
102: ** PURGE DATABASE
103: **
104: ** The database is purged of temporaries, expired relations, and
105: ** junk.
106: */
107:
108: extern DESC Reldes;
109: DESC Btreesec;
110: int Btree_fd;
111: char *Fileset;
112:
113: #ifndef rewinddir
114: typedef DIR FILE;
115: #endif
116: extern DIR *opendir();
117: extern struct direct *readdir();
118:
119:
120: purgedb(db)
121: register char *db;
122: {
123: struct relation rel, key;
124: TID rtid, rlimtid;
125: register int i;
126: register char c;
127: long l;
128: DIR *dirp;
129: struct direct *dp;
130: int darg[3];
131: PARM pv[2];
132: char pbuff[MAXNAME + 1];
133: char *fname;
134: #ifndef rewinddir
135: char fnambuf[DIRSIZ + 1];
136: #endif
137:
138: # ifdef xTTR2
139: tTfp(11, 0, "entered purgedb(%s)\n", db);
140: # endif
141: printf("Database %s", db);
142: if (!ask("? "))
143: return;
144: if (!Ask)
145: printf(":\n");
146: acc_init();
147:
148: /* set exclusive lock on data base */
149: # ifdef xTTR2
150: tTfp(11, 1, "calling db_lock(%d)\n", M_EXCL);
151: # endif
152: db_lock(M_EXCL);
153:
154: /* open the relation relation for read-write */
155: opencatalog("relation", OR_WRITE);
156:
157: if (find(&Reldes, NOKEY, &rtid, &rlimtid))
158: {
159: printf("\tcannot find in %s\n", db);
160: closecatalog(TRUE); /* really close cache */
161: unldb(); /* unlock the database */
162: acc_close();
163: return;
164: }
165:
166: while (get(&Reldes, &rtid, &rlimtid, &rel, 1) == 0)
167: {
168: i = 0;
169:
170: /* check for temp rel */
171: if (bequal(rel.relid, "_SYS", 4))
172: {
173: printf("\t%.14s: temporary", rel.relid);
174: i++;
175: }
176: else if (rel.relsave < Today && rel.relsave != 0)
177: {
178: printf("\t%.14s: expired", rel.relid);
179: if (Purge)
180: if (ask("\n\t\tPURGE? "))
181: i++;
182: }
183: else
184: i = -1;
185:
186: /* if this relation should be purged -- call (local) destroy */
187: if (i > 0)
188: {
189: char *usave;
190: printf("\tpurging\n");
191:
192: /* allow DBA to purge other users relations */
193: usave = 0;
194: if (!bequal(rel.relowner, Usercode, 2)) {
195: usave = Usercode;
196: Usercode = rel.relowner;
197: }
198:
199: /* set up parameter vector for destroy */
200: bmove(rel.relid, pbuff, MAXNAME);
201: pbuff[MAXNAME] = '\0';
202: pv[0].pv_type = PV_STR;
203: pv[0].pv_val.pv_str = pbuff;
204: pv[1].pv_type = PV_EOF;
205: pv[1].pv_val.pv_str = NULL;
206: if (destroy(1, pv) != 0)
207: syserr("cannot destroy %s\n", pbuff);
208: if (usave)
209: Usercode = usave;
210: closecatalog(FALSE); /* to flush */
211: }
212: else if (i == 0)
213: printf("\t\t(not purged)\n");
214: }
215:
216: /* open the directory to check for extra files */
217: if ((dirp = opendir(".")) == NULL)
218: {
219: printf("\tcannot open .\n");
220: closecatalog(TRUE); /* really */
221: unldb(); /* unlock the database */
222: acc_close();
223: return;
224: }
225:
226: /* scan the directory */
227: for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
228:
229: #ifdef rewinddir
230: fname = dp->d_name;
231: if (dp->d_namlen <= 2)
232: continue;
233: #else rewinddir
234: strncpy(fnambuf, dp->d_name, DIRSIZ);
235: fnambuf[DIRSIZ] = '\0';
236: fname = fnambuf;
237: if (!strcmp(fname, ".") || !strcmp(fname, ".."))
238: continue;
239: #endif rewinddir
240:
241: /* throw out legitimate files */
242: if (sequal(fname, "admin"))
243: continue;
244:
245: /* always purge _SYS files */
246: if (!bequal(fname, "_SYS", 4))
247: {
248: if (fname[13] != 0)
249: {
250: /* it might be a relation */
251: clearkeys(&Reldes);
252: setkey(&Reldes, &key, fname, RELID);
253: setkey(&Reldes, &key, &fname[MAXNAME], RELOWNER);
254: if (getequal(&Reldes, &key, &rel, &rtid) <= 0)
255: {
256: /* it is a relation (or should be saved) */
257: continue;
258: }
259: }
260:
261: /* it is a funny file!!! */
262: if (!Clean)
263: {
264: printf("\t%s: file (not unlinked)\n", fname);
265: continue;
266: }
267: }
268:
269: /* purge the file */
270: printf("\tunlinking %s\n", fname);
271: if (unlink(fname))
272: printf("\tcannot unlink\n");
273: }
274: closecatalog(TRUE); /* close catalogs */
275: unldb(); /* unlock the database */
276: acc_close();
277: closedir(dirp);
278: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.