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