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