3 * ptdump: Program to dump the AFS protection server database
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.
12 #include <sys/types.h>
19 #include <netinet/in.h>
20 #define UBIK_INTERNALS
24 #include <afs/ptint.h>
25 #include <afs/ptserver.h>
29 extern char *sys_errlist[];
32 struct ubik_version uv;
34 int grpflag, nmflg, cflag;
44 register struct ubik_hdr *uh;
46 strcpy(file, "/usr/afs/db/prdb.DB0");
47 while ((cc = getopt(argc, argv, "f:gnc")) != EOF) {
50 strncpy (file, optarg, sizeof(file));
59 nmflg++; /* Use the Name hash chain */
62 fprintf(stderr, "ptdump: -%c: unknown option\n", cc);
66 if (cflag && !grpflag) {
67 fprintf(stderr, "ptdump: -c requires -g flag.\n");
70 if ((fd = open(file, O_RDONLY, 0600)) < 0) {
71 fprintf(stderr, "ptdump: cannot open %s: %s\n",
72 file, sys_errlist[errno]);
75 if (read(fd, buffer, HDRSIZE) < 0) {
76 fprintf(stderr, "ptdump: error reading %s: %s\n",
77 file, sys_errlist[errno]);
80 uh = (struct ubik_hdr *)buffer;
81 if (ntohl(uh->magic) != UBIK_MAGIC)
82 fprintf(stderr, "ptdump: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
83 file, ntohl(uh->magic), UBIK_MAGIC);
84 bcopy(&uh->version, &uv, sizeof(struct ubik_version));
85 fprintf(stderr, "Ubik Version is: %D.%d\n",
86 uv.epoch, uv.counter);
87 if (read(fd, &prh, sizeof(struct prheader)) < 0) {
88 fprintf(stderr, "ptdump: error reading %s: %s\n",
89 file, sys_errlist[errno]);
92 for (i = 0; i < HASHSIZE; i++) {
93 offset = nmflg ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
96 offset = display_entry(offset, fd, &didit);
98 lseek (fd, 0, L_SET); /* rewind to beginning of file */
99 if (read(fd, buffer, HDRSIZE) < 0) {
100 fprintf(stderr, "ptdump: error reading %s: %s\n",
101 file, sys_errlist[errno]);
104 uh = (struct ubik_hdr *)buffer;
105 if ((uh->version.epoch != uv.epoch) ||
106 (uh->version.counter != uv.counter)) {
107 fprintf(stderr, "ptdump: Ubik Version number changed during execution.\n");
108 fprintf(stderr, "Old Version = %D.%d, new version = %D.%d\n",
109 uv.epoch, uv.counter, uh->version.epoch,
110 uh->version.counter);
115 int display_entry (offset, fd, didit)
119 void display_useful_groups();
122 lseek (fd, offset+HDRSIZE, L_SET);
123 read(fd, &pre, sizeof(struct prentry));
124 pre.flags = ntohl(pre.flags);
125 pre.id = ntohl(pre.id);
126 pre.cellid = ntohl(pre.cellid);
127 pre.next = ntohl(pre.next);
128 pre.nextID = ntohl(pre.nextID);
129 pre.nextName = ntohl(pre.nextName);
130 pre.owner = ntohl(pre.owner);
131 pre.creator = ntohl(pre.creator);
132 pre.ngroups = ntohl(pre.ngroups);
133 pre.nusers = ntohl(pre.nusers);
134 pre.count = ntohl(pre.count);
135 pre.instance = ntohl(pre.instance);
136 pre.owned = ntohl(pre.owned);
137 pre.nextOwned = ntohl(pre.nextOwned);
138 pre.parent = ntohl(pre.parent);
139 pre.sibling = ntohl(pre.sibling);
140 pre.child = ntohl(pre.child);
141 for (i = 0; i < PRSIZE; i++) {
142 pre.entries[i] = ntohl(pre.entries[i]);
144 if ((pre.flags & PRFREE) == 0) { /* A normal user */
145 if (cflag) (void) checkin(&pre);
146 if (((pre.flags & PRGRP) && grpflag) ||
147 (((pre.flags & PRGRP) == 0) && !grpflag)) {
148 if (!*didit && !cflag) {
150 printf("==========\n");
153 printf("Name: %s ID: %D\n", pre.name, pre.id);
154 else display_useful_groups(&pre, fd);
157 return(nmflg ? pre.nextName : pre.nextID);
159 static struct contentry prco;
160 void display_useful_groups(pre, fd)
161 register struct prentry *pre;
167 if (pre->entries[0] == 0) return;
168 printf("Group: %s\n", pre->name);
169 for (i = 0; i < PRSIZE; i++) {
170 if (pre->entries[i] == 0) break;
171 printf(" Member: %s\n", id_to_name(pre->entries[i], fd));
176 lseek(fd, offset+HDRSIZE, L_SET);
177 read(fd, &prco, sizeof(struct contentry));
178 prco.next = ntohl(prco.next);
179 for (i = 0; i < COSIZE; i++) {
180 prco.entries[i] = ntohl(prco.entries[i]);
181 if (prco.entries[i] == 0) break;
182 printf(" Member(co): %s\n", id_to_name(prco.entries[i], fd));
184 if ((i == COSIZE) && prco.next)
190 char *id_to_name(id, fd)
200 name = check_core(id);
201 if (name != NULL) return(name);
202 offset = ntohl(prh.idHash[IDHash(id)]);
203 if (offset == NULL) return("NOT FOUND");
205 lseek(fd, offset+HDRSIZE, L_SET);
206 if (read(fd, &pre, sizeof(struct prentry)) < 0) {
207 fprintf(stderr, "ptdump: read i/o error: %s\n",
211 pre.id = ntohl(pre.id);
213 name = checkin(&pre);
216 offset = ntohl(pre.nextID);
221 char h_name[PR_MAXNAMELEN];
223 struct hash_entry *next;
225 struct hash_entry *hat[HASHSIZE];
229 struct hash_entry *he, *last;
233 last = (struct hash_entry *)0;
234 he = hat[IDHash(id)];
236 if (id == he->h_id) return(he->h_name);
240 he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
242 fprintf(stderr, "ptdump: No Memory for internal hash table.\n");
246 he->next = (struct hash_entry *)0;
247 strncpy(he->h_name, pre->name, PR_MAXNAMELEN);
248 if (last == (struct hash_entry *)0) hat[IDHash(id)] = he;
249 else last->next = he;
255 struct hash_entry *he;
257 he = hat[IDHash(id)];
259 if (id == he->h_id) return(he->h_name);
268 /* returns hash bucket for x */
269 return ((abs(x)) % HASHSIZE);