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);
43 int show_user_id(void *user)
45 struct user *u = user;
46 printf("User %s (%s, status %d) has duplicate ID\n",
47 u->login, u->fullname, u->status);
51 void handle_duplicate_logins(struct save_queue *sq)
53 struct user *u, *uu, *tmp;
56 if (sq_get_data(sq, &uu))
58 while (sq_get_data(sq, &u))
60 if (!strcmp(u->login, uu->login))
62 if (uu->status == 1 || u->status == 0)
68 printf("User %s (%s, status %d) and\n",
69 u->login, u->fullname, u->status);
70 printf("User %s (%s, status %d) have duplicate logins\n",
71 uu->login, uu->fullname, uu->status);
72 if (!strcmp(u->fullname, uu->fullname) &&
73 single_fix("Delete the second one", 0))
74 single_delete("users", "users_id", uu->users_id);
75 else if (single_fix("Unregister the second one", 0))
77 EXEC SQL BEGIN DECLARE SECTION;
78 int id = uu->users_id, rowcount;
79 EXEC SQL END DECLARE SECTION;
82 SET login = '#' || CHAR(users.unix_uid), status = 0
84 rowcount = sqlca.sqlerrd[2];
87 printf("%d entr%s fixed\n", rowcount,
88 rowcount == 1 ? "y" : "ies");
91 printf("Not fixed\n");
101 void fix_user_id(void *user)
103 struct user *u = user;
104 u->users_id = generic_fix_id("users", "users_id", "login",
105 u->users_id, u->login);
109 void cant_fix(void *id)
111 printf("Sorry, don't know how to fix that\n");
114 int show_mach_id(void *machine)
116 struct machine *m = machine;
117 printf("Machine %s has duplicate ID %d\n", m->name, m->mach_id);
121 int show_mach_name(void *machine)
123 struct machine *m = machine;
124 printf("Machine %s (%d) has duplicate name\n", m->name, m->mach_id);
128 void fix_mach_id(void *machine)
130 struct machine *m = machine;
131 m->mach_id = generic_fix_id("machine", "mach_id", "name",
132 m->mach_id, m->name);
135 int show_snet_name(void *subnet)
137 struct subnet *s = subnet;
138 printf("Subnet %s (%d) has duplicate name\n", s->name, s->snet_id);
142 int show_clu_id(void *cluster)
144 struct cluster *c = cluster;
145 printf("Cluster %s has duplicate ID %d\n", c->name, c->clu_id);
149 int show_clu_name(void *cluster)
151 struct cluster *c = cluster;
152 printf("Cluster %s (%d) has duplicate name\n", c->name, c->clu_id);
156 void fix_clu_id(void *cluster)
158 struct cluster *c = cluster;
159 c->clu_id = generic_fix_id("cluster", "clu_id", "name", c->clu_id, c->name);
162 int show_list_id(void *list)
164 struct list *l = list;
165 printf("List %s has duplicate ID %d\n", l->name, l->list_id);
169 int show_list_name(void *list)
171 struct list *l = list;
172 printf("List %s (%d) has duplicate name\n", l->name, l->list_id);
176 void fix_list_id(void *list)
178 struct list *l = list;
179 l->list_id = generic_fix_id("list", "list_id", "name", l->list_id, l->name);
182 int show_fs_id(void *filesys)
184 struct filesys *f = filesys;
185 printf("Filesys %s has duplicate ID %d\n", f->name, f->filsys_id);
189 void fix_fs_id(void *filesys)
191 struct filesys *f = filesys;
192 f->filsys_id = generic_fix_id("filesys", "filsys_id", "label",
193 f->filsys_id, f->name);
196 int show_fs_name(void *filesys)
198 struct filesys *fs = filesys;
199 printf("Filesys %s (%d) has duplicate name\n", fs->name, fs->filsys_id);
203 int show_np_id(void *nfsphys)
205 struct nfsphys *n = nfsphys;
206 printf("NfsPhys %s:%s has duplicate ID %d\n",
207 ((struct machine *)hash_lookup(machines, n->mach_id))->name,
208 n->dir, n->nfsphys_id);
212 void fix_np_id(void *nfsphys)
214 struct nfsphys *n = nfsphys;
215 n->nfsphys_id = generic_fix_id("nfsphys", "nfsphys_id", "dir",
216 n->nfsphys_id, n->dir);
219 int show_str_id(void *string)
221 struct string *s = string;
222 printf("String %s has duplicate ID %d\n", s->name, s->string_id);
226 int print_str_id(void *id)
228 printf("String %d is a duplicate\n", (int)id);
232 void print_dup_map(int key, void *data, void *hint)
234 printf("String %d is a duplicate of string %d\n", key, (int)data);
239 EXEC SQL BEGIN DECLARE SECTION;
241 EXEC SQL END DECLARE SECTION;
242 int i, q, retval, tmp;
243 struct save_queue *sq;
252 struct printserver *ps;
254 printf("Phase 1 - Looking for duplicates\n");
256 /* self-join strings table on "string" to get duplicate strings, then
257 build a duplicates table to merge them. */
259 dprintf("Looking for duplicate strings...\n");
260 string_dups = create_hash(100);
262 out_of_mem("storing duplicate strings");
264 EXEC SQL DECLARE csr116 CURSOR FOR
265 SELECT s1.string_id, s2.string_id FROM strings s1, strings s2
266 WHERE s1.string = s2.string and s1.string_id < s2.string_id;
267 EXEC SQL OPEN csr116;
268 /* The SELECT gives us two columns, both with non-negative integers.
269 * The number in the left column is always the smaller of the two,
270 * and each row includes string IDs for identical strings. We use
271 * them to make a mapping from id-to-delete to id-to-keep for all
277 EXEC SQL BEGIN DECLARE SECTION;
279 EXEC SQL END DECLARE SECTION;
281 EXEC SQL FETCH csr116 INTO :id1, :id2;
285 /* If id2 is already stored, skip this row. */
286 i = (int)hash_lookup(string_dups, id2);
289 /* Follow the chain of id1 equivalent IDs back to the lowest one. */
291 while ((tmp = (int)hash_lookup(string_dups, id)) > 0)
293 hash_store(string_dups, id2, (void *)id);
295 EXEC SQL CLOSE csr116;
296 dprintf("found %d duplicates\n", q);
297 hash_step(string_dups, print_dup_map, NULL);
298 /* We don't want to delete the duplicates now because if the dbck
299 is cancelled, a LOT of state will be lost. So, we'll just let
300 them not get marked as used and then phase3 will clean them up */
302 dprintf("Loading strings...\n");
304 strings = create_hash(75000);
306 out_of_mem("loading strings");
308 EXEC SQL DECLARE csr101 CURSOR FOR
309 SELECT string_id, string FROM strings ORDER BY string_id;
310 EXEC SQL OPEN csr101;
314 EXEC SQL BEGIN DECLARE SECTION;
316 char buf[STRINGS_STRING_SIZE];
317 EXEC SQL END DECLARE SECTION;
319 EXEC SQL FETCH csr101 INTO :id, :buf;
323 s = malloc(sizeof(struct string));
325 out_of_mem("storing strings");
326 s->name = strdup(strtrim(buf));
329 retval = hash_store(strings, id, s);
331 out_of_mem("storing strings in hash table");
332 else if (retval == 1) /* duplicate string_id */
334 sq_save_data(sq, hash_lookup(strings, id));
338 EXEC SQL CLOSE csr101;
339 /* keep string id 0 (the empty string) even if unreferenced */
342 printf("Loaded %d strings\n", q);
344 dprintf("Loading users...\n");
346 users = create_hash(30000);
348 out_of_mem("loading users");
350 EXEC SQL DECLARE csr102 CURSOR FOR
351 SELECT users_id, login, last, first, status, potype, pop_id, box_id,
352 imap_id, modby, fmodby, pmodby, comments, sigwho FROM users
354 EXEC SQL OPEN csr102;
357 EXEC SQL BEGIN DECLARE SECTION;
358 char login[USERS_LOGIN_SIZE], nbuf[USERS_FIRST_SIZE + USERS_LAST_SIZE];
359 char last[USERS_LAST_SIZE], first[USERS_FIRST_SIZE];
360 char potype[USERS_POTYPE_SIZE];
361 int users_id, status, pop_id, box_id, imap_id, modby, fmodby, pmodby;
362 int comments, sigwho;
363 EXEC SQL END DECLARE SECTION;
365 EXEC SQL FETCH csr102 INTO :users_id, :login, :last, :first,
366 :status, :potype, :pop_id, :box_id, :imap_id, :modby, :fmodby,
367 :pmodby, :comments, :sigwho;
371 u = malloc(sizeof(struct user));
373 out_of_mem("storing users");
374 strcpy(u->login, strtrim(login));
375 u->potype = potype[0];
376 sprintf(nbuf, "%s, %s", strtrim(last), strtrim(first));
377 u->fullname = strdup(nbuf);
379 u->users_id = users_id;
383 u->comment = comments;
388 u->pobox_id = pop_id;
391 /* If potype is SMTP, box_id is a string_id for the strings tbl */
392 u->pobox_id = box_id;
395 u->pobox_id = imap_id;
400 retval = hash_store(users, users_id, u);
402 out_of_mem("storing users in hash table");
403 else if (retval == 1)
405 sq_save_data(sq, hash_lookup(users, users_id));
409 EXEC SQL CLOSE csr102;
411 generic_fix(sq, show_user_id, "Change ID", fix_user_id, 0);
417 out_of_mem("finding duplicate logins");
419 EXEC SQL DECLARE csr103 CURSOR FOR
420 SELECT u1.users_id FROM users u1, users u2
421 WHERE u1.login = u2.login and u1.rowid != u2.rowid;
422 EXEC SQL OPEN csr103;
425 EXEC SQL FETCH csr103 INTO :id;
428 sq_save_data(sq, hash_lookup(users, id));
430 EXEC SQL CLOSE csr103;
431 handle_duplicate_logins(sq);
436 dprintf("Scanning krbmap...\n");
438 EXEC SQL DECLARE csr113 CURSOR FOR
439 SELECT k1.users_id FROM krbmap k1, krbmap k2
440 WHERE k1.users_id = k2.users_id AND k1.rowid != k2.rowid;
441 EXEC SQL OPEN csr113;
444 EXEC SQL FETCH csr113 INTO :id;
448 printf("User %d is in the krbmap more than once!\n", id);
449 printf("Not fixing this error\n");
451 EXEC SQL CLOSE csr113;
453 EXEC SQL DECLARE csr114 CURSOR FOR
454 SELECT k1.string_id FROM krbmap k1, krbmap k2
455 WHERE k1.string_id = k2.string_id AND k1.rowid != k2.rowid;
456 EXEC SQL OPEN csr114;
459 EXEC SQL FETCH csr114 INTO :id;
463 printf("Principal %d is in the krbmap more than once!\n", id);
464 printf("Not fixing this error\n");
466 EXEC SQL CLOSE csr114;
469 dprintf("Loading machines...\n");
471 machines = create_hash(20000);
472 if (!sq || !machines)
473 out_of_mem("loading machines");
475 EXEC SQL DECLARE csr104 CURSOR FOR
476 SELECT mach_id, name, snet_id, owner_type, owner_id,
477 acomment, ocomment, creator, modby
478 FROM machine ORDER BY mach_id;
479 EXEC SQL OPEN csr104;
482 EXEC SQL BEGIN DECLARE SECTION;
483 int mach_id, snet_id, owner_id, acomment, ocomment, creator, modby;
484 char name[MACHINE_NAME_SIZE], owner_type[MACHINE_OWNER_TYPE_SIZE];
485 EXEC SQL END DECLARE SECTION;
487 EXEC SQL FETCH csr104 INTO :mach_id, :name, :snet_id,
488 :owner_type, :owner_id, :acomment, :ocomment, :creator, :modby;
492 m = malloc(sizeof(struct machine));
494 out_of_mem("storing machines");
495 strcpy(m->name, strtrim(name));
496 m->owner_type = owner_type[0];
497 m->owner_id = owner_id;
498 m->snet_id = snet_id;
499 m->mach_id = mach_id;
501 m->acomment = acomment;
502 m->ocomment = ocomment;
503 m->creator = creator;
505 retval = hash_store(machines, mach_id, m);
507 out_of_mem("storing machines in hash table");
508 else if (retval == 1)
510 sq_save_data(sq, hash_lookup(machines, mach_id));
514 EXEC SQL CLOSE csr104;
515 generic_fix(sq, show_mach_id, "Change ID", fix_mach_id, 0);
519 EXEC SQL BEGIN DECLARE SECTION;
520 char name[HOSTALIAS_NAME_SIZE];
522 EXEC SQL END DECLARE SECTION;
526 out_of_mem("looking for duplicate machine names");
528 EXEC SQL DECLARE csr105 CURSOR FOR
529 SELECT m1.mach_id FROM machine m1, machine m2
530 WHERE m1.name = m2.name AND m1.rowid != m2.rowid;
531 EXEC SQL OPEN csr105;
534 EXEC SQL FETCH csr105 INTO :id;
538 sq_save_data(sq, hash_lookup(machines, id));
540 EXEC SQL CLOSE csr105;
541 generic_fix(sq, show_mach_name, "Change name", cant_fix, 0);
543 EXEC SQL DECLARE csr_hal1 CURSOR FOR
544 SELECT h1.name, m1.mach_id, m2.mach_id
545 FROM hostalias h1, machine m1, hostalias h2, machine m2
546 WHERE h1.name = h2.name AND h1.mach_id != h2.mach_id
547 AND m1.mach_id = h1.mach_id AND m2.mach_id = h2.mach_id;
548 EXEC SQL OPEN csr_hal1;
551 EXEC SQL FETCH csr_hal1 INTO :name, :id1, :id2;
554 printf("Aliases for machines %d and %d have duplicate name %s\n",
555 id1, id2, strtrim(name));
558 EXEC SQL CLOSE csr_hal1;
560 EXEC SQL DECLARE csr_hal2 CURSOR FOR
561 SELECT h1.name, m1.mach_id, m2.mach_id
562 FROM hostalias h1, machine m1, machine m2
563 WHERE h1.name = m1.name AND h1.mach_id = m2.mach_id;
564 EXEC SQL OPEN csr_hal2;
567 EXEC SQL FETCH csr_hal2 INTO :name, :id1, :id2;
570 printf("Machine %d has alias %s that conflicts with machine %d\n",
571 id2, strtrim(name), id1);
574 EXEC SQL CLOSE csr_hal2;
577 dprintf("Loading subnets...\n");
578 subnets = create_hash(254);
580 out_of_mem("loading subnets");
582 EXEC SQL DECLARE csr115 CURSOR FOR
583 SELECT snet_id, name, owner_type, owner_id, modby from subnet;
584 EXEC SQL OPEN csr115;
587 EXEC SQL BEGIN DECLARE SECTION;
588 char name[SUBNET_NAME_SIZE], owner_type[SUBNET_OWNER_TYPE_SIZE];
589 int snet_id, owner_id, modby;
590 EXEC SQL END DECLARE SECTION;
592 EXEC SQL FETCH csr115 INTO :snet_id, :name, :owner_type,
597 sn = malloc(sizeof(struct machine));
599 out_of_mem("storing subnets");
600 strcpy(sn->name, strtrim(name));
601 sn->owner_type = owner_type[0];
602 sn->owner_id = owner_id;
603 sn->snet_id = snet_id;
605 retval = hash_store(subnets, snet_id, sn);
607 out_of_mem("storing subnets in hash table");
608 else if (retval == 1)
610 printf("Duplicate subnet ID: %d (%s)\n", id, name);
611 /* should add code to delete */
615 EXEC SQL CLOSE csr115;
621 out_of_mem("looking for duplicate subnet names");
623 EXEC SQL DECLARE csr117 CURSOR FOR
624 SELECT s1.snet_id FROM subnet s1, subnet s2
625 WHERE s1.name = s2.name AND s1.rowid != s2.rowid;
626 EXEC SQL OPEN csr117;
629 EXEC SQL FETCH csr117 INTO :id;
633 sq_save_data(sq, hash_lookup(subnets, id));
635 EXEC SQL CLOSE csr117;
636 generic_fix(sq, show_snet_name, "Change name", cant_fix, 0);
639 dprintf("Loading clusters...\n");
641 clusters = create_hash(100);
642 if (!sq || !clusters)
643 out_of_mem("loading clusters");
645 EXEC SQL DECLARE csr106 CURSOR FOR
646 SELECT clu_id, name, modby FROM clusters;
647 EXEC SQL OPEN csr106;
650 EXEC SQL BEGIN DECLARE SECTION;
652 char name[CLUSTERS_NAME_SIZE];
653 EXEC SQL END DECLARE SECTION;
655 EXEC SQL FETCH csr106 INTO :clu_id, :name, :modby;
659 c = malloc(sizeof(struct cluster));
661 out_of_mem("storing clusters");
662 strcpy(c->name, strtrim(name));
665 retval = hash_store(clusters, clu_id, c);
667 out_of_mem("storing clusters in hash table");
668 else if (retval == 1)
670 sq_save_data(sq, hash_lookup(clusters, clu_id));
674 EXEC SQL CLOSE csr106;
675 generic_fix(sq, show_clu_id, "Change ID", fix_clu_id, 0);
681 out_of_mem("looking for duplicate cluster names");
683 EXEC SQL DECLARE csr107 CURSOR FOR
684 SELECT c1.clu_id FROM clusters c1, clusters c2
685 WHERE c1.name = c2.name AND c1.rowid != c2.rowid;
686 EXEC SQL OPEN csr107;
689 EXEC SQL FETCH csr107 INTO :id;
693 sq_save_data(sq, hash_lookup(clusters, id));
695 EXEC SQL CLOSE csr107;
696 generic_fix(sq, show_clu_name, "Change name", cant_fix, 0);
699 dprintf("Loading lists...\n");
701 lists = create_hash(50000);
703 out_of_mem("loading lists");
705 EXEC SQL DECLARE csr108 CURSOR FOR
706 SELECT list_id, name, acl_id, acl_type, modby FROM list
708 EXEC SQL OPEN csr108;
711 EXEC SQL BEGIN DECLARE SECTION;
712 int list_id, acl_id, modby;
713 char name[LIST_NAME_SIZE], acl_type[LIST_ACL_TYPE_SIZE];
714 EXEC SQL END DECLARE SECTION;
716 EXEC SQL FETCH csr108 INTO :list_id, :name, :acl_id, :acl_type, :modby;
719 l = malloc(sizeof(struct list));
721 out_of_mem("storing lists");
722 strcpy(l->name, strtrim(name));
723 l->acl_type = acl_type[0];
725 l->list_id = list_id;
728 retval = hash_store(lists, list_id, l);
730 out_of_mem("storing lists in hash table");
731 else if (retval == 1)
733 sq_save_data(sq, hash_lookup(lists, list_id));
737 EXEC SQL CLOSE csr108;
738 generic_fix(sq, show_list_id, "Change ID", fix_list_id, 0);
744 out_of_mem("looking for duplicate list names");
746 EXEC SQL DECLARE csr109 CURSOR FOR
747 SELECT l1.list_id FROM list l1, list l2
748 WHERE l1.name = l2.name AND l1.rowid != l2.rowid;
749 EXEC SQL OPEN csr109;
752 EXEC SQL FETCH csr109 INTO :id;
756 sq_save_data(sq, hash_lookup(lists, id));
758 EXEC SQL CLOSE csr109;
759 generic_fix(sq, show_list_name, "Change name", cant_fix, 0);
762 dprintf("Loading filesys...\n");
764 filesys = create_hash(30000);
766 out_of_mem("loading filesys");
768 EXEC SQL DECLARE csr110 CURSOR FOR
769 SELECT filsys_id, label, owner, owners, phys_id, mach_id,
770 type, name, modby FROM filesys ORDER BY filsys_id;
771 EXEC SQL OPEN csr110;
774 EXEC SQL BEGIN DECLARE SECTION;
775 int filsys_id, owner, owners, phys_id, mach_id, modby;
776 char label[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
777 char name[FILESYS_NAME_SIZE];
778 EXEC SQL END DECLARE SECTION;
780 EXEC SQL FETCH csr110 INTO :filsys_id, :label, :owner, :owners,
781 :phys_id, :mach_id, :type, :name, :modby;
785 f = malloc(sizeof(struct filesys));
787 out_of_mem("storing filesystems");
788 strcpy(f->name, strtrim(label));
789 strcpy(f->dir, strtrim(name));
790 f->filsys_id = filsys_id;
793 f->phys_id = phys_id;
794 f->mach_id = mach_id;
796 retval = hash_store(filesys, filsys_id, f);
798 out_of_mem("storing filesys in hash table");
799 else if (retval == 1)
801 sq_save_data(sq, hash_lookup(filesys, filsys_id));
805 EXEC SQL CLOSE csr110;
807 generic_fix(sq, show_fs_id, "Change ID", fix_fs_id, 0);
813 out_of_mem("looking for duplicate filesys names");
815 EXEC SQL DECLARE csr118 CURSOR FOR
816 SELECT fs1.filsys_id FROM filesys fs1, filesys fs2
817 WHERE fs1.label = fs2.label AND fs1.rowid != fs2.rowid;
818 EXEC SQL OPEN csr118;
821 EXEC SQL FETCH csr118 INTO :id;
825 sq_save_data(sq, hash_lookup(filesys, id));
827 EXEC SQL CLOSE csr118;
828 generic_fix(sq, show_fs_name, "Change name", cant_fix, 0);
831 dprintf("Loading nfsphys...\n");
833 nfsphys = create_hash(500);
835 out_of_mem("loading nfsphs");
837 EXEC SQL DECLARE csr111 CURSOR FOR
838 SELECT nfsphys_id, dir, mach_id, allocated, modby FROM nfsphys;
839 EXEC SQL OPEN csr111;
842 EXEC SQL BEGIN DECLARE SECTION;
843 int nfsphys_id, mach_id, allocated, modby;
844 char dir[NFSPHYS_DIR_SIZE];
845 EXEC SQL END DECLARE SECTION;
847 EXEC SQL FETCH csr111 INTO :nfsphys_id, :dir, :mach_id,
852 n = malloc(sizeof(struct nfsphys));
854 out_of_mem("storing nfsphys");
855 strcpy(n->dir, strtrim(dir));
856 n->mach_id = mach_id;
857 n->nfsphys_id = nfsphys_id;
858 n->allocated = allocated;
861 retval = hash_store(nfsphys, nfsphys_id, n);
863 out_of_mem("storing nfsphys in hash table");
864 else if (retval == 1)
866 sq_save_data(sq, hash_lookup(nfsphys, nfsphys_id));
870 EXEC SQL CLOSE csr111;
872 generic_fix(sq, show_np_id, "Change ID", fix_np_id, 0);
876 dprintf("Checking printers...\n");
878 EXEC SQL DECLARE csr119 CURSOR FOR
879 SELECT p1.name FROM printers p1, printers p2
880 WHERE ( p1.name = p2.name AND p1.rowid < p2.rowid )
881 OR ( p1.name = p2.duplexname );
882 EXEC SQL OPEN csr119;
885 EXEC SQL BEGIN DECLARE SECTION;
886 char name[PRINTERS_NAME_SIZE];
887 EXEC SQL END DECLARE SECTION;
889 EXEC SQL FETCH csr119 INTO :name;
893 printf("Printer %s has duplicate name\n", name);
896 EXEC SQL CLOSE csr119;
899 dprintf("Loading printservers...\n");
900 printservers = create_hash(100);
902 out_of_mem("loading printservers");
904 EXEC SQL DECLARE csr_ps CURSOR FOR
905 SELECT mach_id, printer_types, owner_type, owner_id, lpc_acl, modby
907 EXEC SQL OPEN csr_ps;
910 EXEC SQL BEGIN DECLARE SECTION;
911 int mach_id, printer_types, owner_id, lpc_acl, modby;
912 char owner_type[PRINTSERVERS_OWNER_TYPE_SIZE];
913 EXEC SQL END DECLARE SECTION;
915 EXEC SQL FETCH csr_ps INTO :mach_id, :printer_types, :owner_type,
916 :owner_id, :lpc_acl, :modby;
920 ps = malloc(sizeof(struct printserver));
922 out_of_mem("storing printserver");
923 ps->mach_id = mach_id;
924 ps->owner_type = owner_type[0];
925 ps->owner_id = owner_id;
926 ps->lpc_acl = lpc_acl;
928 retval = hash_store(printservers, mach_id, ps);
930 out_of_mem("storing printserver in hash table");
931 else if (retval == 1)
933 printf("Duplicate printserver mach_id %d\n", mach_id);
937 EXEC SQL CLOSE csr111;