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