]> andersk Git - moira.git/blob - afssync/sync.fast.qc
Initial revision
[moira.git] / afssync / sync.fast.qc
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;
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 };
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     strcpy(db, "sms");
58
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     
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];
104 ##  int uid, id;
105     int t, i, status;
106     struct prentry tentry;
107     struct entry *u;
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));
121                 strcpy(tentry.name, login);
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;
129                 usercount++;
130
131                 i = IDHash(uid);
132                 tentry.nextID = cheader.idHash[i];
133                 cheader.idHash[i] = htonl(pos);
134
135                 i = NameHash(tentry.name);
136                 tentry.nextName = cheader.nameHash[i];
137                 cheader.nameHash[i] = htonl(pos);
138                 
139                 pr_Write(0, 0, pos, &tentry, sizeof(tentry));
140
141                 u = (struct entry *)malloc(sizeof(struct entry));
142                 u->id = uid;
143                 u->pos = pos;
144                 u->members = 0;
145                 
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
154                 hash_store(users, id, u);
155 ##  }
156 ##}
157
158
159
160 do_groups()
161 ##{
162     long status;
163     struct prentry gentry, uentry;
164     struct entry *u, *g;
165     struct bucket **p, *b;
166     struct member *m;
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
187             if (aid==ANYUSERID || aid==AUTHUSERID || aid==SYSADMINID)
188                 status = PRIDEXIST;
189             else {
190                 bzero(&gentry, sizeof(gentry));
191                 strcpy(gentry.name, namebuf);
192                 gentry.id = htonl(aid);
193                 gentry.owner = htonl(SYSADMINID);
194                 gentry.creator = htonl(SYSADMINID);
195                 if (hide)
196                     gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
197                 else
198                     gentry.flags = htonl(PRGRP);
199                 if (aid < ntohl(cheader.maxGroup))
200                     cheader.maxGroup = gentry.id;
201                 groupcount++;
202
203                 i = IDHash(aid);
204                 gentry.nextID = cheader.idHash[i];
205                 cheader.idHash[i] = htonl(pos);
206
207                 i = NameHash(gentry.name);
208                 gentry.nextName = cheader.nameHash[i];
209                 cheader.nameHash[i] = htonl(pos);
210
211                 pr_Write(0, 0, pos, &gentry, sizeof(gentry));
212                 AddToOwnerChain(0, aid, SYSADMINID);
213
214                 g = (struct entry *)malloc(sizeof(struct entry));
215                 g->id = aid;
216                 g->pos = pos;
217                 g->members = 0;
218                 
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));
225             if (status==0 || (status==PRIDEXIST && aid==SYSADMINID))
226                 hash_store(groups, lid, g);
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" {
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;
248       }
249 ##  }
250
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) {
261                 pr_ReadEntry(0, 0, u->pos, &uentry);
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
288     t = time(0);
289     fprintf(stderr, "Done: %s", ctime(&t));
290
291 ##}
292
293
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 }
This page took 0.088745 seconds and 5 git commands to generate.