]> andersk Git - moira.git/blame_incremental - afssync/sync.qc
Incorrect number of arguments to get_end_members_of_list query fixed...
[moira.git] / afssync / sync.qc
... / ...
CommitLineData
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))
23char *whoami = "sync";
24
25char *malloc(), *strsave();
26int dbase_fd;
27
28int ucount = 0;
29int gcount = 0;
30int mcount = 0;
31
32struct hash *users;
33struct hash *groups;
34
35struct member {
36 struct entry *user;
37 struct entry *group;
38 struct member *unext;
39 struct member *gnext;
40};
41struct entry {
42 long id;
43 struct member *members;
44};
45
46main(argc, argv)
47int argc;
48char **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
95do_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
131do_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
267static 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.037019 seconds and 5 git commands to generate.