1: # include <stdio.h> 2: # include <sys/types.h> 3: # include <sys/dir.h> 4: 5: # include "../ingres.h" 6: # include "../aux.h" 7: # include "../lock.h" 8: 9: /* 10: ** PURGE DATABASE 11: ** 12: ** This stand-alone routine cleans up a database. This includes: 13: ** 14: ** - Destroy temporary relations, i.e., relations with names 15: ** beginning with "_SYS". 16: ** - Destroy expired relations 17: ** - Clean out junk files, such as core, etc. 18: ** - As a suggested future expansion, reformat relations which 19: ** have many overflow pages, or heaps with lots of old 20: ** deleted tuples, etc. 21: ** 22: ** It may be called by the ingres superuser or by the dba of 23: ** a database. There are two modes. The first is where databases 24: ** to be purged are explicitly named. If none are named, then 25: ** all databases owned by the particular user (or all databases 26: ** if the INGRES superuser) are purged. 27: ** 28: ** Flags: 29: ** -p enable the purge feature, i.e., clean out expired 30: ** relations as well as temporary relations. 31: ** -s attempt to run in superuser mode. The user must be 32: ** login "ingres" for this to succeed. 33: ** -a ask the user before each database. 34: ** -f clean out rather than report junk files. 35: ** 36: ** History: 37: */ 38: 39: 40: char All; 41: char Superuser; 42: char Ask; 43: char Purge; 44: char Clean; 45: extern int Wait_action; 46: extern int Status; 47: extern char *Usercode; 48: long Today; 49: 50: 51: 52: main(argc, argv) 53: int argc; 54: char *argv[]; 55: { 56: register char *db; 57: register int i; 58: char fake[256]; 59: char *getnxtdb(); 60: 61: # ifdef xTTR1 62: tTrace(&argc, argv, 'T'); 63: # endif 64: 65: /* set up arguments and operating modes */ 66: initialize(argc, argv); 67: time(&Today); 68: # ifdef xTTR2 69: tTfp(10, 2, "Usercode: %.2s\n", Usercode); 70: # endif 71: 72: while (db = getnxtdb()) 73: { 74: purgedb(db); 75: } 76: printf("Purge completed.\n"); 77: } 78: 79: 80: 81: rubproc() 82: { 83: unldb(); 84: exit(-1); 85: } 86: 87: 88: 89: /* 90: ** PURGE DATABASE 91: ** 92: ** The database is purged of temporaries, expired relations, and 93: ** junk. 94: */ 95: 96: extern struct descriptor Reldes; 97: 98: 99: purgedb(db1) 100: char *db1; 101: { 102: register char *db; 103: struct relation rel, key; 104: struct tup_id rtid, rlimtid; 105: register int i; 106: register char c; 107: DIR *dirp; 108: struct direct *directp; 109: int darg[3]; 110: char *pv[2]; 111: char pbuff[MAXNAME + 3]; 112: 113: db = db1; 114: # ifdef xTTR2 115: tTfp(11, 0, "entered purgedb(%s)\n", db); 116: # endif 117: printf("Database %s", db); 118: if (!ask("? ")) 119: return; 120: if (!Ask) 121: printf(":\n"); 122: acc_init(); 123: 124: /* set exclusive lock on data base */ 125: # ifdef xTTR2 126: tTfp(11, 1, "calling db_lock(%d)\n", M_EXCL); 127: # endif 128: db_lock(M_EXCL); 129: 130: /* open the relation relation for read-write */ 131: opencatalog("relation", 2); 132: 133: if (find(&Reldes, NOKEY, &rtid, &rlimtid)) 134: { 135: printf("\tcannot find in %s\n", db); 136: closecatalog(TRUE); /* really close cache */ 137: unldb(); /* unlock the database */ 138: acc_close(); 139: return; 140: } 141: 142: while (get(&Reldes, &rtid, &rlimtid, &rel, 1) == 0) 143: { 144: i = 0; 145: 146: /* check for temp rel */ 147: if (bequal(rel.relid, "_SYS", 4)) 148: i++; 149: 150: /* check for expired */ 151: if (rel.relsave < Today && rel.relsave != 0 && i == 0) 152: { 153: printf("\t%.14s: expired\n", rel.relid); 154: if (Purge) 155: if (ask("\t\tPURGE? ")) 156: i++; 157: } 158: 159: /* if this relation should be purged -- call destroy */ 160: if (i != 0) 161: { 162: printf("\tpurging %.12s\n", rel.relid); 163: 164: /* set up parameter vector for destroy */ 165: bmove(rel.relid, pbuff, MAXNAME + 2); 166: pbuff[MAXNAME + 2] = '\0'; 167: pv[0] = pbuff; 168: pv[1] = (char *) -1; 169: if (destroy(1, pv) != 0) 170: syserr("cannot destroy %s\n", pv[0]); 171: closecatalog(FALSE); /* to flush */ 172: } 173: } 174: 175: /* open the directory to check for extra files */ 176: if ((dirp = opendir(".")) == NULL) 177: { 178: printf("\tcannot open .\n"); 179: closecatalog(TRUE); /* really */ 180: unldb(); /* unlock the database */ 181: acc_close(); 182: return; 183: } 184: 185: readdir(dirp); /* skip "." */ 186: readdir(dirp); /* skip ".." */ 187: 188: /* scan the directory */ 189: while ((directp = readdir(dirp)) != NULL) { 190: 191: /* throw out legitimate files */ 192: if (sequal(directp->d_name, "admin")) 193: continue; 194: 195: /* always purge _SYS files */ 196: if (!bequal(directp->d_name, "_SYS", 4)) 197: { 198: if (directp->d_name[MAXNAME+1] != 0) 199: { 200: /* it might be a relation */ 201: clearkeys(&Reldes); 202: setkey(&Reldes, &key, directp->d_name, RELID); 203: setkey(&Reldes, &key, &directp->d_name[MAXNAME], RELOWNER); 204: if (getequal(&Reldes, &key, &rel, &rtid) <= 0) 205: { 206: /* it is a relation (or should be saved) */ 207: continue; 208: } 209: } 210: 211: /* it is a funny file!!! */ 212: if (!Clean) 213: { 214: printf("\t%s: file\n", directp->d_name); 215: continue; 216: } 217: } 218: 219: /* purge the file */ 220: printf("\tunlinking %s\n", directp->d_name); 221: if (unlink(directp->d_name)) 222: printf("\tcannot unlink\n"); 223: } 224: closecatalog(TRUE); /* close catalogs */ 225: unldb(); /* unlock the database */ 226: acc_close(); 227: 228: closedir(dirp); 229: }