]> andersk Git - moira.git/blob - afssync/sync.pc
Command line printer manipulation client, and build goo.
[moira.git] / afssync / sync.pc
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 #include <string.h>
13
14 #include <rx/xdr.h>
15 #include "ptint.h"
16 #include "ptserver.h"
17 #include "pterror.h"
18
19 #include <moira.h>
20 #include <moira_site.h>
21 #include <ctype.h>
22
23 EXEC SQL INCLUDE sqlca;
24
25 EXEC SQL BEGIN DECLARE SECTION;
26 char db[33] = "moira";
27 EXEC SQL END DECLARE SECTION;
28
29 void do_passwd(void);
30 void do_groups(void);
31 void sqlerr(void);
32
33 #ifndef min
34 #define min(x,y)        ((x) < (y) ? (x) : (y))
35 #endif
36 char *whoami = "sync";
37
38 int dbase_fd;
39
40 int ucount = 0;
41 int gcount = 0;
42 int kcount = 0;
43 int mcount = 0;
44
45 struct hash *users;
46 struct hash *groups;
47
48 struct member {
49     struct entry *user;
50     struct entry *group;
51     struct member *unext;
52     struct member *gnext;
53 };
54 struct entry {
55     long id;
56     struct member *members;
57 };
58
59 int main(int argc, char **argv)
60 {
61     int status;
62     long t;
63
64     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
65
66     if (argc > 2 && !strcmp(argv[1], "-db")) {
67         strncpy(db, argv[2], sizeof(db)-1);
68         argc -= 2;
69         argv += 2;
70     }
71     if (argc != 2) {
72         fprintf(stderr, "usage: %s [-db moira] outfile\n", whoami);
73         exit(MR_ARGS);
74     }
75
76     dbase_fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0660);
77     if (dbase_fd < 0) {
78         perror("opening data file");
79         exit(1);
80     }
81
82     initialize_sms_error_table();
83     initialize_pt_error_table();
84     Initdb();                                   /* Initialize prdb */
85     
86     users = create_hash(10000);
87     groups = create_hash(15000);
88
89     EXEC SQL WHENEVER SQLERROR DO sqlerr();
90     EXEC SQL CONNECT :db IDENTIFIED BY :db;
91
92     do_passwd();
93     do_groups();
94
95     t = time(0);
96     fprintf(stderr, "Done (%d users, %d groups, %d kerberos, %d members): %s",
97             ucount, gcount, kcount, mcount, ctime(&t));
98
99     EXEC SQL COMMIT;
100
101     exit(MR_SUCCESS);
102 }
103
104
105 void do_passwd(void)
106 {
107     EXEC SQL BEGIN DECLARE SECTION;
108     char login[9], name[33];
109     int uid, id, status;
110     EXEC SQL END DECLARE SECTION;
111
112     long t;
113     struct prentry tentry;
114     struct entry *u;
115
116     t = time(0);
117     fprintf(stderr, "Doing users: %s", ctime(&t));
118
119     EXEC SQL DECLARE u_cursor CURSOR FOR
120         SELECT u.login, u.unix_uid, u.users_id
121         FROM users u
122         WHERE u.unix_uid > 0 AND (u.status = 1 OR u.status = 2)
123         ORDER BY unix_uid;
124     EXEC SQL OPEN u_cursor;
125     while (1) {
126         EXEC SQL FETCH u_cursor INTO :login, :uid, :id;
127         if (sqlca.sqlcode != 0) break;
128         
129         lowercase(strtrim(login));
130
131         if (FindByID(0,uid))
132             status = PRIDEXIST;
133         else
134             status = CreateEntry(0,login,&uid,1 /*idflag*/,0/*gflag*/,
135                                  SYSADMINID     /*oid*/, SYSADMINID/*cid*/);
136         if (status)
137             fprintf(stderr, "Error adding user %s uid %d: %s\n",
138                     login, uid, error_message(status));
139         else {
140             u = (struct entry *)malloc(sizeof(struct entry));
141             u->id = uid;
142             u->members = 0;
143             hash_store(users, id, u);
144             ucount++;
145         }
146     }
147     EXEC SQL CLOSE u_cursor;
148     return;
149 }
150
151
152
153 void do_groups(void)
154 {
155     EXEC SQL BEGIN DECLARE SECTION;
156     char name[33], string[129];
157     int gid, id, lid, hide, ustatus;
158     EXEC SQL END DECLARE SECTION;
159
160     long status, pos;
161     struct prentry gentry, uentry;
162     struct entry *u, *g;
163     struct member *m;
164     struct bucket **p, *b;
165     char namebuf[40];
166     long aid, t;
167
168     t = time(0);
169     fprintf(stderr, "Doing groups: %s", ctime(&t));
170
171     EXEC SQL DECLARE l_cursor CURSOR FOR
172         SELECT l.name, l.gid, l.list_id, l.hidden
173         FROM list l
174         WHERE l.gid > 0 AND l.active != 0 AND l.grouplist != 0
175         ORDER BY gid;
176     EXEC SQL OPEN l_cursor;
177     while (1) {
178         EXEC SQL FETCH l_cursor INTO :name, :gid, :lid, :hide;
179         if (sqlca.sqlcode != 0) break;
180         
181         lowercase(strtrim(name));
182         sprintf(namebuf, "system:%s", name);
183         aid = -gid;
184
185         if (FindByID(0, aid))
186             status = PRIDEXIST;
187         else
188             status = CreateEntry(0,namebuf,&aid,1 /*idflag*/,PRGRP/*gflag*/,
189                                  SYSADMINID     /*oid*/, SYSADMINID/*cid*/);
190         if (status)
191             fprintf(stderr, "Error adding group %s id %d: %s\n",
192                     namebuf, aid, error_message(status));
193
194         if ((status==0 || status==PRIDEXIST) &&
195             (aid!=ANYUSERID && aid!=AUTHUSERID)) {
196
197             g = (struct entry *)malloc(sizeof(struct entry));
198             g->id = aid;
199             g->members = 0;
200             hash_store(groups, lid, g);
201             gcount++;
202
203             /* Set modes on hidden lists (S----) */
204             if (hide) {
205                 pos = FindByID(0, aid);
206                 status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
207                 if (!status) {
208                     gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
209                     status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
210                 }
211                 if (status)
212                     fprintf(stderr,
213                             "Error setting flags on group %s: %s\n",
214                             namebuf, error_message(status));
215             }
216         }
217     }
218     EXEC SQL CLOSE l_cursor;
219
220     t = time(0);
221     fprintf(stderr, "Reading/preparing members: %s", ctime(&t));
222
223     EXEC SQL DECLARE m_cursor CURSOR FOR
224         SELECT m.list_id, m.member_id, m.member_type
225         FROM imembers m
226         ORDER BY member_id;
227     EXEC SQL OPEN m_cursor;
228     while (1) {
229         EXEC SQL FETCH m_cursor INTO :lid, :id, :name;
230         if (sqlca.sqlcode != 0) break;
231
232         if (!(g = (struct entry *)hash_lookup(groups, lid)))
233             continue;
234
235         strtrim(name);
236         if (!strcmp(name, "USER")) {
237             if (u = (struct entry *)hash_lookup(users, id)) {
238                 m = (struct member *)malloc(sizeof(struct member));
239                 m->user = u;
240                 m->group = g;
241                 m->unext = u->members;
242                 m->gnext = g->members;
243                 u->members = g->members = m;
244                 mcount++;
245             }
246         }
247     }
248     EXEC SQL CLOSE m_cursor;
249
250     t = time(0);
251     fprintf(stderr, "Doing members: %s", ctime(&t));
252
253     /* Do the bulk of the membership quickly.
254      * Add PRSIZE members into the user/group record.  After that, we
255      * require the use of continuation records, but we assume this is
256      * few enough that we do this the slow way (AddToEntry).
257      */
258     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
259         for (b = *p; b; b = b->next) {
260             if ((u = (struct entry *)b->data)->members == 0)
261                 continue;
262             pos = FindByID(0, u->id);
263             pr_Read(0, 0, pos, &uentry, sizeof(uentry));
264             for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
265                 uentry.entries[t] = htonl(m->group->id);
266             uentry.count = htonl(t);
267             pr_Write(0, 0, pos, &uentry, sizeof(uentry));
268             if (m) {
269                 pr_ReadEntry(0, 0, pos, &uentry);
270                 while (m) {
271                     AddToEntry(0, &uentry, pos, m->group->id);
272                     m = m->unext;
273                 }
274             }
275         }
276     }
277     for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
278         for (b = *p; b; b = b->next) {
279             if ((g = (struct entry *)b->data)->members == 0)
280                 continue;
281             pos = FindByID(0, g->id);
282             pr_Read(0, 0, pos, &gentry, sizeof(gentry));
283             for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
284                 gentry.entries[t] = htonl(m->user->id);
285             gentry.count = htonl(t);
286             pr_Write(0, 0, pos, &gentry, sizeof(gentry));
287             if (m) {
288                 pr_ReadEntry(0, 0, pos, &gentry);
289                 while (m) {
290                     AddToEntry(0, &gentry, pos, m->user->id);
291                     m = m->gnext;
292                 }
293             }
294         }
295     }
296     return;
297 }
298
299     
300 void sqlerr(void)
301 {
302     char buf[256];
303     int size=256, len=0;
304
305     sqlglm(buf, &size, &len);
306     buf[len]='\0';
307     com_err(whoami, MR_DBMS_ERR, " code %d\n%s", sqlca.sqlcode, buf);
308     exit(MR_DBMS_ERR);
309 }
This page took 0.111155 seconds and 5 git commands to generate.