From 68bbc9c394dee2d667bce6ce2241bd196c6be06b Mon Sep 17 00:00:00 2001 From: genoa Date: Thu, 19 Nov 1992 23:49:54 +0000 Subject: [PATCH] Initial revision --- dbck/dbck.dc | 185 ++++++++++ dbck/fix.dc | 208 +++++++++++ dbck/members.dc | 537 +++++++++++++++++++++++++++ dbck/phase1.dc | 426 +++++++++++++++++++++ dbck/phase2.dc | 954 ++++++++++++++++++++++++++++++++++++++++++++++++ dbck/phase3.dc | 80 ++++ dbck/phase4.dc | 179 +++++++++ 7 files changed, 2569 insertions(+) create mode 100644 dbck/dbck.dc create mode 100644 dbck/fix.dc create mode 100644 dbck/members.dc create mode 100644 dbck/phase1.dc create mode 100644 dbck/phase2.dc create mode 100644 dbck/phase3.dc create mode 100644 dbck/phase4.dc diff --git a/dbck/dbck.dc b/dbck/dbck.dc new file mode 100644 index 00000000..5595702a --- /dev/null +++ b/dbck/dbck.dc @@ -0,0 +1,185 @@ +/* $Header$ + * + * Moira database consistency checker + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include +#include +#include "dbck.h" + + +static char dbck_qc_rcsid[] = "$Header$"; + + +int debug = 0; +int mode = MODE_ASK; +int fast = 0; +int warn = 1; +int abort = 0; +struct hash *users, *machines, *clusters, *lists, *filesys, *nfsphys; +struct hash *strings, *members; +##int dcmenable; +struct save_queue *modtables, *sq_create(); +int interrupt(); + + +main(argc, argv) +int argc; +char **argv; +{ + char **arg = argv; +## char *database; + int ingerr(); + int countonly = 0; + + database = "sms"; + + while (++arg - argv < argc) { + if (**arg == '-') + switch ((*arg)[1]) { + case 'd': + debug = atoi((*arg)[2] ? *arg+2 : *++arg); + break; + case 'n': + mode = MODE_NO; + break; + case 'y': + mode = MODE_YES; + break; + case 'p': + mode = MODE_PREEN; + break; + case 'a': + mode = MODE_ASK; + break; + case 'c': + countonly++; + break; + case 'f': + fast++; + break; + case 'w': + warn = 0; + break; + default: + printf("Usage: %s [-d level] [-n] [-y] [-p] [-a] [-c] [-f] [-w] [database]\n", + argv[0]); + exit(1); + } + else + database = *arg; + } + if (countonly) + printf("Only doing counts\n"); + else if (fast) + printf("Doing fast version (skipping some checks)\n"); + if (mode == MODE_NO) + printf("Will NOT modify the database\n"); + else if (mode == MODE_PREEN) + printf("Will fix simple things without asking\n"); + else if (mode == MODE_YES) + printf("Will fix everything without asking\n"); + if (debug) + printf("Debug level is %d\n", debug); + + setlinebuf(stdout); + + signal(SIGHUP, interrupt); + signal(SIGQUIT, interrupt); + signal(SIGINT, interrupt); + modtables = sq_create(); + + IIseterr(ingerr); + printf("Opening database %s...", database); + fflush(stdout); +## ingres database + printf("done\n"); +## retrieve (dcmenable = values.value) where values.name = "dcm_enable" + dprintf("DCM disabled (was %d)\n", dcmenable); +## replace values (value = 0) where values.name = "dcm_enable" + +## begin transaction + + if (!countonly) { + phase1(); + phase2(); + phase3(); + } else { + count_only_setup(); + } + phase4(); + +## end transaction + cleanup(); + printf("Done.\n"); + exit(0); +} + +ingerr(num) +int *num; +{ + printf("An ingres error occuurred, code %d\n", *num); + printf("Aborting...\n"); + if (!abort) { + abort++; +## abort + } + exit(1); +} + + +int interrupt() +##{ + printf("Signal caught\n"); + if (prompt("Save database changes")) { + /* break out of a retrieve loop */ + IIbreak(); +## end transaction + cleanup(); + exit(0); + } + printf("Aborting transaction\n"); + if (!abort) { + abort++; + /* break out of a retrieve loop */ + IIbreak(); +## abort + } +## replace values (value = dcmenable) where values.name = "dcm_enable" +## exit + exit(0); +##} + + +modified(table) +char *table; +{ + sq_save_unique_string(modtables, table); +} + +cleanup() +##{ +## char *tab; + + while (sq_get_data(modtables, &tab)) { +## replace tblstats (modtime = "now") where tblstats.table = tab + } +## replace values (value = dcmenable) where values.name = "dcm_enable" +## exit +##} + + +out_of_mem(msg) +char *msg; +{ + fprintf(stderr, "Out of memory while %s\n", msg); +## end transaction + cleanup(); + exit(1); +} diff --git a/dbck/fix.dc b/dbck/fix.dc new file mode 100644 index 00000000..6a05e78f --- /dev/null +++ b/dbck/fix.dc @@ -0,0 +1,208 @@ +/* $Header$ + * + * User interface routines for dbck (Moira database consistency checker) + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include +#include "dbck.h" + +static char fix_qc_rcsid[] = "$Header$"; + + +##char *_table; +##char *_idfield; + +##generic_ffunc(id) +##int id; +##{ +## int rowcount; + +## delete _table where _table._idfield = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified(_table); +##} + + +generic_delete(sq, pfunc, table, idfield, preen) +struct save_queue *sq; +void (*pfunc)(); +char *table, *idfield; +int preen; +{ + _table = table; + _idfield = idfield; + generic_fix(sq, pfunc, "Delete", generic_ffunc, preen); +} + + +single_delete(table, idfield, id) +char *table, *idfield; +int id; +{ + _table = table; + _idfield = idfield; + generic_ffunc(id); +} + + +##zero_fix(table, zrfield, idfield, id) +##char *table, *zrfield, *idfield; +##int id; +##{ +## int rowcount; + +## replace table (zrfield = 0) where table.idfield = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified(table); +##} + + +int single_fix(msg, preen) +char *msg; +int preen; +{ + if (mode == MODE_PREEN) + return(preen); + + switch (mode) { + case MODE_ASK: + if (!prompt(msg)) + break; + case MODE_YES: + return(1); + break; + case MODE_NO: + ; + } + return(0); +} + + +generic_fix(sq, pfunc, msg, ffunc, preen) +struct save_queue *sq; +char *msg; +int (*pfunc)(), (*ffunc)(); +int preen; +{ + int id; + + while (sq_get_data(sq, &id)) { + if ((*pfunc)(id) == 0 && single_fix(msg, preen)) + (*ffunc)(id); + } + sq_destroy(sq); +} + + +int prompt(msg) +char *msg; +{ + char buf[BUFSIZ]; +## extern int dcmenable; + + while (1) { + printf("%s (Y/N/Q)? ", msg); + fflush(stdout); + gets(buf); + if (buf[0] == 'Y' || buf[0] == 'y') + return(1); + if (buf[0] == 'N' || buf[0] == 'n') + return(0); + if (buf[0] == 'Q' || buf[0] == 'q') { + if (prompt("Are you sure you want to quit")) { + if (prompt("Save database changes")) { +## end transaction + cleanup(); + exit(0); + } else { +## abort +## replace values (value = dcmenable) +## where values.name = "dcm_enable" +## exit + exit(1); + } + } + } + } +} + + +/** + ** set_next_object_id - set next object id in values table + ** + ** Inputs: object - object name in values table and in objects + ** table - name of table objects are found in + ** + ** - called before an APPEND operation to set the next object id to + ** be used for the new record to the next free value + ** + **/ + +int set_next_object_id(object, table) + char *object; + char *table; +##{ +## char *name, *tbl; +## int rowcount, exists, value; + + name = object; + tbl = table; +## range of v is values +## repeat retrieve (value = v.#value) where v.#name = @name +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + return(MR_NO_ID); + +## retrieve (exists = any(tbl.name where tbl.name = value)) +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) + return(MR_NO_ID); + while (exists) { + value++; + if (value > MAX_ID_VALUE) + value = MIN_ID_VALUE; +## retrieve (exists = any(tbl.name where tbl.name = value)) + } + + printf("setting ID %s to %d\n", name, value); +## repeat replace v (#value = @value) where v.#name = @name + modified("values"); + return(MR_SUCCESS); +##} + + +##generic_fix_id(table, idfield, txtfield, oldid, name) +##char *table; +##char *idfield; +##char *txtfield; +##int oldid; +##char *name; +##{ +## int rowcount, id; + + set_next_object_id(table, idfield); +## retrieve (id = values.value) where values.#name = idfield +## replace table (idfield = values.value) where values.#name = idfield and +## table.idfield = oldid and table.txtfield = name +## inquire_equel(rowcount = "rowcount") + if (rowcount == 1) + printf("Fixed\n"); + else + printf("Not fixed, rowcount = %d\n", rowcount); + modified(table); + return(id); +##} diff --git a/dbck/members.dc b/dbck/members.dc new file mode 100644 index 00000000..f5eae0a3 --- /dev/null +++ b/dbck/members.dc @@ -0,0 +1,537 @@ +/* $Header$ + */ + +#include +#include +#include + +#define FIXERRORS + +#define max(x, y) ((x) > (y) ? (x) : (y)) + +struct member { + int list_id; + int member_id; + union { + short all; + struct { + short u_ref_count:12; + unsigned short u_direct:1; + unsigned short u_baddirect:1; + unsigned short u_found:1; + unsigned short u_scanned:1; + } u_flags; + } flags; +} *find_member(), *allocmember(); +#define frefc flags.u_flags.u_ref_count +#define fdirect flags.u_flags.u_direct +#define fbaddirect flags.u_flags.u_baddirect +#define ffound flags.u_flags.u_found +#define fscanned flags.u_flags.u_scanned +#define fall flags.all + +#define member2id(c, id) (((c & 0xff) << 24) | (id & 0xffffff)) +#define id2type(id) ((id >> 24) & 0xff) +#define id2id(id) (id & 0xffffff) + +struct member_list { + struct member_list *next; + struct member *member; +}; + +struct hash *lists, *members; +void fix_member(), display_member(); +int debug = 0, records = 0; + + +main(argc, argv) +int argc; +char **argv; +##{ + char buf[256]; + +#ifdef DEBUG + if (argc > 1) + debug = atoi(argv[1]); +#endif DEBUG + +## ingres sms +## begin transaction +## range of m is imembers + + lists = create_hash(10000); + members = create_hash(10000); + records = 0; + + load_members(); +#ifdef DEBUG + if (debug > 3) + hash_step(lists, display_member, NULL); +#endif DEBUG + verify_members(); + fix_members(); + +#ifdef FIXERRORS + printf("Commit changes (Y/N)?"); + fflush(stdout); + fgets(buf, sizeof(buf), stdin); + if (buf[0] == 'Y' || buf[0] == 'y') { + printf("Ending transaction\n"); +## end transaction + } else { +#endif FIXERRORS + printf("Aborting transaction\n"); +## abort +#ifdef FIXERRORS + } +#endif FIXERRORS + +## exit + printf("Done.\n"); + + exit(0); +##} + + + +load_members() +##{ + struct member *m, *m1, *md, *ma; + struct member_list *descendants, *ancestors, *desc, *ance, la, ld; +## int list_id, member_id, ref_count, ref; +## char mtype[9]; + struct save_queue *sq; + + printf("Loading members\n"); + sq = sq_create(); + +## retrieve (list_id = m.#list_id, member_id = m.#member_id, +## mtype = m.#member_type, ref_count = m.#ref_count) +## where m.direct = 1 { +#ifdef DEBUG + if (debug > 5) + printf("Working on list %d member %s %d refc %d\n", + list_id, mtype, member_id, ref_count); +#endif DEBUG + if ((m = find_member(list_id, member2id(mtype[0], member_id))) == NULL) { + m = allocmember(); + m->list_id = list_id; + m->member_id = member2id(mtype[0], member_id); + insert_list(m); + insert_member(m); + } + m->fdirect = 1; + la.next = (struct member_list *) hash_lookup(members, + member2id('L', list_id)); + la.member = m; + if (isinchain(m, la.next)) + ance = la.next; + else + ance = &la; + if (mtype[0] == 'L') + ld.next = (struct member_list *) hash_lookup(lists, member_id); + else + ld.next = NULL; + ld.member = m; + if (isinchain(m, ld.next)) + desc = ld.next; + else + desc = &ld; +#ifdef DEBUG + if (debug > 5) + printf("%d ancestors, %d descendants\n", + chainlen(ance), chainlen(desc)); +#endif DEBUG + for (ancestors = ance; ancestors; ancestors = ancestors->next) { + ma = ancestors->member; + for (descendants = desc; descendants; descendants=descendants->next) { + md = descendants->member; + if (member2id('L', ma->list_id) == md->member_id) + fprintf(stderr, "Loop detected! list %d member %d\n", + md->list_id, ma->member_id); + ref = md->frefc * ma->frefc; + if (ref == 0) { + ref = max(md->frefc, ma->frefc); + if (ref == 0) + ref = 1; + } +#ifdef DEBUG + if (debug > 5) + printf("Checking list %d member %d, ref = %d\n", + ma->list_id, id2id(md->member_id), ref); +#endif DEBUG + if (m1 = find_member(ma->list_id, md->member_id)) { + m1->frefc += ref; +#ifdef DEBUG + if (debug > 5) + printf("set refc to %d (%d) on list %d, member %d\n", + m1->frefc, ref, m1->list_id, id2id(m1->member_id)); +#endif DEBUG + if (ma == m && md == m) + m1->fdirect = 1; + } else { + m1 = allocmember(); + m1->list_id = ma->list_id; + m1->member_id = md->member_id; + m1->frefc = ref; +#ifdef DEBUG + if (debug > 5) + printf("set new refc to %d (%d) on list %d, member %d\n", + m1->frefc, ref, m1->list_id, id2id(m1->member_id)); +#endif DEBUG + sq_save_data(sq, m1); + } + } + } + while (sq_get_data(sq, &m)) { + insert_list(m); + insert_member(m); + } + sq_destroy(sq); + sq = sq_create(); +## } + printf("created %d records\n", records); +##} + +verify_members() +##{ + struct member *m; + struct save_queue *sq; +## int list_id, member_id, ref_count, dflag; +## char mtype[9]; + int errxtra, errbref, errbdir; +#ifdef DEBUG + int ref0, ref1, ref2, ref3, refg; + int db0, db1, db2, db3, dbg; +#endif DEBUG + + /* verify members from database */ + printf("Verifying members\n"); + errxtra = errbref = errbdir = 0; +#ifdef DEBUG + ref0 = ref1 = ref2 = ref3 = refg = 0; + db0 = db1 = db2 = db3 = dbg = 0; +#endif DEBUG + sq = sq_create(); +## retrieve (list_id = m.#list_id, member_id = m.#member_id, +## mtype = m.member_type, ref_count = m.#ref_count, +## dflag = m.#direct) { +#ifdef DEBUG + if (debug > 1) + switch (ref_count) { + case 0: db0++; break; + case 1: db1++; break; + case 2: db2++; break; + case 3: db3++; break; + default: dbg++; + } +#endif DEBUG + m = find_member(list_id, member2id(mtype[0], member_id)); + if (m == NULL) { + m = allocmember(); + m->list_id = list_id; + m->member_id = member2id(mtype[0], member_id); + m->fdirect = dflag; + m->frefc = ref_count; + sq_save_data(sq, m); + errxtra++; + } else { + m->ffound = 1; +#ifdef DEBUG + if (debug > 1) + switch (m->frefc) { + case 0: ref0++; break; + case 1: ref1++; break; + case 2: ref2++; break; + case 3: ref3++; break; + default: refg++; + } +#endif DEBUG + m->frefc -= ref_count; + if (m->frefc != 0) + errbref++; + if (m->fdirect != dflag) { + m->fbaddirect = 1; + errbdir++; + } + } +## } + printf("Found %d extra records, %d bad ref counts, %d bad direct flags\n", + errxtra, errbref, errbdir); +#ifdef DEBUG + if (debug > 1) { + printf("Found in db: %d 0; %d 1; %d 2; %d 3; %d > 3\n", + db0, db1, db2, db3, dbg); + printf("Found refs: %d 0; %d 1; %d 2; %d 3; %d > 3\n", + ref0, ref1, ref2, ref3, refg); + } +#endif DEBUG +##} + + +fix_members() +##{ + struct member *m; + struct save_queue *sq; + int errmis = 0; +## int list_id, member_id, rowcount; +## char mtype[9]; + char buf[512]; + + /* fix any errors */ + printf("Fixing errors\n"); + hash_step(lists, fix_member, &errmis); + while (sq_get_data(sq, &m)) { + printf("Extraneous member record, deleting:\n"); + list_id = m->list_id; + member_id = id2id(m->member_id); + switch (id2type(m->member_id)) { + case 'U': strcpy(mtype, "USER"); break; + case 'L': strcpy(mtype, "LIST"); break; + case 'S': strcpy(mtype, "STRING"); break; + case 'K': strcpy(mtype, "KERBEROS"); break; + default: + mtype[0] = id2type(m->member_id); + mtype[1] = 0; + } + printf(" List: %d, Member: %s %d, Refc: %d, Direct %d\n", + list_id, mtype, member_id, m->frefc, m->fdirect); +#ifdef FIXERRORS +## delete m where m.#list_id = list_id and m.#member_id = member_id +## and m.member_type = mtype +## inquire_equel(rowcount = "rowcount") + printf(" %d rows deleted\n", rowcount); +#endif FIXERRORS + } + if (errmis > 0) + printf("Added %d missing records\n", errmis); +##} + + +insert_list(m) +struct member *m; +{ + register struct member_list *l, *l1; + + l = (struct member_list *) hash_lookup(lists, m->list_id); + if (l == NULL) { + l = (struct member_list *)malloc(sizeof(struct member_list)); + if (l == NULL) { + fprintf(stderr, "No memory for insert_list\n"); + exit(1); + } + l->next = NULL; + l->member = m; + hash_store(lists, m->list_id, l); + return; + } + for (l1 = l; l1; l1 = l1->next) + if (l1->member->member_id == m->member_id) { + fprintf(stderr, "Found 2nd copy of list record for\n"); + fprintf(stderr, "List: %d, Member: %c %d, Refc: %d, Direct %d\n", + m->list_id, id2type(m->member_id), id2id(m->member_id), + m->frefc, m->fdirect); + kill(getpid(), SIGQUIT); + exit(2); + } + + l1 = (struct member_list *)malloc(sizeof(struct member_list)); + if (l1 == NULL) { + fprintf(stderr, "No memory for insert_list\n"); + exit(1); + } + l1->next = l->next; + l->next = l1; + l1->member = m; +} + + +insert_member(m) +struct member *m; +{ + register struct member_list *l, *l1; + + l = (struct member_list *) hash_lookup(members, m->member_id); + if (l == NULL) { + l = (struct member_list *)malloc(sizeof(struct member_list)); + if (l == NULL) { + fprintf(stderr, "No memory for insert_member\n"); + exit(1); + } + l->next = NULL; + l->member = m; + hash_store(members, m->member_id, l); + return; + } + + for (l1 = l; l1; l1 = l1->next) + if (l1->member->list_id == m->list_id) { + fprintf(stderr, "Found 2nd copy of member record for\n"); + fprintf(stderr, "List: %d, Member: %c %d, Refc: %d, Direct %d\n", + m->list_id, id2type(m->member_id), id2id(m->member_id), + m->frefc, m->fdirect); + kill(getpid(), SIGQUIT); + exit(2); + } + + l1 = (struct member_list *)malloc(sizeof(struct member_list)); + if (l1 == NULL) { + fprintf(stderr, "No memory for insert_member\n"); + exit(1); + } + l1->next = l->next; + l->next = l1; + l1->member = m; +} + + +struct member *find_member(listid, memberid) +int listid; +int memberid; +{ + register struct member_list *l; + + for (l = (struct member_list *) hash_lookup(lists, listid); l; l = l->next) + if (l->member->member_id == memberid) + return(l->member); + return(NULL); +} + + +/*ARGSUSED*/ +void fix_member(dummy, l, errmis) +int dummy; +struct member_list *l; +int *errmis; +##{ +## int list_id, member_id, ref_count, dflag, rowcount; +## char *mtype; + char buf[2]; + register struct member *m; + + for (; l; l = l->next) { + m = l->member; + + if (m->fscanned) + continue; + m->fscanned = 1; + if (m->fbaddirect == 0 && m->frefc == 0 && m->ffound == 1) + continue; + if (m->ffound == 0) { + printf("Missing member record, adding:\n"); + list_id = m->list_id; + member_id = id2id(m->member_id); + ref_count = m->frefc; + dflag = m->fdirect; + switch (id2type(m->member_id)) { + case 'U': mtype = "USER"; break; + case 'L': mtype = "LIST"; break; + case 'S': mtype = "STRING"; break; + case 'K': mtype = "KERBEROS"; break; + default: + mtype = buf; + buf[0] = id2type(m->member_id); + buf[1] = 0; + } + printf(" List: %d, Member: %s %d, Refc: %d, Direct %d\n", + list_id, mtype, member_id, ref_count, dflag); + (*errmis)++; +#ifdef FIXERRORS +## append imembers (#list_id = list_id, #member_id = member_id, +## member_type = mtype, #ref_count = ref_count, +## direct = dflag); +## inquire_equel(rowcount = "rowcount") + printf(" %d rows added\n", rowcount); +#endif FIXERRORS + continue; + } + printf("Member record has bad ref_count and/or direct flag, fixing\n"); + list_id = m->list_id; + member_id = id2id(m->member_id); + ref_count = m->frefc; + dflag = m->fdirect; + switch (id2type(m->member_id)) { + case 'U': mtype = "USER"; break; + case 'L': mtype = "LIST"; break; + case 'S': mtype = "STRING"; break; + case 'K': mtype = "KERBEROS"; break; + default: + mtype = buf; + buf[0] = id2type(m->member_id); + buf[1] = 0; + } + printf(" List: %d, Member: %s %d, Refc: %d, Direct %d\n", + list_id, mtype, member_id, ref_count, dflag); +#ifdef FIXERRORS +## replace m (#ref_count = m.#ref_count + ref_count, direct = dflag) +## where m.#list_id = list_id and m.#member_id = member_id and +## m.member_type = mtype +## inquire_equel(rowcount = "rowcount"); + printf(" %d rows fixed\n", rowcount); +#endif FIXERRORS + } +##} + + +struct member *allocmember() +{ + register struct member *m; + + m = (struct member *) malloc(sizeof(struct member)); + if (m == NULL) { + fprintf(stderr, "No memory for new member\n"); + exit(1); + } + m->fall = 0; + records++; + return(m); +} + + +int isinchain(m, l) +struct member *m; +register struct member_list *l; +{ + for (; l; l = l->next) + if (l->member == m) + return(1); + return(0); +} + + +int chainlen(l) +register struct member_list *l; +{ + register int i; + for (i = 0; l; l = l->next, i++); + return(i); +} + + +#ifdef DEBUG + +/*ARGSUSED*/ +void display_member(key, l, dummy1) +int key, dummy1; +struct member_list *l; +{ + struct member *m; + char *mtype; + + printf("%d*", key); + for(; l; l = l->next) { + m = l->member; + switch (id2type(m->member_id)) { + case 'U': mtype = "USER"; break; + case 'L': mtype = "LIST"; break; + case 'S': mtype = "STRING"; break; + case 'K': mtype = "KERBEROS"; break; + default: mtype = "???"; break; + } + printf("List: %d, Member: %s %d, Refc: %d, Direct %d\n", + m->list_id, mtype, id2id(m->member_id), m->frefc, + m->fdirect); + } +} + +#endif DEBUG diff --git a/dbck/phase1.dc b/dbck/phase1.dc new file mode 100644 index 00000000..a5e0e692 --- /dev/null +++ b/dbck/phase1.dc @@ -0,0 +1,426 @@ +/* $Header$ + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include "dbck.h" + +static char phase1_qc_rcsid[] = "$Header$"; + + +show_user_id(u) +struct user *u; +{ + printf("User %s (%s, status %d) has duplicate ID\n", + u->login, u->fullname, u->status); + return(0); +} + +handle_duplicate_logins(sq) +struct save_queue *sq; +{ + struct user *u, *uu, *tmp; + + uu = (struct user *)0; + while (sq_get_data(sq, &u)) { + if (!strcmp(u->login, uu->login)) { + if (uu->status == 1 || u->status == 0) { + tmp = u; + u = uu; + uu = tmp; + } + printf("User %s (%s, status %d) and\n", + u->login, u->fullname, u->status); + printf("User %s (%s, status %d) have duplicate logins\n", + uu->login, uu->fullname, uu->status); + if (!strcmp(u->fullname, uu->fullname) && + single_fix("Delete the second one")) { + single_delete("users", "users_id", uu->users_id); + } else if (single_fix("Unregister the second one")) +## { +## int id = uu->users_id, rowcount; + +## replace users (login = "#"+text(users.uid), status = 0) +## where users.users_id = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("users"); +## } + } else { + uu = u; + } + } +} + +fix_user_id(u) +struct user *u; +{ + u->users_id = generic_fix_id("users", "users_id", "login", + u->users_id, u->login); +} + + +cant_fix(id) +int id; +{ + printf("Sorry, don't know how to fix that\n"); +} + +show_mach_id(m) +struct machine *m; +{ + printf("Machine %s has duplicate ID %d\n", m->name, m->mach_id); + return(0); +} + +show_mach_name(m) +struct machine *m; +{ + printf("Machine %s (%d) has duplicate name\n", m->name, m->mach_id); + return(0); +} + +fix_mach_id(m) +struct machine *m; +{ + m->mach_id = generic_fix_id("machine", "mach_id", "name", + m->mach_id, m->name); +} + +show_clu_id(c) +struct cluster *c; +{ + printf("Cluster %s has duplicate ID %d\n", c->name, c->clu_id); + return(0); +} + +show_clu_name(c) +struct cluster *c; +{ + printf("Cluster %s (%d) has duplicate name\n", c->name, c->clu_id); + return(0); +} + +fix_clu_id(c) +struct cluster *c; +{ + c->clu_id = generic_fix_id("cluster", "clu_id", "name", c->clu_id, c->name); +} + +show_list_id(l) +struct list *l; +{ + printf("List %s has duplicate ID %d\n", l->name, l->list_id); + return(0); +} + +show_list_name(l) +struct list *l; +{ + printf("List %s (%d) has duplicate name\n", l->name, l->list_id); + return(0); +} + +fix_list_id(l) +struct list *l; +{ + l->list_id = generic_fix_id("list", "list_id", "name", l->list_id, l->name); +} + +show_fs_id(f) +struct filesys *f; +{ + printf("Filesys %s has duplicate ID %d\n", f->name, f->filsys_id); + return(0); +} + +fix_fs_id(f) +struct filesys *f; +{ + f->filsys_id = generic_fix_id("filesys", "filsys_id", "label", + f->filsys_id, f->name); +} + + +show_np_id(n) +struct nfsphys *n; +{ + printf("NfsPhys %s:%s has duplicate ID %d\n", + ((struct machine *)hash_lookup(machines, n->mach_id))->name, + n->dir, n->nfsphys_id); + return(0); +} + +fix_np_id(n) +struct nfsphys *n; +{ + n->nfsphys_id = generic_fix_id("nfsphys", "nfsphys_id", "dir", + n->nfsphys_id, n->dir); +} + +show_str_id(s) +struct string *s; +{ + printf("String %s has duplicate ID %d\n", s->name, s->string_id); + return(0); +} + + +phase1() +##{ +## char name[81], name1[81], last[17], first[17], buf[257]; +## int id, id2, id3, aid, aid2, status, sid, sid2, sid3, sid4, sid5; + struct save_queue *sq; + struct user *u; + struct machine *m; + struct list *l; + struct cluster *c; + struct string *s; + struct filesys *f; + struct nfsphys *n; + + printf("Phase 1 - Looking for duplicates\n"); + + dprintf("Loading strings...\n"); + sq = sq_create(); + strings = create_hash(5000); +## range of s is strings +## retrieve (id = s.string_id, buf = s.string) { + s = (struct string *) malloc(sizeof(struct string)); + if (s == NULL) + out_of_mem("storing strings"); + s->name = strsave(strtrim(buf)); + s->string_id = id; + s->refc = 0; + if (hash_store(strings, id, s)) { + sq_save_data(sq, hash_lookup(strings, id)); + sq_save_data(sq, s); + } +## } + generic_delete(sq, show_str_id, "strings", "string_id", 0); + string_check(0); + + dprintf("Loading users...\n"); + sq = sq_create(); + users = create_hash(10000); +## range of u is users +## retrieve (id = u.users_id, name = u.login, last = u.#last, +## first = u.#first, status = u.#status, buf = u.potype, +## id2 = u.pop_id, id3 = u.box_id, sid = u.modby, sid2 = u.fmodby, +## sid3 = u.pmodby, sid4 = u.comment, sid5 = u.sigwho) { + u = (struct user *) malloc(sizeof(struct user)); + if (u == NULL) + out_of_mem("storing users"); + strcpy(u->login, strtrim(name)); + u->potype = buf[0]; + sprintf(buf, "%s, %s", strtrim(last), strtrim(first)); + u->fullname = strsave(buf); + u->status = status; + u->users_id = id; + switch (u->potype) { + case 'P': + u->pobox_id = id2; + break; + case 'S': + u->pobox_id = id3; + break; + default: + u->pobox_id = 0; + } + if (hash_store(users, id, u)) { + sq_save_data(sq, hash_lookup(users, id)); + sq_save_data(sq, u); + } + if (sid < 0) + string_check(-sid); + if (sid2 < 0) + string_check(-sid2); + if (sid3 < 0) + string_check(-sid3); + if (sid4) + string_check(sid4); + if (sid5) + string_check(sid5); +## } + generic_fix(sq, show_user_id, "Change ID", fix_user_id, 0); + + if (!fast) { + sq = sq_create(); +## retrieve (id = u.users_id) +## where u.login = users.login and u.tid != users.tid { + sq_save_data(sq, hash_lookup(users, id)); +## } + handle_duplicate_logins(sq); + } + + dprintf("Loading machines...\n"); + machines = create_hash(1000); + sq = sq_create(); +## range of m is machine +## retrieve (id = m.mach_id, name = m.#name, sid = m.modby) { + m = (struct machine *) malloc(sizeof(struct machine)); + if (m == NULL) + out_of_mem("storing machines"); + strcpy(m->name, strtrim(name)); + m->mach_id = id; + m->clucount = 0; + if (hash_store(machines, id, m)) { + sq_save_data(sq, hash_lookup(machines, id)); + sq_save_data(sq, m); + } + if (sid < 0) + string_check(-sid); +## } + generic_fix(sq, show_mach_id, "Change ID", fix_mach_id, 0); + + if (!fast) { + sq = sq_create(); +## retrieve (id = m.mach_id) +## where m.#name = machine.#name and m.tid != machine.tid { + sq_save_data(sq, hash_lookup(machines, id)); +## } + generic_fix(sq, show_mach_name, "Change name", cant_fix, 0); + } + + dprintf("Loading clusters...\n"); + sq = sq_create(); + clusters = create_hash(100); +## range of c is cluster +## retrieve (id = c.clu_id, name = c.#name, sid = c.modby) { + c = (struct cluster *) malloc(sizeof(struct cluster)); + if (c == NULL) + out_of_mem("storing clusters"); + strcpy(c->name, strtrim(name)); + c->clu_id = id; + if (hash_store(clusters, id, c)) { + sq_save_data(sq, hash_lookup(clusters, id)); + sq_save_data(sq, c); + } + if (sid < 0) + string_check(-sid); +## } + generic_fix(sq, show_clu_id, "Change ID", fix_clu_id, 0); + + if (!fast) { + sq = sq_create(); +## retrieve (id = c.clu_id) +## where c.#name = cluster.#name and c.tid != cluster.tid { + sq_save_data(sq, hash_lookup(clusters, id)); +## } + generic_fix(sq, show_clu_name, "Change name", cant_fix, 0); + } + + dprintf("Loading lists...\n"); + sq = sq_create(); + lists = create_hash(10000); +## range of l is list +## retrieve (id = l.list_id, name = l.#name, +## aid = l.acl_id, buf = l.acl_type, sid = l.modby) { + l = (struct list *) malloc(sizeof(struct list)); + if (l == NULL) + out_of_mem("storing lists"); + strcpy(l->name, strtrim(name)); + l->acl_type = buf[0]; + l->acl_id = aid; + l->list_id = id; + l->members = 0; + if (hash_store(lists, id, l)) { + sq_save_data(sq, hash_lookup(lists, id)); + sq_save_data(sq, l); + } + if (sid < 0) + string_check(-sid); +## } + generic_fix(sq, show_list_id, "Change ID", fix_list_id, 0); + + if (!fast) { + sq = sq_create(); +## retrieve (id = l.list_id) +## where l.#name = list.#name and l.tid != list.tid { + sq_save_data(sq, hash_lookup(lists, id)); +## } + generic_fix(sq, show_list_name, "Change name", cant_fix, 0); + } + + dprintf("Loading filesys...\n"); + sq = sq_create(); + filesys = create_hash(10000); +## retrieve (id = filesys.filsys_id, name = filesys.label, aid = filesys.owner, +## aid2 = filesys.owners, id2 = filesys.phys_id, +## id3 = filesys.mach_id, buf = filesys.type, +## name1 = filesys.#name, sid = filesys.modby) { + f = (struct filesys *) malloc(sizeof(struct filesys)); + if (f == NULL) + out_of_mem("storing filesystems"); + strcpy(f->name, strtrim(name)); + strcpy(f->dir, strtrim(name1)); + f->filsys_id = id; + f->owner = aid; + f->owners = aid2; + f->phys_id = id2; + f->mach_id = id3; + f->type = buf[0]; + if (hash_store(filesys, id, f)) { + sq_save_data(sq, hash_lookup(filesys, id)); + sq_save_data(sq, f); + } + if (sid < 0) + string_check(-sid); +## } + generic_fix(sq, show_fs_id, "Change ID", fix_fs_id, 0); + + dprintf("Loading nfsphys...\n"); + sq = sq_create(); + nfsphys = create_hash(500); +## retrieve (id = nfsphys.nfsphys_id, name = nfsphys.dir, +## id2 = nfsphys.mach_id, id3 = nfsphys.allocated, +## sid = nfsphys.modby) { + n = (struct nfsphys *) malloc(sizeof(struct nfsphys)); + if (n == NULL) + out_of_mem("storing nfsphys"); + strcpy(n->dir, strtrim(name)); + n->mach_id = id2; + n->nfsphys_id = id; + n->allocated = id3; + n->count = 0; + if (hash_store(nfsphys, id, n)) { + sq_save_data(sq, hash_lookup(nfsphys, id)); + sq_save_data(sq, n); + } + if (sid < 0) + string_check(-sid); +## } + generic_fix(sq, show_np_id, "Change ID", fix_np_id, 0); + + if (!fast) { +## range of s is strings +## retrieve (id = s.string_id, buf = s.string) +## where s.string = strings.string and s.tid != strings.tid { + printf("String %s(%d) is a duplicate!\n", strtrim(buf), id); + printf("Not fixing this error\n"); +## } + } + + if (!fast) { + dprintf("Scanning krbmap...\n"); +## range of k is krbmap +## retrieve (id = k.users_id) +## where k.users_id = krbmap.users_id and k.tid != krbmap.tid { + printf("User %d is in the krbmap more than once!\n", id); + printf("Not fixing this error\n"); +## } +## retrieve (id = k.string_id) +## where k.string_id = krbmap.string_id and k.tid != krbmap.tid { + printf("Principal %d is in the krbmap more than once!\n", id); + printf("Not fixing this error\n"); +## } + } +##} + diff --git a/dbck/phase2.dc b/dbck/phase2.dc new file mode 100644 index 00000000..9a0840d6 --- /dev/null +++ b/dbck/phase2.dc @@ -0,0 +1,954 @@ +/* $Header$ + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include +#include "dbck.h" + +static char phase2_qc_rcsid[] = "$Header$"; + + +show_mcm_mach(id) +int id; +##{ +## int iid = id, found = 1; +## char name[33]; + +## retrieve (name = cluster.#name) where cluster.clu_id = mcmap.clu_id +## and mcmap.mach_id = iid { + strtrim(name); + found = 0; + printf("Cluster %s, non-existant machine %d in cluster map\n", name, id); +## } + return(found); +##} + +show_mcm_clu(id) +int id; +##{ +## int iid = id, found = 1; +## char name[33]; + +## retrieve (name = machine.#name) where machine.mach_id = mcmap.mach_id +## and mcmap.clu_id = iid { + strtrim(name); + found = 0; + printf("Machine %s, non-existant cluster %d in cluster map\n", name, id); +## } + return(found); +##} + +pobox_check(id, u, hint) +int id; +struct user *u; +int hint; +{ + switch (u->potype) { + case 'P': + if (!hash_lookup(machines, u->pobox_id)) { + printf("User %s(%s) has P.O.Box on non-existant machine %d\n", + u->login, u->fullname, u->pobox_id); + if (single_fix("Delete", 0)) { + remove_pobox(u->users_id); + u->potype = 'N'; + } + } + break; + case 'S': + if (!string_check(u->pobox_id)) { + printf("User %s(%s) has P.O.Box with non-existant string %d\n", + u->login, u->fullname, u->pobox_id); + if (single_fix("Delete", 0)) { + remove_pobox(u->users_id); + u->potype = 'N'; + } + } + break; + default: + ; + } +} + + +remove_pobox(id) +int id; +##{ +## int rowcount, iid = id; +## replace users (potype = "NONE") where users.users_id = iid +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s removed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not removed\n"); + modified("users"); +##} + +show_svc(id) +int id; +##{ +## int iid = id, found = 1; +## char label[17], data[33]; + +## retrieve (label = svc.serv_label, data = svc.serv_cluster) +## where svc.clu_id = iid { + strtrim(label); + strtrim(data); + found = 0; + printf("Cluster data [%s] %s for non-existant cluster %d\n", + label, data, id); +## } + return(found); +##} + +list_check(id, l, hint) +int id; +struct list *l; +int hint; +{ + switch (l->acl_type) { + case 'L': + if (!hash_lookup(lists, l->acl_id)) { + printf("List %s has bad LIST acl %d\n", l->name, l->acl_id); + if (single_fix("Patch", 1)) { + fix_list_acl(l->list_id); + } + } + break; + case 'U': + if (!hash_lookup(users, l->acl_id)) { + printf("List %s has bad USER acl %d\n", l->name, l->acl_id); + if (single_fix("Patch", 1)) { + fix_list_acl(l->list_id); + } + } + break; + } +} + +fix_list_acl(id) +int id; +##{ +## int rowcount, iid = id; +## replace list (acl_id = iid, acl_type = "LIST") where list.list_id = iid +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("list"); +##} + + +show_member_list(id) +int id; +##{ +## int mid, iid = id, found = 1; +## char mtype[9], *name = ""; + +## retrieve (mtype = imembers.member_type, mid = imembers.member_id) +## where imembers.list_id = iid and imembers.direct = 1 { + strtrim(mtype); + found = 0; + if (mtype[0] == 'L') + name = ((struct list *) hash_lookup(lists, mid))->name; + else if (mtype[0] == 'U') + name = ((struct user *) hash_lookup(users, mid))->login; + else if (mtype[0] == 'S' || mtype[0] == 'K') + name = ((struct string *) hash_lookup(strings, mid))->name; + printf("Non-existant list %d has member %s %s\n", iid, mtype, name); +## } + return(found); +##} + +show_mem_user(id) +int id; +##{ +## int lid, iid = id, found = 1; +## char name[33]; + +## retrieve (lid = imembers.list_id) +## where imembers.member_id = iid and imembers.member_type = "USER" and +## imembers.direct = 1 { + found = 0; + printf("List %s has non-existant user member, id %d\n", + ((struct list *)hash_lookup(lists, lid))->name, iid); +## } + return(found); +##} + +show_mem_list(id) +int id; +##{ +## int lid, iid = id, found = 1; +## char name[33]; + +## retrieve (lid = imembers.list_id) +## where imembers.member_id = iid and imembers.member_type = "LIST" and +## imembers.direct = 1 { + found = 0; + printf("List %s has non-existant list member, id %d\n", + ((struct list *)hash_lookup(lists, lid))->name, iid); +## } + return(found); +##} + +show_mem_str(id) +int id; +##{ +## int lid, iid = id, found = 1; +## char name[33]; + +## retrieve (lid = imembers.list_id) +## where imembers.member_id = iid and imembers.member_type = "STRING" and +## imembers.direct = 1 { + found = 0; + printf("List %s has non-existant string member, id %d\n", + ((struct list *)hash_lookup(lists, lid))->name, iid); +## } + return(found); +##} + + +show_mem_krb(id) +int id; +##{ +## int lid, iid = id, found = 1; +## char name[33]; + +## retrieve (lid = imembers.list_id) +## where imembers.member_id = iid and imembers.member_type = "KERBEROS" and +## imembers.direct = 1 { + found = 0; + printf("List %s has non-existant kerberos member, id %d\n", + ((struct list *)hash_lookup(lists, lid))->name, iid); +## } + return(found); +##} + + +##del_mem_user(id) +##int id; +##{ +## int rowcount; + +## delete imembers where imembers.member_type = "USER" and +## imembers.member_id = id and imembers.direct = 1 +## inquire_equel(rowcount = "rowcount"); + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("imembers"); +##} + +##del_mem_list(id) +##int id; +##{ +## int rowcount; + +## delete imembers where imembers.member_type = "LIST" and +## imembers.member_id = id and imembers.direct = 1 +## inquire_equel(rowcount = "rowcount"); + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("imembers"); +##} + +##del_mem_str(id) +##int id; +##{ +## int rowcount; + +## delete imembers where imembers.member_type = "STRING" and +## imembers.member_id = id and imembers.direct = 1 +## inquire_equel(rowcount = "rowcount"); + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("imembers"); +##} + + +##del_mem_krb(id) +##int id; +##{ +## int rowcount; + +## delete imembers where imembers.member_type = "KERBEROS" and +## imembers.member_id = id and imembers.direct = 1 +## inquire_equel(rowcount = "rowcount"); + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("imembers"); +##} + + +##show_sh(id) +##int id; +##{ +## char name[33]; + int found = 1; + +## retrieve (name = serverhosts.service) where serverhosts.mach_id = id { + found = 0; + printf("ServerHost entry for service %s non-existant host %d\n", + name, id); +## } + return(found); +##} + +##del_sh_mach(id) +##int id; +##{ +## int rowcount; + +## delete serverhosts where serverhosts.mach_id = id +## inquire_equel(rowcount = "rowcount"); + if (rowcount > 0) + printf("%d entr%s deleted\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("serverhosts"); +##} + + +static int fnchecklen; + +fsmatch(id, n, f) +int id; +struct nfsphys *n; +struct filesys *f; +{ + if (n->mach_id == f->mach_id && + !strncmp(f->dir, n->dir, strlen(n->dir)) && + strlen(n->dir) > fnchecklen) { + f->phys_id = id; + fnchecklen = strlen(n->dir); + } +} + + +##check_fs(id, f, hint) +##int id; +register struct filesys *f; +int hint; +##{ +## int id1, id2, id3, rowcount; +## char *dir; + struct nfsphys *n; + struct machine *m; + + if (!hash_lookup(machines, f->mach_id)) { + printf("Filesys %s with bad machine %d\n", f->name, f->mach_id); + if (single_fix("Fix", 0)) { +## replace filesys (mach_id = 0) where filesys.filsys_id = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n",rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("filesys"); + f->mach_id = 0; + } + } + + if (!hash_lookup(users, f->owner)) { + printf("Filesys %s with bad owning user %d\n", f->name, f->owner); + if (single_fix("Fix", 1)) { + zero_fix("filesys", "owner", "filsys_id", f->filsys_id); + f->owner = 0; + } + } + if (!hash_lookup(lists, f->owners)) { + printf("Filesys %s with bad owning group %d\n", f->name, f->owners); + if (single_fix("Fix", 1)) { + zero_fix("filesys", "owners", "filsys_id", f->filsys_id); + f->owners = 0; + } + } + + if (f->type == 'N') { + if (!hash_lookup(nfsphys, f->phys_id)) { + m = (struct machine *)hash_lookup(machines, f->mach_id); + printf("Filesys %s with bad phys_id %d\n", f->name, f->phys_id); + if (single_fix("Fix", 1)) { + fnchecklen = 0; + hash_step(nfsphys, fsmatch, f); + if (fnchecklen != 0) { + id1 = f->phys_id; + id2 = f->filsys_id; + id3 = f->mach_id; +## replace filesys (phys_id = id1) where filesys.filsys_id = id2 +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n",rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("filesys"); + } else { + printf("No NFSphys exsits for %s:%s\n", m->name, f->dir); + if (single_fix("Create", 0)) { + dir = f->dir; + id1 = f->phys_id; + id2 = f->filsys_id; + id3 = f->mach_id; + if (set_next_object_id("nfsphys_id", "nfsphys") != + MR_SUCCESS) { + printf("Unable to assign unique ID\n"); + return; + } +## retrieve (id1 = values.value) +## where values.name = "nfsphys_id" +## inquire_equel(rowcount = "rowcount") + if (rowcount != 1) { + printf("Unable to retrieve unique ID\n"); + return; + } +## append nfsphys (nfsphys_id = id1, mach_id = id3, +## device = "???", #dir = dir, status = 0, +## allocated = 0, size = 0, +## modtime = "now", modby = 0, +## modwith = "dbck") +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s created\n", rowcount, + rowcount==1?"y":"ies"); + else + printf("Not created\n"); + modified("nfsphys"); + n = (struct nfsphys *)malloc(sizeof(struct nfsphys)); + if (n == NULL) + out_of_mem("storing new nfsphys"); + strcpy(n->dir, dir); + n->mach_id = id3; + n->nfsphys_id = id1; + n->allocated = 0; + n->count = 0; + hash_store(nfsphys, id1, n); +## replace filesys (phys_id = id1) +## where filesys.filsys_id = id2 +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d filesys entr%s fixed\n", rowcount, + rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("filesys"); + } + } + } + } + } +##} + + +check_nfsphys(id, n, hint) +int id; +struct nfsphys *n; +int hint; +{ + if (!hash_lookup(machines, n->mach_id)) { + printf("NFSphys %d(%s) on non-existant machine %d\n", + id, n->dir, n->mach_id); + if (single_fix("Delete", 0)) + single_delete("nfsphys", "nfsphys_id", id); + } +} + +##show_fsg_missing(id) +##int id; +##{ +## int id1, found = 1; + struct filesys *f; + +## retrieve (id1 = fsgroup.filsys_id) where fsgroup.group_id = id { + found = 0; + if (f = (struct filesys *) hash_lookup(filesys, id1)) + printf("Missing fsgroup %d has member filesystem %s\n", id, f->name); + else + printf("Missing fsgroup %d has member filesystem %d\n", id, id1); +## } + return(found); +##} + +show_fsg_type(f) +struct filesys *f; +{ + char *t; + + switch (f->type) { + case 'N': + t = "NFS"; + break; + case 'R': + t = "RVD"; + break; + case 'A': + t = "AFS"; + break; + case 'E': + t = "ERR"; + break; + case 'F': + t = "FSGROUP"; + break; + case 'M': + t = "MUL"; + break; + default: + t = "???"; + } + printf("FSGroup %s has type %s instead of FSGROUP\n", f->name, t); + return(0); +} + +fix_fsg_type(f) +struct filesys *f; +##{ +## int rowcount, id = f->filsys_id; + +## replace filesys (type = "FSGROUP") where filesys.filsys_id = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("filesys"); +##} + +##show_fsg_nomember(id) +##int id; +##{ +## int id1, found = 1; + struct filesys *f; + +## retrieve (id1 = fsgroup.group_id) where fsgroup.filsys_id = id { + found = 0; + if (f = (struct filesys *) hash_lookup(filesys, id1)) + printf("FSGroup %s has missing member %d\n", f->name, id); + else + printf("FSGroup %d has missing member %d\n", id1, id); +## } + return(found); +##} + +##show_quota_nouser(id) +##int id; +##{ +## int id1, found = 1; + +## retrieve (id1 = quota.filsys_id) where quota.entity_id = id and +## quota.type = "USER" { + found = 0; + printf("Quota on fs %d for non-existant user %d\n", id1, id); +## } + return(found); +##} + +##show_quota_nolist(id) +##int id; +##{ +## int id1, found = 1; + +## retrieve (id1 = quota.filsys_id) where quota.entity_id = id and +## quota.type = "GROUP" { + found = 0; + printf("Quota on fs %d for non-existant list %d\n", id1, id); +## } + return(found); +##} + +##fix_quota_nouser(id) +##int id; +##{ +## int rowcount, id1; + + id1 = ((struct filesys *)hash_lookup(filesys, id))->phys_id; +## delete quota where quota.entity_id = id and quota.type = "USER" +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s deleted\n",rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("quota"); +##} + +##fix_quota_nolist(id) +##int id; +##{ +## int rowcount, id1; + + id1 = ((struct filesys *)hash_lookup(filesys, id))->phys_id; +## delete quota where quota.entity_id = id and quota.type = "GROUP" +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s deleted\n",rowcount, rowcount==1?"y":"ies"); + else + printf("Not deleted\n"); + modified("quota"); +##} + +##show_quota_nofs(id) +##int id; +##{ +## int id1, found = 1; +## char type[9]; + +## retrieve (id1 = quota.entity_id, type = quota.#type) +## where quota.filsys_id = id { + found = 0; + printf("Quota for %s %d on non-existant filesys %d\n", type, id1, id); +## } + return(found); +##} + +fix_quota_nofs(id) +{ + single_delete("quota", "filsys_id", id); +} + +##show_quota_wrongpid(id) +##int id; +##{ +## int id1, found = 1; +## char type[9]; + struct user *u; + struct filesys *f; + + f = (struct filesys *)hash_lookup(filesys, id); +## retrieve (id1 = quota.entity_id, type = quota.#type) +## where quota.filsys_id = id { + found = 0; + printf("Quota for %s %d on filesys %s has wrong phys_id %d\n", + type, id1, f->name, id); +## } + return(found); +##} + +##fix_quota_physid(id) +##int id; +##{ +## int rowcount, id1; + + id1 = ((struct filesys *)hash_lookup(filesys, id))->phys_id; +## replace quota (phys_id = id1) where quota.filsys_id = id and +## quota.phys_id != id1 +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n",rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("quota"); +##} + +##show_srv_user(id) +##int id; +##{ +## char name[33]; + int found = 1; + +## retrieve (name = s.#name) where s.acl_type = "USER" and s.acl_id = id { + strtrim(name); + printf("Service %s has acl non-existant user %d\n", name, id); + found = 0; +## } + return(found); +##} + +##show_srv_list(id) +##int id; +##{ +## char name[33]; + int found = 1; + +## retrieve (name = s.#name) where s.acl_type = "LIST" and s.acl_id = id { + strtrim(name); + printf("Service %s has acl non-existant list %d\n", name, id); + found = 0; +## } + return(found); +##} + +##zero_srv_user(id) +##int id; +##{ +## int rowcount; + +## replace servers (acl_id = 0) where servers.acl_id = id and +## servers.acl_type = "USER" +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("servers"); +##} + +##zero_srv_list(id) +##int id; +##{ +## int rowcount; + +## replace servers (acl_id = 0) where servers.acl_id = id and +## servers.acl_type = "LIST" +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("servers"); +##} + + +##show_krb_usr(id) +##int id; +##{ +## int found = 1, id1; + struct string *s; + char *ss; + +## retrieve (id1 = krbmap.string_id) where krbmap.users_id = id { + if (s = ((struct string *)hash_lookup(strings, id1))) + ss = s->name; + else + ss = "[unknown]"; + found = 0; + printf("Kerberos map for non-existant user %d to principal %s\n", + id, s); +## } + return(found); +##} + + +##show_krb_str(id) +##int id; +##{ +## int found = 1, id1; + struct user *u; + char *s; + +## retrieve (id1 = krbmap.users_id) where krbmap.string_id = id { + if (u = ((struct user *)hash_lookup(users, id1))) + s = u->login; + else + s = "[???]"; + found = 0; + printf("Kerberos map for user %s (%d) to non-existant string %d\n", + s, id1, id); +## } + return(found); +##} + + +##show_pdm_mach(id) +##int id; +##{ +## char name[33]; + int found = 1; + +## retrieve (name = palladium.#name) where palladium.mach_id = id { + strtrim(name); + printf("Palladium server/supervisor %s is on non-existant machine %d\n", + name, id); + found = 0; +## } + return(found); +##} + + +phase2() +##{ +## int id1, id2, id3, id4, id5; +## char type[9], name[33]; + struct save_queue *sq, *sq1, *sq2, *sq3, *sq4, *sq5; + struct filesys *f; + struct list *l; + struct nfsphys *n; + struct machine *m; + + printf("Phase 2 - Checking references\n"); + + dprintf("Checking users...\n"); + hash_step(users, pobox_check, NULL); + + dprintf("Checking mcmap...\n"); + sq1 = sq_create(); + sq2 = sq_create(); +## retrieve (id1 = mcmap.mach_id, id2 = mcmap.clu_id) { + if (!(m = (struct machine *)hash_lookup(machines, id1))) + sq_save_unique_data(sq1, id1); + if (!hash_lookup(clusters, id2)) + sq_save_unique_data(sq2, id2); + if (m) m->clucount++; +## } + generic_delete(sq1, show_mcm_mach, "mcmap", "mach_id", 1); + generic_delete(sq2, show_mcm_clu, "mcmap", "clu_id", 1); + + dprintf("Checking service clusters...\n"); + sq1 = sq_create(); +## retrieve (id1 = svc.clu_id) { + if (!hash_lookup(clusters, id1)) + sq_save_unique_data(sq1, id1); +## } + generic_delete(sq1, show_svc, "svc", "clu_id", 1); + + dprintf("Checking lists...\n"); + hash_step(lists, list_check, NULL); + + dprintf("Checking members...\n"); + sq1 = sq_create(); + sq2 = sq_create(); + sq3 = sq_create(); + sq4 = sq_create(); + sq5 = sq_create(); +## range of m is imembers +## retrieve (id1 = m.list_id, type = m.member_type, id2 = m.member_id, +## id3 = m.ref_count, id4 = m.direct) { + if ((l = (struct list *) hash_lookup(lists, id1)) == NULL) + sq_save_unique_data(sq1, id1); + else if (type[0] == 'U' && !hash_lookup(users, id2)) + sq_save_unique_data(sq2, id2); + else if (type[0] == 'L' && !hash_lookup(lists, id2)) + sq_save_unique_data(sq3, id2); + else if (type[0] == 'S' && !string_check(id2)) + sq_save_unique_data(sq4, id2); + else if (type[0] == 'K' && !string_check(id2)) + sq_save_unique_data(sq5, id2); + else + l->members++; +## } + generic_delete(sq1, show_member_list, "imembers", "list_id", 1); + generic_fix(sq2, show_mem_user, "Delete", del_mem_user, 1); + generic_fix(sq3, show_mem_list, "Delete", del_mem_list, 1); + generic_fix(sq4, show_mem_str, "Delete", del_mem_str, 1); + generic_fix(sq5, show_mem_krb, "Delete", del_mem_krb, 1); + + dprintf("Checking servers...\n"); + sq1 = sq_create(); + sq2 = sq_create(); +## range of s is servers +## retrieve (name = s.#name, type = s.acl_type, id1 = s.acl_id) { + strtrim(type); + if (!strcmp(type, "USER") && !hash_lookup(users, id1)) { + sq_save_data(sq1, id1); + } else if (!strcmp(type, "LIST") && !hash_lookup(lists, id1)) { + sq_save_data(sq2, id1); + } +## } + generic_fix(sq1, show_srv_user, "Fix", zero_srv_user, 1); + generic_fix(sq2, show_srv_list, "Fix", zero_srv_list, 1); + + dprintf("Checking servershosts...\n"); + sq = sq_create(); +## retrieve (id1 = serverhosts.mach_id) { + if (!hash_lookup(machines, id1)) + sq_save_data(sq, id1); +## } + generic_fix(sq, show_sh, "Delete", del_sh_mach, 0); + + dprintf("Checking nfsphys...\n"); + hash_step(nfsphys, check_nfsphys, NULL); + + dprintf("Checking filesys...\n"); + hash_step(filesys, check_fs, NULL); + + dprintf("Checking filesystem groups...\n"); + sq1 = sq_create(); + sq2 = sq_create(); + sq3 = sq_create(); +## retrieve (id1 = fsgroup.group_id, id2 = fsgroup.filsys_id) { + if (!(f = (struct filesys *) hash_lookup(filesys, id1))) + sq_save_data(sq1, id1); + if (!hash_lookup(filesys, id2)) + sq_save_data(sq3, id2); +## } + generic_delete(sq1, show_fsg_missing, "fsgroup", "group_id", 0); + generic_delete(sq3, show_fsg_nomember, "fsgroup", "filsys_id", 1); + + dprintf("Checking quotas...\n"); + sq1 = sq_create(); + sq2 = sq_create(); + sq3 = sq_create(); + sq4 = sq_create(); +## retrieve (id1 = quota.entity_id, type = quota.#type, id2 = quota.filsys_id, +## id3 = quota.phys_id, id4 = quota.quota) { + if (type[0] == 'U' && id1 != 0 && !hash_lookup(users, id1)) + sq_save_data(sq1, id1); + else if (type[0] == 'G' && !hash_lookup(lists, id1)) + sq_save_data(sq4, id1); + else if (!(f = (struct filesys *) hash_lookup(filesys, id2))) + sq_save_data(sq2, id2); + else if (id3 != f->phys_id || + ((n = (struct nfsphys*) hash_lookup(nfsphys, id3)) == + (struct nfsphys *)NULL)) + sq_save_data(sq3, id2); + else + n->count += id4; +## } + generic_fix(sq1, show_quota_nouser, "Delete", fix_quota_nouser, 1); + generic_fix(sq2, show_quota_nofs, "Delete", fix_quota_nofs, 0); + generic_fix(sq3, show_quota_wrongpid, "Fix", fix_quota_physid, 1); + generic_fix(sq4, show_quota_nolist, "Delete", fix_quota_nolist, 1); + + dprintf("Not checking zephyr.\n"); + + dprintf("Checking hostaccess...\n"); +## range of h is hostaccess +## retrieve (id1 = h.mach_id, type = h.acl_type, id2 = h.acl_id) { + strtrim(type); + if (!hash_lookup(machines, id1)) { + printf("Hostaccess for non-existant host %d\n", id1); + printf("Not fixing this error\n"); + } + if (!strcmp(type, "USER") && !hash_lookup(users, id2)) { + printf("Hostaccess for %d is non-existant user %d\n", id1, id2); + printf("Not fixing this error\n"); + } else if (!strcmp(type, "LIST") && !hash_lookup(lists, id2)) { + printf("Hostaccess for %d is non-existant list %d\n", id1, id2); + printf("Not fixing this error\n"); + } +## } + + dprintf("Checking palladium...\n"); + sq1 = sq_create(); +## range of p is palladium +## retrieve (id1 = p.mach_id) { + if (!hash_lookup(machines, id1)) { + sq_save_unique_data(sq1, id1); + } +## } + generic_delete(sq1, show_pdm_mach, "palladium", "mach_id", 1); + + dprintf("Checking krbmap...\n"); + sq1 = sq_create(); + sq2 = sq_create(); +## range of k is krbmap +## retrieve (id1 = k.users_id, id2 = k.string_id) { + if (!hash_lookup(users, id1)) + sq_save_unique_data(sq1, id1); + if (!string_check(id2)) + sq_save_unique_data(sq2, id2); +## } + generic_delete(sq1, show_krb_usr, "krbmap", "users_id", 1); + generic_delete(sq2, show_krb_str, "krbmap", "string_id", 1); + + dprintf("Checking capacls...\n"); +## retrieve (id1 = capacls.list_id, name = capacls.tag) { + if (!hash_lookup(lists, id1)) { + printf("Capacl for %s is non-existant list %d\n", name, id1); + printf("Not fixing this error\n"); + } +## } + +##} + diff --git a/dbck/phase3.dc b/dbck/phase3.dc new file mode 100644 index 00000000..0a85f746 --- /dev/null +++ b/dbck/phase3.dc @@ -0,0 +1,80 @@ +/* $Header$ + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include "dbck.h" + +#define NULL 0 + +static char phase3_qc_rcsid[] = "$Header$"; + + +empty_list_check(id, l, hint) +int id, hint; +struct list *l; +{ + if (l->members == 0 && l->list_id != 0) + printf("Warning: List %s is empty\n", l->name); +} + + +/* Used by other parts of the program to check that a string_id is good. + * This returns TRUE if it is, or FALSE if it is not, and as a side effect + * increments the string reference count. + */ + +struct string *string_check(id) +int id; +{ + register struct string *s; + + s = (struct string *) hash_lookup(strings, id); + if (s == NULL) + return(s); + s->refc++; + return(s); +} + + +unref_string_check(id, s, hint) +int id, hint; +struct string *s; +{ + if (s->refc == 0) { + printf("Unreferenced string %s id %d\n", s->name, id); + if (single_fix("Delete", 1)) + single_delete("strings", "string_id", id); + } +} + + +noclu_mach_check(id, m, hint) +int id, hint; +struct machine *m; +{ + if (m->clucount == 0 && m->mach_id != 0) + printf("Warning: machine %s is not in any clusters\n", m->name); +} + + +phase3() +##{ + printf("Phase 3 - Finding unused objects\n"); + + if (warn) { + dprintf("Checking machines...\n"); + hash_step(machines, noclu_mach_check, NULL); + + dprintf("Checking lists...\n"); + hash_step(lists, empty_list_check, NULL); + } + + dprintf("Checking strings...\n"); + hash_step(strings, unref_string_check, NULL); + +##} + diff --git a/dbck/phase4.dc b/dbck/phase4.dc new file mode 100644 index 00000000..535a22a3 --- /dev/null +++ b/dbck/phase4.dc @@ -0,0 +1,179 @@ +/* $Header$ + * + * (c) Copyright 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include "dbck.h" + +static char phase4_qc_rcsid[] = "$Header$"; + + +count_boxes(id, u, boxes) +int id; +struct user *u; +struct hash *boxes; +{ + int i; + + if (u->potype == 'P') { + if (i = (int) hash_lookup(boxes, u->pobox_id)) + hash_store(boxes, u->pobox_id, i+1); + else { + printf("User %s(%s) has pobox on non-POP server %d\n", + u->fullname, u->login, u->pobox_id); + printf("Not fixing this error\n"); + } + } +} + + +##check_box_counts(id, cnt, counts) +##int id, cnt; +struct hash *counts; +##{ +## int oldval, rowcount; + + oldval = (int) hash_lookup(counts, id); + cnt--; + if (oldval != cnt) { + printf("Count wrong on POBox machine %s; is %d in db, counted %d\n", + ((struct machine *) hash_lookup(machines, id))->name, + oldval, cnt); + if (single_fix("Update", 1)) { +## range of s is serverhosts +## replace s (value1 = cnt) where +## s.service = "POP" and s.mach_id = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("serverhosts"); + } + } +##} + + +##check_nfs_counts(id, n, hint) +##int id, hint; +struct nfsphys *n; +##{ +## int val, rowcount; + + val = n->count; + if (n->allocated != val) { + printf("Count wrong on NFSphys %s:%s; is %d in db, counted %d\n", + ((struct machine *) hash_lookup(machines, n->mach_id))->name, + n->dir, n->allocated, val); + if (single_fix("Update", 1)) { +## replace nfsphys (allocated = val) where nfsphys.nfsphys_id = id +## inquire_equel(rowcount = "rowcount") + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("nfsphys"); + } + } +##} + + +phase4() +##{ + struct hash *boxes, *counts; +## int id, cnt; + + printf("Phase 4 - Checking counts\n"); + + dprintf("Doing POBoxes...\n"); + boxes = create_hash(10); + counts = create_hash(10); +## retrieve (id = serverhosts.mach_id, cnt = serverhosts.value1) +## where serverhosts.service = "POP" { + hash_store(boxes, id, 1); + hash_store(counts, id, cnt); +## } + hash_step(users, count_boxes, boxes); + hash_step(boxes, check_box_counts, counts); + + dprintf("Doing NFSphys...\n"); + hash_step(nfsphys, check_nfs_counts, 0); +##} + + +count_only_setup() +##{ +## int id, status, id2, id3; +## char name[33], last[17], first[17], buf[257]; + struct save_queue *sq; + struct user *u; + struct nfsphys *n; + struct machine *m; + + dprintf("Loading users...\n"); + users = create_hash(10000); +## range of u is users +## retrieve (id = u.users_id, name = u.login, last = u.#last, +## first = u.#first, status = u.#status, buf = u.potype, +## id2 = u.pop_id, id3 = u.box_id) +## where u.potype = "POP" { + u = (struct user *) malloc(sizeof(struct user)); + if (u == NULL) + out_of_mem("storing users"); + strcpy(u->login, strtrim(name)); + u->potype = buf[0]; + sprintf(buf, "%s, %s", strtrim(last), strtrim(first)); + u->fullname = strsave(buf); + u->status = status; + u->users_id = id; + switch (u->potype) { + case 'P': + u->pobox_id = id2; + break; + case 'S': + u->pobox_id = id3; + break; + default: + u->pobox_id = 0; + } + hash_store(users, id, u); +## } + + dprintf("Loading machines...\n"); + machines = create_hash(1000); +## range of m is machine +## retrieve (id = m.mach_id, name = m.#name) { + m = (struct machine *) malloc(sizeof(struct machine)); + if (m == NULL) + out_of_mem("storing machines"); + strcpy(m->name, strtrim(name)); + m->mach_id = id; + hash_store(machines, id, m); +## } + + dprintf("Loading nfsphys...\n"); + nfsphys = create_hash(500); +## retrieve (id = nfsphys.nfsphys_id, name = nfsphys.dir, +## id2 = nfsphys.mach_id, id3 = nfsphys.allocated) { + n = (struct nfsphys *) malloc(sizeof(struct nfsphys)); + if (n == NULL) + out_of_mem("storing nfsphys"); + strcpy(n->dir, strtrim(name)); + n->mach_id = id2; + n->nfsphys_id = id; + n->allocated = id3; + n->count = 0; + hash_store(nfsphys, id, n); +## } + + dprintf("Counting quotas...\n"); +## retrieve (id = quota.phys_id, id2 = quota.quota) { + if (n = (struct nfsphys *) hash_lookup(nfsphys, id)) { + n->count += id2; + } +## } +##} -- 2.45.2