]> andersk Git - moira.git/blob - dbck/dbck.dc
dbck fixes by kcr, dkk, and myself from the end of the summer.
[moira.git] / dbck / dbck.dc
1 /* $Header$
2  *
3  * Moira database consistency checker
4  *
5  *  (c) Copyright 1988 by the Massachusetts Institute of Technology.
6  *  For copying and distribution information, please see the file
7  *  <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include <stdio.h>
12 #include <strings.h>
13 #include <signal.h>
14 #include "dbck.h"
15 EXEC SQL INCLUDE sqlca;
16
17
18 static char dbck_qc_rcsid[] = "$Header$";
19
20
21 int debug = 0;
22 int mode = MODE_ASK;
23 int fast = 0;
24 int warn = 1;
25 int abort_p = 0;
26 struct hash *users, *machines, *clusters, *lists, *filesys, *nfsphys;
27 struct hash *strings, *members, *subnets, *string_dups;
28 EXEC SQL BEGIN DECLARE SECTION; 
29 int dcmenable;
30 EXEC SQL END DECLARE SECTION; 
31 struct save_queue *modtables, *sq_create();
32 int interrupt();
33
34
35 main(argc, argv)
36 int argc;
37 char **argv;
38 {
39     char **arg = argv;
40 EXEC SQL BEGIN DECLARE SECTION; 
41     char *database;
42 EXEC SQL END DECLARE SECTION; 
43     int ingerr();
44     int countonly = 0;
45
46     database = "moira";
47
48     while (++arg - argv < argc) {
49         if  (**arg == '-')
50           switch ((*arg)[1]) {
51           case 'd':
52               debug = atoi((*arg)[2] ? *arg+2 : *++arg);
53               break;
54           case 'n':
55               mode = MODE_NO;
56               break;
57           case 'y':
58               mode = MODE_YES;
59               break;
60           case 'p':
61               mode = MODE_PREEN;
62               break;
63           case 'a':
64               mode = MODE_ASK;
65               break;
66           case 'c':
67               countonly++;
68               break;
69           case 'f':
70               fast++;
71               break;
72           case 'w':
73               warn = 0;
74               break;
75           default:
76               printf("Usage: %s [-d level] [-n] [-y] [-p] [-a] [-c] [-f] [-w] [database]\n",
77                      argv[0]);
78               exit(1);
79           }
80         else
81           database = *arg;
82     }
83     if (countonly)
84       printf("Only doing counts\n");
85     else if (fast)
86       printf("Doing fast version (skipping some checks)\n");
87     if (mode == MODE_NO)
88       printf("Will NOT modify the database\n");
89     else if (mode == MODE_PREEN)
90       printf("Will fix simple things without asking\n");
91     else if (mode == MODE_YES)
92       printf("Will fix everything without asking\n");
93     if (debug)
94       printf("Debug level is %d\n", debug);
95
96     setlinebuf(stdout);
97
98     signal(SIGHUP, interrupt);
99     signal(SIGQUIT, interrupt);
100     signal(SIGINT, interrupt);
101     modtables = sq_create();
102
103     IIseterr(ingerr);
104     printf("Opening database %s...", database);
105     fflush(stdout);
106     EXEC SQL CONNECT :database;
107     printf("done\n");
108     EXEC SQL SELECT value INTO :dcmenable FROM numvalues 
109         WHERE name='dcm_enable'; 
110     dprintf("DCM disabled (was %d)\n", dcmenable);
111     EXEC SQL UPDATE numvalues SET value=0 WHERE name='dcm_enable';
112
113     /* Begin transaction here. */
114
115     if (!countonly) {
116         phase1();
117         EXEC SQL COMMIT WORK;
118         phase2();
119         EXEC SQL COMMIT WORK;
120         phase3();
121         EXEC SQL COMMIT WORK;
122     } else {
123         count_only_setup();
124         EXEC SQL COMMIT WORK;
125     }
126     phase4();
127     EXEC SQL COMMIT WORK;
128
129     cleanup();
130     printf("Done.\n");
131     exit(0);
132 }
133
134 ingerr(num)
135 int     *num;
136 {
137 EXEC SQL BEGIN DECLARE SECTION;
138     char buf[512];
139 EXEC SQL END DECLARE SECTION;
140
141     if (*num == 100) return;
142     printf("An ingres error occurred, code %d\n", *num);
143     EXEC SQL INQUIRE_SQL(:buf = errortext);
144     printf("%s\n", buf);
145     printf("Aborting...\n");
146     if (!abort_p) {
147         abort_p++;
148         EXEC SQL ROLLBACK WORK;
149     }
150     exit(1);
151 }
152
153
154 int interrupt()
155 {
156     printf("Signal caught\n");
157     if (prompt("Save database changes")) {
158         /* break out of a retrieve loop */
159         IIbreak();
160
161         EXEC SQL COMMIT WORK;
162         cleanup();
163         exit(0);
164     }
165     printf("Aborting transaction\n");
166     if (!abort_p) {
167         abort_p++;
168         /* break out of a retrieve loop */
169         IIbreak();
170         EXEC SQL ROLLBACK WORK;
171     }
172
173     EXEC SQL UPDATE numvalues SET value=:dcmenable
174         WHERE name='dcm_enable';
175
176     exit(0);
177 }
178
179
180 modified(table)
181 char *table;
182 {
183     sq_save_unique_string(modtables, table);
184 }
185
186 cleanup()
187 {
188     EXEC SQL BEGIN DECLARE SECTION; 
189     char *tab;
190     EXEC SQL END DECLARE SECTION; 
191
192     while (sq_get_data(modtables, &tab)) {
193         EXEC SQL REPEATED UPDATE tblstats SET modtime='now'
194             WHERE table_name = :tab;
195     }
196     EXEC SQL UPDATE numvalues SET value = :dcmenable
197         WHERE name='dcm_enable';
198 }
199
200
201 out_of_mem(msg)
202 char *msg;
203 {
204     fprintf(stderr, "Out of memory while %s\n", msg);
205     if (prompt("Save database changes")) {
206         /* break out of a retrieve loop */
207         IIbreak();
208
209         EXEC SQL COMMIT WORK;
210         cleanup();
211         exit(1);
212     }
213     printf("Aborting transaction\n");
214     IIbreak();
215     EXEC SQL ROLLBACK WORK;
216     exit(1);
217 }
This page took 0.053084 seconds and 5 git commands to generate.