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 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
47 strcpy(file, "/usr/afs/db/prdb.DB0");
48 while ((cc = getopt(argc, argv, "f:gnc")) != EOF) {
51 strncpy (file, optarg, sizeof(file));
60 nmflg++; /* Use the Name hash chain */
63 fprintf(stderr, "ptdump: -%c: unknown option\n", cc);
67 if (cflag && !grpflag) {
68 fprintf(stderr, "ptdump: -c requires -g flag.\n");
71 if ((fd = open(file, O_RDONLY, 0600)) < 0) {
72 fprintf(stderr, "ptdump: cannot open %s: %s\n",
73 file, sys_errlist[errno]);
76 if (read(fd, buffer, HDRSIZE) < 0) {
77 fprintf(stderr, "ptdump: error reading %s: %s\n",
78 file, sys_errlist[errno]);
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]);
93 for (i = 0; i < HASHSIZE; i++) {
94 offset = nmflg ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
97 offset = display_entry(offset, fd, &didit);
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]);
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);
116 int display_entry (offset, fd, didit)
120 void display_useful_groups();
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]);
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) {
151 printf("==========\n");
154 printf("Name: %s ID: %D\n", pre.name, pre.id);
155 else display_useful_groups(&pre, fd);
158 return(nmflg ? pre.nextName : pre.nextID);
160 static struct contentry prco;
161 void display_useful_groups(pre, fd)
162 register struct prentry *pre;
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));
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));
187 if ((i == COSIZE) && prco.next)
193 char *id_to_name(id, fd)
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");
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",
214 pre.id = ntohl(pre.id);
216 name = checkin(&pre);
219 offset = ntohl(pre.nextID);
224 char h_name[PR_MAXNAMELEN];
226 struct hash_entry *next;
228 struct hash_entry *hat[HASHSIZE];
232 struct hash_entry *he, *last;
236 last = (struct hash_entry *)0;
237 he = hat[IDHash(id)];
239 if (id == he->h_id) return(he->h_name);
243 he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
245 fprintf(stderr, "ptdump: No Memory for internal hash table.\n");
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;
258 struct hash_entry *he;
260 he = hat[IDHash(id)];
262 if (id == he->h_id) return(he->h_name);
271 /* returns hash bucket for x */
272 return ((abs(x)) % HASHSIZE);