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