]> andersk Git - moira.git/blob - afssync/sync.qc
Incorrect number of arguments to get_end_members_of_list query fixed...
[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
55     strcpy(db, "sms");
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     
78     users = create_hash(10000);
79     groups = create_hash(15000);
80     
81 ##  ingres db
82 ##  set lockmode session where level = table
83 ##  begin transaction
84
85     do_passwd();
86     do_groups();
87
88 ##  end transaction
89 ##  exit
90
91     exit(MR_SUCCESS);
92 }
93
94
95 do_passwd()
96 ##{
97 ##  char login[9];
98 ##  int uid, id, status;
99     int t;
100     struct prentry tentry;
101     struct entry *u;
102
103     t = time(0);
104     fprintf(stderr, "Doing users: %s", ctime(&t));
105     
106 ##  range of u is users
107 ##  retrieve (login = u.#login, uid = u.#uid, id = u.users_id)
108 ##      where u.#uid > 0 and (u.#status = 1 or u.#status = 2) {
109             lowercase(strtrim(login));
110
111             if (FindByID(0,uid))
112                 status = PRIDEXIST;
113             else
114                 status = CreateEntry(0,login,&uid,1/*idflag*/,0/*gflag*/,
115                                      SYSADMINID/*oid*/, SYSADMINID/*cid*/);
116             if (status)
117                 fprintf(stderr, "Error adding user %s uid %d: %s\n",
118                         login, uid, error_message(status));
119             else {
120                 u = (struct entry *)malloc(sizeof(struct entry));
121                 u->id = uid;
122                 u->members = 0;
123                 hash_store(users, id, u);
124                 ucount++;
125             }
126 ##  }
127 ##}
128
129
130
131 do_groups()
132 ##{
133     long status, pos;
134     struct prentry gentry, uentry;
135     struct entry *u, *g;
136     struct member *m;
137     struct bucket **p, *b;
138     char namebuf[40];
139     int aid, t;
140 ##  char name[33];
141 ##  int gid, id, lid, hide;
142
143     t = time(0);
144     fprintf(stderr, "Doing groups: %s", ctime(&t));
145
146 ##  range of l is list
147 ##  range of m is imembers
148     /* get lock records */
149 ##  retrieve (name = l.modtime) where l.list_id = 0
150 ##  retrieve (name = users.modtime) where users.users_id = 0
151
152 ##  retrieve (name = l.#name, gid = l.#gid, lid = l.list_id, hide = l.hidden)
153 ##      where l.group != 0 and l.active != 0 and l.#gid > 0 {
154             lowercase(strtrim(name));
155             sprintf(namebuf, "system:%s", name);
156             aid = -gid;
157
158             if (FindByID(0, aid))
159                 status = PRIDEXIST;
160             else
161                 status = CreateEntry(0,namebuf,&aid,1/*idflag*/,PRGRP/*gflag*/,
162                                      SYSADMINID/*oid*/, SYSADMINID/*cid*/);
163             if (status)
164                 fprintf(stderr, "Error adding group %s id %d: %s\n",
165                         namebuf, aid, error_message(status));
166
167             if ((status==0 || status==PRIDEXIST) &&
168                 (aid!=ANYUSERID && aid!=AUTHUSERID)) {
169
170                 g = (struct entry *)malloc(sizeof(struct entry));
171                 g->id = aid;
172                 g->members = 0;
173                 hash_store(groups, lid, g);
174                 gcount++;
175
176                 /* Set modes on hidden lists (S----) */
177                 if (hide) {
178                     pos = FindByID(0, aid);
179                     status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
180                     if (!status) {
181                         gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
182                         status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
183                     }
184                     if (status)
185                         fprintf(stderr,
186                                 "Error setting flags on group %s: %s\n",
187                                 namebuf, error_message(status));
188                 }
189             }
190 ##  }
191
192     t = time(0);
193     fprintf(stderr, "Doing members: %s", ctime(&t));
194
195 ##  retrieve (lid = m.list_id, id = m.member_id)
196 ##      where m.member_type = "USER" {
197       if ((u = (struct entry *)hash_lookup(users, id)) &&
198           (g = (struct entry *)hash_lookup(groups, lid))) {
199               m = (struct member *)malloc(sizeof(struct member));
200               m->user = u;
201               m->group = g;
202               m->unext = u->members;
203               m->gnext = g->members;
204               u->members = g->members = m;
205               mcount++;
206       }
207 ##  }
208
209     /* Do the bulk of the membership quickly.
210      * Add PRSIZE members into the user/group record.  After that, we
211      * require the use of continuation records, but we assume this is
212      * few enough that we do this the slow way (AddToEntry).
213      */
214     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
215         for (b = *p; b; b = b->next) {
216             if ((u = (struct entry *)b->data)->members == 0)
217                 continue;
218             pos = FindByID(0, u->id);
219             pr_Read(0, 0, pos, &uentry, sizeof(uentry));
220             for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
221                 uentry.entries[t] = htonl(m->group->id);
222             uentry.count = htonl(t);
223             pr_Write(0, 0, pos, &uentry, sizeof(uentry));
224             if (m) {
225                 pr_ReadEntry(0, 0, pos, &uentry);
226                 while (m) {
227                     AddToEntry(0, &uentry, pos, m->group->id);
228                     m = m->unext;
229                 }
230             }
231         }
232     }
233     for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
234         for (b = *p; b; b = b->next) {
235             if ((g = (struct entry *)b->data)->members == 0)
236                 continue;
237             pos = FindByID(0, g->id);
238             pr_Read(0, 0, pos, &gentry, sizeof(gentry));
239             for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
240                 gentry.entries[t] = htonl(m->user->id);
241             gentry.count = htonl(t);
242             pr_Write(0, 0, pos, &gentry, sizeof(gentry));
243             if (m) {
244                 pr_ReadEntry(0, 0, pos, &gentry);
245                 while (m) {
246                     AddToEntry(0, &gentry, pos, m->user->id);
247                     m = m->gnext;
248                 }
249             }
250         }
251     }
252
253     t = time(0);
254     fprintf(stderr, "Done (%d users, %d groups, %d members): %s",
255             ucount, gcount, mcount, ctime(&t));
256
257 ##}
258
259
260 /*
261  * ingerr: (supposedly) called when Ingres indicates an error.
262  * I have not yet been able to get this to work to intercept a
263  * database open error.
264  */
265 #define INGRES_DEADLOCK 4700
266
267 static int ingerr(num)
268     int *num;
269 {
270     char buf[256];
271     int ingres_errno;
272
273     switch (*num) {
274     case INGRES_DEADLOCK:
275         ingres_errno = MR_DEADLOCK;
276         break;
277     default:
278         ingres_errno = MR_INGRES_ERR;
279     }
280     com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
281     exit(ingres_errno);
282 }
This page took 0.060121 seconds and 5 git commands to generate.