3 * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
4 * For copying and distribution information, please see the file
8 #include <mit-copyright.h>
15 EXEC SQL INCLUDE sqlca;
19 EXEC SQL WHENEVER SQLERROR DO dbmserr();
20 int show_user_id(void *user);
21 void handle_duplicate_logins(struct save_queue *sq);
22 void fix_user_id(void *user);
23 void cant_fix(void *id);
24 int show_mach_id(void *machine);
25 int show_mach_name(void *machine);
26 void fix_mach_id(void *machine);
27 int show_snet_name(void *subnet);
28 int show_clu_id(void *cluster);
29 int show_clu_name(void *cluster);
30 void fix_clu_id(void *cluster);
31 int show_list_id(void *list);
32 int show_list_name(void *list);
33 void fix_list_id(void *list);
34 int show_fs_id(void *filesys);
35 void fix_fs_id(void *filesys);
36 int show_fs_name(void *fs);
37 int show_np_id(void *nfsphys);
38 void fix_np_id(void *nfsphys);
39 int show_str_id(void *string);
40 int print_str_id(void *id);
41 void print_dup_map(int key, void *data, void *hint);
42 int show_cnt_name(void *cnt);
44 int show_user_id(void *user)
46 struct user *u = user;
47 printf("User %s (%s, status %d) has duplicate ID\n",
48 u->login, u->fullname, u->status);
52 void handle_duplicate_logins(struct save_queue *sq)
54 struct user *u, *uu, *tmp;
57 if (sq_get_data(sq, &uu))
59 while (sq_get_data(sq, &u))
61 if (!strcmp(u->login, uu->login))
63 if (uu->status == 1 || u->status == 0)
69 printf("User %s (%s, status %d) and\n",
70 u->login, u->fullname, u->status);
71 printf("User %s (%s, status %d) have duplicate logins\n",
72 uu->login, uu->fullname, uu->status);
73 if (!strcmp(u->fullname, uu->fullname) &&
74 single_fix("Delete the second one", 0))
75 single_delete("users", "users_id", uu->users_id);
76 else if (single_fix("Unregister the second one", 0))
78 EXEC SQL BEGIN DECLARE SECTION;
79 int id = uu->users_id, rowcount;
80 EXEC SQL END DECLARE SECTION;
83 SET login = '#' || CHAR(users.unix_uid), status = 0
85 rowcount = sqlca.sqlerrd[2];
88 printf("%d entr%s fixed\n", rowcount,
89 rowcount == 1 ? "y" : "ies");
92 printf("Not fixed\n");
102 void fix_user_id(void *user)
104 struct user *u = user;
105 u->users_id = generic_fix_id("users", "users_id", "login",
106 u->users_id, u->login);
110 void cant_fix(void *id)
112 printf("Sorry, don't know how to fix that\n");
115 int show_mach_id(void *machine)
117 struct machine *m = machine;
118 printf("Machine %s has duplicate ID %d\n", m->name, m->mach_id);
122 int show_mach_name(void *machine)
124 struct machine *m = machine;
125 printf("Machine %s (%d) has duplicate name\n", m->name, m->mach_id);
129 void fix_mach_id(void *machine)
131 struct machine *m = machine;
132 m->mach_id = generic_fix_id("machine", "mach_id", "name",
133 m->mach_id, m->name);
136 int show_snet_name(void *subnet)
138 struct subnet *s = subnet;
139 printf("Subnet %s (%d) has duplicate name\n", s->name, s->snet_id);
143 int show_clu_id(void *cluster)
145 struct cluster *c = cluster;
146 printf("Cluster %s has duplicate ID %d\n", c->name, c->clu_id);
150 int show_clu_name(void *cluster)
152 struct cluster *c = cluster;
153 printf("Cluster %s (%d) has duplicate name\n", c->name, c->clu_id);
157 void fix_clu_id(void *cluster)
159 struct cluster *c = cluster;
160 c->clu_id = generic_fix_id("cluster", "clu_id", "name", c->clu_id, c->name);
163 int show_list_id(void *list)
165 struct list *l = list;
166 printf("List %s has duplicate ID %d\n", l->name, l->list_id);
170 int show_list_name(void *list)
172 struct list *l = list;
173 printf("List %s (%d) has duplicate name\n", l->name, l->list_id);
177 void fix_list_id(void *list)
179 struct list *l = list;
180 l->list_id = generic_fix_id("list", "list_id", "name", l->list_id, l->name);
183 int show_fs_id(void *filesys)
185 struct filesys *f = filesys;
186 printf("Filesys %s has duplicate ID %d\n", f->name, f->filsys_id);
190 void fix_fs_id(void *filesys)
192 struct filesys *f = filesys;
193 f->filsys_id = generic_fix_id("filesys", "filsys_id", "label",
194 f->filsys_id, f->name);
197 int show_fs_name(void *filesys)
199 struct filesys *fs = filesys;
200 printf("Filesys %s (%d) has duplicate name\n", fs->name, fs->filsys_id);
204 int show_np_id(void *nfsphys)
206 struct nfsphys *n = nfsphys;
207 printf("NfsPhys %s:%s has duplicate ID %d\n",
208 ((struct machine *)hash_lookup(machines, n->mach_id))->name,
209 n->dir, n->nfsphys_id);
213 void fix_np_id(void *nfsphys)
215 struct nfsphys *n = nfsphys;
216 n->nfsphys_id = generic_fix_id("nfsphys", "nfsphys_id", "dir",
217 n->nfsphys_id, n->dir);
220 int show_str_id(void *string)
222 struct string *s = string;
223 printf("String %s has duplicate ID %d\n", s->name, s->string_id);
227 int print_str_id(void *id)
229 printf("String %d is a duplicate\n", (int)id);
233 void print_dup_map(int key, void *data, void *hint)
235 printf("String %d is a duplicate of string %d\n", key, (int)data);
238 int show_cnt_name(void *container)
240 struct container *cnt = container;
241 printf("Container %s (%d) has duplicate name\n", cnt->name, cnt->cnt_id);
247 EXEC SQL BEGIN DECLARE SECTION;
249 EXEC SQL END DECLARE SECTION;
250 int i, q, retval, tmp;
251 struct save_queue *sq;
260 struct printserver *ps;
261 struct container *cnt;
263 printf("Phase 1 - Looking for duplicates\n");
265 /* self-join strings table on "string" to get duplicate strings, then
266 build a duplicates table to merge them. */
268 dprintf("Looking for duplicate strings...\n");
269 string_dups = create_hash(100);
271 out_of_mem("storing duplicate strings");
273 EXEC SQL DECLARE csr116 CURSOR FOR
274 SELECT s1.string_id, s2.string_id FROM strings s1, strings s2
275 WHERE s1.string = s2.string and s1.string_id < s2.string_id;
276 EXEC SQL OPEN csr116;
277 /* The SELECT gives us two columns, both with non-negative integers.
278 * The number in the left column is always the smaller of the two,
279 * and each row includes string IDs for identical strings. We use
280 * them to make a mapping from id-to-delete to id-to-keep for all
286 EXEC SQL BEGIN DECLARE SECTION;
288 EXEC SQL END DECLARE SECTION;
290 EXEC SQL FETCH csr116 INTO :id1, :id2;
294 /* If id2 is already stored, skip this row. */
295 i = (int)hash_lookup(string_dups, id2);
298 /* Follow the chain of id1 equivalent IDs back to the lowest one. */
300 while ((tmp = (int)hash_lookup(string_dups, id)) > 0)
302 hash_store(string_dups, id2, (void *)id);
304 EXEC SQL CLOSE csr116;
305 dprintf("found %d duplicates\n", q);
306 hash_step(string_dups, print_dup_map, NULL);
307 /* We don't want to delete the duplicates now because if the dbck
308 is cancelled, a LOT of state will be lost. So, we'll just let
309 them not get marked as used and then phase3 will clean them up */
311 dprintf("Loading strings...\n");
313 strings = create_hash(75000);
315 out_of_mem("loading strings");
317 EXEC SQL DECLARE csr101 CURSOR FOR
318 SELECT string_id, string FROM strings ORDER BY string_id;
319 EXEC SQL OPEN csr101;
323 EXEC SQL BEGIN DECLARE SECTION;
325 char buf[STRINGS_STRING_SIZE];
326 EXEC SQL END DECLARE SECTION;
328 EXEC SQL FETCH csr101 INTO :id, :buf;
332 s = malloc(sizeof(struct string));
334 out_of_mem("storing strings");
335 s->name = strdup(strtrim(buf));
338 retval = hash_store(strings, id, s);
340 out_of_mem("storing strings in hash table");
341 else if (retval == 1) /* duplicate string_id */
343 sq_save_data(sq, hash_lookup(strings, id));
347 EXEC SQL CLOSE csr101;
348 /* keep string id 0 (the empty string) even if unreferenced */
351 printf("Loaded %d strings\n", q);
353 dprintf("Loading users...\n");
355 users = create_hash(65000);
357 out_of_mem("loading users");
359 EXEC SQL DECLARE csr102 CURSOR FOR
360 SELECT users_id, login, last, first, status, potype, pop_id, box_id,
361 imap_id, modby, fmodby, pmodby, comments, sigwho, sponsor_type, sponsor_id
362 FROM users ORDER BY users_id;
363 EXEC SQL OPEN csr102;
366 EXEC SQL BEGIN DECLARE SECTION;
367 char login[USERS_LOGIN_SIZE], nbuf[USERS_FIRST_SIZE + USERS_LAST_SIZE];
368 char last[USERS_LAST_SIZE], first[USERS_FIRST_SIZE];
369 char potype[USERS_POTYPE_SIZE], sponsor_type[USERS_SPONSOR_TYPE_SIZE];
370 int users_id, status, pop_id, box_id, imap_id, modby, fmodby, pmodby;
371 int comments, sigwho, sponsor_id;
372 EXEC SQL END DECLARE SECTION;
374 EXEC SQL FETCH csr102 INTO :users_id, :login, :last, :first,
375 :status, :potype, :pop_id, :box_id, :imap_id, :modby, :fmodby,
376 :pmodby, :comments, :sigwho, :sponsor_type, :sponsor_id;
380 u = malloc(sizeof(struct user));
382 out_of_mem("storing users");
383 strcpy(u->login, strtrim(login));
384 u->potype = potype[0];
385 sprintf(nbuf, "%s, %s", strtrim(last), strtrim(first));
386 u->fullname = strdup(nbuf);
388 u->users_id = users_id;
392 u->comment = comments;
394 u->sponsor_type = sponsor_type[0];
395 u->sponsor_id = sponsor_id;
399 u->pobox_id = pop_id;
402 /* If potype is SMTP, box_id is a string_id for the strings tbl */
403 u->pobox_id = box_id;
406 u->pobox_id = imap_id;
411 retval = hash_store(users, users_id, u);
413 out_of_mem("storing users in hash table");
414 else if (retval == 1)
416 sq_save_data(sq, hash_lookup(users, users_id));
420 EXEC SQL CLOSE csr102;
422 generic_fix(sq, show_user_id, "Change ID", fix_user_id, 0);
428 out_of_mem("finding duplicate logins");
430 EXEC SQL DECLARE csr103 CURSOR FOR
431 SELECT u1.users_id FROM users u1, users u2
432 WHERE u1.login = u2.login and u1.rowid != u2.rowid;
433 EXEC SQL OPEN csr103;
436 EXEC SQL FETCH csr103 INTO :id;
439 sq_save_data(sq, hash_lookup(users, id));
441 EXEC SQL CLOSE csr103;
442 handle_duplicate_logins(sq);
447 dprintf("Scanning krbmap...\n");
449 EXEC SQL DECLARE csr113 CURSOR FOR
450 SELECT k1.users_id FROM krbmap k1, krbmap k2
451 WHERE k1.users_id = k2.users_id AND k1.rowid != k2.rowid;
452 EXEC SQL OPEN csr113;
455 EXEC SQL FETCH csr113 INTO :id;
459 printf("User %d is in the krbmap more than once!\n", id);
460 printf("Not fixing this error\n");
462 EXEC SQL CLOSE csr113;
464 EXEC SQL DECLARE csr114 CURSOR FOR
465 SELECT k1.string_id FROM krbmap k1, krbmap k2
466 WHERE k1.string_id = k2.string_id AND k1.rowid != k2.rowid;
467 EXEC SQL OPEN csr114;
470 EXEC SQL FETCH csr114 INTO :id;
474 printf("Principal %d is in the krbmap more than once!\n", id);
475 printf("Not fixing this error\n");
477 EXEC SQL CLOSE csr114;
480 dprintf("Loading machines...\n");
482 machines = create_hash(20000);
483 if (!sq || !machines)
484 out_of_mem("loading machines");
486 EXEC SQL DECLARE csr104 CURSOR FOR
487 SELECT mach_id, name, snet_id, owner_type, owner_id,
488 acomment, ocomment, creator, modby
489 FROM machine ORDER BY mach_id;
490 EXEC SQL OPEN csr104;
493 EXEC SQL BEGIN DECLARE SECTION;
494 int mach_id, snet_id, owner_id, acomment, ocomment, creator, modby;
495 char name[MACHINE_NAME_SIZE], owner_type[MACHINE_OWNER_TYPE_SIZE];
496 EXEC SQL END DECLARE SECTION;
498 EXEC SQL FETCH csr104 INTO :mach_id, :name, :snet_id,
499 :owner_type, :owner_id, :acomment, :ocomment, :creator, :modby;
503 m = malloc(sizeof(struct machine));
505 out_of_mem("storing machines");
506 strcpy(m->name, strtrim(name));
507 m->owner_type = owner_type[0];
508 m->owner_id = owner_id;
509 m->snet_id = snet_id;
510 m->mach_id = mach_id;
512 m->acomment = acomment;
513 m->ocomment = ocomment;
514 m->creator = creator;
516 retval = hash_store(machines, mach_id, m);
518 out_of_mem("storing machines in hash table");
519 else if (retval == 1)
521 sq_save_data(sq, hash_lookup(machines, mach_id));
525 EXEC SQL CLOSE csr104;
526 generic_fix(sq, show_mach_id, "Change ID", fix_mach_id, 0);
530 EXEC SQL BEGIN DECLARE SECTION;
531 char name[HOSTALIAS_NAME_SIZE];
533 EXEC SQL END DECLARE SECTION;
537 out_of_mem("looking for duplicate machine names");
539 EXEC SQL DECLARE csr105 CURSOR FOR
540 SELECT m1.mach_id FROM machine m1, machine m2
541 WHERE m1.name = m2.name AND m1.rowid != m2.rowid;
542 EXEC SQL OPEN csr105;
545 EXEC SQL FETCH csr105 INTO :id;
549 sq_save_data(sq, hash_lookup(machines, id));
551 EXEC SQL CLOSE csr105;
552 generic_fix(sq, show_mach_name, "Change name", cant_fix, 0);
554 EXEC SQL DECLARE csr_hal1 CURSOR FOR
555 SELECT h1.name, m1.mach_id, m2.mach_id
556 FROM hostalias h1, machine m1, hostalias h2, machine m2
557 WHERE h1.name = h2.name AND h1.mach_id != h2.mach_id
558 AND m1.mach_id = h1.mach_id AND m2.mach_id = h2.mach_id;
559 EXEC SQL OPEN csr_hal1;
562 EXEC SQL FETCH csr_hal1 INTO :name, :id1, :id2;
565 printf("Aliases for machines %d and %d have duplicate name %s\n",
566 id1, id2, strtrim(name));
569 EXEC SQL CLOSE csr_hal1;
571 EXEC SQL DECLARE csr_hal2 CURSOR FOR
572 SELECT h1.name, m1.mach_id, m2.mach_id
573 FROM hostalias h1, machine m1, machine m2
574 WHERE h1.name = m1.name AND h1.mach_id = m2.mach_id;
575 EXEC SQL OPEN csr_hal2;
578 EXEC SQL FETCH csr_hal2 INTO :name, :id1, :id2;
581 printf("Machine %d has alias %s that conflicts with machine %d\n",
582 id2, strtrim(name), id1);
585 EXEC SQL CLOSE csr_hal2;
588 dprintf("Loading subnets...\n");
589 subnets = create_hash(254);
591 out_of_mem("loading subnets");
593 EXEC SQL DECLARE csr115 CURSOR FOR
594 SELECT snet_id, name, owner_type, owner_id, modby from subnet;
595 EXEC SQL OPEN csr115;
598 EXEC SQL BEGIN DECLARE SECTION;
599 char name[SUBNET_NAME_SIZE], owner_type[SUBNET_OWNER_TYPE_SIZE];
600 int snet_id, owner_id, modby;
601 EXEC SQL END DECLARE SECTION;
603 EXEC SQL FETCH csr115 INTO :snet_id, :name, :owner_type,
608 sn = malloc(sizeof(struct machine));
610 out_of_mem("storing subnets");
611 strcpy(sn->name, strtrim(name));
612 sn->owner_type = owner_type[0];
613 sn->owner_id = owner_id;
614 sn->snet_id = snet_id;
616 retval = hash_store(subnets, snet_id, sn);
618 out_of_mem("storing subnets in hash table");
619 else if (retval == 1)
621 printf("Duplicate subnet ID: %d (%s)\n", id, name);
622 /* should add code to delete */
626 EXEC SQL CLOSE csr115;
632 out_of_mem("looking for duplicate subnet names");
634 EXEC SQL DECLARE csr117 CURSOR FOR
635 SELECT s1.snet_id FROM subnet s1, subnet s2
636 WHERE s1.name = s2.name AND s1.rowid != s2.rowid;
637 EXEC SQL OPEN csr117;
640 EXEC SQL FETCH csr117 INTO :id;
644 sq_save_data(sq, hash_lookup(subnets, id));
646 EXEC SQL CLOSE csr117;
647 generic_fix(sq, show_snet_name, "Change name", cant_fix, 0);
650 dprintf("Loading clusters...\n");
652 clusters = create_hash(100);
653 if (!sq || !clusters)
654 out_of_mem("loading clusters");
656 EXEC SQL DECLARE csr106 CURSOR FOR
657 SELECT clu_id, name, modby FROM clusters;
658 EXEC SQL OPEN csr106;
661 EXEC SQL BEGIN DECLARE SECTION;
663 char name[CLUSTERS_NAME_SIZE];
664 EXEC SQL END DECLARE SECTION;
666 EXEC SQL FETCH csr106 INTO :clu_id, :name, :modby;
670 c = malloc(sizeof(struct cluster));
672 out_of_mem("storing clusters");
673 strcpy(c->name, strtrim(name));
676 retval = hash_store(clusters, clu_id, c);
678 out_of_mem("storing clusters in hash table");
679 else if (retval == 1)
681 sq_save_data(sq, hash_lookup(clusters, clu_id));
685 EXEC SQL CLOSE csr106;
686 generic_fix(sq, show_clu_id, "Change ID", fix_clu_id, 0);
692 out_of_mem("looking for duplicate cluster names");
694 EXEC SQL DECLARE csr107 CURSOR FOR
695 SELECT c1.clu_id FROM clusters c1, clusters c2
696 WHERE c1.name = c2.name AND c1.rowid != c2.rowid;
697 EXEC SQL OPEN csr107;
700 EXEC SQL FETCH csr107 INTO :id;
704 sq_save_data(sq, hash_lookup(clusters, id));
706 EXEC SQL CLOSE csr107;
707 generic_fix(sq, show_clu_name, "Change name", cant_fix, 0);
710 dprintf("Loading lists...\n");
712 lists = create_hash(50000);
714 out_of_mem("loading lists");
716 EXEC SQL DECLARE csr108 CURSOR FOR
717 SELECT list_id, name, acl_id, acl_type, memacl_id, memacl_type, modby
720 EXEC SQL OPEN csr108;
723 EXEC SQL BEGIN DECLARE SECTION;
724 int list_id, acl_id, memacl_id, modby;
725 char name[LIST_NAME_SIZE], acl_type[LIST_ACL_TYPE_SIZE];
726 char memacl_type[LIST_ACL_TYPE_SIZE];
727 EXEC SQL END DECLARE SECTION;
729 EXEC SQL FETCH csr108 INTO :list_id, :name, :acl_id, :acl_type,
730 :memacl_id, :memacl_type, :modby;
733 l = malloc(sizeof(struct list));
735 out_of_mem("storing lists");
736 strcpy(l->name, strtrim(name));
737 l->acl_type = acl_type[0];
739 l->memacl_type = memacl_type[0];
740 l->memacl_id = memacl_id;
741 l->list_id = list_id;
744 retval = hash_store(lists, list_id, l);
746 out_of_mem("storing lists in hash table");
747 else if (retval == 1)
749 sq_save_data(sq, hash_lookup(lists, list_id));
753 EXEC SQL CLOSE csr108;
754 generic_fix(sq, show_list_id, "Change ID", fix_list_id, 0);
760 out_of_mem("looking for duplicate list names");
762 EXEC SQL DECLARE csr109 CURSOR FOR
763 SELECT l1.list_id FROM list l1, list l2
764 WHERE l1.name = l2.name AND l1.rowid != l2.rowid;
765 EXEC SQL OPEN csr109;
768 EXEC SQL FETCH csr109 INTO :id;
772 sq_save_data(sq, hash_lookup(lists, id));
774 EXEC SQL CLOSE csr109;
775 generic_fix(sq, show_list_name, "Change name", cant_fix, 0);
778 dprintf("Loading filesys...\n");
780 filesys = create_hash(30000);
782 out_of_mem("loading filesys");
784 EXEC SQL DECLARE csr110 CURSOR FOR
785 SELECT filsys_id, label, owner, owners, phys_id, mach_id,
786 type, name, modby FROM filesys ORDER BY filsys_id;
787 EXEC SQL OPEN csr110;
790 EXEC SQL BEGIN DECLARE SECTION;
791 int filsys_id, owner, owners, phys_id, mach_id, modby;
792 char label[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
793 char name[FILESYS_NAME_SIZE];
794 EXEC SQL END DECLARE SECTION;
796 EXEC SQL FETCH csr110 INTO :filsys_id, :label, :owner, :owners,
797 :phys_id, :mach_id, :type, :name, :modby;
801 f = malloc(sizeof(struct filesys));
803 out_of_mem("storing filesystems");
804 strcpy(f->name, strtrim(label));
805 strcpy(f->dir, strtrim(name));
806 f->filsys_id = filsys_id;
809 f->phys_id = phys_id;
810 f->mach_id = mach_id;
812 retval = hash_store(filesys, filsys_id, f);
814 out_of_mem("storing filesys in hash table");
815 else if (retval == 1)
817 sq_save_data(sq, hash_lookup(filesys, filsys_id));
821 EXEC SQL CLOSE csr110;
823 generic_fix(sq, show_fs_id, "Change ID", fix_fs_id, 0);
829 out_of_mem("looking for duplicate filesys names");
831 EXEC SQL DECLARE csr118 CURSOR FOR
832 SELECT fs1.filsys_id FROM filesys fs1, filesys fs2
833 WHERE fs1.label = fs2.label AND fs1.rowid != fs2.rowid;
834 EXEC SQL OPEN csr118;
837 EXEC SQL FETCH csr118 INTO :id;
841 sq_save_data(sq, hash_lookup(filesys, id));
843 EXEC SQL CLOSE csr118;
844 generic_fix(sq, show_fs_name, "Change name", cant_fix, 0);
847 dprintf("Loading nfsphys...\n");
849 nfsphys = create_hash(500);
851 out_of_mem("loading nfsphs");
853 EXEC SQL DECLARE csr111 CURSOR FOR
854 SELECT nfsphys_id, dir, mach_id, TO_CHAR(allocated), modby FROM nfsphys;
855 EXEC SQL OPEN csr111;
858 EXEC SQL BEGIN DECLARE SECTION;
859 int nfsphys_id, mach_id, modby;
860 char dir[NFSPHYS_DIR_SIZE];
862 EXEC SQL END DECLARE SECTION;
864 EXEC SQL FETCH csr111 INTO :nfsphys_id, :dir, :mach_id,
869 n = malloc(sizeof(struct nfsphys));
871 out_of_mem("storing nfsphys");
872 strcpy(n->dir, strtrim(dir));
873 n->mach_id = mach_id;
874 n->nfsphys_id = nfsphys_id;
875 n->allocated = strtoull(allocated, NULL, 0);
878 retval = hash_store(nfsphys, nfsphys_id, n);
880 out_of_mem("storing nfsphys in hash table");
881 else if (retval == 1)
883 sq_save_data(sq, hash_lookup(nfsphys, nfsphys_id));
887 EXEC SQL CLOSE csr111;
889 generic_fix(sq, show_np_id, "Change ID", fix_np_id, 0);
893 dprintf("Checking printers...\n");
895 EXEC SQL DECLARE csr119 CURSOR FOR
896 SELECT p1.name FROM printers p1, printers p2
897 WHERE ( p1.name = p2.name AND p1.rowid < p2.rowid )
898 OR ( p1.name = p2.duplexname );
899 EXEC SQL OPEN csr119;
902 EXEC SQL BEGIN DECLARE SECTION;
903 char name[PRINTERS_NAME_SIZE];
904 EXEC SQL END DECLARE SECTION;
906 EXEC SQL FETCH csr119 INTO :name;
910 printf("Printer %s has duplicate name\n", name);
913 EXEC SQL CLOSE csr119;
916 dprintf("Loading printservers...\n");
917 printservers = create_hash(100);
919 out_of_mem("loading printservers");
921 EXEC SQL DECLARE csr_ps CURSOR FOR
922 SELECT mach_id, printer_types, owner_type, owner_id, lpc_acl, modby
924 EXEC SQL OPEN csr_ps;
927 EXEC SQL BEGIN DECLARE SECTION;
928 int mach_id, printer_types, owner_id, lpc_acl, modby;
929 char owner_type[PRINTSERVERS_OWNER_TYPE_SIZE];
930 EXEC SQL END DECLARE SECTION;
932 EXEC SQL FETCH csr_ps INTO :mach_id, :printer_types, :owner_type,
933 :owner_id, :lpc_acl, :modby;
937 ps = malloc(sizeof(struct printserver));
939 out_of_mem("storing printserver");
940 ps->mach_id = mach_id;
941 ps->printer_types = printer_types;
942 ps->owner_type = owner_type[0];
943 ps->owner_id = owner_id;
944 ps->lpc_acl = lpc_acl;
946 retval = hash_store(printservers, mach_id, ps);
948 out_of_mem("storing printserver in hash table");
949 else if (retval == 1)
951 printf("Duplicate printserver mach_id %d\n", mach_id);
955 EXEC SQL CLOSE csr_ps;
959 dprintf("Checking zephyr...\n");
961 EXEC SQL DECLARE csr120 CURSOR FOR
962 SELECT z1.class FROM zephyr z1, zephyr z2
963 WHERE (z1.class = z2.class AND z1.rowid < z1.rowid);
964 EXEC SQL OPEN csr120;
967 EXEC SQL BEGIN DECLARE SECTION;
968 char class[ZEPHYR_CLASS_SIZE];
969 EXEC SQL END DECLARE SECTION;
971 EXEC SQL FETCH csr120 INTO :class;
975 printf("Zephyr class %s has duplicate name\n", class);
978 EXEC SQL CLOSE csr120;
981 dprintf("Loading containers...\n");
982 containers = create_hash(1000);
984 out_of_mem("loading containers");
986 EXEC SQL DECLARE csr_cnts CURSOR FOR
987 SELECT name, cnt_id, list_id, acl_type, acl_id, memacl_type, memacl_id,
988 modby FROM containers;
989 EXEC SQL OPEN csr_cnts;
992 EXEC SQL BEGIN DECLARE SECTION;
993 int cnt_id, list_id, acl_id, memacl_id, modby;
994 char name[CONTAINERS_NAME_SIZE];
995 char acl_type[CONTAINERS_ACL_TYPE_SIZE];
996 char memacl_type[CONTAINERS_MEMACL_TYPE_SIZE];
997 EXEC SQL END DECLARE SECTION;
999 EXEC SQL FETCH csr_cnts INTO :name, :cnt_id, :list_id, :acl_type,
1000 :acl_id, :memacl_type, :memacl_id, :modby;
1004 cnt = malloc(sizeof(struct container));
1006 out_of_mem("storing container");
1007 strcpy(cnt->name, strtrim(name));
1008 cnt->cnt_id = cnt_id;
1009 cnt->list_id = list_id;
1010 cnt->acl_type = acl_type[0];
1011 cnt->acl_id = acl_id;
1012 cnt->memacl_type = memacl_type[0];
1013 cnt->memacl_id = memacl_id;
1015 retval = hash_store(containers, cnt_id, cnt);
1017 out_of_mem("storing container in hash table");
1018 else if (retval == 1)
1020 printf("Duplicate container cnt_id %d\n", cnt_id);
1024 EXEC SQL CLOSE csr_cnts;
1030 out_of_mem("looking for duplicate container names");
1032 EXEC SQL DECLARE csr121 CURSOR FOR
1033 SELECT cnt1.cnt_id FROM containers cnt1, containers cnt2
1034 WHERE cnt1.name = cnt2.name AND cnt1.cnt_id != cnt2.cnt_id;
1035 EXEC SQL OPEN csr121;
1038 EXEC SQL FETCH csr121 INTO :id;
1042 sq_save_data(sq, hash_lookup(containers, id));
1044 EXEC SQL CLOSE csr121;
1045 generic_fix(sq, show_cnt_name, "Change name", cant_fix, 0);