]> andersk Git - moira.git/blob - afssync/sync.qc
New database and column names for Moira2.
[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             else {
167                 g = (struct entry *)malloc(sizeof(struct entry));
168                 g->id = aid;
169                 g->members = 0;
170                 hash_store(groups, lid, g);
171                 gcount++;
172             }
173
174             /* Set modes on hidden lists (S----) */
175             if (hide && (status==0 || status==PRIDEXIST)) {
176                 pos = FindByID(0, aid);
177                 status = pr_Read(0, 0, pos, &gentry, sizeof(gentry));
178                 if (!status) {
179                     gentry.flags = htonl(PRGRP|PRACCESS|PRP_STATUS_ANY);
180                     status = pr_Write(0, 0, pos, &gentry, sizeof(gentry));
181                 }
182                 if (status)
183                     fprintf(stderr,
184                             "Error setting flags on group %s: %s\n",
185                             namebuf, error_message(status));
186             }
187 ##  }
188
189     t = time(0);
190     fprintf(stderr, "Doing members: %s", ctime(&t));
191
192 ##  retrieve (lid = m.list_id, id = m.member_id)
193 ##      where m.member_type = "USER" {
194       if ((u = (struct entry *)hash_lookup(users, id)) &&
195           (g = (struct entry *)hash_lookup(groups, lid))) {
196               m = (struct member *)malloc(sizeof(struct member));
197               m->user = u;
198               m->group = g;
199               m->unext = u->members;
200               m->gnext = g->members;
201               u->members = g->members = m;
202               mcount++;
203       }
204 ##  }
205     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
206         for (b = *p; b; b = b->next) {
207             if ((u = (struct entry *)b->data)->members == 0)
208                 continue;
209             pos = FindByID(0, u->id);
210             pr_Read(0, 0, pos, &uentry, sizeof(uentry));
211             for (t=0, m=u->members; m && t<PRSIZE; m=m->unext, t++)
212                 uentry.entries[t] = htonl(m->group->id);
213             uentry.count = htonl(t);
214             pr_Write(0, 0, pos, &uentry, sizeof(uentry));
215             if (m) {
216                 pr_ReadEntry(0, 0, pos, &uentry);
217                 while (m) {
218                     AddToEntry(0, &uentry, pos, m->group->id);
219                     m = m->unext;
220                 }
221             }
222         }
223     }
224     for (p = &(groups->data[groups->size - 1]); p >= groups->data; p--) {
225         for (b = *p; b; b = b->next) {
226             if ((g = (struct entry *)b->data)->members == 0)
227                 continue;
228             pos = FindByID(0, g->id);
229             pr_Read(0, 0, pos, &gentry, sizeof(gentry));
230             for (t=0, m=g->members; m && t<PRSIZE; m=m->gnext, t++)
231                 gentry.entries[t] = htonl(m->user->id);
232             gentry.count = htonl(t);
233             pr_Write(0, 0, pos, &gentry, sizeof(gentry));
234             if (m) {
235                 pr_ReadEntry(0, 0, pos, &gentry);
236                 while (m) {
237                     AddToEntry(0, &gentry, pos, m->user->id);
238                     m = m->gnext;
239                 }
240             }
241         }
242     }
243
244     t = time(0);
245     fprintf(stderr, "Done (%d users, %d groups, %d members): %s",
246             ucount, gcount, mcount, ctime(&t));
247
248 ##}
249
250
251 /*
252  * ingerr: (supposedly) called when Ingres indicates an error.
253  * I have not yet been able to get this to work to intercept a
254  * database open error.
255  */
256 #define INGRES_DEADLOCK 4700
257
258 static int ingerr(num)
259     int *num;
260 {
261     char buf[256];
262     int ingres_errno;
263
264     switch (*num) {
265     case INGRES_DEADLOCK:
266         ingres_errno = MR_DEADLOCK;
267         break;
268     default:
269         ingres_errno = MR_INGRES_ERR;
270     }
271     com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
272     exit(ingres_errno);
273 }
This page took 0.068811 seconds and 5 git commands to generate.