]> andersk Git - moira.git/blob - gen/nfs.pc
.dc -> .pc
[moira.git] / gen / nfs.pc
1 /* $Header$
2  *
3  * This generates the files necessary to load an nfs server.
4  *
5  *  (c) Copyright 1988, 1990 by the Massachusetts Institute of Technology.
6  *  For copying and distribution information, please see the file
7  *  <mit-copyright.h>.
8  */
9
10 #include <mit-copyright.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <moira.h>
14 #include <moira_site.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <sys/time.h>
18 EXEC SQL INCLUDE sqlca;
19
20
21 #define min(x,y)        ((x) < (y) ? (x) : (y))
22
23 char *whoami = "nfs.gen";
24 char *db = "moira/moira";
25 char *malloc(), *strsave();
26 char nfs_dir[64];
27 struct hash *users, *groups;
28
29
30 main(argc, argv)
31 int argc;
32 char **argv;
33 {
34     char cmd[64];
35     struct stat sb;
36     int changed = 0;
37
38     if (argc > 2) {
39         fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
40         exit(MR_ARGS);
41     }
42
43     initialize_sms_error_table();
44     sprintf(nfs_dir, "%s/nfs", DCM_DIR);
45
46     EXEC SQL CONNECT :db;
47
48     changed = do_nfs();
49
50     EXEC SQL COMMIT;
51
52     if (!changed) {
53         fprintf(stderr, "No files updated.\n");
54         if (argc == 2 && stat(argv[1], &sb) == 0)
55           exit(MR_NO_CHANGE);
56     }
57
58     if (argc == 2) {
59         sprintf(cmd, "cd %s; cp %s/nfs/* .; tar cf %s .",
60                 nfs_dir, SMS_DIR, argv[1]);
61         if (system(cmd))
62           exit(MR_TAR_FAIL);
63     }
64
65     exit(MR_SUCCESS);
66 }
67
68
69 /* Generate the files.  Returns zero if nothing changed, non-zero otherwise. */
70
71 int do_nfs()
72 {
73     EXEC SQL BEGIN DECLARE SECTION;
74     char machname[41], listname[33];
75     EXEC SQL END DECLARE SECTION;
76     struct save_queue *machs, *lists;
77     int changed;
78
79     machs = sq_create();
80     lists = sq_create();
81
82     /* The following is declarative, not executed,
83      * and so is dependent on where it is in the file,
84      * not in the order of execution of statements.
85      */
86     EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
87
88     EXEC SQL DECLARE s_cursor CURSOR FOR
89       SELECT m.name, s.value3
90       FROM machine m, serverhosts s
91       WHERE m.mach_id = s.mach_id AND s.service = 'NFS' AND s.enable != 0;
92     EXEC SQL OPEN s_cursor;
93     while (1) {
94         EXEC SQL FETCH s_cursor INTO :machname, :listname;
95         if (sqlca.sqlcode != 0) break;
96         sq_save_unique_string(machs, strsave(strtrim(machname)));
97         sq_save_unique_string(lists, strsave(strtrim(listname)));
98       }
99     EXEC SQL CLOSE s_cursor;
100
101     changed = do_lists(lists);
102     EXEC SQL COMMIT;
103     changed += do_machs(machs);
104     return(changed);
105  sqlerr:
106     db_error(sqlca.sqlcode);
107     exit(MR_DBMS_ERR);
108 }
109
110
111 /* Make all of the credentials lists that will be needed.  Returns 0 if
112  * no files were actually changed 
113  */
114
115 int do_lists(lists)
116 struct save_queue *lists;
117 {
118     char file[64], *u;
119     struct stat sb;
120     FILE *fd;
121     EXEC SQL BEGIN DECLARE SECTION;
122     char *listname, *lsname, lname[33], uname[9];
123     int uid, id, flag1, flag2, flag3, flag4;
124     EXEC SQL END DECLARE SECTION;
125
126     sprintf(file, "%s/list-", nfs_dir);
127     /*
128     if (stat(file, &sb) == 0) {
129         if ((ModDiff (&flag1, "users", sb.st_mtime)) ||
130             (ModDiff (&flag2, "list", sb.st_mtime)) ||
131             (ModDiff (&flag3, "imembers", sb.st_mtime)) ||
132             (ModDiff (&flag4, "serverhosts", sb.st_mtime))) exit (MR_DATE);
133         if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0) {
134             fprintf(stderr, "The lists do not need to be rebuilt.\n");
135             return(0);
136         }
137     }
138     */
139
140
141     /* build the list of everyone, and store it in a file whose name
142      * corresponds to the empty list.
143      */
144     do_everyone();
145
146     fprintf(stderr, "Building specific lists\n");
147     /* now do each of the lists used by an NFS server */
148
149     while (sq_get_data(lists, &listname)) {
150         if (strlen(listname) == 0)
151           continue;
152         sprintf(file, "%s/list-%s", nfs_dir, listname);
153         fd = fopen(file, "w");
154         if (!fd) {
155             fprintf(stderr, "cannot open %s for output\n", file);
156             exit(MR_OCONFIG);
157         }
158
159         EXEC SQL DECLARE m_cursor CURSOR FOR
160           SELECT m.member_id
161           FROM imembers m, list l
162           WHERE m.list_id=l.list_id AND l.name = :listname AND
163             m.member_type='USER'
164           ORDER BY member_id;
165         EXEC SQL OPEN m_cursor;
166         while (1) {
167             EXEC SQL FETCH m_cursor INTO :id;
168             if (sqlca.sqlcode != 0) break;
169             if (u = hash_lookup(users, id))
170               fprintf(fd, "%s\n", u);
171         }
172         EXEC SQL CLOSE m_cursor;
173         if (fclose(fd) == EOF) {
174             fprintf(stderr, "error closing %s\n", file);
175             exit(MR_CCONFIG);
176         }
177     }
178 /* don't free here either
179     sq_destroy(lists);
180  */
181     return(1);
182  sqlerr:
183     db_error(sqlca.sqlcode);
184     exit(MR_DBMS_ERR);
185 }
186
187
188 /*  Build the list of everybody. */
189 struct grp {
190     struct grp *next;
191     char *lid;
192 };
193 struct user {
194     char name[9];
195     int uid;
196     struct grp *lists;
197 };
198
199
200 do_everyone()
201 {
202     char buf[BUFSIZ], *l;
203     struct user *u;
204     struct grp *g;
205     struct bucket *b, **p;
206     EXEC SQL BEGIN DECLARE SECTION;
207     char name[33];
208     int gid, id, lid, maxid, uid;
209     EXEC SQL END DECLARE SECTION;
210     FILE *fd;
211     int i;
212     struct save_queue *sq;
213
214     fprintf(stderr, "Building the list of everybody\n");
215     sprintf(buf, "%s/list-", nfs_dir);
216     fd = fopen(buf, "w");
217     if (!fd) {
218         fprintf(stderr, "cannot open %s for output\n", buf);
219         exit(MR_OCONFIG);
220     }
221
222     /* make space for group list */
223     groups = create_hash(15000);
224
225     /* retrieve simple groups */
226     EXEC SQL DECLARE l_cursor CURSOR FOR
227      SELECT gid, list_id
228      FROM list
229      WHERE grouplist != 0 AND active != 0
230      ORDER BY list_id;
231     EXEC SQL OPEN l_cursor;
232     while (1) {
233         EXEC SQL FETCH l_cursor INTO :gid, :lid;
234         if (sqlca.sqlcode != 0) break;
235         sprintf(buf, ":%d", gid);
236         hash_store(groups, lid, strsave(buf));
237       }
238     EXEC SQL CLOSE l_cursor;
239
240     /* now do grplists */
241     users = create_hash(10000);
242     EXEC SQL DECLARE u_cursor CURSOR FOR
243       SELECT users_id, login, unix_uid
244       FROM users
245       WHERE status = 1
246       ORDER BY users_id;
247     EXEC SQL OPEN u_cursor;
248     while (1) {
249         EXEC SQL FETCH u_cursor INTO :id, :name, :uid;
250         if (sqlca.sqlcode != 0) break;
251         u = (struct user *) malloc(sizeof(struct user));
252         strcpy(u->name, strtrim(name));
253         u->uid = uid;
254         u->lists = NULL;
255         hash_store(users, id, u);
256       }
257     EXEC SQL CLOSE u_cursor;
258
259     EXEC SQL DECLARE m_cursor2 CURSOR FOR
260       SELECT list_id, member_id
261       FROM imembers
262       WHERE member_type = 'USER'
263       ORDER BY list_id;
264     EXEC SQL OPEN m_cursor2;
265     while (1) {
266         EXEC SQL FETCH m_cursor2 INTO :lid, :id;
267         if (sqlca.sqlcode != 0) break;
268         if ((u = (struct user *) hash_lookup(users, id)) &&
269             ((l = hash_lookup(groups, lid)) != NULL)) {
270             g = (struct grp *) malloc(sizeof(struct grp));
271             g->next = u->lists;
272             u->lists = g;
273             g->lid = l;
274           }
275       }
276     EXEC SQL CLOSE m_cursor2;
277
278     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
279         for (b = *p; b; b = b->next) {
280             u = (struct user *)b->data;
281             sprintf(buf, "%s:%d", u->name, u->uid);
282             for (g = u->lists; g; g = g->next)
283               strcat(buf, g->lid);
284             b->data = strsave(buf);
285             fprintf(fd, "%s\n", buf);
286         }
287     }
288
289     fclose(fd);
290     free(groups);
291     return(1);
292  sqlerr:
293     db_error(sqlca.sqlcode);
294     exit(MR_DBMS_ERR);
295 }
296
297
298 /* Now do each of the servers, linking the credentials list file and 
299  * compiling the quota and dirs files.
300  */
301
302 int do_machs(machs)
303 struct save_queue *machs;
304 {
305     EXEC SQL BEGIN DECLARE SECTION;
306     char *machname, listname[33], dev[33], dir[81], fstype[9];
307     int uid, quota, id, gid, flag1, flag2, flag3, flag4;
308     EXEC SQL END DECLARE SECTION;
309     char file[64], f1[64], f2[64], *cp;
310     int prevuid, quotasum, olddev, oldmach;
311     FILE *fd;
312     struct hash *machines;
313
314     fprintf(stderr, "Building machine files\n");
315
316
317     machines = create_hash(100);
318     while (sq_get_data(machs, &machname)) {
319         EXEC SQL SELECT s.value3, m.mach_id
320           INTO :listname, :id
321           FROM serverhosts s, machine m
322           WHERE s.mach_id = m.mach_id AND m.name = :machname AND 
323             s.service = 'NFS';
324         strtrim(machname);
325         sprintf(f1, "%s/list-%s", nfs_dir, strtrim(listname));
326         sprintf(f2, "%s/%s.cred", nfs_dir, machname);
327         unlink(f2); /* ignore errors on this unlink */
328         if (link(f1, f2)) {
329             fprintf(stderr, "Cannot link %s to %s\n", f1, f2);
330             exit(MR_OCONFIG);
331         }
332         hash_store(machines, id, machname);
333     }
334
335
336     olddev = oldmach = -1;
337     fd = stdin;
338
339     EXEC SQL DECLARE q_cursor CURSOR FOR
340       SELECT DISTINCT q.quota, q.entity_id, q.phys_id, n.device, n.mach_id 
341       FROM quota q, nfsphys n
342       WHERE n.nfsphys_id = q.phys_id AND q.phys_id != 0 AND
343         n.status < 16 AND q.type = 'USER'
344       ORDER BY n.mach_id, q.phys_id, q.entity_id;
345     EXEC SQL OPEN q_cursor;
346     while (1) {
347         EXEC SQL FETCH q_cursor INTO :quota, :uid, :flag1, :dev, :flag2;
348         if (sqlca.sqlcode != 0) break;
349         if (flag1 != olddev || flag2 != oldmach) {
350             if (quotasum)
351               fprintf(fd, "%d %d\n", prevuid, quotasum);
352             if (flag2 == 0 || !hash_lookup(machines, flag2))
353               continue;
354             if (fd != stdin)
355               fclose(fd);
356             olddev = flag1;
357             oldmach = flag2;
358             while (cp = strchr(dev, '/')) *cp = '@';
359             sprintf(file, "%s/%s.%s.quotas", nfs_dir,
360                     hash_lookup(machines, flag2), strtrim(dev));
361             fd = fopen(file, "w");
362             if (!fd) {
363                 fprintf(stderr, "cannot open %s for output\n", file);
364                 exit(MR_OCONFIG);
365             }
366             prevuid = -1;
367             quotasum = 0;
368         }
369         if (uid != prevuid) {
370             if ((cp = hash_lookup(users, prevuid)) &&
371                 (cp = strchr(cp, ':')))
372               prevuid = atoi(cp+1);
373             if (quotasum)
374               fprintf(fd, "%d %d\n", prevuid, quotasum);
375             prevuid = uid;
376             quotasum = quota;
377         } else {
378             quotasum += quota;
379         }
380     }
381     EXEC SQL CLOSE q_cursor;
382     if ((cp = hash_lookup(users, prevuid)) &&
383         (cp = strchr(cp, ':')))
384       prevuid = atoi(cp+1);
385     if (quotasum)
386       fprintf(fd, "%d %d\n", prevuid, quotasum);
387     if (fd != stdin && fclose(fd) == EOF) {
388         fprintf(stderr, "error closing %s", file);
389         exit(MR_CCONFIG);
390       }
391
392     olddev = oldmach = -1;
393     fd = stdin;
394     EXEC SQL DECLARE q_cursor2 CURSOR FOR
395       SELECT DISTINCT q.quota, q.entity_id, q.phys_id, n.device, n.mach_id,
396         n.status 
397       FROM quota q, nfsphys n
398       WHERE n.nfsphys_id = q.phys_id AND q.phys_id != 0 AND
399         n.status > 15 AND q.type = 'GROUP'
400       ORDER BY mach_id, phys_id, entity_id;
401     EXEC SQL OPEN q_cursor2;
402     while (1) {
403         EXEC SQL FETCH q_cursor2 INTO :quota, :gid, :flag1, :dev,
404                 :flag2, :flag3;
405         if (sqlca.sqlcode != 0) break;
406         if (flag1 != olddev || flag2 != oldmach) {
407             if (quotasum)
408               fprintf(fd, "%d %d\n", prevuid, quotasum);
409             if (flag2 == 0 || !hash_lookup(machines, flag2))
410               continue;
411             if (fd != stdin)
412               fclose(fd);
413             olddev = flag1;
414             oldmach = flag2;
415             while (cp = strchr(dev, '/')) *cp = '@';
416             sprintf(file, "%s/%s.%s.quotas", nfs_dir,
417                     hash_lookup(machines, flag2), strtrim(dev));
418             fd = fopen(file, "w");
419             if (!fd) {
420                 fprintf(stderr, "cannot open %s for output\n", file);
421                 exit(MR_OCONFIG);
422             }
423             prevuid = -1;
424             quotasum = 0;
425         }
426         if (gid != prevuid) {
427             if (cp = hash_lookup(groups, prevuid))
428               prevuid = atoi(cp + 1);
429             if (quotasum)
430               fprintf(fd, "%d %d\n", prevuid, quotasum);
431             prevuid = gid;
432             quotasum = quota;
433         } else {
434             quotasum += quota;
435         }
436     }
437     EXEC SQL CLOSE q_cursor2;
438     if (cp = hash_lookup(groups, prevuid))
439       prevuid = atoi(cp + 1);
440     if (quotasum)
441       fprintf(fd, "%d %d\n", prevuid, quotasum);
442     if (fd != stdin && fclose(fd) == EOF) {
443         fprintf(stderr, "error closing %s", file);
444         exit(MR_CCONFIG);
445       }
446
447     olddev = oldmach = -1;
448     fd = stdin;
449
450     EXEC SQL DECLARE q_cursor3 CURSOR FOR
451       SELECT DISTINCT f.name, f.lockertype, u.unix_uid, l.gid, f.phys_id, 
452                 f.mach_id, n.device 
453       FROM users u, list l, nfsphys n, filesys f
454       WHERE u.users_id = f.owner AND 
455               l.list_id = f.owners AND
456               f.createflg != 0 AND f.phys_id != 0 AND
457               f.type = 'NFS' AND 
458               f.phys_id = n.nfsphys_id
459       ORDER BY mach_id, phys_id;
460     EXEC SQL OPEN q_cursor3;
461     while (1) {
462         EXEC SQL FETCH q_cursor3 INTO :dir, :fstype, :uid, :gid, :flag1,
463                         :flag2, :dev;
464         if (sqlca.sqlcode != 0) break;
465         if ((flag1 != olddev || flag2 != oldmach) &&
466             hash_lookup(machines, flag2)) {
467             if (fd != stdin)
468               fclose(fd);
469             olddev = flag1;
470             oldmach = flag2;
471             while (cp = strchr(dev, '/')) *cp = '@';
472             sprintf(file, "%s/%s.%s.dirs", nfs_dir,
473                     hash_lookup(machines, flag2), strtrim(dev));
474             fd = fopen(file, "w");
475             if (!fd) {
476                 fprintf(stderr, "cannot open %s for output\n", file);
477                 exit(MR_OCONFIG);
478             }
479         }
480         fprintf(fd, "%s %d %d %s\n", strtrim(dir), uid, gid, strtrim(fstype));
481     }    
482     EXEC SQL CLOSE q_cursor3;
483     if (fclose(fd) == EOF) {
484         fprintf(stderr, "error closing %s", file);
485         exit(MR_CCONFIG);
486     }
487     return(1);
488  sqlerr:
489     db_error(sqlca.sqlcode);
490     exit(MR_DBMS_ERR);
491 }
This page took 0.090256 seconds and 5 git commands to generate.