]>
Commit | Line | Data |
---|---|---|
4b329233 | 1 | /* $Header$ |
2 | * | |
3 | * | |
4 | * (c) Copyright 1989 by the Massachusetts Institute of Technology. | |
5 | * For copying and distribution information, please see the file | |
6 | * <mit-copyright.h>. | |
7 | */ | |
8 | ||
9 | #include <mit-copyright.h> | |
10 | #include <stdio.h> | |
11 | #include <sys/file.h> | |
12 | ||
13 | #include <rx/xdr.h> | |
14 | #include "ptint.h" | |
15 | #include "ptserver.h" | |
16 | #include "pterror.h" | |
17 | ||
18 | #include <moira.h> | |
19 | #include <moira_site.h> | |
20 | #include <ctype.h> | |
21 | ||
22 | #define min(x,y) ((x) < (y) ? (x) : (y)) | |
23 | char *whoami = "sync"; | |
24 | ||
25 | char *malloc(), *strsave(); | |
26 | int dbase_fd; | |
27 | ||
28 | long pos; /* cheader.eofPtr */ | |
29 | long usercount; /* cheader.usercount */ | |
30 | long groupcount; /* cheader.groupcount */ | |
31 | ||
32 | struct hash *users; | |
33 | struct hash *groups; | |
6ade5328 | 34 | |
35 | struct member { | |
36 | struct entry *user; | |
37 | struct entry *group; | |
38 | struct member *unext; | |
39 | struct member *gnext; | |
40 | }; | |
41 | ||
42 | struct entry { | |
43 | long id; | |
44 | long pos; | |
45 | struct member *members; | |
46 | }; | |
4b329233 | 47 | |
48 | main(argc, argv) | |
49 | int argc; | |
50 | char **argv; | |
51 | { | |
52 | ## char db[9]; | |
53 | ||
54 | int status; | |
55 | int ingerr(); | |
56 | ||
57 | if (!strcmp(argv[1], "-db")) { | |
58 | strncpy(db, argv[2], sizeof(db)-1); | |
59 | argc -= 2; | |
60 | argv += 2; | |
61 | } | |
62 | if (argc != 2) { | |
63 | fprintf(stderr, "usage: %s [-db sms] outfile\n", whoami); | |
64 | exit(MR_ARGS); | |
65 | } | |
66 | ||
67 | dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660); | |
68 | if (dbase_fd < 0) { | |
69 | perror("opening file %s", argv[1]); | |
70 | exit(1); | |
71 | } | |
72 | IIseterr(ingerr); | |
73 | ||
74 | initialize_sms_error_table(); | |
75 | initialize_pt_error_table(); | |
76 | Initdb(); /* Initialize prdb */ | |
77 | ||
4b329233 | 78 | users = create_hash(10000); |
79 | groups = create_hash(15000); | |
80 | ||
81 | pos = ntohl(cheader.eofPtr); | |
82 | usercount = ntohl(cheader.usercount); | |
83 | groupcount = ntohl(cheader.groupcount); | |
84 | ||
85 | ## ingres db | |
86 | ## set lockmode session where level = table | |
87 | ## begin transaction | |
88 | ||
89 | do_passwd(); | |
90 | do_groups(); | |
91 | ||
92 | ## end transaction | |
93 | ## exit | |
94 | ||
95 | exit(MR_SUCCESS); | |
96 | } | |
97 | ||
98 | ||
99 | do_passwd() | |
100 | ##{ | |
101 | ## char login[9]; | |
6ade5328 | 102 | ## int uid, id; |
103 | int t, i, status; | |
4b329233 | 104 | struct prentry tentry; |
6ade5328 | 105 | struct entry *u; |
4b329233 | 106 | |
107 | t = time(0); | |
108 | fprintf(stderr, "Doing users: %s", ctime(&t)); | |
109 | ||
110 | ## range of u is users | |
111 | ## retrieve (login = u.#login, uid = u.#uid, id = u.users_id) | |
112 | ## where u.#uid > 0 and (u.#status = 1 or u.#status = 2) { | |
113 | lowercase(strtrim(login)); | |
114 | ||
115 | if (uid==ANONYMOUSID) | |
116 | status = PRIDEXIST; | |
117 | else { | |
118 | bzero(&tentry, sizeof(tentry)); | |
4b329233 | 119 | strcpy(tentry.name, login); |
120 | tentry.id = uid; | |
121 | tentry.owner = SYSADMINID; | |
122 | tentry.creator = SYSADMINID; | |
123 | tentry.flags = PRQUOTA; | |
124 | tentry.ngroups = tentry.nusers = 20; | |
125 | if (tentry.id > ntohl(cheader.maxID)) | |
126 | cheader.maxID = htonl(tentry.id); | |
127 | usercount++; | |
128 | ||
129 | i = IDHash(tentry.id); | |
130 | tentry.nextID = ntohl(cheader.idHash[i]); | |
131 | cheader.idHash[i] = htonl(pos); | |
132 | ||
133 | i = NameHash(tentry.name); | |
134 | tentry.nextName = ntohl(cheader.nameHash[i]); | |
135 | cheader.nameHash[i] = htonl(pos); | |
136 | ||
137 | pr_WriteEntry(0, 0, pos, &tentry); | |
6ade5328 | 138 | |
139 | u = (struct entry *)malloc(sizeof(struct entry)); | |
140 | u->id = uid; | |
141 | u->pos = pos; | |
142 | u->members = 0; | |
143 | ||
4b329233 | 144 | pos += ENTRYSIZE; |
145 | status = 0; | |
146 | } | |
147 | ||
148 | if (status) | |
149 | fprintf(stderr, "Error adding user %s uid %d: %s\n", | |
150 | login, uid, error_message(status)); | |
151 | else | |
6ade5328 | 152 | hash_store(users, id, u); |
4b329233 | 153 | ## } |
154 | ##} | |
155 | ||
156 | ||
157 | ||
158 | do_groups() | |
159 | ##{ | |
6ade5328 | 160 | long status; |
4b329233 | 161 | struct prentry gentry, uentry; |
6ade5328 | 162 | struct entry *u, *g; |
163 | struct bucket **p, *b; | |
164 | struct member *m; | |
4b329233 | 165 | char namebuf[41]; |
166 | int aid, t, i; | |
167 | ## char name[33]; | |
168 | ## int gid, id, lid, hide; | |
169 | ||
170 | t = time(0); | |
171 | fprintf(stderr, "Doing groups: %s", ctime(&t)); | |
172 | ||
173 | ## range of l is list | |
174 | ## range of m is imembers | |
175 | ||
176 | /* get lock records */ | |
177 | ## retrieve (name = l.modtime) where l.list_id = 0 | |
178 | ## retrieve (name = users.modtime) where users.users_id = 0 | |
179 | ## retrieve (name = l.#name, gid = l.#gid, lid = l.list_id, hide = l.hidden) | |
180 | ## where l.group != 0 and l.active != 0 and l.#gid > 0 { | |
181 | lowercase(strtrim(name)); | |
182 | sprintf(namebuf, "system:%s", name); | |
183 | aid = -gid; | |
184 | ||
185 | if (aid==ANYUSERID || aid==AUTHUSERID) | |
186 | status = PRIDEXIST; | |
187 | else { | |
188 | bzero(&gentry, sizeof(gentry)); | |
4b329233 | 189 | strcpy(gentry.name, namebuf); |
190 | gentry.id = aid; | |
191 | gentry.owner = SYSADMINID; | |
192 | gentry.creator = SYSADMINID; | |
193 | if (hide) | |
194 | gentry.flags = PRGRP|PRACCESS|PRP_STATUS_ANY; | |
195 | else | |
196 | gentry.flags = PRGRP; | |
197 | if (gentry.id < ntohl(cheader.maxGroup)) | |
198 | cheader.maxGroup = htonl(gentry.id); | |
199 | groupcount++; | |
200 | ||
201 | i = IDHash(gentry.id); | |
202 | gentry.nextID = ntohl(cheader.idHash[i]); | |
203 | cheader.idHash[i] = htonl(pos); | |
204 | ||
205 | i = NameHash(gentry.name); | |
206 | gentry.nextName = ntohl(cheader.nameHash[i]); | |
207 | cheader.nameHash[i] = htonl(pos); | |
208 | ||
209 | pr_WriteEntry(0, 0, pos, &gentry); | |
210 | AddToOwnerChain(0,gentry.id,gentry.owner); | |
6ade5328 | 211 | |
212 | g = (struct entry *)malloc(sizeof(struct entry)); | |
213 | g->id = aid; | |
214 | g->pos = pos; | |
215 | g->members = 0; | |
216 | ||
4b329233 | 217 | pos += ENTRYSIZE; |
218 | status = 0; | |
219 | } | |
220 | if (status) | |
221 | fprintf(stderr, "Error adding group %s id %d: %s\n", | |
222 | namebuf, aid, error_message(status)); | |
223 | else | |
6ade5328 | 224 | hash_store(groups, lid, g); |
4b329233 | 225 | |
226 | ## } | |
227 | ||
228 | cheader.groupcount = htonl(groupcount); | |
229 | cheader.usercount = htonl(usercount); | |
230 | cheader.eofPtr = htonl(pos); | |
231 | pr_Write(0, 0, 0, &cheader, sizeof(cheader)); | |
232 | ||
233 | t = time(0); | |
234 | fprintf(stderr, "Doing members: %s", ctime(&t)); | |
235 | ||
236 | ## retrieve (lid = m.list_id, id = m.member_id) | |
237 | ## where m.member_type = "USER" { | |
6ade5328 | 238 | if ((u = (struct entry *)hash_lookup(users, id)) && |
239 | (g = (struct entry *)hash_lookup(groups, lid))) { | |
240 | m = (struct member *)malloc(sizeof(struct member)); | |
241 | m->user = u; | |
242 | m->group = g; | |
243 | m->unext = u->members; | |
244 | m->gnext = g->members; | |
245 | u->members = g->members = m; | |
4b329233 | 246 | } |
247 | ## } | |
248 | ||
6ade5328 | 249 | for (p = &(users->data[users->size - 1]); p >= users->data; p--) { |
250 | for (b = *p; b; b = b->next) { | |
251 | if ((u = (struct entry *)b->data)->members == 0) | |
252 | continue; | |
253 | pr_Read(0, 0, u->pos, &uentry, sizeof(uentry)); | |
254 | for (i=0, m=u->members; m && i<PRSIZE; m=m->unext, i++) | |
255 | uentry.entries[i] = htonl(m->group->id); | |
256 | uentry.count = htonl(i); | |
257 | pr_Write(0, 0, u->pos, &uentry, sizeof(uentry)); | |
258 | if (m) { | |
259 | pr_ReadEntry(0, 0, g->pos, &gentry); | |
260 | while (m) { | |
261 | AddToEntry(0, &uentry, u->pos, m->group->id); | |
262 | m = m->unext; | |
263 | } | |
264 | } | |
265 | } | |
266 | } | |
267 | for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) { | |
268 | for (b = *p; b; b = b->next) { | |
269 | if ((g = (struct entry *)b->data)->members == 0) | |
270 | continue; | |
271 | pr_Read(0, 0, g->pos, &gentry, sizeof(gentry)); | |
272 | for (i=0, m=g->members; m && i<PRSIZE; m=m->gnext, i++) | |
273 | gentry.entries[i] = htonl(m->user->id); | |
274 | gentry.count = htonl(i); | |
275 | pr_Write(0, 0, g->pos, &gentry, sizeof(gentry)); | |
276 | if (m) { | |
277 | pr_ReadEntry(0, 0, g->pos, &gentry); | |
278 | while (m) { | |
279 | AddToEntry(0, &gentry, g->pos, m->user->id); | |
280 | m = m->gnext; | |
281 | } | |
282 | } | |
283 | } | |
284 | } | |
285 | ||
4b329233 | 286 | t = time(0); |
287 | fprintf(stderr, "Done: %s", ctime(&t)); | |
288 | ||
289 | ##} | |
290 | ||
291 | ||
4b329233 | 292 | /* |
293 | * ingerr: (supposedly) called when Ingres indicates an error. | |
294 | * I have not yet been able to get this to work to intercept a | |
295 | * database open error. | |
296 | */ | |
297 | #define INGRES_DEADLOCK 4700 | |
298 | ||
299 | static int ingerr(num) | |
300 | int *num; | |
301 | { | |
302 | char buf[256]; | |
303 | int ingres_errno; | |
304 | ||
305 | switch (*num) { | |
306 | case INGRES_DEADLOCK: | |
307 | ingres_errno = MR_DEADLOCK; | |
308 | break; | |
309 | default: | |
310 | ingres_errno = MR_INGRES_ERR; | |
311 | } | |
312 | com_err(whoami, MR_INGRES_ERR, " code %d\n", *num); | |
313 | exit(ingres_errno); | |
314 | } |