]> andersk Git - moira.git/blob - dbck/phase2.pc
Command line printer manipulation client, and build goo.
[moira.git] / dbck / phase2.pc
1 /* $Id$
2  *
3  * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
4  * For copying and distribution information, please see the file
5  * <mit-copyright.h>.
6  */
7
8 #include <mit-copyright.h>
9 #include <moira.h>
10 #include "dbck.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 EXEC SQL INCLUDE sqlca;
17
18 RCSID("$Header$");
19
20 EXEC SQL WHENEVER SQLERROR DO dbmserr();
21
22 int show_mcm_mach(void *id);
23 int show_mcm_clu(void *id);
24 int show_mcntmap_mach(void *id);
25 int show_mcntmap_cnt(void *id);
26 int show_hostalias(void *id);
27 int show_printer_mach(void *id);
28 int show_printer_server(void *id);
29 int show_printer_loghost(void *id);
30 int show_printer_spool(void *id);
31 int show_printer_quota(void *id);
32 int show_printer_ac(void *id);
33 int show_printer_lpc_acl(void *id);
34 void fix_printer_ac(void *id);
35 void fix_printer_lpc_acl(void *id);
36 void user_check(int id, void *user, void *hint);
37 void clear_user_sponsor(struct user *u);
38 int maybe_fixup_unref_string(int sid, int oid, char *oname, char *table,
39                              char *field, char *idfield);
40 int maybe_fixup_modby(int sid, int oid, char *oname, char *table,
41                       char *field, char *idfield);
42 int maybe_fixup_unref_string2(char *table, char *field, char *rowid, int sid);
43 int maybe_fixup_modby2(char *table, char *field, char *rowid, int id);
44 void pobox_check(int id, struct user *u);
45 void remove_pobox(int id);
46 void fix_smtp_pobox(int id, int sid);
47 void mach_check(int id, void *machine, void *hint);
48 void subnet_check(int id, void *subnet, void *hint);
49 void clear_subnet_owner(struct subnet *s);
50 void clear_mach_owner(struct machine *m);
51 void cluster_check(int id, void *cluster, void *hint);
52 int show_svc(void *id);
53 void list_check(int id, void *list, void *hint);
54 void fix_list_acl(int id);
55 void fix_list_memacl(int id);
56 int show_member_list(void *id);
57 int show_mem_user(void *id);
58 int show_mem_list(void *id);
59 int show_mem_str(void *id);
60 int show_mem_krb(void *id);
61 int show_mem_mach(void *id);
62 void del_mem_user(void *id);
63 void del_mem_list(void *id);
64 void del_mem_str(void *id);
65 void del_mem_krb(void *id);
66 void del_mem_mach(void *id);
67 int show_sh(void *id);
68 void del_sh_mach(void *id);
69 void fsmatch(int id, void *nfsphys, void *filesys);
70 void check_fs(int id, void *filesys, void *hint);
71 void check_nfsphys(int id, void *nfsphys, void *hint);
72 void check_ps(int id, void *printserver, void *hint);
73 void check_container(int id, void *container, void *hint);
74 void fix_container_acl(int id);
75 void fix_container_memacl(int id);
76 int show_fsg_missing(void *id);
77 int show_fsg_type(void *filesys);
78 void fix_fsg_type(void *filesys);
79 int show_fsg_nomember(void *id);
80 int show_quota_nouser(void *id);
81 int show_quota_nolist(void *id);
82 void fix_quota_nouser(void *id);
83 void fix_quota_nolist(void *id);
84 int show_quota_nofs(void *id);
85 void fix_quota_nofs(void *id);
86 int show_quota_wrongpid(void *id);
87 void fix_quota_physid(void *id);
88 int show_srv_user(void *id);
89 int show_srv_list(void *id);
90 void zero_srv_user(void *id);
91 void zero_srv_list(void *id);
92 int show_krb_usr(void *id);
93 int show_krb_str(void *id);
94 int show_pdm_mach(void *id);
95
96 int show_mcm_mach(void *id)
97 {
98   EXEC SQL BEGIN DECLARE SECTION;
99   int iid = (int)id, found = 1;
100   char name[CLUSTERS_NAME_SIZE];
101   EXEC SQL END DECLARE SECTION;
102
103   EXEC SQL DECLARE csr201 CURSOR FOR
104     SELECT clusters.name FROM clusters, mcmap
105     WHERE clusters.clu_id = mcmap.clu_id AND mcmap.mach_id = :iid;
106   EXEC SQL OPEN csr201;
107   while (1)
108     {
109       EXEC SQL FETCH csr201 INTO :name;
110       if (sqlca.sqlcode)
111         break;
112
113       strtrim(name);
114       found = 0;
115       printf("Cluster %s, non-existant machine %d in cluster map\n",
116              name, iid);
117     }
118   EXEC SQL CLOSE csr201;
119   return found;
120 }
121
122 int show_mcm_clu(void *id)
123 {
124   EXEC SQL BEGIN DECLARE SECTION;
125   int iid = (int)id, found = 1;
126   char name[MACHINE_NAME_SIZE];
127   EXEC SQL END DECLARE SECTION;
128
129   EXEC SQL DECLARE csr202 CURSOR FOR
130     SELECT machine.name FROM machine, mcmap
131     WHERE machine.mach_id = mcmap.mach_id AND mcmap.clu_id = :iid;
132   EXEC SQL OPEN csr202;
133   while (1)
134     {
135       EXEC SQL FETCH csr202 INTO :name;
136       if (sqlca.sqlcode)
137         break;
138
139       strtrim(name);
140
141       found = 0;
142       printf("Machine %s, non-existant cluster %d in cluster map\n",
143              name, iid);
144     }
145   EXEC SQL CLOSE csr202;
146   return found;
147 }
148
149 int show_mcntmap_mach(void *id)
150 {
151   EXEC SQL BEGIN DECLARE SECTION;
152   int iid = (int)id, found = 1;
153   char name[CONTAINERS_NAME_SIZE];
154   EXEC SQL END DECLARE SECTION;
155
156   EXEC SQL DECLARE csr_show_mcnt_mach CURSOR FOR
157     SELECT cnt.name FROM container cnt, mcntmap mc
158     WHERE cnt.cnt_id = mc.cnt_id AND mc.mach_id = :iid;
159   EXEC SQL OPEN csr_show_mcnt_mach;
160   while (1)
161     {
162       EXEC SQL FETCH csr_show_mcnt_mach INTO :name;
163       if (sqlca.sqlcode)
164         break;
165
166       strtrim(name);
167       found = 0;
168       printf("Container %s, non-existant machine %d in container map\n",
169              name, iid);
170     }
171   EXEC SQL CLOSE csr_show_mcnt_mach;
172   return found;
173 }
174
175 int show_mcntmap_cnt(void *id)
176 {
177   EXEC SQL BEGIN DECLARE SECTION;
178   int iid = (int)id, found = 1;
179   char name[MACHINE_NAME_SIZE];
180   EXEC SQL END DECLARE SECTION;
181
182   EXEC SQL DECLARE csr_show_mcnt_cnt CURSOR FOR
183     SELECT m.name FROM machine m, mcntmap mc
184     WHERE m.mach_id = mc.mach_id AND mc.cnt_id = :iid;
185   EXEC SQL OPEN csr_show_mcnt_cnt;
186   while (1)
187     {
188       EXEC SQL FETCH csr_show_mcnt_cnt INTO :name;
189       if (sqlca.sqlcode)
190         break;
191
192       strtrim(name);
193
194       found = 0;
195       printf("Machine %s, non-existant container %d in container map\n",
196              name, iid);
197     }
198   EXEC SQL CLOSE csr_show_mcnt_cnt;
199   return found;
200 }
201
202 int show_hostalias(void *id)
203 {
204   EXEC SQL BEGIN DECLARE SECTION;
205   int iid = (int)id, found = 1;
206   char name[HOSTALIAS_NAME_SIZE];
207   EXEC SQL END DECLARE SECTION;
208
209   EXEC SQL DECLARE csr234 CURSOR FOR
210     SELECT name FROM hostalias WHERE mach_id = :iid;
211   EXEC SQL OPEN csr234;
212   while (1)
213     {
214       EXEC SQL FETCH csr234 INTO :name;
215       if (sqlca.sqlcode)
216         break;
217
218       strtrim(name);
219
220       found = 0;
221       printf("Alias %s, non-existant machine %d in hostalias map\n",
222              name, iid);
223     }
224   EXEC SQL CLOSE csr234;
225   return found;
226 }
227
228 int show_printer_mach(void *id)
229 {
230   EXEC SQL BEGIN DECLARE SECTION;
231   int iid = (int)id, found = 1;
232   char name[PRINTERS_NAME_SIZE];
233   EXEC SQL END DECLARE SECTION;
234
235   EXEC SQL DECLARE csr235 CURSOR FOR
236     SELECT name FROM printers WHERE mach_id = :iid;
237   EXEC SQL OPEN csr235;
238   while (1)
239     {
240       EXEC SQL FETCH csr235 INTO :name;
241       if (sqlca.sqlcode)
242         break;
243
244       strtrim(name);
245
246       found = 0;
247       printf("Printer %s, non-existant machine %d in printers table\n",
248              name, iid);
249     }
250   EXEC SQL CLOSE csr235;
251   return found;
252 }
253
254 int show_printer_server(void *id)
255 {
256   EXEC SQL BEGIN DECLARE SECTION;
257   int iid = (int)id, found = 1;
258   char name[PRINTERS_NAME_SIZE];
259   EXEC SQL END DECLARE SECTION;
260
261   EXEC SQL DECLARE csr_sps CURSOR FOR
262     SELECT name FROM printers WHERE mach_id = :iid;
263   EXEC SQL OPEN csr_sps;
264   while (1)
265     {
266       EXEC SQL FETCH csr_sps INTO :name;
267       if (sqlca.sqlcode)
268         break;
269
270       strtrim(name);
271
272       found = 0;
273       printf("Printer %s, non-existant printserver %d in printers table\n",
274              name, iid);
275     }
276   EXEC SQL CLOSE csr_sps;
277   return found;
278 }
279
280 int show_printer_loghost(void *id)
281 {
282   EXEC SQL BEGIN DECLARE SECTION;
283   int iid = (int)id, found = 1;
284   char name[PRINTERS_NAME_SIZE];
285   EXEC SQL END DECLARE SECTION;
286
287   EXEC SQL DECLARE csr236 CURSOR FOR
288     SELECT name FROM printers WHERE loghost = :iid;
289   EXEC SQL OPEN csr236;
290   while (1)
291     {
292       EXEC SQL FETCH csr236 INTO :name;
293       if (sqlca.sqlcode)
294         break;
295
296       strtrim(name);
297
298       found = 0;
299       printf("Printer %s, non-existant spool machine %d in printers table\n",
300              name, iid);
301     }
302   EXEC SQL CLOSE csr236;
303   return found;
304 }
305
306 int show_printer_spool(void *id)
307 {
308   EXEC SQL BEGIN DECLARE SECTION;
309   int iid = (int)id, found = 1;
310   char name[PRINTERS_NAME_SIZE];
311   EXEC SQL END DECLARE SECTION;
312
313   EXEC SQL DECLARE csr237 CURSOR FOR
314     SELECT name FROM printers WHERE rm = :iid;
315   EXEC SQL OPEN csr237;
316   while (1)
317     {
318       EXEC SQL FETCH csr237 INTO :name;
319       if (sqlca.sqlcode)
320         break;
321
322       strtrim(name);
323
324       found = 0;
325       printf("Printer %s, non-existant spool machine %d in printers table\n",
326              name, iid);
327     }
328   EXEC SQL CLOSE csr237;
329   return found;
330 }
331
332 int show_printer_quota(void *id)
333 {
334   EXEC SQL BEGIN DECLARE SECTION;
335   int iid = (int)id, found = 1;
336   char name[PRINTERS_NAME_SIZE];
337   EXEC SQL END DECLARE SECTION;
338
339   EXEC SQL DECLARE csr238 CURSOR FOR
340     SELECT name FROM printers WHERE rq = :iid;
341   EXEC SQL OPEN csr238;
342   while (1)
343     {
344       EXEC SQL FETCH csr238 INTO :name;
345       if (sqlca.sqlcode)
346         break;
347
348       strtrim(name);
349
350       found = 0;
351       printf("Printer %s, non-existant quota server %d in printers table\n",
352              name, iid);
353     }
354   EXEC SQL CLOSE csr238;
355   return found;
356 }
357
358 int show_printer_ac(void *id)
359 {
360   EXEC SQL BEGIN DECLARE SECTION;
361   int iid = (int)id, found = 1;
362   char name[PRINTERS_NAME_SIZE];
363   EXEC SQL END DECLARE SECTION;
364
365   EXEC SQL DECLARE csr239 CURSOR FOR
366     SELECT name FROM printers WHERE ac = :iid;
367   EXEC SQL OPEN csr239;
368   while (1)
369     {
370       EXEC SQL FETCH csr239 INTO :name;
371       if (sqlca.sqlcode)
372         break;
373
374       strtrim(name);
375
376       found = 0;
377       printf("Printer %s, non-existant restrict list %d in printers table\n",
378              name, iid);
379     }
380   EXEC SQL CLOSE csr239;
381   return found;
382 }
383
384 int show_printer_lpc_acl(void *id)
385 {
386   EXEC SQL BEGIN DECLARE SECTION;
387   int iid = (int)id, found = 1;
388   char name[PRINTERS_NAME_SIZE];
389   EXEC SQL END DECLARE SECTION;
390
391   EXEC SQL DECLARE csr240 CURSOR FOR
392     SELECT name FROM printers WHERE lpc_acl = :iid;
393   EXEC SQL OPEN csr240;
394   while (1)
395     {
396       EXEC SQL FETCH csr240 INTO :name;
397       if (sqlca.sqlcode)
398         break;
399
400       strtrim(name);
401
402       found = 0;
403       printf("Printer %s, non-existant lpc ACL %d in printers table\n",
404              name, iid);
405     }
406   EXEC SQL CLOSE csr240;
407   return found;
408 }
409
410 void fix_printer_ac(void *id)
411 {
412   EXEC SQL BEGIN DECLARE SECTION;
413   int rowcount, iid = (int)id;
414   EXEC SQL END DECLARE SECTION;
415
416   EXEC SQL UPDATE printers SET ac = 0 WHERE ac = :iid;
417   rowcount = sqlca.sqlerrd[2];
418   if (rowcount > 0)
419     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
420   else
421     printf("Not fixed\n");
422   modified("printers");
423 }
424
425 void fix_printer_lpc_acl(void *id)
426 {
427   EXEC SQL BEGIN DECLARE SECTION;
428   int rowcount, iid = (int)id;
429   EXEC SQL END DECLARE SECTION;
430
431   EXEC SQL UPDATE printers SET lpc_acl = 0 WHERE lpc_acl = :iid;
432   rowcount = sqlca.sqlerrd[2];
433   if (rowcount > 0)
434     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
435   else
436     printf("Not fixed\n");
437   modified("printers");
438 }
439
440 void user_check(int id, void *user, void *hint)
441 {
442   struct user *u = user;
443
444   u->comment = maybe_fixup_unref_string(u->comment, id, u->login, "users",
445                                         "comments", "users_id");
446
447   u->modby = maybe_fixup_modby(u->modby, id, u->login, "users",
448                                "modby", "users_id");
449
450   u->fmodby = maybe_fixup_modby(u->fmodby, id, u->login, "users",
451                                 "fmodby", "users_id");
452
453   u->pmodby = maybe_fixup_modby(u->pmodby, id, u->login, "users",
454                                 "pmodby", "users_id");
455
456   u->sigwho = maybe_fixup_unref_string(u->sigwho, id, u->login, "users",
457                                        "sigwho", "users_id");
458
459   switch (u->sponsor_type)
460     {
461     case 'U':
462       if (!hash_lookup(users, u->sponsor_id))
463         {
464           printf("User %s has non-existant USER sponsor %d\n",
465                  u->login, u->sponsor_id);
466           if (single_fix("Set to no sponsor", 1))
467             clear_user_sponsor(u);
468         }
469       break;
470     case 'L':
471       if (!hash_lookup(lists, u->sponsor_id))
472         {
473           printf("User %s has non-existant LIST sponsor %d\n",
474                  u->login, u->sponsor_id);
475           if (single_fix("Set to no sponsor", 1))
476             clear_user_sponsor(u);
477         }
478       break;
479     case 'S':
480     case 'K':
481       if (u->sponsor_id)
482         u->sponsor_id = maybe_fixup_unref_string(u->sponsor_id, id, u->login,
483                                                "users", "sponsor_id",
484                                                "users_id");
485       if (u->sponsor_id == 0)
486         clear_user_sponsor(u);
487     }
488
489   pobox_check(id, u);
490 }
491
492 int maybe_fixup_unref_string(int sid, int oid, char *oname, char *table,
493                              char *field, char *idfield)
494 {
495   int ret = (sid < 0) ? -sid : sid, doit = 0, newid;
496   EXEC SQL BEGIN DECLARE SECTION;
497   int rowcount;
498   char stmt_buf[500];
499   EXEC SQL END DECLARE SECTION;
500
501   if ((newid = (int)hash_lookup(string_dups, ret)))
502     {
503       printf("%s entry %s(%d) has a %s with duplicate string %d\n",
504              table, oname, oid, field, ret);
505       if (single_fix("Replace duplicate", 0))
506         {
507           ret = newid;
508           doit = 1;
509         }
510       string_check(ret);
511     }
512   else if (!string_check(ret))
513     {
514       printf("%s entry %s(%d) has a %s with non-existant string %d\n",
515              table, oname, oid, field, ret);
516       if (single_fix("Delete", 1))
517         {
518           ret = 0;
519           doit = 1;
520         }
521     }
522
523   if (doit)
524     {
525       sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE %s = %d",
526               table, field, (sid < 0) ? -ret : ret, idfield, oid);
527       EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
528       rowcount = sqlca.sqlerrd[2];
529       if (rowcount == 1)
530         printf("Fixed\n");
531       else
532         printf("Not fixed, rowcount = %d\n", rowcount);
533       modified(table);
534     }
535
536   return (sid < 0) ? -ret : ret;
537 }
538
539 int maybe_fixup_modby(int sid, int oid, char *oname, char *table,
540                       char *field, char *idfield)
541 {
542   EXEC SQL BEGIN DECLARE SECTION;
543   char stmt_buf[500];
544   int rowcount;
545   EXEC SQL END DECLARE SECTION;
546
547   if (sid < 0)
548     return maybe_fixup_unref_string(sid, oid, oname, table, field, idfield);
549   else
550     {
551       if (!hash_lookup(users, sid))
552         {
553           printf("%s entry %s(%d) has a %s with non-existant user %d\n",
554                  table, oname, oid, field, sid);
555           if (single_fix("Delete", 1))
556             {
557               sprintf(stmt_buf, "UPDATE %s SET %s = 0 WHERE %s = %d",
558                       table, field, idfield, oid);
559               EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
560               rowcount = sqlca.sqlerrd[2];
561               if (rowcount == 1)
562                 printf("Fixed\n");
563               else
564                 printf("Not fixed, rowcount = %d\n", rowcount);
565               modified(table);
566             }
567           return 0;
568         }
569     }
570   return sid;
571 }
572
573 int maybe_fixup_unref_string2(char *table, char *field, char *rowid, int sid)
574 {
575   int ret = (sid < 0) ? -sid : sid, doit = 0, newid;
576   EXEC SQL BEGIN DECLARE SECTION;
577   int rowcount;
578   char stmt_buf[500];
579   EXEC SQL END DECLARE SECTION;
580
581   if ((newid = (int)hash_lookup(string_dups, ret)))
582     {
583       printf("%s entry has a %s with duplicate string %d\n",
584              table, field, ret);
585       if (single_fix("Replace duplicate", 0))
586         {
587           ret = newid;
588           doit = 1;
589         }
590       string_check(ret);
591     }
592   else if (!string_check(ret))
593     {
594       printf("%s entry has a %s with non-existant string %d\n",
595              table, field, ret);
596       if (single_fix("Clear", 1))
597         {
598           ret = 0;
599           doit = 1;
600         }
601     }
602
603   if (doit)
604     {
605       sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE rowid = '%s'",
606               table, field, (sid < 0) ? -ret : ret, rowid);
607       EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
608       rowcount = sqlca.sqlerrd[2];
609       if (rowcount == 1)
610         printf("Fixed\n");
611       else
612         printf("Not fixed, rowcount = %d\n", rowcount);
613       modified(table);
614     }
615   return (sid < 0) ? -ret : ret;
616 }
617
618 int maybe_fixup_modby2(char *table, char *field, char *rowid, int id)
619 {
620   EXEC SQL BEGIN DECLARE SECTION;
621   char stmt_buf[500];
622   int rowcount;
623   EXEC SQL END DECLARE SECTION;
624
625   if (id < 0)
626     return maybe_fixup_unref_string2(table, field, rowid, id);
627   else
628     {
629       if (!hash_lookup(users, id))
630         {
631           printf("%s entry has a %s with non-existant user %d\n",
632                  table, field, id);
633           if (single_fix("Clear", 1))
634             {
635               sprintf(stmt_buf, "UPDATE %s SET %s = 0 WHERE rowid = '%s'",
636                       table, field, rowid);
637               EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
638               rowcount = sqlca.sqlerrd[2];
639               if (rowcount == 1)
640                 printf("Fixed\n");
641               else
642                 printf("Not fixed, rowcount = %d\n", rowcount);
643               modified(table);
644             }
645           return 0;
646         }
647     }
648   return 1;
649 }
650
651 void pobox_check(int id, struct user *u)
652 {
653   struct filesys *fs;
654
655   switch (u->potype)
656     {
657     case 'P':
658       if (!hash_lookup(machines, u->pobox_id))
659         {
660           printf("User %s(%s) has P.O.Box on non-existant machine %d\n",
661                  u->login, u->fullname, u->pobox_id);
662           if (single_fix("Delete", 0))
663             {
664               remove_pobox(u->users_id);
665               u->potype = 'N';
666             }
667         }
668       break;
669
670     case 'E':
671       if (!hash_lookup(machines, u->pobox_id))
672         {
673           printf("User %s(%s) has P.O.Box on non-existant machine %d\n",
674                  u->login, u->fullname, u->pobox_id);
675           if (single_fix("Delete", 0))
676             {
677               remove_pobox(u->users_id);
678               u->potype = 'N';
679             }
680         }
681       break;
682
683     case 'S':
684       if (hash_lookup(string_dups, u->pobox_id))
685         {
686           printf("User %s(%s) has P.O.Box with duplicate string %d\n",
687                  u->login, u->fullname, u->pobox_id);
688           if (single_fix("Update", 0))
689             {
690               printf("Replacing box_id dup string ID %d with %d\n",
691                      u->pobox_id,
692                      (int)hash_lookup(string_dups, u->pobox_id));
693               u->pobox_id = (int)hash_lookup(string_dups, u->pobox_id);
694               fix_smtp_pobox(u->users_id, u->pobox_id);
695               string_check(u->pobox_id);
696             }
697         }
698       else if (!string_check(u->pobox_id))
699         {
700           printf("User %s(%s) has P.O.Box with non-existant string %d\n",
701                  u->login, u->fullname, u->pobox_id);
702           if (single_fix("Delete", 0))
703             {
704               remove_pobox(u->users_id);
705               u->potype = 'N';
706             }
707         }
708       break;
709
710     case 'I':
711       fs = hash_lookup(filesys, u->pobox_id);
712       if (!fs)
713         {
714           printf("User %s(%s) has P.O.Box on non-existant filesystem %d\n",
715                  u->login, u->fullname, u->pobox_id);
716           if (single_fix("Delete", 0))
717             {
718               remove_pobox(u->users_id);
719               u->potype = 'N';
720             }
721         }
722       else if (fs->type != 'I')
723         {
724           printf("User %s(%s) has IMAP P.O.Box on non-IMAP filesystem %s\n",
725                  u->login, u->fullname, fs->name);
726           if (single_fix("Delete", 0))
727             {
728               remove_pobox(u->users_id);
729               u->potype = 'N';
730             }
731         }
732       break;
733
734     default:
735       ;
736     }
737 }
738
739
740 void remove_pobox(int id)
741 {
742   EXEC SQL BEGIN DECLARE SECTION;
743   int rowcount, iid = (int)id;
744   EXEC SQL END DECLARE SECTION;
745
746   EXEC SQL UPDATE users SET potype = 'NONE' WHERE users.users_id = :iid;
747   rowcount = sqlca.sqlerrd[2];
748   if (rowcount > 0)
749     printf("%d entr%s removed\n", rowcount, rowcount == 1 ? "y" : "ies");
750   else
751     printf("Not removed\n");
752   modified("users");
753 }
754
755 void fix_smtp_pobox(int id, int sid)
756 {
757   EXEC SQL BEGIN DECLARE SECTION;
758   int rowcount, iid = id, isid = sid;
759   EXEC SQL END DECLARE SECTION;
760
761   EXEC SQL UPDATE users SET box_id = :isid WHERE users.users_id = :iid;
762   rowcount = sqlca.sqlerrd[2];
763   if (rowcount > 0)
764     printf("%d entr%s updated\n", rowcount, rowcount == 1 ? "y" : "ies");
765   else
766     printf("Not updated\n");
767   modified("users");
768 }
769
770 void mach_check(int id, void *machine, void *hint)
771 {
772   struct machine *m = machine;
773
774   if (!hash_lookup(subnets, m->snet_id))
775     {
776       printf("Machine %s is on a non-existant subnet %d\n",
777              m->name, m->snet_id);
778       if (single_fix("Move to null-subnet", 1))
779         {
780           EXEC SQL BEGIN DECLARE SECTION;
781           int rowcount, iid = id;
782           EXEC SQL END DECLARE SECTION;
783
784           EXEC SQL UPDATE machine SET snet_id = 0 WHERE mach_id = :iid;
785           rowcount = sqlca.sqlerrd[2];
786           if (rowcount > 0)
787             printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
788           else
789             printf("Not fixed\n");
790           modified("machine");
791         }
792     }
793
794   switch (m->owner_type)
795     {
796     case 'U':
797       if (!hash_lookup(users, m->owner_id))
798         {
799           printf("Machine %s has non-existant USER owner %d\n",
800                  m->name, m->owner_id);
801           if (single_fix("Set to no owner", 1))
802             clear_mach_owner(m);
803         }
804       break;
805     case 'L':
806       if (!hash_lookup(lists, m->owner_id))
807         {
808           printf("Machine %s has non-existant LIST owner %d\n",
809                  m->name, m->owner_id);
810           if (single_fix("Set to no owner", 1))
811             clear_mach_owner(m);
812         }
813       break;
814     case 'S':
815     case 'K':
816       if (m->owner_id)
817         m->owner_id = maybe_fixup_unref_string(m->owner_id, id, m->name,
818                                                "machine", "owner_id",
819                                                "mach_id");
820       if (m->owner_id == 0)
821         clear_mach_owner(m);
822     }
823
824   if (m->acomment)
825     m->acomment = maybe_fixup_unref_string(m->acomment, id, m->name,
826                                            "machine", "acomment", "mach_id");
827   if (m->ocomment)
828     m->ocomment = maybe_fixup_unref_string(m->ocomment, id, m->name,
829                                            "machine", "ocomment", "mach_id");
830
831   m->creator = maybe_fixup_modby(m->creator, id, m->name, "machine",
832                                  "creator", "mach_id");
833   m->modby = maybe_fixup_modby(m->modby, id, m->name, "machine",
834                                "modby", "mach_id");
835 }
836
837 void subnet_check(int id, void *subnet, void *hint)
838 {
839   struct subnet *s = subnet;
840
841   switch (s->owner_type)
842     {
843     case 'U':
844       if (!hash_lookup(users, s->owner_id))
845         {
846           printf("Subnet %s has non-existant USER owner %d\n",
847                  s->name, s->owner_id);
848           if (single_fix("Set to no owner", 1))
849             clear_subnet_owner(s);
850         }
851       break;
852     case 'L':
853       if (!hash_lookup(lists, s->owner_id))
854         {
855           printf("Machine %s has non-existant LIST owner %d\n",
856                  s->name, s->owner_id);
857           if (single_fix("Set to no owner", 1))
858             clear_subnet_owner(s);
859         }
860       break;
861     case 'S':
862     case 'K':
863       if (s->owner_id)
864         s->owner_id = maybe_fixup_unref_string(s->owner_id, id, s->name,
865                                                "machine", "owner_id",
866                                                "mach_id");
867       if (s->owner_id == 0)
868         clear_subnet_owner(s);
869     }
870
871   s->modby = maybe_fixup_modby(s->modby, id, s->name, "subnet",
872                                "modby", "snet_id");
873 }
874
875 void clear_user_sponsor(struct user *u)
876 {
877   EXEC SQL BEGIN DECLARE SECTION;
878   int rowcount, id = u->users_id;
879   EXEC SQL END DECLARE SECTION;
880
881   EXEC SQL UPDATE users SET sponsor_type = 'NONE', sponsor_id = 0
882     WHERE users_id = :id;
883   rowcount = sqlca.sqlerrd[2];
884   if (rowcount > 0)
885     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
886   else
887     printf("Not fixed\n");
888   modified("users");
889 }
890
891 void clear_subnet_owner(struct subnet *s)
892 {
893   EXEC SQL BEGIN DECLARE SECTION;
894   int rowcount, id = s->snet_id;
895   EXEC SQL END DECLARE SECTION;
896
897   EXEC SQL UPDATE subnet SET owner_type = 'NONE', owner_id = 0
898     WHERE snet_id = :id;
899   rowcount = sqlca.sqlerrd[2];
900   if (rowcount > 0)
901     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
902   else
903     printf("Not fixed\n");
904   modified("subnet");
905 }
906
907 void clear_mach_owner(struct machine *m)
908 {
909   EXEC SQL BEGIN DECLARE SECTION;
910   int rowcount, id = m->mach_id;
911   EXEC SQL END DECLARE SECTION;
912
913   EXEC SQL UPDATE machine SET owner_type = 'NONE', owner_id = 0
914     WHERE mach_id = :id;
915   rowcount = sqlca.sqlerrd[2];
916   if (rowcount > 0)
917     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
918   else
919     printf("Not fixed\n");
920   modified("machine");
921 }
922
923 void cluster_check(int id, void *cluster, void *hint)
924 {
925   struct cluster *c = cluster;
926
927   c->modby = maybe_fixup_modby(c->modby, id, c->name, "clusters",
928                                "modby", "clu_id");
929 }
930
931 int show_svc(void *id)
932 {
933   EXEC SQL BEGIN DECLARE SECTION;
934   int iid = (int)id, found = 1;
935   char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
936   EXEC SQL END DECLARE SECTION;
937
938   EXEC SQL DECLARE csr203 CURSOR FOR
939     SELECT serv_label, serv_cluster FROM svc
940     WHERE clu_id = :iid;
941   EXEC SQL OPEN csr203;
942   while (1)
943     {
944       EXEC SQL FETCH csr203 INTO :label, :data;
945       if (sqlca.sqlcode)
946         break;
947
948       strtrim(label);
949       strtrim(data);
950       found = 0;
951       printf("Cluster data [%s] %s for non-existant cluster %d\n",
952              label, data, iid);
953     }
954   EXEC SQL CLOSE csr203;
955   return found;
956 }
957
958 void list_check(int id, void *list, void *hint)
959 {
960   struct list *l = list;
961
962   l->modby = maybe_fixup_modby(l->modby, id, l->name, "list",
963                                "modby", "list_id");
964
965   switch (l->acl_type)
966     {
967     case 'L':
968       if (!hash_lookup(lists, l->acl_id))
969         {
970           printf("List %s has bad LIST acl %d\n", l->name, l->acl_id);
971           if (single_fix("Patch", 1))
972             fix_list_acl(l->list_id);
973         }
974       break;
975     case 'U':
976       if (!hash_lookup(users, l->acl_id))
977         {
978           printf("List %s has bad USER acl %d\n", l->name, l->acl_id);
979           if (single_fix("Patch", 1))
980             fix_list_acl(l->list_id);
981         }
982       break;
983     case 'K':
984       l->acl_id = maybe_fixup_unref_string(l->acl_id, id, l->name,
985                                            "list", "acl_id", "list_id");
986       if (!l->acl_id)
987         {
988           printf("List %s has bad KERBEROS acl %d\n", l->name, l->acl_id);
989           if (single_fix("Patch", 1))
990             fix_list_acl(l->list_id);
991         }
992       break;
993     }
994
995   switch (l->memacl_type)
996     {
997     case 'L':
998       if (!hash_lookup(lists, l->memacl_id))
999         {
1000           printf("List %s has bad LIST memacl %d\n", l->name, l->memacl_id);
1001           if (single_fix("Patch", 1))
1002             fix_list_memacl(l->list_id);
1003         }
1004       break;
1005     case 'U':
1006       if (!hash_lookup(users, l->memacl_id))
1007         {
1008           printf("List %s has bad USER acl %d\n", l->name, l->memacl_id);
1009           if (single_fix("Patch", 1))
1010             fix_list_memacl(l->list_id);
1011         }
1012       break;
1013     case 'K':
1014       l->memacl_id = maybe_fixup_unref_string(l->memacl_id, id, l->name,
1015                                               "list", "memacl_id", "list_id");
1016           if (!l->memacl_id)
1017             {
1018               printf("List %s has bad KERBEROS acl %d\n", l->name, 
1019                      l->memacl_id);
1020               if (single_fix("Patch", 1))
1021                 fix_list_memacl(l->list_id);
1022             }
1023           break;
1024     }
1025 }
1026
1027 void fix_list_acl(int id)
1028 {
1029   EXEC SQL BEGIN DECLARE SECTION;
1030   int rowcount, iid = (int)id;
1031   EXEC SQL END DECLARE SECTION;
1032
1033   EXEC SQL UPDATE list SET acl_id = :iid, acl_type = 'LIST'
1034     WHERE list_id = :iid;
1035   rowcount = sqlca.sqlerrd[2];
1036   if (rowcount > 0)
1037     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1038   else
1039     printf("Not fixed\n");
1040   modified("list");
1041 }
1042
1043 void fix_list_memacl(int id)
1044 {
1045   EXEC SQL BEGIN DECLARE SECTION;
1046   int rowcount, iid = (int)id;
1047   EXEC SQL END DECLARE SECTION;
1048
1049   EXEC SQL UPDATE list SET memacl_id = 0, memacl_type = 'NONE'
1050     WHERE list_id = :iid;
1051   rowcount = sqlca.sqlerrd[2];
1052   if (rowcount > 0)
1053     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1054   else
1055     printf("Not fixed\n");
1056   modified("list");
1057 }
1058
1059 int show_member_list(void *id)
1060 {
1061   EXEC SQL BEGIN DECLARE SECTION;
1062   int mid, iid = (int)id, found = 1;
1063   char mtype[IMEMBERS_MEMBER_TYPE_SIZE], *name = NULL;
1064   EXEC SQL END DECLARE SECTION;
1065
1066   EXEC SQL DECLARE csr204 CURSOR FOR
1067     SELECT member_type, member_id FROM imembers
1068     WHERE list_id = :iid;
1069   EXEC SQL OPEN csr204;
1070   while (1)
1071     {
1072       EXEC SQL FETCH csr204 INTO :mtype, :mid;
1073       if (sqlca.sqlcode)
1074         break;
1075
1076       strtrim(mtype);
1077       found = 0;
1078       if (mtype[0] == 'L')
1079         {
1080           struct list *l = hash_lookup(lists, mid);
1081           if (l)
1082             name = l->name;
1083         }
1084       else if (mtype[0] == 'U')
1085         {
1086           struct user *u = hash_lookup(users, mid);
1087           if (u)
1088             name = u->login;
1089         }
1090       else if (mtype[0] == 'S' || mtype[0] == 'K')
1091         {
1092           struct string *s = hash_lookup(strings, mid);
1093           if (s)
1094             name = s->name;
1095         }
1096       if (name)
1097         printf("Non-existant list %d has member %s %s\n", iid, mtype, name);
1098       else
1099         {
1100           printf("Non-existant list %d has non-existent member %s %d\n",
1101                  iid, mtype, mid);
1102         }
1103     }
1104   EXEC SQL CLOSE csr204;
1105   return found;
1106 }
1107
1108 int show_mem_user(void *id)
1109 {
1110   EXEC SQL BEGIN DECLARE SECTION;
1111   int lid, iid = (int)id, found = 1;
1112   EXEC SQL END DECLARE SECTION;
1113   struct list *l;
1114
1115   EXEC SQL DECLARE csr205 CURSOR FOR
1116     SELECT list_id FROM imembers
1117     WHERE member_id = :iid AND member_type = 'USER';
1118   EXEC SQL OPEN csr205;
1119   while (1)
1120     {
1121       EXEC SQL FETCH csr205 INTO :lid;
1122       if (sqlca.sqlcode)
1123         break;
1124       l = hash_lookup(lists, lid);
1125       if (!l)
1126         continue;
1127
1128       found = 0;
1129       printf("List %s has non-existant user member, id %d\n", l->name, iid);
1130     }
1131   EXEC SQL CLOSE csr205;
1132   return found;
1133 }
1134
1135 int show_mem_list(void *id)
1136 {
1137   EXEC SQL BEGIN DECLARE SECTION;
1138   int lid, iid = (int)id, found = 1;
1139   EXEC SQL END DECLARE SECTION;
1140   struct list *l;
1141
1142   EXEC SQL DECLARE csr206 CURSOR FOR
1143     SELECT list_id FROM imembers
1144     WHERE member_id = :iid AND member_type = 'LIST';
1145   EXEC SQL OPEN csr206;
1146   while (1)
1147     {
1148       EXEC SQL FETCH csr206 INTO :lid;
1149       if (sqlca.sqlcode)
1150         break;
1151       l = hash_lookup(lists, lid);
1152       if (!l)
1153         continue;
1154
1155       found = 0;
1156       printf("List %s has non-existant list member, id %d\n", l->name, iid);
1157     }
1158   EXEC SQL CLOSE csr206;
1159   return found;
1160 }
1161
1162 int show_mem_str(void *id)
1163 {
1164   EXEC SQL BEGIN DECLARE SECTION;
1165   int lid, iid = (int)id, found = 1;
1166   EXEC SQL END DECLARE SECTION;
1167   struct list *l;
1168
1169   EXEC SQL DECLARE csr207 CURSOR FOR
1170     SELECT list_id FROM imembers
1171     WHERE member_id = :iid AND member_type = 'STRING';
1172   EXEC SQL OPEN csr207;
1173   while (1)
1174     {
1175       EXEC SQL FETCH csr207 INTO :lid;
1176       if (sqlca.sqlcode)
1177         break;
1178       l = hash_lookup(lists, lid);
1179       if (!l)
1180         continue;
1181
1182       found = 0;
1183       printf("List %s has non-existant string member, id %d\n", l->name, iid);
1184     }
1185   EXEC SQL CLOSE csr207;
1186   return found;
1187 }
1188
1189
1190 int show_mem_krb(void *id)
1191 {
1192   EXEC SQL BEGIN DECLARE SECTION;
1193   int lid, iid = (int)id, found = 1;
1194   EXEC SQL END DECLARE SECTION;
1195   struct list *l;
1196
1197   EXEC SQL DECLARE csr208 CURSOR FOR
1198     SELECT list_id FROM imembers
1199     WHERE member_id = :iid AND member_type = 'KERBEROS';
1200   EXEC SQL OPEN csr208;
1201   while (1)
1202     {
1203       EXEC SQL FETCH csr208 INTO :lid;
1204       if (sqlca.sqlcode)
1205         break;
1206       l = hash_lookup(lists, lid);
1207       if (!l)
1208         continue;
1209
1210       found = 0;
1211       printf("List %s has non-existant kerberos member, id %d\n",
1212              l->name, iid);
1213     }
1214   EXEC SQL CLOSE csr208;
1215   return found;
1216 }
1217
1218 int show_mem_mach(void *id)
1219 {
1220   EXEC SQL BEGIN DECLARE SECTION;
1221   int lid, iid = (int)id, found = 1;
1222   EXEC SQL END DECLARE SECTION;
1223   struct list *l; 
1224
1225   EXEC SQL DECLARE csr208a CURSOR FOR
1226     SELECT list_id FROM imembers
1227     WHERE member_id = :iid AND member_type = 'MACHINE';
1228   EXEC SQL OPEN csr208a;
1229   while (1)
1230     {
1231       EXEC SQL FETCH csr208a INTO :lid;
1232       if (sqlca.sqlcode)
1233         break;
1234       l = hash_lookup(lists, lid);
1235       if (!l)
1236         continue;
1237
1238       found = 0;
1239       printf("List %s has nonexistant machine member, id %d\n",
1240              l->name, iid);
1241     }
1242   EXEC SQL CLOSE csr208a;
1243   return found;
1244 }
1245
1246 void del_mem_user(void *id)
1247 {
1248   EXEC SQL BEGIN DECLARE SECTION;
1249   int iid = (int)id, rowcount;
1250   EXEC SQL END DECLARE SECTION;
1251
1252   EXEC SQL DELETE FROM imembers WHERE member_type = 'USER' AND
1253     member_id = :iid;
1254   rowcount = sqlca.sqlerrd[2];
1255   if (rowcount > 0)
1256     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1257   else
1258     printf("Not deleted\n");
1259   modified("imembers");
1260 }
1261
1262 void del_mem_list(void *id)
1263 {
1264   EXEC SQL BEGIN DECLARE SECTION;
1265   int iid = (int)id, rowcount;
1266   EXEC SQL END DECLARE SECTION;
1267
1268   EXEC SQL DELETE FROM imembers WHERE member_type = 'LIST' AND
1269     member_id = :iid;
1270   rowcount = sqlca.sqlerrd[2];
1271   if (rowcount > 0)
1272     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1273   else
1274     printf("Not deleted\n");
1275   modified("imembers");
1276 }
1277
1278 void del_mem_str(void *id)
1279 {
1280   EXEC SQL BEGIN DECLARE SECTION;
1281   int iid = (int)id, rowcount;
1282   EXEC SQL END DECLARE SECTION;
1283
1284   EXEC SQL DELETE FROM imembers WHERE member_type = 'STRING' AND
1285     member_id = :iid;
1286   rowcount = sqlca.sqlerrd[2];
1287   if (rowcount > 0)
1288     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1289   else
1290     printf("Not deleted\n");
1291   modified("imembers");
1292 }
1293
1294
1295 void del_mem_krb(void *id)
1296 {
1297   EXEC SQL BEGIN DECLARE SECTION;
1298   int iid = (int)id, rowcount;
1299   EXEC SQL END DECLARE SECTION;
1300
1301   EXEC SQL DELETE FROM imembers WHERE member_type = 'KERBEROS' AND
1302     member_id = :iid;
1303   rowcount = sqlca.sqlerrd[2];
1304   if (rowcount > 0)
1305     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1306   else
1307     printf("Not deleted\n");
1308   modified("imembers");
1309 }
1310
1311 void del_mem_mach(void *id)
1312 {
1313   EXEC SQL BEGIN DECLARE SECTION;
1314   int iid = (int)id, rowcount;
1315   EXEC SQL END DECLARE SECTION;
1316
1317   EXEC SQL DELETE FROM imembers WHERE member_type = 'MACHINE' AND
1318     member_id = :iid;
1319   rowcount = sqlca.sqlerrd[2];
1320   if (rowcount > 0)
1321     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1322   else
1323     printf("Not deleted\n");
1324   modified("imembers");
1325 }
1326
1327 int show_sh(void *id)
1328 {
1329   EXEC SQL BEGIN DECLARE SECTION;
1330   char name[SERVERHOSTS_SERVICE_SIZE];
1331   int iid = (int)id;
1332   EXEC SQL END DECLARE SECTION;
1333   int found = 1;
1334
1335   EXEC SQL DECLARE csr209 CURSOR FOR
1336     SELECT service FROM serverhosts
1337     WHERE mach_id = :iid;
1338   EXEC SQL OPEN csr209;
1339   while (1)
1340     {
1341       EXEC SQL FETCH csr209 INTO :name;
1342       if (sqlca.sqlcode)
1343         break;
1344
1345       found = 0;
1346       printf("ServerHost entry for service %s non-existant host %d\n",
1347              name, iid);
1348     }
1349   EXEC SQL CLOSE csr209;
1350   return found;
1351 }
1352
1353 void del_sh_mach(void *id)
1354 {
1355   EXEC SQL BEGIN DECLARE SECTION;
1356   int iid = (int)id, rowcount;
1357   EXEC SQL END DECLARE SECTION;
1358
1359   EXEC SQL DELETE FROM serverhosts WHERE mach_id = :iid;
1360   rowcount = sqlca.sqlerrd[2];
1361   if (rowcount > 0)
1362     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1363   else
1364     printf("Not deleted\n");
1365   modified("serverhosts");
1366 }
1367
1368
1369 static int fnchecklen;
1370
1371 void fsmatch(int id, void *nfsphys, void *filesys)
1372 {
1373   struct nfsphys *n = nfsphys;
1374   struct filesys *f = filesys;
1375
1376   if (n->mach_id == f->mach_id &&
1377       !strncmp(f->dir, n->dir, strlen(n->dir)) &&
1378       strlen(n->dir) > fnchecklen)
1379     {
1380       f->phys_id = id;
1381       fnchecklen = strlen(n->dir);
1382     }
1383 }
1384
1385
1386 void check_fs(int id, void *filesys, void *hint)
1387 {
1388   EXEC SQL BEGIN DECLARE SECTION;
1389   int iid = id, id1, id2, id3, rowcount;
1390   char *dir;
1391   EXEC SQL END DECLARE SECTION;
1392   struct filesys *f = filesys;
1393   struct nfsphys *n;
1394   struct machine *m;
1395
1396   if (!hash_lookup(machines, f->mach_id))
1397     {
1398       printf("Filesys %s with bad machine %d\n", f->name, f->mach_id);
1399       if (single_fix("Fix", 0))
1400         {
1401           EXEC SQL UPDATE filesys SET mach_id = 0 WHERE filsys_id = :iid;
1402           rowcount = sqlca.sqlerrd[2];
1403           if (rowcount > 0)
1404             printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1405           else
1406             printf("Not fixed\n");
1407           modified("filesys");
1408           f->mach_id = 0;
1409         }
1410     }
1411
1412   if (!hash_lookup(users, f->owner))
1413     {
1414       printf("Filesys %s with bad owning user %d\n", f->name, f->owner);
1415       if (single_fix("Fix", 1))
1416         {
1417           zero_fix("filesys", "owner", "filsys_id", f->filsys_id);
1418           f->owner = 0;
1419         }
1420     }
1421   if (!hash_lookup(lists, f->owners))
1422     {
1423       printf("Filesys %s with bad owning group %d\n", f->name, f->owners);
1424       if (single_fix("Fix", 1))
1425         {
1426           zero_fix("filesys", "owners", "filsys_id", f->filsys_id);
1427           f->owners = 0;
1428         }
1429     }
1430
1431   if (f->type == 'N' || f->type == 'I')
1432     {
1433       if (!hash_lookup(nfsphys, f->phys_id))
1434         {
1435           m = hash_lookup(machines, f->mach_id);
1436           printf("Filesys %s with bad phys_id %d\n", f->name, f->phys_id);
1437           if (single_fix("Fix", 1))
1438             {
1439               fnchecklen = 0;
1440               hash_step(nfsphys, fsmatch, f);
1441               if (fnchecklen != 0)
1442                 {
1443                   id1 = f->phys_id;
1444                   id2 = f->filsys_id;
1445                   id3 = f->mach_id;
1446                   EXEC SQL UPDATE filesys SET phys_id = :id1
1447                     WHERE filsys_id = :id2;
1448                   rowcount = sqlca.sqlerrd[2];
1449                   if (rowcount > 0)
1450                     printf("%d entr%s fixed\n", rowcount,
1451                            rowcount == 1 ? "y" : "ies");
1452                   else
1453                     printf("Not fixed\n");
1454                   modified("filesys");
1455                 }
1456               else
1457                 {
1458                   printf("No NFSphys exsits for %s:%s\n", m->name, f->dir);
1459                   if (single_fix("Create", 0))
1460                     {
1461                       dir = f->dir;
1462                       id1 = f->phys_id;
1463                       id2 = f->filsys_id;
1464                       id3 = f->mach_id;
1465                       if (set_next_object_id("nfsphys_id", "nfsphys") !=
1466                           MR_SUCCESS)
1467                         {
1468                           printf("Unable to assign unique ID\n");
1469                           return;
1470                         }
1471                       EXEC SQL SELECT COUNT(*) INTO :rowcount FROM numvalues
1472                         WHERE name = 'nfsphys_id';
1473                       if (rowcount != 1)
1474                         {
1475                           printf("Unable to retrieve unique ID\n");
1476                           return;
1477                         }
1478                       EXEC SQL INSERT INTO nfsphys
1479                         (nfsphys_id, mach_id, device, dir, status, allocated,
1480                          size, modtime, modby, modwith) VALUES
1481                         (:id1, :id3, '\?\?\?', :dir, 0, 0, 0, SYSDATE, 0,
1482                          'dbck');
1483                         rowcount = sqlca.sqlerrd[2];
1484                         if (rowcount > 0)
1485                           {
1486                             printf("%d entr%s created\n", rowcount,
1487                                    rowcount == 1 ? "y" : "ies");
1488                           }
1489                         else
1490                           printf("Not created\n");
1491                         modified("nfsphys");
1492                         n = malloc(sizeof(struct nfsphys));
1493                         if (!n)
1494                           out_of_mem("storing new nfsphys");
1495                         strcpy(n->dir, dir);
1496                         n->mach_id = id3;
1497                         n->nfsphys_id = id1;
1498                         n->allocated = 0;
1499                         n->count = 0;
1500                         if (hash_store(nfsphys, id1, n) == -1)
1501                           out_of_mem("storing nfsphys in hash table");
1502                         EXEC SQL UPDATE filesys SET phys_id = :id1
1503                           WHERE filsys_id = :id2;
1504                         rowcount = sqlca.sqlerrd[2];
1505                         if (rowcount > 0)
1506                           {
1507                             printf("%d filesys entr%s fixed\n", rowcount,
1508                                    rowcount == 1 ? "y" : "ies");
1509                           }
1510                         else
1511                           printf("Not fixed\n");
1512                         modified("filesys");
1513                     }
1514                 }
1515             }
1516         }
1517     }
1518 }
1519
1520 void check_nfsphys(int id, void *nfsphys, void *hint)
1521 {
1522   struct nfsphys *n = nfsphys;
1523
1524   n->modby = maybe_fixup_modby(n->modby, id, n->dir, "nfsphys",
1525                                "modby", "nfsphys_id");
1526
1527   if (!hash_lookup(machines, n->mach_id))
1528     {
1529       printf("NFSphys %d(%s) on non-existant machine %d\n",
1530              id, n->dir, n->mach_id);
1531       if (single_fix("Delete", 0))
1532         single_delete("nfsphys", "nfsphys_id", id);
1533     }
1534 }
1535
1536 static void clear_ps_owner(struct printserver *ps)
1537 {
1538   EXEC SQL BEGIN DECLARE SECTION;
1539   int rowcount, id = ps->mach_id;
1540   EXEC SQL END DECLARE SECTION;
1541
1542   EXEC SQL UPDATE printserver SET owner_type = 'NONE', owner_id = 0
1543     WHERE mach_id = :id;
1544   rowcount = sqlca.sqlerrd[2];
1545   if (rowcount > 0)
1546     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1547   else
1548     printf("Not fixed\n");
1549   modified("printservers");
1550 }
1551
1552 static void clear_ps_lpc(struct printserver *ps)
1553 {
1554   EXEC SQL BEGIN DECLARE SECTION;
1555   int rowcount, id = ps->mach_id;
1556   EXEC SQL END DECLARE SECTION;
1557
1558   EXEC SQL UPDATE printserver SET lpc_acl = 0
1559     WHERE mach_id = :id;
1560   rowcount = sqlca.sqlerrd[2];
1561   if (rowcount > 0)
1562     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1563   else
1564     printf("Not fixed\n");
1565   modified("printservers");
1566 }
1567
1568 void check_ps(int id, void *printserver, void *hint)
1569 {
1570   struct printserver *ps = printserver;
1571   struct machine *m;
1572   char *name;
1573
1574   m = hash_lookup(machines, id);
1575   if (!m)
1576     {
1577       printf("Printserver on non-existant machine %d\n", id);
1578       if (single_fix("Delete", 0))
1579         {
1580           single_delete("printservers", "mach_id", id);
1581           return;
1582         }
1583       else
1584         name = "[UNKNOWN]";
1585     }
1586   else
1587     name = m->name;      
1588
1589   ps->modby = maybe_fixup_modby(ps->modby, id, name, "printservers",
1590                                 "modby", "mach_id");
1591   ps->printer_types = maybe_fixup_unref_string(ps->printer_types, id, name,
1592                                                "printservers", "printer_types",
1593                                                "mach_id");
1594
1595   switch (ps->owner_type)
1596     {
1597     case 'U':
1598       if (!hash_lookup(users, ps->owner_id))
1599         {
1600           printf("Printserver %s has non-existant USER owner %d\n",
1601                  name, ps->owner_id);
1602           if (single_fix("Set to no owner", 1))
1603             clear_ps_owner(ps);
1604         }
1605       break;
1606     case 'L':
1607       if (!hash_lookup(lists, ps->owner_id))
1608         {
1609           printf("Printserver %s has non-existant LIST owner %d\n",
1610                  name, ps->owner_id);
1611           if (single_fix("Set to no owner", 1))
1612             clear_ps_owner(ps);
1613         }
1614       break;
1615     case 'K':
1616       if (ps->owner_id)
1617         ps->owner_id = maybe_fixup_unref_string(ps->owner_id, id, name,
1618                                                "printserver", "owner_id",
1619                                                "mach_id");
1620       if (ps->owner_id == 0)
1621         clear_ps_owner(ps);
1622     }
1623
1624   if (!hash_lookup(lists, ps->lpc_acl))
1625     {
1626       printf("Printserver %s has non-existent lpc_acl %d\n",
1627              name, ps->lpc_acl);
1628       if (single_fix("Set to no lpc_acl", 1))
1629         clear_ps_lpc(ps);
1630     }
1631 }
1632
1633 static void clear_container_list(struct container *cnt)
1634 {
1635   EXEC SQL BEGIN DECLARE SECTION;
1636   int rowcount, id = cnt->cnt_id;
1637   EXEC SQL END DECLARE SECTION;
1638
1639   EXEC SQL UPDATE containers SET list_id = 0
1640     WHERE cnt_id = :id;
1641   rowcount = sqlca.sqlerrd[2];
1642   if (rowcount > 0)
1643     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1644   else
1645     printf("Not fixed\n");
1646   modified("containers");
1647 }
1648
1649 void fix_container_acl(int id)
1650 {
1651   EXEC SQL BEGIN DECLARE SECTION;
1652   int rowcount, iid = (int)id;
1653   EXEC SQL END DECLARE SECTION;
1654
1655   EXEC SQL UPDATE containers SET acl_id = 0, acl_type = 'NONE'
1656     WHERE cnt_id = :iid;
1657   rowcount = sqlca.sqlerrd[2];
1658   if (rowcount > 0)
1659     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1660   else
1661     printf("Not fixed\n");
1662   modified("containers");
1663 }
1664
1665 void fix_container_memacl(int id)
1666 {
1667   EXEC SQL BEGIN DECLARE SECTION;
1668   int rowcount, iid = (int)id;
1669   EXEC SQL END DECLARE SECTION;
1670
1671   EXEC SQL UPDATE containers SET memacl_id = 0, memacl_type = 'NONE'
1672     WHERE cnt_id = :iid;
1673   rowcount = sqlca.sqlerrd[2];
1674   if (rowcount > 0)
1675     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1676   else
1677     printf("Not fixed\n");
1678   modified("containers");
1679 }
1680
1681 void check_container(int id, void *container, void *hint)
1682 {
1683   struct container *cnt = container;
1684
1685   if (!hash_lookup(lists, cnt->list_id))
1686     {
1687       printf("Container %s has non-existent associated list_id %d\n",
1688              cnt->name, cnt->list_id);
1689       if (single_fix("Set to no associated list", 1))
1690         clear_container_list(cnt);
1691     }
1692
1693   switch (cnt->acl_type)
1694     {
1695     case 'L':
1696       if (!hash_lookup(lists, cnt->acl_id))
1697         {
1698           printf("Container %s has bad LIST acl %d\n", cnt->name, cnt->acl_id);
1699           if (single_fix("Patch", 1))
1700             fix_container_acl(cnt->cnt_id);
1701         }
1702       break;
1703     case 'U':
1704       if (!hash_lookup(users, cnt->acl_id))
1705         {
1706           printf("Container %s has bad USER acl %d\n", cnt->name, cnt->acl_id);
1707           if (single_fix("Patch", 1))
1708             fix_container_acl(cnt->cnt_id);
1709         }
1710       break;
1711     case 'K':
1712       cnt->acl_id = maybe_fixup_unref_string(cnt->acl_id, id, cnt->name,
1713                                              "container", "acl_id", "cnt_id");
1714       if (!cnt->acl_id)
1715         {
1716           printf("Container %s has bad KERBEROS acl %d\n", cnt->name,
1717                  cnt->acl_id);
1718           if (single_fix("Patch", 1))
1719             fix_container_acl(cnt->cnt_id);
1720         }
1721       break;
1722     }
1723
1724  switch (cnt->memacl_type)
1725     {
1726     case 'L':
1727       if (!hash_lookup(lists, cnt->memacl_id))
1728         {
1729           printf("Container %s has bad LIST memacl %d\n", cnt->name,
1730                  cnt->memacl_id);
1731           if (single_fix("Patch", 1))
1732             fix_container_memacl(cnt->cnt_id);
1733         }
1734       break;
1735     case 'U':
1736       if (!hash_lookup(users, cnt->memacl_id))
1737         {
1738           printf("Container %s has bad USER memacl %d\n", cnt->name,
1739                  cnt->memacl_id);
1740           if (single_fix("Patch", 1))
1741             fix_container_memacl(cnt->cnt_id);
1742         }
1743       break;
1744     case 'K':
1745       cnt->memacl_id = maybe_fixup_unref_string(cnt->memacl_id, id, cnt->name,
1746                                              "container", "memacl_id",
1747                                                 "cnt_id");
1748       if (!cnt->memacl_id)
1749         {
1750           printf("Container %s has bad KERBEROS memacl %d\n", cnt->name,
1751                  cnt->memacl_id);
1752           if (single_fix("Patch", 1))
1753             fix_container_memacl(cnt->cnt_id);
1754         }
1755       break;
1756     }  
1757
1758   cnt->modby = maybe_fixup_modby(cnt->modby, id, cnt->name, "containers",
1759                                  "modby", "cnt_id");
1760 }
1761
1762 int show_fsg_missing(void *id)
1763 {
1764   EXEC SQL BEGIN DECLARE SECTION;
1765   int iid = (int)id, id1, found = 1;
1766   EXEC SQL END DECLARE SECTION;
1767   struct filesys *f;
1768
1769   EXEC SQL DECLARE csr210 CURSOR FOR
1770     SELECT filsys_id FROM fsgroup
1771     WHERE group_id = :iid;
1772   EXEC SQL OPEN csr210;
1773   while (1)
1774     {
1775       EXEC SQL FETCH csr210 INTO :id1;
1776       if (sqlca.sqlcode)
1777         break;
1778
1779       found = 0;
1780       if ((f = hash_lookup(filesys, id1)))
1781         printf("Missing fsgroup %d has member filesystem %s\n", iid, f->name);
1782       else
1783         printf("Missing fsgroup %d has member filesystem %d\n", iid, id1);
1784     }
1785   EXEC SQL CLOSE csr210;
1786   return found;
1787 }
1788
1789 int show_fsg_type(void *filesys)
1790 {
1791   struct filesys *f = filesys;
1792   char *t;
1793
1794   switch (f->type)
1795     {
1796     case 'N':
1797       t = "NFS";
1798       break;
1799     case 'R':
1800       t = "RVD";
1801       break;
1802     case 'A':
1803       t = "AFS";
1804       break;
1805     case 'E':
1806       t = "ERR";
1807       break;
1808     case 'F':
1809       t = "FSGROUP";
1810       break;
1811     case 'M':
1812       t = "MUL";
1813       break;
1814     default:
1815       t = "\?\?\?";
1816     }
1817   printf("FSGroup %s has type %s instead of FSGROUP\n", f->name, t);
1818   return 0;
1819 }
1820
1821 void fix_fsg_type(void *filesys)
1822 {
1823   struct filesys *f = filesys;
1824   EXEC SQL BEGIN DECLARE SECTION;
1825   int rowcount, id = f->filsys_id;
1826   EXEC SQL END DECLARE SECTION;
1827
1828   EXEC SQL UPDATE filesys SET type = 'FSGROUP' WHERE filsys_id = :id;
1829   rowcount = sqlca.sqlerrd[2];
1830   if (rowcount > 0)
1831     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1832   else
1833     printf("Not fixed\n");
1834   modified("filesys");
1835 }
1836
1837 int show_fsg_nomember(void *id)
1838 {
1839   EXEC SQL BEGIN DECLARE SECTION;
1840   int iid = (int)id, id1, found = 1;
1841   EXEC SQL END DECLARE SECTION;
1842   struct filesys *f;
1843
1844   EXEC SQL DECLARE csr211 CURSOR FOR
1845     SELECT group_id FROM fsgroup
1846     WHERE filsys_id = :iid;
1847   EXEC SQL OPEN csr211;
1848   while (1)
1849     {
1850       EXEC SQL FETCH csr211 INTO :id1;
1851       if (sqlca.sqlcode)
1852         break;
1853
1854       found = 0;
1855       if ((f = hash_lookup(filesys, id1)))
1856         printf("FSGroup %s has missing member %d\n", f->name, iid);
1857       else
1858         printf("FSGroup %d has missing member %d\n", id1, iid);
1859     }
1860   EXEC SQL CLOSE csr211;
1861   return found;
1862 }
1863
1864 int show_quota_nouser(void *id)
1865 {
1866   EXEC SQL BEGIN DECLARE SECTION;
1867   int iid = (int)id, id1, found = 1;
1868   EXEC SQL END DECLARE SECTION;
1869
1870   EXEC SQL DECLARE csr212 CURSOR FOR
1871     SELECT filsys_id FROM quota
1872     WHERE entity_id = :iid AND type = 'USER';
1873   EXEC SQL OPEN csr212;
1874   while (1)
1875     {
1876       EXEC SQL FETCH csr212 INTO :id1;
1877       if (sqlca.sqlcode)
1878         break;
1879
1880       found = 0;
1881       printf("Quota on fs %d for non-existant user %d\n", id1, iid);
1882     }
1883   EXEC SQL CLOSE csr212;
1884   return found;
1885 }
1886
1887 int show_quota_nolist(void *id)
1888 {
1889   EXEC SQL BEGIN DECLARE SECTION;
1890   int iid = (int)id, id1, found = 1;
1891   EXEC SQL END DECLARE SECTION;
1892
1893   EXEC SQL DECLARE csr213 CURSOR FOR
1894     SELECT filsys_id FROM quota
1895     WHERE entity_id = :iid AND type = 'GROUP';
1896   EXEC SQL OPEN csr213;
1897   while (1)
1898     {
1899       EXEC SQL FETCH csr213 INTO :id1;
1900       if (sqlca.sqlcode)
1901         break;
1902
1903       found = 0;
1904       printf("Quota on fs %d for non-existant list %d\n", id1, iid);
1905     }
1906   EXEC SQL CLOSE csr213;
1907   return found;
1908 }
1909
1910 void fix_quota_nouser(void *id)
1911 {
1912   EXEC SQL BEGIN DECLARE SECTION;
1913   int iid = (int)id, rowcount;
1914   EXEC SQL END DECLARE SECTION;
1915
1916   EXEC SQL DELETE FROM quota
1917     WHERE entity_id = :iid AND type = 'USER';
1918   rowcount = sqlca.sqlerrd[2];
1919   if (rowcount > 0)
1920     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1921   else
1922     printf("Not deleted\n");
1923   modified("quota");
1924 }
1925
1926 void fix_quota_nolist(void *id)
1927 {
1928   EXEC SQL BEGIN DECLARE SECTION;
1929   int iid = (int)id, rowcount;
1930   EXEC SQL END DECLARE SECTION;
1931
1932   EXEC SQL DELETE FROM quota WHERE entity_id = :iid AND type = 'GROUP';
1933   rowcount = sqlca.sqlerrd[2];
1934   if (rowcount > 0)
1935     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1936   else
1937     printf("Not deleted\n");
1938   modified("quota");
1939 }
1940
1941 int show_quota_nofs(void *id)
1942 {
1943   EXEC SQL BEGIN DECLARE SECTION;
1944   int iid = (int)id, id1, found = 1;
1945   char type[QUOTA_TYPE_SIZE];
1946   EXEC SQL END DECLARE SECTION;
1947
1948   EXEC SQL DECLARE csr214 CURSOR FOR
1949     SELECT entity_id, type FROM quota
1950     WHERE filsys_id = :iid;
1951   EXEC SQL OPEN csr214;
1952   while (1)
1953     {
1954       EXEC SQL FETCH csr214 INTO :id1, :type;
1955       if (sqlca.sqlcode)
1956         break;
1957
1958       found = 0;
1959       printf("Quota for %s %d on non-existant filesys %d\n", type, id1, iid);
1960     }
1961   EXEC SQL CLOSE csr214;
1962   return found;
1963 }
1964
1965 void fix_quota_nofs(void *id)
1966 {
1967   single_delete("quota", "filsys_id", (int)id);
1968 }
1969
1970 int show_quota_wrongpid(void *id)
1971 {
1972   EXEC SQL BEGIN DECLARE SECTION;
1973   int iid = (int)id, id1, found = 1;
1974   char type[QUOTA_TYPE_SIZE];
1975   EXEC SQL END DECLARE SECTION;
1976   struct filesys *f;
1977
1978   f = hash_lookup(filesys, iid);
1979   EXEC SQL DECLARE csr215 CURSOR FOR
1980     SELECT entity_id, type FROM quota
1981     WHERE filsys_id = :iid;
1982   EXEC SQL OPEN csr215;
1983   while (1)
1984     {
1985       EXEC SQL FETCH csr215 INTO :id1, :type;
1986       if (sqlca.sqlcode)
1987         break;
1988
1989       found = 0;
1990       printf("Quota for %s %d on filesys %s has wrong phys_id %d\n",
1991              type, id1, f->name, iid);
1992     }
1993   EXEC SQL CLOSE csr215;
1994   return found;
1995 }
1996
1997 void fix_quota_physid(void *id)
1998 {
1999   EXEC SQL BEGIN DECLARE SECTION;
2000   int iid = (int)id, rowcount, id1;
2001   EXEC SQL END DECLARE SECTION;
2002
2003   id1 = ((struct filesys *)hash_lookup(filesys, iid))->phys_id;
2004   EXEC SQL UPDATE quota SET phys_id = :id1
2005     WHERE filsys_id = :iid AND phys_id != :id1;
2006   rowcount = sqlca.sqlerrd[2];
2007   if (rowcount > 0)
2008     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
2009   else
2010     printf("Not fixed\n");
2011   modified("quota");
2012 }
2013
2014 int show_srv_user(void *id)
2015 {
2016   EXEC SQL BEGIN DECLARE SECTION;
2017   char name[SERVERS_NAME_SIZE];
2018   int iid = (int)id;
2019   EXEC SQL END DECLARE SECTION;
2020   int found = 1;
2021
2022   EXEC SQL DECLARE csr216 CURSOR FOR
2023     SELECT name FROM servers
2024     WHERE acl_type = 'USER' and acl_id = :iid;
2025   EXEC SQL OPEN csr216;
2026   while (1)
2027     {
2028       EXEC SQL FETCH csr216 INTO :name;
2029       if (sqlca.sqlcode)
2030         break;
2031
2032       strtrim(name);
2033       printf("Service %s has acl non-existant user %d\n", name, iid);
2034       found = 0;
2035     }
2036   EXEC SQL CLOSE csr216;
2037   return found;
2038 }
2039
2040 int show_srv_list(void *id)
2041 {
2042   EXEC SQL BEGIN DECLARE SECTION;
2043   char name[SERVERS_NAME_SIZE];
2044   int iid = (int)id;
2045   EXEC SQL END DECLARE SECTION;
2046   int found = 1;
2047
2048   EXEC SQL DECLARE csr217 CURSOR FOR
2049     SELECT name FROM servers
2050     WHERE acl_type = 'LIST' AND acl_id = :iid;
2051   EXEC SQL OPEN csr217;
2052   while (1)
2053     {
2054       EXEC SQL FETCH csr217 INTO :name;
2055       if (sqlca.sqlcode)
2056         break;
2057
2058       strtrim(name);
2059       printf("Service %s has acl non-existant list %d\n", name, iid);
2060       found = 0;
2061     }
2062   EXEC SQL CLOSE csr217;
2063   return found;
2064 }
2065
2066 void zero_srv_user(void *id)
2067 {
2068   EXEC SQL BEGIN DECLARE SECTION;
2069   int iid = (int)id, rowcount;
2070   EXEC SQL END DECLARE SECTION;
2071
2072   EXEC SQL UPDATE servers SET acl_id = 0 WHERE acl_id = :iid AND
2073     acl_type = 'USER';
2074   rowcount = sqlca.sqlerrd[2];
2075   if (rowcount > 0)
2076     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
2077   else
2078     printf("Not fixed\n");
2079   modified("servers");
2080 }
2081
2082 void zero_srv_list(void *id)
2083 {
2084   EXEC SQL BEGIN DECLARE SECTION;
2085   int iid = (int)id, rowcount;
2086   EXEC SQL END DECLARE SECTION;
2087
2088   EXEC SQL UPDATE servers SET acl_id = 0 WHERE acl_id = :iid AND
2089     acl_type = 'LIST';
2090   rowcount = sqlca.sqlerrd[2];
2091   if (rowcount > 0)
2092     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
2093   else
2094     printf("Not fixed\n");
2095   modified("servers");
2096 }
2097
2098 int show_krb_usr(void *id)
2099 {
2100   EXEC SQL BEGIN DECLARE SECTION;
2101   int iid = (int)id, found = 1, id1;
2102   EXEC SQL END DECLARE SECTION;
2103   struct string *s;
2104   char *ss;
2105
2106   EXEC SQL DECLARE csr218 CURSOR FOR
2107     SELECT string_id FROM krbmap
2108     WHERE users_id = :iid;
2109   EXEC SQL OPEN csr218;
2110   while (1)
2111     {
2112       EXEC SQL FETCH csr218 INTO :id1;
2113       if (sqlca.sqlcode)
2114         break;
2115
2116       if ((s = hash_lookup(strings, id1)))
2117         ss = s->name;
2118       else
2119         ss = "[unknown]";
2120       found = 0;
2121       printf("Kerberos map for non-existant user %d to principal %s\n",
2122              iid, ss);
2123     }
2124   EXEC SQL CLOSE csr218;
2125   return found;
2126 }
2127
2128 int show_krb_str(void *id)
2129 {
2130   EXEC SQL BEGIN DECLARE SECTION;
2131   int iid = (int)id, found = 1, id1;
2132   EXEC SQL END DECLARE SECTION;
2133   struct user *u;
2134   char *s;
2135
2136   EXEC SQL DECLARE csr219 CURSOR FOR
2137     SELECT users_id FROM krbmap
2138     WHERE string_id = :iid;
2139   EXEC SQL OPEN csr219;
2140   while (1)
2141     {
2142       EXEC SQL FETCH csr219 INTO :id1;
2143       if (sqlca.sqlcode)
2144         break;
2145
2146       if ((u = hash_lookup(users, id1)))
2147         s = u->login;
2148       else
2149         s = "[\?\?\?]";
2150       found = 0;
2151       printf("Kerberos map for user %s (%d) to non-existant string %d\n",
2152              s, id1, iid);
2153     }
2154   EXEC SQL CLOSE csr219;
2155   return found;
2156 }
2157
2158 void phase2(void)
2159 {
2160   struct save_queue *sq, *sq1, *sq2, *sq3, *sq4, *sq5, *sq6;
2161   struct filesys *f;
2162   struct list *l;
2163   struct nfsphys *n;
2164   struct machine *m;
2165   char rowid[32];
2166
2167   printf("Phase 2 - Checking references\n");
2168
2169   dprintf("Checking users...\n");
2170   hash_step(users, user_check, NULL);
2171
2172   dprintf("Checking machines...\n");
2173   hash_step(machines, mach_check, NULL);
2174
2175   dprintf("Checking subnets...\n");
2176   hash_step(subnets, subnet_check, NULL);
2177
2178   dprintf("Checking clusters...\n");
2179   hash_step(clusters, cluster_check, NULL);
2180
2181   dprintf("Checking mcmap...\n");
2182   sq1 = sq_create();
2183   sq2 = sq_create();
2184   EXEC SQL DECLARE csr221 CURSOR FOR
2185     SELECT mach_id, clu_id FROM mcmap;
2186   EXEC SQL OPEN csr221;
2187   while (1)
2188     {
2189       EXEC SQL BEGIN DECLARE SECTION;
2190       int mach_id, clu_id;
2191       EXEC SQL END DECLARE SECTION;
2192
2193       EXEC SQL FETCH csr221 INTO :mach_id, :clu_id;
2194       if (sqlca.sqlcode)
2195         break;
2196
2197       if (!(m = hash_lookup(machines, mach_id)))
2198         sq_save_unique_data(sq1, (void *)mach_id);
2199       else if (!hash_lookup(clusters, clu_id))
2200         sq_save_unique_data(sq2, (void *)clu_id);
2201       if (m)
2202         m->clucount++;
2203     }
2204   EXEC SQL CLOSE csr221;
2205   generic_delete(sq1, show_mcm_mach, "mcmap", "mach_id", 1);
2206   generic_delete(sq2, show_mcm_clu, "mcmap", "clu_id", 1);
2207
2208   dprintf("Checking service clusters...\n");
2209   sq1 = sq_create();
2210   EXEC SQL DECLARE csr222 CURSOR FOR
2211     SELECT clu_id FROM svc;
2212   EXEC SQL OPEN csr222;
2213   while (1)
2214     {
2215       EXEC SQL BEGIN DECLARE SECTION;
2216       int clu_id;
2217       EXEC SQL END DECLARE SECTION;
2218
2219       EXEC SQL FETCH csr222 INTO :clu_id;
2220       if (sqlca.sqlcode)
2221         break;
2222
2223       if (!hash_lookup(clusters, clu_id))
2224         sq_save_unique_data(sq1, (void *)clu_id);
2225     }
2226   EXEC SQL CLOSE csr222;
2227   generic_delete(sq1, show_svc, "svc", "clu_id", 1);
2228
2229   dprintf("Checking lists...\n");
2230   hash_step(lists, list_check, NULL);
2231
2232   dprintf("Checking members...\n");
2233   sq1 = sq_create();
2234   sq2 = sq_create();
2235   sq3 = sq_create();
2236   sq4 = sq_create();
2237   sq5 = sq_create();
2238   sq6 = sq_create();
2239
2240   EXEC SQL DECLARE csr223 CURSOR FOR
2241     SELECT list_id, member_type, member_id, tag, ref_count, direct, rowid
2242     FROM imembers FOR UPDATE OF member_id;
2243   EXEC SQL OPEN csr223;
2244   while (1)
2245     {
2246       EXEC SQL BEGIN DECLARE SECTION;
2247       int list_id, id, tag, ref_count, direct;
2248       char type[IMEMBERS_MEMBER_TYPE_SIZE];
2249       EXEC SQL END DECLARE SECTION;
2250
2251       EXEC SQL FETCH csr223 INTO :list_id, :type, :id, :tag,
2252         :ref_count, :direct, :rowid;
2253       if (sqlca.sqlcode)
2254         break;
2255       strtrim(rowid);
2256
2257       if (!(l = hash_lookup(lists, list_id)))
2258         sq_save_unique_data(sq1, (void *)list_id);
2259       else if (type[0] == 'U' && !hash_lookup(users, id))
2260         sq_save_unique_data(sq2, (void *)id);
2261       else if (type[0] == 'L' && !hash_lookup(lists, id))
2262         sq_save_unique_data(sq3, (void *)id);
2263       else if (type[0] == 'S' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
2264         sq_save_unique_data(sq4, (void *)id);
2265       else if (type[0] == 'K' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
2266         sq_save_unique_data(sq5, (void *)id);
2267       else if (type[0] == 'M' && !hash_lookup(machines, id))
2268         sq_save_unique_data(sq6, (void *)id);
2269       else
2270         l->members++;
2271       maybe_fixup_unref_string2("imembers", "tag", rowid, tag);
2272     }
2273   EXEC SQL CLOSE csr223;
2274   generic_delete(sq1, show_member_list, "imembers", "list_id", 1);
2275   generic_fix(sq2, show_mem_user, "Delete", del_mem_user, 1);
2276   generic_fix(sq3, show_mem_list, "Delete", del_mem_list, 1);
2277   generic_fix(sq4, show_mem_str, "Delete", del_mem_str, 1);
2278   generic_fix(sq5, show_mem_krb, "Delete", del_mem_krb, 1);
2279   generic_fix(sq6, show_mem_mach, "Delete", del_mem_mach, 1);
2280
2281   dprintf("Checking servers...\n");
2282   sq1 = sq_create();
2283   sq2 = sq_create();
2284   EXEC SQL DECLARE csr224 CURSOR FOR
2285     SELECT name, acl_type, acl_id, modby, rowid FROM servers
2286     FOR UPDATE of modby;
2287   EXEC SQL OPEN csr224;
2288   while (1)
2289     {
2290       EXEC SQL BEGIN DECLARE SECTION;
2291       int acl_id, modby;
2292       char name[SERVERS_NAME_SIZE], acl_type[SERVERS_ACL_TYPE_SIZE];
2293       EXEC SQL END DECLARE SECTION;
2294
2295       EXEC SQL FETCH csr224 INTO :name, :acl_type, :acl_id, :modby, :rowid;
2296       if (sqlca.sqlcode)
2297         break;
2298
2299       maybe_fixup_modby2("servers", "modby", strtrim(rowid), modby);
2300       strtrim(acl_type);
2301       if (!strcmp(acl_type, "USER") && !hash_lookup(users, acl_id))
2302         sq_save_data(sq1, (void *)acl_id);
2303       else if (!strcmp(acl_type, "LIST") && !hash_lookup(lists, acl_id))
2304         sq_save_data(sq2, (void *)acl_id);
2305     }
2306   EXEC SQL CLOSE csr224;
2307   generic_fix(sq1, show_srv_user, "Fix", zero_srv_user, 1);
2308   generic_fix(sq2, show_srv_list, "Fix", zero_srv_list, 1);
2309
2310   dprintf("Checking serverhosts...\n");
2311   sq = sq_create();
2312   EXEC SQL DECLARE csr225 CURSOR FOR
2313     SELECT mach_id, modby, rowid FROM serverhosts
2314     FOR UPDATE OF modby;
2315   EXEC SQL OPEN csr225;
2316   while (1)
2317     {
2318       EXEC SQL BEGIN DECLARE SECTION;
2319       int mach_id, modby;
2320       EXEC SQL END DECLARE SECTION;
2321
2322       EXEC SQL FETCH csr225 INTO :mach_id, :modby, :rowid;
2323       if (sqlca.sqlcode)
2324         break;
2325
2326       maybe_fixup_modby2("serverhosts", "modby", strtrim(rowid), modby);
2327       if (!hash_lookup(machines, mach_id))
2328         sq_save_data(sq, (void *)mach_id);
2329     }
2330   EXEC SQL CLOSE csr225;
2331   generic_fix(sq, show_sh, "Delete", del_sh_mach, 0);
2332
2333   dprintf("Checking nfsphys...\n");
2334   hash_step(nfsphys, check_nfsphys, NULL);
2335
2336   dprintf("Checking filesys...\n");
2337   hash_step(filesys, check_fs, NULL);
2338
2339   dprintf("Checking filesystem groups...\n");
2340   sq1 = sq_create();
2341   sq2 = sq_create();
2342   sq3 = sq_create();
2343   EXEC SQL DECLARE csr226 CURSOR FOR
2344     SELECT group_id, filsys_id FROM fsgroup;
2345   EXEC SQL OPEN csr226;
2346   while (1)
2347     {
2348       EXEC SQL BEGIN DECLARE SECTION;
2349       int group_id, filsys_id;
2350       EXEC SQL END DECLARE SECTION;
2351
2352       EXEC SQL FETCH csr226 INTO :group_id, :filsys_id;
2353       if (sqlca.sqlcode)
2354         break;
2355
2356       if (!(f = hash_lookup(filesys, group_id)))
2357         sq_save_data(sq1, (void *)group_id);
2358       if (!hash_lookup(filesys, filsys_id))
2359         sq_save_data(sq3, (void *)filsys_id);
2360     }
2361   EXEC SQL CLOSE csr226;
2362   generic_delete(sq1, show_fsg_missing, "fsgroup", "group_id", 0);
2363   generic_delete(sq3, show_fsg_nomember, "fsgroup", "filsys_id", 1);
2364
2365   dprintf("Checking quotas...\n");
2366   sq1 = sq_create();
2367   sq2 = sq_create();
2368   sq3 = sq_create();
2369   sq4 = sq_create();
2370   EXEC SQL DECLARE csr227 CURSOR FOR
2371     SELECT entity_id, type, filsys_id, phys_id, quota, modby, rowid
2372     FROM quota FOR UPDATE OF modby;
2373   EXEC SQL OPEN csr227;
2374   while (1)
2375     {
2376       EXEC SQL BEGIN DECLARE SECTION;
2377       int entity_id, filsys_id, phys_id, quota, modby;
2378       char type[QUOTA_TYPE_SIZE];
2379       EXEC SQL END DECLARE SECTION;
2380
2381       EXEC SQL FETCH csr227 INTO :entity_id, :type, :filsys_id,
2382         :phys_id, :quota, :modby, :rowid;
2383       if (sqlca.sqlcode)
2384         break;
2385
2386       maybe_fixup_modby2("quota", "modby", strtrim(rowid), modby);
2387       if (type[0] == 'U' && entity_id != 0 && !hash_lookup(users, entity_id))
2388         sq_save_data(sq1, (void *)entity_id);
2389       else if (type[0] == 'G' && !hash_lookup(lists, entity_id))
2390         sq_save_data(sq4, (void *)entity_id);
2391       else if (!(f = hash_lookup(filesys, filsys_id)))
2392         sq_save_data(sq2, (void *)filsys_id);
2393       else if (phys_id != f->phys_id || !(n = hash_lookup(nfsphys, phys_id)))
2394         sq_save_data(sq3, (void *)phys_id);
2395       else
2396         n->count += quota;
2397     }
2398   EXEC SQL CLOSE csr227;
2399   generic_fix(sq1, show_quota_nouser, "Delete", fix_quota_nouser, 1);
2400   generic_fix(sq2, show_quota_nofs, "Delete", fix_quota_nofs, 0);
2401   generic_fix(sq3, show_quota_wrongpid, "Fix", fix_quota_physid, 1);
2402   generic_fix(sq4, show_quota_nolist, "Delete", fix_quota_nolist, 1);
2403
2404   dprintf("Checking zephyr...\n");
2405   EXEC SQL DECLARE csr_zc CURSOR FOR
2406     SELECT class, xmt_type, xmt_id, sub_type, sub_id, iws_type, iws_id,
2407     iui_type, iui_id, modby FROM zephyr;
2408   EXEC SQL OPEN csr_zc;
2409   while(1)
2410     {
2411       EXEC SQL BEGIN DECLARE SECTION;
2412       int xmt_id, sub_id, iws_id, iui_id, modby;
2413       char class[ZEPHYR_CLASS_SIZE];
2414       char xmt_type[ZEPHYR_XMT_TYPE_SIZE];
2415       char sub_type[ZEPHYR_SUB_TYPE_SIZE];
2416       char iws_type[ZEPHYR_IWS_TYPE_SIZE];
2417       char iui_type[ZEPHYR_IUI_TYPE_SIZE];
2418       EXEC SQL END DECLARE SECTION;
2419
2420       EXEC SQL FETCH csr_zc INTO :class, :xmt_type, :xmt_id, :sub_type, 
2421         :sub_id, :iws_type, :iws_id, :iui_type, :iui_id, :modby;
2422
2423       if (sqlca.sqlcode)
2424         break;
2425
2426       maybe_fixup_modby2("zephyr", "modby", strtrim(rowid), modby);
2427
2428       strtrim(xmt_type);
2429       if (!strcmp(xmt_type, "USER") && !hash_lookup(users, xmt_id))
2430         {
2431           printf("xmt acl for %s is non-existant user %d\n", class, xmt_id);
2432           printf("Not fixing this error\n");
2433         }
2434       else if (!strcmp(xmt_type, "LIST") && !hash_lookup(lists, xmt_id))
2435         {
2436           printf("xmt acl for %s is non-existant list %d\n", class, xmt_id);
2437           printf("Not fixing this error\n");
2438         }
2439       else if (!strcmp(xmt_type, "STRING") || !strcmp(xmt_type, "KERBEROS"))
2440         maybe_fixup_unref_string2("zephyr", "xmt_id", strtrim(rowid), xmt_id);
2441
2442       strtrim(sub_type);
2443       if (!strcmp(sub_type, "USER") && !hash_lookup(users, sub_id))
2444         {
2445           printf("sub acl for %s is non-existant user %d\n", class, sub_id);
2446           printf("Not fixing this error\n");
2447         }
2448       else if (!strcmp(sub_type, "LIST") && !hash_lookup(lists, sub_id))
2449         {
2450           printf("sub acl for %s is non-existant list %d\n", class, sub_id);
2451           printf("Not fixing this error\n");
2452         }
2453       else if (!strcmp(sub_type, "STRING") || !strcmp(sub_type, "KERBEROS"))
2454         maybe_fixup_unref_string2("zephyr", "sub_id", strtrim(rowid), sub_id);
2455
2456       strtrim(iws_type);
2457       if (!strcmp(iws_type, "USER") && !hash_lookup(users, iws_id))
2458         {
2459           printf("iws acl for %s is non-existant user %d\n", class, iws_id);
2460           printf("Not fixing this error\n");
2461         }
2462       else if (!strcmp(iws_type, "LIST") && !hash_lookup(lists, iws_id))
2463         {
2464           printf("iws acl for %s is non-existant list %d\n", class, iws_id);
2465           printf("Not fixing this error\n");
2466         }
2467       else if (!strcmp(iws_type, "STRING") || !strcmp(iws_type, "KERBEROS"))
2468         maybe_fixup_unref_string2("zephyr", "iws_id", strtrim(rowid), iws_id);
2469
2470       strtrim(iui_type);
2471       if (!strcmp(iui_type, "USER") && !hash_lookup(users, iui_id))
2472         {
2473           printf("iui acl for %s is non-existant user %d\n", class, iui_id);
2474           printf("Not fixing this error\n");
2475         }
2476       else if (!strcmp(iui_type, "LIST") && !hash_lookup(lists, iui_id))
2477         {
2478           printf("iui acl for %s is non-existant list %d\n", class, iui_id);
2479           printf("Not fixing this error\n");
2480         }
2481       else if (!strcmp(iui_type, "STRING") || !strcmp(iui_type, "KERBEROS"))
2482         maybe_fixup_unref_string2("zephyr", "iui_id", strtrim(rowid), iui_id);
2483     }
2484
2485   dprintf("Checking hostaccess...\n");
2486   EXEC SQL DECLARE csr228 CURSOR FOR
2487     SELECT mach_id, acl_type, acl_id, modby, rowid FROM hostaccess
2488     FOR UPDATE OF modby;
2489   EXEC SQL OPEN csr228;
2490   while (1)
2491     {
2492       EXEC SQL BEGIN DECLARE SECTION;
2493       int mach_id, acl_id, modby;
2494       char acl_type[HOSTACCESS_ACL_TYPE_SIZE];
2495       EXEC SQL END DECLARE SECTION;
2496
2497       EXEC SQL FETCH csr228 INTO :mach_id, :acl_type, :acl_id, :modby, :rowid;
2498       if (sqlca.sqlcode)
2499         break;
2500
2501       maybe_fixup_modby2("hostaccess", "modby", strtrim(rowid), modby);
2502       strtrim(acl_type);
2503       if (!hash_lookup(machines, mach_id))
2504         {
2505           printf("Hostaccess for non-existant host %d\n", mach_id);
2506           printf("Not fixing this error\n");
2507         }
2508       if (!strcmp(acl_type, "USER") && !hash_lookup(users, acl_id))
2509         {
2510           printf("Hostaccess for %d is non-existant user %d\n", mach_id, acl_id);
2511           printf("Not fixing this error\n");
2512         }
2513       else if (!strcmp(acl_type, "LIST") && !hash_lookup(lists, acl_id))
2514         {
2515           printf("Hostaccess for %d is non-existant list %d\n", mach_id, acl_id);
2516           printf("Not fixing this error\n");
2517         }
2518     }
2519   EXEC SQL CLOSE csr228;
2520
2521   dprintf("Checking krbmap...\n");
2522   sq1 = sq_create();
2523   sq2 = sq_create();
2524   EXEC SQL DECLARE csr230 CURSOR FOR
2525     SELECT users_id, string_id, rowid FROM krbmap
2526     FOR UPDATE OF string_id;
2527   EXEC SQL OPEN csr230;
2528   while (1)
2529     {
2530       EXEC SQL BEGIN DECLARE SECTION;
2531       int users_id, string_id;
2532       EXEC SQL END DECLARE SECTION;
2533
2534       EXEC SQL FETCH csr230 INTO :users_id, :string_id, :rowid;
2535       if (sqlca.sqlcode)
2536         break;
2537
2538       if (!hash_lookup(users, users_id))
2539         sq_save_unique_data(sq1, (void *)users_id);
2540       else if (!maybe_fixup_unref_string2("krbmap", "string_id", strtrim(rowid), string_id))
2541         sq_save_unique_data(sq2, (void *)string_id);
2542     }
2543   EXEC SQL CLOSE csr230;
2544   generic_delete(sq1, show_krb_usr, "krbmap", "users_id", 1);
2545   generic_delete(sq2, show_krb_str, "krbmap", "string_id", 1);
2546
2547   dprintf("Checking capacls...\n");
2548   EXEC SQL DECLARE csr231 CURSOR FOR
2549     SELECT list_id, tag FROM capacls;
2550   EXEC SQL OPEN csr231;
2551   while (1)
2552     {
2553       EXEC SQL BEGIN DECLARE SECTION;
2554       int list_id;
2555       char tag[CAPACLS_TAG_SIZE];
2556       EXEC SQL END DECLARE SECTION;
2557
2558       EXEC SQL FETCH csr231 INTO :list_id, :tag;
2559       if (sqlca.sqlcode)
2560         break;
2561
2562       if (!hash_lookup(lists, list_id))
2563         {
2564           printf("Capacl for %s is non-existant list %d\n", tag, list_id);
2565           printf("Not fixing this error\n");
2566         }
2567     }
2568   EXEC SQL CLOSE csr231;
2569
2570   dprintf("Checking hostaliases...\n");
2571   sq1 = sq_create();
2572   EXEC SQL DECLARE csr232 CURSOR FOR
2573     SELECT mach_id FROM hostalias;
2574   EXEC SQL OPEN csr232;
2575   while (1)
2576     {
2577       EXEC SQL BEGIN DECLARE SECTION;
2578       int mach_id;
2579       EXEC SQL END DECLARE SECTION;
2580
2581       EXEC SQL FETCH csr232 INTO :mach_id;
2582       if (sqlca.sqlcode)
2583         break;
2584
2585       if (!hash_lookup(machines, mach_id))
2586         sq_save_unique_data(sq1, (void *)mach_id);
2587     }
2588   EXEC SQL CLOSE csr232;
2589   generic_delete(sq1, show_hostalias, "hostalias", "mach_id", 1);
2590
2591   dprintf("Checking printers...\n");
2592   sq1 = sq_create();
2593   sq2 = sq_create();
2594   sq3 = sq_create();
2595   sq4 = sq_create();
2596   sq5 = sq_create();
2597   sq6 = sq_create();
2598   EXEC SQL DECLARE csr233 CURSOR FOR
2599     SELECT mach_id, loghost, rm, rq, ac, lpc_acl, modby, rowid FROM printers;
2600   EXEC SQL OPEN csr233;
2601   while (1)
2602     {
2603       EXEC SQL BEGIN DECLARE SECTION;
2604       int mach_id, loghost, rm, rq, ac, lpc_acl, modby;
2605       EXEC SQL END DECLARE SECTION;
2606
2607       EXEC SQL FETCH csr233 INTO :mach_id, :loghost, :rm, :rq, :ac,
2608         :lpc_acl, :modby, :rowid;
2609       if (sqlca.sqlcode)
2610         break;
2611
2612       maybe_fixup_modby2("printers", "modby", strtrim(rowid), modby);
2613       if (!hash_lookup(machines, mach_id))
2614         sq_save_unique_data(sq1, (void *)mach_id);
2615       else if (!hash_lookup(machines, rm))
2616         sq_save_unique_data(sq2, (void *)rm);
2617       else if (!hash_lookup(printservers, rm))
2618         sq_save_unique_data(sq6, (void *)mach_id);
2619       else if (!hash_lookup(machines, rq))
2620         sq_save_unique_data(sq3, (void *)rq);
2621       else {
2622         if (!hash_lookup(lists, ac))
2623           sq_save_unique_data(sq4, (void *)ac);
2624         if (!hash_lookup(lists, lpc_acl))
2625           sq_save_unique_data(sq5, (void *)lpc_acl);
2626         if (!hash_lookup(machines, loghost))
2627           {
2628             show_printer_loghost((void *)loghost);
2629             cant_fix();
2630           }
2631       }
2632     }
2633   EXEC SQL CLOSE csr233;
2634   generic_delete(sq1, show_printer_mach, "printers", "mach_id", 1);
2635   generic_delete(sq6, show_printer_server, "printers", "mach_id", 1);
2636   generic_delete(sq2, show_printer_spool, "printers", "rm", 1);
2637   generic_delete(sq3, show_printer_quota, "printers", "rq", 1);
2638   generic_fix(sq4, show_printer_ac, "Clear", fix_printer_ac, 1);
2639   generic_fix(sq5, show_printer_lpc_acl, "Clear", fix_printer_lpc_acl, 1);
2640
2641   dprintf("Checking printservers...\n");
2642   hash_step(printservers, check_ps, NULL);
2643
2644   dprintf("Checking containers...\n");
2645   hash_step(containers, check_container, NULL);
2646
2647   dprintf("Checking mcntmap...\n");
2648   sq1 = sq_create();
2649   sq2 = sq_create();
2650   EXEC SQL DECLARE csr_mcntmap CURSOR FOR
2651     SELECT mach_id, cnt_id FROM mcntmap;
2652   EXEC SQL OPEN csr_mcntmap;
2653   while (1)
2654     {
2655       EXEC SQL BEGIN DECLARE SECTION;
2656       int mach_id, cnt_id;
2657       EXEC SQL END DECLARE SECTION;
2658
2659       EXEC SQL FETCH csr_mcntmap INTO :mach_id, :cnt_id;
2660       if (sqlca.sqlcode)
2661         break;
2662
2663       if (!(m = hash_lookup(machines, mach_id)))
2664         sq_save_unique_data(sq1, (void *)mach_id);
2665       else if (!hash_lookup(containers, cnt_id))
2666         sq_save_unique_data(sq2, (void *)cnt_id);
2667     }
2668   EXEC SQL CLOSE csr_mcntmap;
2669   generic_delete(sq1, show_mcntmap_mach, "mcntmap", "mach_id", 1);
2670   generic_delete(sq2, show_mcntmap_cnt, "mcntmap", "cnt_id", 1);
2671
2672 }
2673  
This page took 0.236426 seconds and 5 git commands to generate.