]> andersk Git - moira.git/blob - afssync/sync.qc
Used /bin/sh format instead of /bin/csh format, by accident.
[moira.git] / afssync / sync.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 int ucount = 0;
29 int gcount = 0;
30 int mcount = 0;
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 struct entry {
42     long id;
43     struct member *members;
44 };
45
46 main(argc, argv)
47 int argc;
48 char **argv;
49 {
50 ##  char db[9];
51     
52     int status;
53     int ingerr();
54     long t;
55
56     strcpy(db, "sms");
57
58     if (!strcmp(argv[1], "-db")) {
59         strncpy(db, argv[2], sizeof(db)-1);
60         argc -= 2;
61         argv += 2;
62     }
63     if (argc != 2) {
64         fprintf(stderr, "usage: %s [-db sms] outfile\n", whoami);
65         exit(MR_ARGS);
66     }
67
68     dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660);
69     if (dbase_fd < 0) {
70         perror("opening file %s", argv[1]);
71         exit(1);
72     }   
73     IIseterr(ingerr);
74
75     initialize_sms_error_table();
76     initialize_pt_error_table();
77     Initdb();                                   /* Initialize prdb */
78     
79     users = create_hash(10000);
80     groups = create_hash(15000);
81     
82 ##  ingres db
83 ##  set lockmode session where level = table
84 ##  begin transaction
85
86     do_passwd();
87     do_groups();
88
89     t = time(0);
90     fprintf(stderr, "Done (%d users, %d groups, %d members): %s",
91             ucount, gcount, mcount, ctime(&t));
92
93 ##  end transaction
94 ##  exit
95
96     exit(MR_SUCCESS);
97 }
98
99
100 do_passwd()
101 ##{
102 ##  char login[9];
103 ##  int uid, id, status;
104     long t;
105     struct prentry tentry;
106     struct entry *u;
107
108     t = time(0);
109     fprintf(stderr, "Doing users: %s", ctime(&t));
110     
111 ##  range of u is users
112 ##  retrieve (login = u.#login, uid = u.#uid, id = u.users_id)
113 ##      where u.#uid > 0 and (u.#status = 1 or u.#status = 2) {
114             lowercase(strtrim(login));
115
116             if (FindByID(0,uid))
117                 status = PRIDEXIST;
118             else
119                 status = CreateEntry(0,login,&uid,1/*idflag*/,0/*gflag*/,
120                                      SYSADMINID/*oid*/, SYSADMINID/*cid*/);
121             if (status)
122                 fprintf(stderr, "Error adding user %s uid %d: %s\n",
123                         login, uid, error_message(status));
124             else {
125                 u = (struct entry *)malloc(sizeof(struct entry));
126                 u->id = uid;
127                 u->members = 0;
128                 hash_store(users, id, u);
129                 ucount++;
130             }
131 ##  }
132 ##}
133
134
135
136 do_groups()
137 ##{
138     long status, pos;
139     struct prentry gentry, uentry;
140     struct entry *u, *g;
141     struct member *m;
142     struct bucket **p, *b;
143     char namebuf[40];
144     long aid, t;
145 ##  char name[33];
146 ##  int gid, id, lid, hide;
147
148     t = time(0);
149     fprintf(stderr, "Doing groups: %s", ctime(&t));
150
151 ##  range of l is list
152 ##  range of m is imembers
153     /* get lock records */
154 ##  retrieve (name = l.modtime) where l.list_id = 0
155 ##  retrieve (name = users.modtime) where users.users_id = 0
156
157 ##  retrieve (name = l.#name, gid = l.#gid, lid = l.list_id, hide = l.hidden)
158 ##      where l.group != 0 and l.active != 0 and l.#gid > 0 {
159             lowercase(strtrim(name));
160             sprintf(namebuf, "system:%s", name);
161             aid = -gid;
162
163             if (FindByID(0, aid))
164                 status = PRIDEXIST;
165             else
166                 status = CreateEntry(0,namebuf,&aid,1/*idflag*/,PRGRP/*gflag*/,
167                                      SYSADMINID/*oid*/, SYSADMINID/*cid*/);
168             if (status)
169                 fprintf(stderr, "Error adding group %s id %d: %s\n",
170                         namebuf, aid, error_message(status));
171
172             if ((status==0 || status==PRIDEXIST) &&
173                 (aid!=ANYUSERID && aid!=AUTHUSERID)) {
174
175                 g = (struct entry *)malloc(sizeof(struct entry));
176                 g->id = aid;
177                 g->members = 0;
178                 hash_store(groups, lid, g);
179                 gcount++;
180
181                 /* Set modes on hidden lists (S----) */
182                 if (hide) {
183                     pos = FindByID(0, aid);
184                     status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
185                     if (!status) {
186                         gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
187                         status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
188                     }
189                     if (status)
190                         fprintf(stderr,
191                                 "Error setting flags on group %s: %s\n",
192                                 namebuf, error_message(status));
193                 }
194             }
195 ##  }
196
197     t = time(0);
198     fprintf(stderr, "Doing members: %s", ctime(&t));
199
200 ##  retrieve (lid = m.list_id, id = m.member_id)
201 ##      where m.member_type = "USER" {
202       if ((u = (struct entry *)hash_lookup(users, id)) &&
203           (g = (struct entry *)hash_lookup(groups, lid))) {
204               m = (struct member *)malloc(sizeof(struct member));
205               m->user = u;
206               m->group = g;
207               m->unext = u->members;
208               m->gnext = g->members;
209               u->members = g->members = m;
210               mcount++;
211       }
212 ##  }
213
214     /* Do the bulk of the membership quickly.
215      * Add PRSIZE members into the user/group record.  After that, we
216      * require the use of continuation records, but we assume this is
217      * few enough that we do this the slow way (AddToEntry).
218      */
219     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
220         for (b = *p; b; b = b->next) {
221             if ((u = (struct entry *)b->data)->members == 0)
222                 continue;
223             pos = FindByID(0, u->id);
224             pr_Read(0, 0, pos, &uentry, sizeof(uentry));
225             for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
226                 uentry.entries[t] = htonl(m->group->id);
227             uentry.count = htonl(t);
228             pr_Write(0, 0, pos, &uentry, sizeof(uentry));
229             if (m) {
230                 pr_ReadEntry(0, 0, pos, &uentry);
231                 while (m) {
232                     AddToEntry(0, &uentry, pos, m->group->id);
233                     m = m->unext;
234                 }
235             }
236         }
237     }
238     for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
239         for (b = *p; b; b = b->next) {
240             if ((g = (struct entry *)b->data)->members == 0)
241                 continue;
242             pos = FindByID(0, g->id);
243             pr_Read(0, 0, pos, &gentry, sizeof(gentry));
244             for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
245                 gentry.entries[t] = htonl(m->user->id);
246             gentry.count = htonl(t);
247             pr_Write(0, 0, pos, &gentry, sizeof(gentry));
248             if (m) {
249                 pr_ReadEntry(0, 0, pos, &gentry);
250                 while (m) {
251                     AddToEntry(0, &gentry, pos, m->user->id);
252                     m = m->gnext;
253                 }
254             }
255         }
256     }
257 ##}
258
259 #if 0
260 do_kerberos()
261 ##{
262     long status, pos;
263     struct prentry gentry, uentry;
264     struct entry *u, *g;
265     struct member *m;
266     struct bucket **p, *b;
267     char namebuf[40];
268     int aid, t;
269 ##  char name[129];
270 ##  int gid, id, lid, hide;
271
272     t = time(0);
273     fprintf(stderr, "Doing kerberos members: %s", ctime(&t));
274
275 ##  range of s is strings
276 ##  range of m is imembers
277     /* get lock records */
278 ##  retrieve (name = list.modtime) where list.list_id = 0
279 ##  retrieve (name = s.modtime) where s.string_id = 0
280
281 ##  retrieve (lid = m.list_id, id = m.member_id)
282 ##      where m.member_type = "KERBEROS" {
283         xxx;
284         {
285         }
286 ##  }
287
288 ##}
289 #endif
290     
291     
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 }
This page took 0.459494 seconds and 5 git commands to generate.