]> andersk Git - moira.git/blob - dbck/dbck.pc
eliminate use of the `register' keyword: let the compiler decide
[moira.git] / dbck / dbck.pc
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 <string.h>
13 #include <signal.h>
14 #include "dbck.h"
15 EXEC SQL INCLUDE sqlca;
16 EXEC SQL INCLUDE sqlda;
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 void interrupt();
33 SQLDA *mr_sqlda;
34
35 extern SQLDA *sqlald(int, int, int);
36
37 int main(int argc, 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   setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
48
49   while (++arg - argv < argc)
50     {
51       if  (**arg == '-')
52         {
53           switch ((*arg)[1])
54             {
55             case 'd':
56               debug = atoi((*arg)[2] ? *arg + 2 : *++arg);
57               break;
58             case 'n':
59               mode = MODE_NO;
60               break;
61             case 'y':
62               mode = MODE_YES;
63               break;
64             case 'p':
65               mode = MODE_PREEN;
66               break;
67             case 'a':
68               mode = MODE_ASK;
69               break;
70             case 'c':
71               countonly++;
72               break;
73             case 'f':
74               fast++;
75               break;
76             case 'w':
77               warn = 0;
78               break;
79             default:
80               printf("Usage: %s [-d level] [-n] [-y] [-p] [-a] [-c] [-f] [-w] [database]\n",
81                      argv[0]);
82               exit(1);
83             }
84         }
85       else
86         database = *arg;
87     }
88   if (countonly)
89     printf("Only doing counts\n");
90   else if (fast)
91     printf("Doing fast version (skipping some checks)\n");
92   if (mode == MODE_NO)
93     printf("Will NOT modify the database\n");
94   else if (mode == MODE_PREEN)
95     printf("Will fix simple things without asking\n");
96   else if (mode == MODE_YES)
97     printf("Will fix everything without asking\n");
98   if (debug)
99     printf("Debug level is %d\n", debug);
100
101   signal(SIGHUP, interrupt);
102   signal(SIGQUIT, interrupt);
103   signal(SIGINT, interrupt);
104
105   modtables = sq_create();
106   mr_sqlda = sqlald(1, 255, 0);
107
108   EXEC SQL WHENEVER SQLERROR DO dbmserr();
109   printf("Opening database %s...", database);
110   fflush(stdout);
111   EXEC SQL CONNECT :database IDENTIFIED BY :database;
112   printf("done\n");
113   EXEC SQL SELECT value INTO :dcmenable FROM numvalues
114     WHERE name = 'dcm_enable';
115   dprintf("DCM disabled (was %d)\n", dcmenable);
116   EXEC SQL UPDATE numvalues SET value = 0 WHERE name = 'dcm_enable';
117
118   /* Begin transaction here. */
119
120   if (!countonly)
121     {
122       phase1();
123       EXEC SQL COMMIT WORK;
124       phase2();
125       EXEC SQL COMMIT WORK;
126       phase3();
127       EXEC SQL COMMIT WORK;
128     }
129   else
130     {
131       count_only_setup();
132       EXEC SQL COMMIT WORK;
133     }
134   phase4();
135   EXEC SQL COMMIT WORK;
136
137   cleanup();
138   printf("Done.\n");
139   exit(0);
140 }
141
142 int dbmserr(void)
143 {
144   EXEC SQL BEGIN DECLARE SECTION;
145   char buf[512];
146   EXEC SQL END DECLARE SECTION;
147   int bufsize = 256, msglength = 0;
148
149   if (sqlca.sqlcode == 1403)
150     return;
151   printf("A DBMS error occurred, code %d\n", sqlca.sqlcode);
152   sqlglm(buf, &bufsize, &msglength);
153   buf[msglength] = '\0';
154   printf("%s\n", buf);
155   printf("Aborting...\n");
156   if (!abort_p)
157     {
158       abort_p++;
159       EXEC SQL ROLLBACK WORK;
160     }
161   exit(1);
162 }
163
164
165 void interrupt(void)
166 {
167   printf("Signal caught\n");
168   if (prompt("Save database changes"))
169     {
170       EXEC SQL COMMIT WORK;
171       cleanup();
172       exit(0);
173     }
174   printf("Aborting transaction\n");
175   if (!abort_p)
176     {
177       abort_p++;
178       EXEC SQL ROLLBACK WORK;
179     }
180
181   EXEC SQL UPDATE numvalues SET value = :dcmenable
182     WHERE name = 'dcm_enable';
183
184   exit(0);
185 }
186
187
188 int modified(char *table)
189 {
190   sq_save_unique_string(modtables, table);
191 }
192
193 int cleanup(void)
194 {
195   EXEC SQL BEGIN DECLARE SECTION;
196   char *tab;
197   EXEC SQL END DECLARE SECTION;
198
199   while (sq_get_data(modtables, &tab))
200     {
201       EXEC SQL UPDATE tblstats SET modtime = SYSDATE
202         WHERE table_name = :tab;
203     }
204   EXEC SQL UPDATE numvalues SET value = :dcmenable
205     WHERE name = 'dcm_enable';
206 }
207
208
209 int out_of_mem(char *msg)
210 {
211   fprintf(stderr, "Out of memory while %s\n", msg);
212   if (prompt("Save database changes"))
213     {
214       EXEC SQL COMMIT WORK;
215       cleanup();
216       exit(1);
217     }
218   printf("Aborting transaction\n");
219   EXEC SQL ROLLBACK WORK;
220   exit(1);
221 }
This page took 0.106213 seconds and 5 git commands to generate.