gdp / apps / gdp-log-view.c @ master
History | View | Annotate | Download (11.9 KB)
1 | be19c14d | Eric Allman | /* vim: set ai sw=4 sts=4 ts=4 : */
|
---|---|---|---|
2 | |||
3 | /***********************************************************************
|
||
4 | ** ----- BEGIN LICENSE BLOCK -----
|
||
5 | ** Applications for the Global Data Plane
|
||
6 | ** From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
|
||
7 | **
|
||
8 | c87dd166 | Eric Allman | ** Copyright (c) 2015-2019, Regents of the University of California.
|
9 | be19c14d | Eric Allman | ** All rights reserved.
|
10 | **
|
||
11 | ** Permission is hereby granted, without written agreement and without
|
||
12 | ** license or royalty fees, to use, copy, modify, and distribute this
|
||
13 | ** software and its documentation for any purpose, provided that the above
|
||
14 | ** copyright notice and the following two paragraphs appear in all copies
|
||
15 | ** of this software.
|
||
16 | **
|
||
17 | ** IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||
18 | ** SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
|
||
19 | ** PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
|
||
20 | ** EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
21 | **
|
||
22 | ** REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||
23 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
24 | ** FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
|
||
25 | ** IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
|
||
26 | ** OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
|
||
27 | ** OR MODIFICATIONS.
|
||
28 | ** ----- END LICENSE BLOCK -----
|
||
29 | ***********************************************************************/
|
||
30 | |||
31 | #include <ep/ep.h> |
||
32 | #include <ep/ep_dbg.h> |
||
33 | #include <ep/ep_hash.h> |
||
34 | #include <ep/ep_hexdump.h> |
||
35 | #include <ep/ep_net.h> |
||
36 | #include <ep/ep_prflags.h> |
||
37 | #include <ep/ep_string.h> |
||
38 | #include <ep/ep_time.h> |
||
39 | #include <ep/ep_xlate.h> |
||
40 | #include <gdp/gdp.h> |
||
41 | |||
42 | #include <dirent.h> |
||
43 | #include <errno.h> |
||
44 | #include <getopt.h> |
||
45 | #include <inttypes.h> |
||
46 | #include <stddef.h> |
||
47 | #include <stdint.h> |
||
48 | #include <stdio.h> |
||
49 | #include <string.h> |
||
50 | #include <sysexits.h> |
||
51 | #include <time.h> |
||
52 | #include <sys/stat.h> |
||
53 | |||
54 | // leverage existing code (this is a hack!)
|
||
55 | 537a3cba | Eric Allman | #define GDP_LOG_VIEW 1 |
56 | #define Dbg DbgLogdSqlite
|
||
57 | be19c14d | Eric Allman | #include "../gdplogd/logd_sqlite.c" |
58 | #undef Dbg
|
||
59 | 5c666732 | Eric Allman | #include "../gdp/gdp_hongd.h" |
60 | be19c14d | Eric Allman | |
61 | |||
62 | /*
|
||
63 | ** GDP-LOG-VIEW --- display raw on-disk storage
|
||
64 | **
|
||
65 | ** Not for user consumption.
|
||
66 | ** This does peek into private header files.
|
||
67 | */
|
||
68 | |||
69 | static EP_DBG Dbg = EP_DBG_INIT("gdp-log-view", "Dump GDP logs for debugging"); |
||
70 | |||
71 | |||
72 | #define LIST_NO_METADATA 0x00000001 // only list logs with no metadata |
||
73 | |||
74 | |||
75 | void
|
||
76 | pr_pubkey(uint32_t md_id, uint32_t md_len, uint8_t *mdata, int plev)
|
||
77 | { |
||
78 | { |
||
79 | int keylen = mdata[2] << 8 | mdata[3]; |
||
80 | printf("\tmd_alg %s (%d), keytype %s (%d), keylen %d\n",
|
||
81 | ep_crypto_md_alg_name(mdata[0]), mdata[0], |
||
82 | ep_crypto_keytype_name(mdata[1]), mdata[1], |
||
83 | keylen); |
||
84 | } |
||
85 | if (plev > 1) |
||
86 | { |
||
87 | EP_CRYPTO_KEY *key; |
||
88 | |||
89 | key = ep_crypto_key_read_mem(mdata + 4,
|
||
90 | md_len - 4,
|
||
91 | EP_CRYPTO_KEYFORM_DER, |
||
92 | EP_CRYPTO_F_PUBLIC); |
||
93 | ep_crypto_key_print(key, stdout, EP_CRYPTO_F_PUBLIC); |
||
94 | ep_crypto_key_free(key); |
||
95 | } |
||
96 | if (plev >= 4) |
||
97 | ep_hexdump(mdata + 4, md_len - 4, stdout, EP_HEXDUMP_HEX, 0); |
||
98 | } |
||
99 | |||
100 | |||
101 | EP_STAT |
||
102 | pr_verbose_metadata(gdp_gob_t *gob, int plev)
|
||
103 | { |
||
104 | gdp_md_t *md = gob->gob_md; |
||
105 | |||
106 | printf("\n --------------- Metadata ---------------\n");
|
||
107 | if (md == NULL) |
||
108 | { |
||
109 | fprintf(stderr, "%s: no metadata\n", gob->pname);
|
||
110 | return EP_STAT_ERROR; //XXX something more specific? |
||
111 | } |
||
112 | |||
113 | int mdx = 0; |
||
114 | for (;; ++mdx)
|
||
115 | { |
||
116 | gdp_md_id_t md_id; |
||
117 | size_t md_len; |
||
118 | const uint8_t *md_data;
|
||
119 | EP_STAT estat; |
||
120 | |||
121 | estat = gdp_md_get(md, mdx, &md_id, &md_len, (const void **) &md_data); |
||
122 | EP_STAT_CHECK(estat, break);
|
||
123 | |||
124 | uint8_t mdata[md_len + 1]; // +1 for null-terminator |
||
125 | memcpy(mdata, md_data, md_len); |
||
126 | mdata[md_len] = '\0';
|
||
127 | |||
128 | if (plev > 1) |
||
129 | { |
||
130 | int printtype = 0; |
||
131 | fprintf(stdout, |
||
132 | "\nMetadata entry %d: name 0x%08" PRIx32
|
||
133 | ", len %zd",
|
||
134 | mdx, md_id, md_len); |
||
135 | switch (md_id)
|
||
136 | { |
||
137 | case GDP_MD_XID:
|
||
138 | printf(" (external id)\n");
|
||
139 | printtype = 1;
|
||
140 | break;
|
||
141 | |||
142 | case GDP_MD_NONCE:
|
||
143 | printf(" (nonce)\n ");
|
||
144 | ep_hexdump(mdata, md_len, stdout, EP_HEXDUMP_TERSE, 0);
|
||
145 | printtype = 0;
|
||
146 | break;
|
||
147 | |||
148 | case GDP_MD_CTIME:
|
||
149 | printf(" (creation time)\n");
|
||
150 | printtype = 1;
|
||
151 | break;
|
||
152 | |||
153 | case GDP_MD_EXPIRE:
|
||
154 | printf(" (expiration time)\n");
|
||
155 | printtype = 1;
|
||
156 | break;
|
||
157 | |||
158 | case GDP_MD_CREATOR:
|
||
159 | printf(" (creator)\n");
|
||
160 | printtype = 1;
|
||
161 | break;
|
||
162 | |||
163 | case GDP_MD_PUBKEY:
|
||
164 | printf(" (public key, deprecated)\n");
|
||
165 | pr_pubkey(md_id, md_len, mdata, plev); |
||
166 | break;
|
||
167 | |||
168 | case GDP_MD_OWNERPUBKEY:
|
||
169 | printf(" (owner public key)\n");
|
||
170 | pr_pubkey(md_id, md_len, mdata, plev); |
||
171 | break;
|
||
172 | |||
173 | case GDP_MD_WRITERPUBKEY:
|
||
174 | printf(" (writer public key)\n");
|
||
175 | pr_pubkey(md_id, md_len, mdata, plev); |
||
176 | break;
|
||
177 | |||
178 | case GDP_MD_SYNTAX:
|
||
179 | printf(" (syntax)\n");
|
||
180 | printtype = 1;
|
||
181 | break;
|
||
182 | |||
183 | case GDP_MD_LOCATION:
|
||
184 | printf(" (location)\n");
|
||
185 | printtype = 1;
|
||
186 | break;
|
||
187 | |||
188 | default:
|
||
189 | printf("\n");
|
||
190 | fe9fd7f9 | Eric Allman | printtype = 1;
|
191 | be19c14d | Eric Allman | break;
|
192 | } |
||
193 | if (printtype == 1) |
||
194 | { |
||
195 | printf("\t%s", EpChar->lquote);
|
||
196 | ep_xlate_out(mdata, md_len, |
||
197 | stdout, "", EP_XLATE_PLUS | EP_XLATE_NPRINT);
|
||
198 | fprintf(stdout, "%s\n", EpChar->rquote);
|
||
199 | } |
||
200 | else if (printtype == 2) |
||
201 | { |
||
202 | ep_hexdump(mdata, md_len, stdout, EP_HEXDUMP_HEX, 0);
|
||
203 | } |
||
204 | else if (printtype == 3) |
||
205 | { |
||
206 | ep_hexdump(mdata, md_len, stdout, EP_HEXDUMP_ASCII, 0);
|
||
207 | } |
||
208 | } |
||
209 | else if (md_id == GDP_MD_XID) |
||
210 | { |
||
211 | fprintf(stdout, "\tExternal name: %s\n", mdata);
|
||
212 | } |
||
213 | else if (md_id == GDP_MD_CREATOR) |
||
214 | { |
||
215 | fprintf(stdout, "\tCreator: %s\n", mdata);
|
||
216 | } |
||
217 | else if (md_id == GDP_MD_CTIME) |
||
218 | { |
||
219 | fprintf(stdout, "\tCreation Time: %s\n", mdata);
|
||
220 | } |
||
221 | |||
222 | if (plev >= 4) |
||
223 | { |
||
224 | ep_hexdump(mdata, md_len, stdout, EP_HEXDUMP_ASCII, 0);
|
||
225 | } |
||
226 | } |
||
227 | return EP_STAT_OK;
|
||
228 | } |
||
229 | |||
230 | |||
231 | static EP_STAT
|
||
232 | show_rec(EP_STAT estat, gdp_datum_t *datum, gdp_result_ctx_t *ctx) |
||
233 | { |
||
234 | bae4ad18 | Eric Allman | uintptr_t ptrint = (uintptr_t) ctx; |
235 | uint32_t pflags = (uint32_t) ptrint; |
||
236 | be19c14d | Eric Allman | if (EP_STAT_IS_SAME(estat, GDP_STAT_ACK_CONTENT))
|
237 | gdp_datum_print(datum, stdout, pflags); |
||
238 | else
|
||
239 | ep_app_message(estat, "show_rec: unknown estat");
|
||
240 | return EP_STAT_OK;
|
||
241 | } |
||
242 | |||
243 | |||
244 | EP_STAT |
||
245 | show_log(gdp_name_t log_name, int plev)
|
||
246 | { |
||
247 | gdp_pname_t log_pname; |
||
248 | fe9fd7f9 | Eric Allman | gdp_gob_t *gob = NULL;
|
249 | be19c14d | Eric Allman | EP_STAT estat; |
250 | |||
251 | (void) gdp_printable_name(log_name, log_pname);
|
||
252 | if (plev <= 0) |
||
253 | { |
||
254 | printf("%s\n", log_pname);
|
||
255 | return EP_STAT_OK;
|
||
256 | } |
||
257 | |||
258 | // create a GOB data structure for this log
|
||
259 | estat = _gdp_gob_new(log_name, &gob); |
||
260 | EP_STAT_CHECK(estat, return estat);
|
||
261 | gob->x = (struct gdp_gob_xtra *) ep_mem_zalloc(sizeof *gob->x); |
||
262 | _gdp_gob_lock(gob); |
||
263 | |||
264 | // open the on-disk database
|
||
265 | estat = sqlite_open(gob); |
||
266 | EP_STAT_CHECK(estat, goto fail0);
|
||
267 | |||
268 | // figure out what we want to actually print
|
||
269 | fe9fd7f9 | Eric Allman | if (plev == 1) |
270 | { |
||
271 | 062cb614 | Eric Allman | // show log name, number of records, external name if known
|
272 | fe9fd7f9 | Eric Allman | size_t md_len; |
273 | const void *md_data; |
||
274 | |||
275 | estat = gdp_md_find(gob->gob_md, GDP_MD_XID, &md_len, &md_data); |
||
276 | if (!EP_STAT_ISOK(estat))
|
||
277 | { |
||
278 | md_data = (void *) "-"; |
||
279 | md_len = 1;
|
||
280 | } |
||
281 | printf("%s %" PRIgdp_recno " %.*s\n", |
||
282 | log_pname, gob->nrecs, (int) md_len, (const char *) md_data); |
||
283 | goto done;
|
||
284 | } |
||
285 | 062cb614 | Eric Allman | if (plev == 2) |
286 | { |
||
287 | // show log name, nrecs, brief metadata overview
|
||
288 | printf("%s %" PRIgdp_recno "\n", log_pname, gob->nrecs); |
||
289 | gdp_md_t *md = gob->gob_md; |
||
290 | if (md == NULL) |
||
291 | goto done;
|
||
292 | int mdx = 0; |
||
293 | for (;; mdx++)
|
||
294 | { |
||
295 | gdp_md_id_t md_id; |
||
296 | size_t md_len; |
||
297 | const uint8_t *md_data;
|
||
298 | |||
299 | estat = gdp_md_get(md, mdx, &md_id, &md_len, (const void **) &md_data); |
||
300 | EP_STAT_CHECK(estat, break);
|
||
301 | |||
302 | int ptype = 0; |
||
303 | 00c9fe94 | Eric Allman | const char *ptag = NULL; |
304 | 062cb614 | Eric Allman | switch (md_id)
|
305 | { |
||
306 | case GDP_MD_XID:
|
||
307 | 00c9fe94 | Eric Allman | ptag = "external id";
|
308 | 062cb614 | Eric Allman | ptype = 1;
|
309 | break;
|
||
310 | case GDP_MD_NONCE:
|
||
311 | 00c9fe94 | Eric Allman | ptag = "nonce";
|
312 | ptype = 2;
|
||
313 | 062cb614 | Eric Allman | break;
|
314 | case GDP_MD_CTIME:
|
||
315 | 00c9fe94 | Eric Allman | ptag = "creation time";
|
316 | 062cb614 | Eric Allman | ptype = 1;
|
317 | break;
|
||
318 | case GDP_MD_EXPIRE:
|
||
319 | 00c9fe94 | Eric Allman | ptag = "expiration time";
|
320 | 062cb614 | Eric Allman | ptype = 1;
|
321 | break;
|
||
322 | case GDP_MD_CREATOR:
|
||
323 | 00c9fe94 | Eric Allman | ptag = "creator";
|
324 | 062cb614 | Eric Allman | ptype = 1;
|
325 | break;
|
||
326 | case GDP_MD_PUBKEY:
|
||
327 | 00c9fe94 | Eric Allman | ptag = "public key, deprecated";
|
328 | 062cb614 | Eric Allman | break;
|
329 | case GDP_MD_OWNERPUBKEY:
|
||
330 | 00c9fe94 | Eric Allman | ptag = "owner public key";
|
331 | 062cb614 | Eric Allman | break;
|
332 | case GDP_MD_WRITERPUBKEY:
|
||
333 | 00c9fe94 | Eric Allman | ptag = "writer public key";
|
334 | 062cb614 | Eric Allman | break;
|
335 | default:
|
||
336 | 00c9fe94 | Eric Allman | printf(" 0x%08x len %zd ", md_id, md_len);
|
337 | 062cb614 | Eric Allman | break;
|
338 | } |
||
339 | a5c31c76 | Eric Allman | printf(" %22s ", ptag == NULL ? "" : ptag); |
340 | 062cb614 | Eric Allman | switch (ptype)
|
341 | { |
||
342 | case 1: |
||
343 | 00c9fe94 | Eric Allman | // print as string
|
344 | printf("%s", EpChar->lquote);
|
||
345 | 062cb614 | Eric Allman | ep_xlate_out(md_data, md_len, stdout, "",
|
346 | EP_XLATE_PLUS | EP_XLATE_NPRINT); |
||
347 | 00c9fe94 | Eric Allman | printf("%s\n", EpChar->rquote);
|
348 | break;
|
||
349 | |||
350 | case 2: |
||
351 | // print as hex
|
||
352 | ep_hexdump(md_data, md_len, stdout, EP_HEXDUMP_TERSE, 0);
|
||
353 | break;
|
||
354 | |||
355 | default:
|
||
356 | printf("(omitted)\n");
|
||
357 | 062cb614 | Eric Allman | break;
|
358 | } |
||
359 | } |
||
360 | goto done;
|
||
361 | } |
||
362 | |||
363 | fe9fd7f9 | Eric Allman | if (plev >= 3) |
364 | 062cb614 | Eric Allman | printf("\n\n----------------------------------------------------------\n");
|
365 | printf("%s: %" PRIgdp_recno " recs\n", log_pname, gob->nrecs); |
||
366 | be19c14d | Eric Allman | uint32_t pflags = GDP_DATUM_PRMETAONLY; |
367 | fe9fd7f9 | Eric Allman | if (plev >= 3) |
368 | be19c14d | Eric Allman | { |
369 | pflags |= GDP_DATUM_PRSIG; |
||
370 | pr_verbose_metadata(gob, plev); |
||
371 | } |
||
372 | fe9fd7f9 | Eric Allman | if (plev >= 5) |
373 | be19c14d | Eric Allman | pflags &= ~GDP_DATUM_PRMETAONLY; |
374 | |||
375 | // now dump the contents
|
||
376 | fe9fd7f9 | Eric Allman | if (plev >= 4) |
377 | be19c14d | Eric Allman | { |
378 | printf("\n --------------- Data ---------------\n");
|
||
379 | uintptr_t intptrpflags = pflags; |
||
380 | estat = sqlite_read_by_recno(gob, 1, UINT32_MAX, show_rec,
|
||
381 | (void *) intptrpflags);
|
||
382 | } |
||
383 | |||
384 | fe9fd7f9 | Eric Allman | if (false) |
385 | { |
||
386 | char ebuf[60]; |
||
387 | be19c14d | Eric Allman | fail0:
|
388 | fe9fd7f9 | Eric Allman | fprintf(stderr, "%s: %s\n",
|
389 | log_pname, ep_stat_tostr(estat, ebuf, sizeof ebuf));
|
||
390 | } |
||
391 | done:
|
||
392 | if (gob != NULL) |
||
393 | _gdp_gob_free(&gob); |
||
394 | be19c14d | Eric Allman | return estat;
|
395 | } |
||
396 | |||
397 | |||
398 | int
|
||
399 | list_logs(const char *gcl_dir_name, int plev) |
||
400 | { |
||
401 | DIR *dir; |
||
402 | int subdir;
|
||
403 | gdp_name_t gcl_iname; |
||
404 | |||
405 | ep_dbg_cprintf(Dbg, 11, "list_logs(%s)\n", gcl_dir_name); |
||
406 | dir = opendir(gcl_dir_name); |
||
407 | if (dir == NULL) |
||
408 | { |
||
409 | fprintf(stderr, "Could not open %s, errno = %d\n",
|
||
410 | gcl_dir_name, errno); |
||
411 | return EX_NOINPUT;
|
||
412 | } |
||
413 | closedir(dir); |
||
414 | |||
415 | for (subdir = 0; subdir < 0x100; subdir++) |
||
416 | { |
||
417 | char dbuf[400]; |
||
418 | |||
419 | snprintf(dbuf, sizeof dbuf, "%s/_%02x", gcl_dir_name, subdir); |
||
420 | dir = opendir(dbuf); |
||
421 | if (dir == NULL) |
||
422 | continue;
|
||
423 | |||
424 | for (;;)
|
||
425 | { |
||
426 | struct dirent *dent;
|
||
427 | |||
428 | // read the next directory entry
|
||
429 | c70b1607 | Eric Allman | dent = readdir(dir); |
430 | be19c14d | Eric Allman | if (dent == NULL) |
431 | break;
|
||
432 | |||
433 | // we're only interested in .data files
|
||
434 | char *p = strrchr(dent->d_name, '.'); |
||
435 | if (p == NULL || strcmp(p, GLOG_SUFFIX) != 0) |
||
436 | continue;
|
||
437 | |||
438 | // save the full pathname in case we need it
|
||
439 | snprintf(dbuf, sizeof dbuf, "%s/_%02x/%s", |
||
440 | gcl_dir_name, subdir, dent->d_name); |
||
441 | |||
442 | // strip off the ".db"
|
||
443 | *p = '\0';
|
||
444 | |||
445 | // print the name and maybe other info
|
||
446 | gdp_parse_name(dent->d_name, gcl_iname); |
||
447 | show_log(gcl_iname, plev); |
||
448 | } |
||
449 | closedir(dir); |
||
450 | } |
||
451 | |||
452 | return EX_OK;
|
||
453 | } |
||
454 | |||
455 | |||
456 | void
|
||
457 | usage(const char *msg) |
||
458 | { |
||
459 | fprintf(stderr, |
||
460 | "Usage error: %s\n"
|
||
461 | 612f6b6a | Eric Allman | "Usage: log-view [-d dir] [-D dbgspec ] [-l] [-r] [-v] [log_name ...]\n"
|
462 | be19c14d | Eric Allman | "\t-d dir -- set log database root directory\n"
|
463 | "\t-D spec -- set debug flags\n"
|
||
464 | 612f6b6a | Eric Allman | "\t-l -- list all local logs\n"
|
465 | "\t-n -- only list logs with no metadata\n"
|
||
466 | be19c14d | Eric Allman | "\t-v -- print verbose information (-vv for more detail)\n",
|
467 | msg); |
||
468 | |||
469 | exit(EX_USAGE); |
||
470 | } |
||
471 | |||
472 | int
|
||
473 | main(int argc, char *argv[]) |
||
474 | { |
||
475 | int opt;
|
||
476 | int verbosity = 0; |
||
477 | bool ls_logs = false; |
||
478 | char *log_xname = NULL; |
||
479 | const char *log_dir_name = NULL; |
||
480 | EP_STAT estat; |
||
481 | |||
482 | // ep_lib_init(0);
|
||
483 | |||
484 | while ((opt = getopt(argc, argv, "d:D:lnv")) > 0) |
||
485 | { |
||
486 | switch (opt)
|
||
487 | { |
||
488 | case 'd': |
||
489 | log_dir_name = optarg; |
||
490 | break;
|
||
491 | |||
492 | case 'D': |
||
493 | ep_dbg_set(optarg); |
||
494 | break;
|
||
495 | |||
496 | case 'l': |
||
497 | ls_logs = true;
|
||
498 | break;
|
||
499 | |||
500 | case 'v': |
||
501 | verbosity++; |
||
502 | break;
|
||
503 | |||
504 | default:
|
||
505 | usage("unknown flag");
|
||
506 | } |
||
507 | } |
||
508 | argc -= optind; |
||
509 | argv += optind; |
||
510 | |||
511 | // initialization
|
||
512 | e6bd4828 | Eric Allman | estat = gdp_init_phase_0(NULL, 0); |
513 | 612f6b6a | Eric Allman | EP_STAT_CHECK(estat, goto fail0);
|
514 | be19c14d | Eric Allman | ep_adm_readparams("gdplogd");
|
515 | 0e2c49f6 | Eric Allman | _gdp_name_init(NULL);
|
516 | be19c14d | Eric Allman | |
517 | // initialize logd_sqlite
|
||
518 | estat = sqlite_init(log_dir_name); |
||
519 | EP_STAT_CHECK(estat, goto fail0);
|
||
520 | |||
521 | if (ls_logs)
|
||
522 | { |
||
523 | if (argc > 0) |
||
524 | 612f6b6a | Eric Allman | usage("cannot use a log name with -l");
|
525 | be19c14d | Eric Allman | return list_logs(LogDir, verbosity);
|
526 | } |
||
527 | |||
528 | if (argc <= 0) |
||
529 | 612f6b6a | Eric Allman | usage("log name required");
|
530 | be19c14d | Eric Allman | for (; argc > 0; argc--, argv++) |
531 | { |
||
532 | gdp_name_t log_name; |
||
533 | log_xname = argv[0];
|
||
534 | |||
535 | estat = gdp_parse_name(log_xname, log_name); |
||
536 | if (!EP_STAT_ISOK(estat))
|
||
537 | { |
||
538 | 612f6b6a | Eric Allman | ep_app_message(estat, "unparsable log name");
|
539 | be19c14d | Eric Allman | continue;
|
540 | } |
||
541 | estat = show_log(log_name, verbosity); |
||
542 | } |
||
543 | fail0:
|
||
544 | if (EP_STAT_ISFAIL(estat))
|
||
545 | exit(EX_UNAVAILABLE); |
||
546 | exit(EX_OK); |
||
547 | } |