source: trunk/third/moira/afssync/ptdump.c @ 23095

Revision 23095, 7.0 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
Line 
1/*
2 *
3 * ptdump: Program to dump the AFS protection server database
4 *         into an ascii file.
5 *
6 *      Assumptions: We *cheat* here and read the datafile directly, ie.
7 *                   not going through the ubik distributed data manager.
8 *                   therefore the database must be quiescent for the
9 *                   output of this program to be valid.
10 */
11
12#include <sys/types.h>
13#include <sys/time.h>
14#include <stdio.h>
15#include <ctype.h>
16#include <string.h>
17#include <sys/file.h>
18#include <lock.h>
19#include <netinet/in.h>
20#define UBIK_INTERNALS
21#include <ubik.h>
22#include <rx/xdr.h>
23#include <rx/rx.h>
24#include <afs/ptint.h>
25#include <afs/ptserver.h>
26extern char *optarg;
27extern int optind;
28extern int errno;
29extern char *sys_errlist[];
30struct prheader prh;
31struct prentry pre;
32struct ubik_version uv;
33char buffer[1024];
34int grpflag, nmflg, cflag;
35
36main(argc, argv)
37int argc;
38char **argv;
39{
40    int cc;
41    int fd, offset;
42    register int i;
43    char file[512];
44    register struct ubik_hdr *uh;
45    int didit;
46    setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
47    strcpy(file, "/usr/afs/db/prdb.DB0");
48    while ((cc = getopt(argc, argv, "f:gnc")) != EOF) {
49        switch (cc) {
50        case 'f':
51            strncpy (file, optarg, sizeof(file));
52            break;
53        case 'g':
54            grpflag++;
55            break;
56        case 'c':
57            cflag++;
58            break;
59        case 'n':
60            nmflg++;            /* Use the Name hash chain */
61            break;
62        default:
63            fprintf(stderr, "ptdump: -%c: unknown option\n", cc);
64            break;
65        }
66    }
67    if (cflag && !grpflag) {
68        fprintf(stderr, "ptdump: -c requires -g flag.\n");
69        exit (1);
70    }
71    if ((fd = open(file, O_RDONLY, 0600)) < 0) {
72        fprintf(stderr, "ptdump: cannot open %s: %s\n",
73                file, sys_errlist[errno]);
74        exit (1);
75    }
76    if (read(fd, buffer, HDRSIZE) < 0) {
77        fprintf(stderr, "ptdump: error reading %s: %s\n",
78                file, sys_errlist[errno]);
79        exit (1);
80    }
81    uh = (struct ubik_hdr *)buffer;
82    if (ntohl(uh->magic) != UBIK_MAGIC)
83        fprintf(stderr, "ptdump: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
84                file, ntohl(uh->magic), UBIK_MAGIC);
85    memcpy(&uv, &uh->version, sizeof(struct ubik_version));
86    fprintf(stderr, "Ubik Version is: %D.%d\n",
87            uv.epoch, uv.counter);
88    if (read(fd, &prh, sizeof(struct prheader)) < 0) {
89        fprintf(stderr, "ptdump: error reading %s: %s\n",
90                file, sys_errlist[errno]);
91        exit (1);
92    }
93    for (i = 0; i < HASHSIZE; i++) {
94        offset = nmflg ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
95        didit = 0;
96        while (offset)
97            offset = display_entry(offset, fd, &didit);
98    }
99    lseek (fd, 0, L_SET);               /* rewind to beginning of file */
100    if (read(fd, buffer, HDRSIZE) < 0) {
101        fprintf(stderr, "ptdump: error reading %s: %s\n",
102                file, sys_errlist[errno]);
103        exit (1);
104    }
105    uh = (struct ubik_hdr *)buffer;
106    if ((uh->version.epoch != uv.epoch) ||
107        (uh->version.counter != uv.counter)) {
108        fprintf(stderr, "ptdump: Ubik Version number changed during execution.\n");
109        fprintf(stderr, "Old Version = %D.%d, new version = %D.%d\n",
110                uv.epoch, uv.counter, uh->version.epoch,
111                uh->version.counter);
112    }
113    close (fd);
114    exit (0);
115}
116int display_entry (offset, fd, didit)
117int offset, fd;
118int *didit;
119{
120    void display_useful_groups();
121    char *checkin();
122    register int i;
123    lseek (fd, offset+HDRSIZE, L_SET);
124    read(fd, &pre, sizeof(struct prentry));
125    pre.flags = ntohl(pre.flags);
126    pre.id = ntohl(pre.id);
127    pre.cellid = ntohl(pre.cellid);
128    pre.next = ntohl(pre.next);
129    pre.nextID = ntohl(pre.nextID);
130    pre.nextName = ntohl(pre.nextName);
131    pre.owner = ntohl(pre.owner);
132    pre.creator = ntohl(pre.creator);
133    pre.ngroups = ntohl(pre.ngroups);
134    pre.nusers = ntohl(pre.nusers);
135    pre.count = ntohl(pre.count);
136    pre.instance = ntohl(pre.instance);
137    pre.owned = ntohl(pre.owned);
138    pre.nextOwned = ntohl(pre.nextOwned);
139    pre.parent = ntohl(pre.parent);
140    pre.sibling = ntohl(pre.sibling);
141    pre.child = ntohl(pre.child);
142    for (i = 0; i < PRSIZE; i++) {
143        pre.entries[i] = ntohl(pre.entries[i]);
144    }
145    if ((pre.flags & PRFREE) == 0) { /* A normal user */
146        if (cflag) (void) checkin(&pre);
147        if (((pre.flags & PRGRP) && grpflag) ||
148            (((pre.flags & PRGRP) == 0) && !grpflag)) {
149            if (!*didit && !cflag) {
150                *didit = 1;
151                printf("==========\n");
152            }
153            if (!cflag)
154                printf("Name: %s ID: %D\n", pre.name, pre.id);
155            else display_useful_groups(&pre, fd);
156        }
157    }
158    return(nmflg ? pre.nextName : pre.nextID);
159}
160static struct contentry prco;
161void display_useful_groups(pre, fd)
162register struct prentry *pre;
163int fd;
164{
165    register int i;
166    register int offset;
167    char *id_to_name();
168    if (pre->entries[0] == 0) return;
169    printf("Group: %s\n", pre->name);
170    for (i = 0; i < PRSIZE; i++) {
171        if (pre->entries[i] == 0) break;
172        if (pre->entries[i] == PRBADID) continue;
173        printf("   Member:  %s\n", id_to_name(pre->entries[i], fd));
174    }
175    if (i == PRSIZE) {
176        offset = pre->next;
177        while (offset) {
178            lseek(fd, offset+HDRSIZE, L_SET);
179            read(fd, &prco, sizeof(struct contentry));
180            prco.next = ntohl(prco.next);
181            for (i = 0; i < COSIZE; i++) {
182                prco.entries[i] = ntohl(prco.entries[i]);
183                if (prco.entries[i] == 0) break;
184                if (prco.entries[i] == PRBADID) continue;
185                printf("   Member(co):  %s\n", id_to_name(prco.entries[i], fd));
186            }
187            if ((i == COSIZE) && prco.next)
188                offset = prco.next;
189            else offset = 0;
190        }
191    }
192}
193char *id_to_name(id, fd)
194int id;
195int fd;
196{
197    register int offset;
198    struct prentry pre;
199    char *name;
200    char *check_core();
201    char *checkin();
202    long IDHash();
203    name = check_core(id);
204    if (name != NULL) return(name);
205    offset = ntohl(prh.idHash[IDHash(id)]);
206    if (offset == NULL) return("NOT FOUND");
207    while (offset) {
208        lseek(fd, offset+HDRSIZE, L_SET);
209        if (read(fd, &pre, sizeof(struct prentry)) < 0) {
210            fprintf(stderr, "ptdump: read i/o error: %s\n",
211                    sys_errlist[errno]);
212            exit (1);
213        }
214        pre.id = ntohl(pre.id);
215        if (pre.id == id) {
216            name = checkin(&pre);
217            return(name);
218        }
219        offset = ntohl(pre.nextID);
220    }
221    return("NOT FOUND");
222}
223struct hash_entry {
224    char h_name[PR_MAXNAMELEN];
225    int h_id;
226    struct hash_entry *next;
227};
228struct hash_entry *hat[HASHSIZE];
229char *checkin(pre)
230struct prentry *pre;
231{
232    struct hash_entry *he, *last;
233    register int id;
234    long IDHash();
235    id = pre->id;
236    last = (struct hash_entry *)0;
237    he = hat[IDHash(id)];
238    while (he) {
239        if (id == he->h_id) return(he->h_name);
240        last = he;
241        he = he->next;
242    }
243    he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
244    if (he == NULL) {
245        fprintf(stderr, "ptdump: No Memory for internal hash table.\n");
246        exit (1);
247    }
248    he->h_id = id;
249    he->next = (struct hash_entry *)0;
250    strncpy(he->h_name, pre->name, PR_MAXNAMELEN);
251    if (last == (struct hash_entry *)0) hat[IDHash(id)] = he;
252    else last->next = he;
253    return(he->h_name);
254}
255char *check_core(id)
256register int id;
257{
258    struct hash_entry *he;
259    long IDHash();
260    he = hat[IDHash(id)];
261    while (he) {
262        if (id == he->h_id) return(he->h_name);
263        he = he->next;
264    }
265    return(NULL);
266}
267
268long IDHash(x)
269long x;
270{
271    /* returns hash bucket for x */
272    return ((abs(x)) % HASHSIZE);
273}
Note: See TracBrowser for help on using the repository browser.