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