]> andersk Git - moira.git/blob - dbck/dbck.pc
make things depend on libmoira.a, libgdss.a, and rsaref.a as appropriate
[moira.git] / dbck / dbck.pc
1 /* $Id$
2  *
3  * Moira database consistency checker
4  *
5  * (c) Copyright 1988-1998 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 <moira.h>
12 #include "dbck.h"
13
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 EXEC SQL INCLUDE sqlca;
19 EXEC SQL INCLUDE sqlda;
20
21 RCSID("$Header$");
22
23 int debug = 0;
24 int mode = MODE_ASK;
25 int fast = 0;
26 int warn = 1;
27 int abort_p = 0;
28 struct hash *users, *machines, *clusters, *lists, *filesys, *nfsphys;
29 struct hash *strings, *members, *subnets, *string_dups;
30 EXEC SQL BEGIN DECLARE SECTION;
31 int dcmenable;
32 EXEC SQL END DECLARE SECTION;
33 struct save_queue *modtables;
34 SQLDA *mr_sqlda;
35
36 void interrupt(void);
37 extern SQLDA *sqlald(int, int, int);
38 extern void sqlglm(char *, unsigned int *, unsigned int *);
39
40 int main(int argc, char **argv)
41 {
42   char **arg = argv;
43   EXEC SQL BEGIN DECLARE SECTION;
44   char *database;
45   EXEC SQL END DECLARE SECTION;
46   struct sigaction sa;
47
48   database = "moira";
49   setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
50
51   while (++arg - argv < argc)
52     {
53       if  (**arg == '-')
54         {
55           switch ((*arg)[1])
56             {
57             case 'd':
58               debug = atoi((*arg)[2] ? *arg + 2 : *++arg);
59               break;
60             case 'n':
61               mode = MODE_NO;
62               break;
63             case 'y':
64               mode = MODE_YES;
65               break;
66             case 'p':
67               mode = MODE_PREEN;
68               break;
69             case 'a':
70               mode = MODE_ASK;
71               break;
72             case 'f':
73               fast++;
74               break;
75             case 'w':
76               warn = 0;
77               break;
78             default:
79               printf("Usage: %s [-d level] [-n] [-y] [-p] [-a] [-f] [-w] [database]\n",
80                      argv[0]);
81               exit(1);
82             }
83         }
84       else
85         database = *arg;
86     }
87   if (fast)
88     printf("Doing fast version (skipping some checks)\n");
89   if (mode == MODE_NO)
90     printf("Will NOT modify the database\n");
91   else if (mode == MODE_PREEN)
92     printf("Will fix simple things without asking\n");
93   else if (mode == MODE_YES)
94     printf("Will fix everything without asking\n");
95   if (debug)
96     printf("Debug level is %d\n", debug);
97
98   sa.sa_handler = interrupt;
99   sa.sa_flags = 0;
100   sigemptyset(&sa.sa_mask);
101   sigaction(SIGHUP, &sa, NULL);
102   sigaction(SIGQUIT, &sa, NULL);
103   sigaction(SIGINT, &sa, NULL);
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   if (mode != MODE_NO)
114     {
115       EXEC SQL SELECT value INTO :dcmenable FROM numvalues
116         WHERE name = 'dcm_enable';
117       dprintf("DCM disabled (was %d)\n", dcmenable);
118       EXEC SQL UPDATE numvalues SET value = 0 WHERE name = 'dcm_enable';
119     }
120
121   /* Begin transaction here. */
122
123   phase1();
124   EXEC SQL COMMIT WORK;
125   phase2();
126   EXEC SQL COMMIT WORK;
127   phase3();
128   EXEC SQL COMMIT WORK;
129   phase4();
130   EXEC SQL COMMIT WORK;
131
132   cleanup();
133   printf("Done.\n");
134   exit(0);
135 }
136
137 void dbmserr(void)
138 {
139   EXEC SQL BEGIN DECLARE SECTION;
140   char buf[256];
141   EXEC SQL END DECLARE SECTION;
142   int bufsize = 256, msglength = 0;
143
144   if (sqlca.sqlcode == 1403)
145     return;
146   printf("A DBMS error occurred, code %ld\n", sqlca.sqlcode);
147   sqlglm(buf, &bufsize, &msglength);
148   buf[msglength] = '\0';
149   printf("%s\n", buf);
150   printf("Aborting...\n");
151   if (!abort_p)
152     {
153       abort_p++;
154       EXEC SQL ROLLBACK WORK;
155     }
156   exit(1);
157 }
158
159
160 void interrupt(void)
161 {
162   printf("Signal caught\n");
163   if (prompt("Save database changes"))
164     {
165       EXEC SQL COMMIT WORK;
166       cleanup();
167       exit(0);
168     }
169   printf("Aborting transaction\n");
170   if (!abort_p)
171     {
172       abort_p++;
173       EXEC SQL ROLLBACK WORK;
174     }
175
176   EXEC SQL UPDATE numvalues SET value = :dcmenable
177     WHERE name = 'dcm_enable';
178
179   exit(0);
180 }
181
182
183 void modified(char *table)
184 {
185   sq_save_unique_string(modtables, table);
186 }
187
188 void cleanup(void)
189 {
190   EXEC SQL BEGIN DECLARE SECTION;
191   char *tab;
192   EXEC SQL END DECLARE SECTION;
193
194   while (sq_get_data(modtables, &tab))
195     {
196       EXEC SQL UPDATE tblstats SET modtime = SYSDATE
197         WHERE table_name = :tab;
198     }
199   EXEC SQL UPDATE numvalues SET value = :dcmenable
200     WHERE name = 'dcm_enable';
201 }
202
203
204 void out_of_mem(char *msg)
205 {
206   fprintf(stderr, "Out of memory while %s\n", msg);
207   if (prompt("Save database changes"))
208     {
209       EXEC SQL COMMIT WORK;
210       cleanup();
211       exit(1);
212     }
213   printf("Aborting transaction\n");
214   EXEC SQL ROLLBACK WORK;
215   exit(1);
216 }
This page took 0.055013 seconds and 5 git commands to generate.