|
|
1.1 root 1: /* uulog.c
2: Display the UUCP log file.
3:
4: Copyright (C) 1991, 1992 Ian Lance Taylor
5:
6: This file is part of the Taylor UUCP package.
7:
8: This program is free software; you can redistribute it and/or
9: modify it under the terms of the GNU General Public License as
10: published by the Free Software Foundation; either version 2 of the
11: License, or (at your option) any later version.
12:
13: This program is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16: General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with this program; if not, write to the Free Software
20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucp.h"
27:
28: #if USE_RCS_ID
29: const char uulog_rcsid[] = "$Id: uulog.c,v 1.1 93/07/30 07:59:04 bin Exp Locker: bin $";
30: #endif
31:
32: #include <ctype.h>
33: #include <errno.h>
34:
35: #include "getopt.h"
36:
37: #include "uudefs.h"
38: #include "uuconf.h"
39: #include "system.h"
40:
41: /* This is a pretty bad implementation of uulog, which I don't think
42: is a very useful program anyhow. It only takes a single -s and/or
43: -u switch. When using HAVE_HDB_LOGGING it requires a system. */
44:
45: /* The program name. */
46: char abProgram[] = "uulog";
47:
48: /* Local functions. */
49:
50: static void ulusage P((void));
51:
52: /* Long getopt options. */
53: static const struct option asLlongopts[] = { { NULL, 0, NULL, 0 } };
54:
55: int
56: main (argc, argv)
57: int argc;
58: char **argv;
59: {
60: /* -D: display Debug file */
61: boolean fdebug = FALSE;
62: /* -f: keep displaying lines forever. */
63: boolean fforever = FALSE;
64: /* -n lines: number of lines to display. */
65: int cshow = 0;
66: /* -s: system name. */
67: const char *zsystem = NULL;
68: /* -S: display Stats file */
69: boolean fstats = FALSE;
70: /* -u: user name. */
71: const char *zuser = NULL;
72: /* -I: configuration file name. */
73: const char *zconfig = NULL;
74: /* -x: display uuxqt log file. */
75: boolean fuuxqt = FALSE;
76: int i;
77: int iopt;
78: pointer puuconf;
79: int iuuconf;
80: const char *zlogfile;
81: const char *zstatsfile;
82: const char *zdebugfile;
83: const char *zfile;
84: FILE *e;
85: char **pzshow = NULL;
86: int ishow = 0;
87: size_t csystem = 0;
88: size_t cuser = 0;
89: char *zline;
90: size_t cline;
91:
92: /* Look for a straight number argument, and convert it to -n before
93: passing the arguments to getopt. */
94: for (i = 0; i < argc; i++)
95: {
96: if (argv[i][0] == '-' && isdigit (argv[i][1]))
97: {
98: size_t clen;
99: char *znew;
100:
101: clen = strlen (argv[i]);
102: znew = zbufalc (clen + 2);
103: znew[0] = '-';
104: znew[1] = 'n';
105: memcpy (znew + 2, argv[i] + 1, clen);
106: argv[i] = znew;
107: }
108: }
109:
110: while ((iopt = getopt_long (argc, argv, "Df:FI:n:s:Su:xX:", asLlongopts,
111: (int *) NULL)) != EOF)
112: {
113: switch (iopt)
114: {
115: case 'D':
116: /* Show debugging file. */
117: fdebug = TRUE;
118: break;
119:
120: case 'f':
121: /* Keep displaying lines forever for a particular system. */
122: fforever = TRUE;
123: zsystem = optarg;
124: if (cshow == 0)
125: cshow = 10;
126: break;
127:
128: case 'F':
129: /* Keep displaying lines forever. */
130: fforever = TRUE;
131: if (cshow == 0)
132: cshow = 10;
133: break;
134:
135: case 'I':
136: /* Configuration file name. */
137: if (fsysdep_other_config (optarg))
138: zconfig = optarg;
139: break;
140:
141: case 'n':
142: /* Number of lines to display. */
143: cshow = (int) strtol (optarg, (char **) NULL, 10);
144: break;
145:
146: case 's':
147: /* System name. */
148: zsystem = optarg;
149: break;
150:
151: case 'S':
152: /* Show statistics file. */
153: fstats = TRUE;
154: break;
155:
156: case 'u':
157: /* User name. */
158: zuser = optarg;
159: break;
160:
161: case 'x':
162: /* Display uuxqt log file. */
163: fuuxqt = TRUE;
164: break;
165:
166: case 'X':
167: #if DEBUG > 1
168: /* Set debugging level. */
169: iDebug |= idebug_parse (optarg);
170: #endif
171: break;
172:
173: case 0:
174: /* Long option found and flag set. */
175: break;
176:
177: default:
178: ulusage ();
179: break;
180: }
181: }
182:
183: if (optind != argc || (fstats && fdebug))
184: ulusage ();
185:
186: iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
187: if (iuuconf != UUCONF_SUCCESS)
188: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
189:
190: #if DEBUG > 1
191: {
192: const char *zdebug;
193:
194: iuuconf = uuconf_debuglevel (puuconf, &zdebug);
195: if (iuuconf != UUCONF_SUCCESS)
196: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
197: if (zdebug != NULL)
198: iDebug |= idebug_parse (zdebug);
199: }
200: #endif
201:
202: iuuconf = uuconf_logfile (puuconf, &zlogfile);
203: if (iuuconf != UUCONF_SUCCESS)
204: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
205:
206: iuuconf = uuconf_statsfile (puuconf, &zstatsfile);
207: if (iuuconf != UUCONF_SUCCESS)
208: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
209:
210: iuuconf = uuconf_debugfile (puuconf, &zdebugfile);
211: if (iuuconf != UUCONF_SUCCESS)
212: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
213:
214: usysdep_initialize (puuconf, 0);
215:
216: if (zsystem != NULL)
217: {
218: #if HAVE_HDB_LOGGING
219: if (strcmp (zsystem, "ANY") != 0)
220: #endif
221: {
222: struct uuconf_system ssys;
223:
224: iuuconf = uuconf_system_info (puuconf, zsystem, &ssys);
225: if (iuuconf != UUCONF_SUCCESS)
226: {
227: if (iuuconf != UUCONF_NOT_FOUND)
228: ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
229: ulog (LOG_FATAL, "%s: System not found", zsystem);
230: }
231: zsystem = zbufcpy (ssys.uuconf_zname);
232: (void) uuconf_system_free (puuconf, &ssys);
233: }
234: }
235:
236: if (fstats)
237: zfile = zstatsfile;
238: else if (fdebug)
239: zfile = zdebugfile;
240: else
241: {
242: #if ! HAVE_HDB_LOGGING
243: zfile = zlogfile;
244: #else
245: const char *zprogram;
246: char *zalc;
247:
248: /* We need a system to find a HDB log file. */
249: if (zsystem == NULL)
250: ulusage ();
251:
252: if (fuuxqt)
253: zprogram = "uuxqt";
254: else
255: zprogram = "uucico";
256:
257: zalc = zbufalc (strlen (zlogfile)
258: + strlen (zprogram)
259: + strlen (zsystem)
260: + 1);
261: sprintf (zalc, zlogfile, zprogram, zsystem);
262: zfile = zalc;
263:
264: if (strcmp (zsystem, "ANY") == 0)
265: zsystem = NULL;
266: #endif
267: }
268:
269: e = fopen (zfile, "r");
270: if (e == NULL)
271: {
272: ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
273: usysdep_exit (FALSE);
274: }
275:
276: if (cshow > 0)
277: {
278: pzshow = (char **) xmalloc (cshow * sizeof (char *));
279: for (ishow = 0; ishow < cshow; ishow++)
280: pzshow[ishow] = NULL;
281: ishow = 0;
282: }
283:
284: /* Read the log file and output the appropriate lines. */
285: if (zsystem != NULL)
286: csystem = strlen (zsystem);
287:
288: if (zuser != NULL)
289: cuser = strlen (zuser);
290:
291: zline = NULL;
292: cline = 0;
293:
294: while (TRUE)
295: {
296: while (getline (&zline, &cline, e) > 0)
297: {
298: char *zluser, *zlsys, *znext;
299: size_t cluser, clsys;
300:
301: /* Skip any leading whitespace (not that there should be
302: any). */
303: znext = zline + strspn (zline, " \t");
304:
305: if (! fstats)
306: {
307: #if ! HAVE_TAYLOR_LOGGING
308: /* The user name is the first field on the line. */
309: zluser = znext;
310: cluser = strcspn (znext, " \t");
311: #endif
312:
313: /* Skip the first field. */
314: znext += strcspn (znext, " \t");
315: znext += strspn (znext, " \t");
316:
317: /* The system is the second field on the line. */
318: zlsys = znext;
319: clsys = strcspn (znext, " \t");
320:
321: /* Skip the second field. */
322: znext += clsys;
323: znext += strspn (znext, " \t");
324:
325: #if HAVE_TAYLOR_LOGGING
326: /* The user is the third field on the line. */
327: zluser = znext;
328: cluser = strcspn (znext, " \t");
329: #endif
330: }
331: else
332: {
333: #if ! HAVE_HDB_LOGGING
334: /* The user name is the first field on the line, and the
335: system name is the second. */
336: zluser = znext;
337: cluser = strcspn (znext, " \t");
338: znext += cluser;
339: znext += strspn (znext, " \t");
340: zlsys = znext;
341: clsys = strcspn (znext, " \t");
342: #else
343: /* The first field is system!user. */
344: zlsys = znext;
345: clsys = strcspn (znext, "!");
346: znext += clsys + 1;
347: zlsys = znext;
348: clsys = strcspn (znext, " \t");
349: #endif
350: }
351:
352: /* See if we should print this line. */
353: if (zsystem != NULL
354: && (csystem != clsys
355: || strncmp (zsystem, zlsys, clsys) != 0))
356: continue;
357:
358: if (zuser != NULL
359: && (cuser != cluser
360: || strncmp (zuser, zluser, cluser) != 0))
361: continue;
362:
363: /* Output the line, or save it if we are outputting only a
364: particular number of lines. */
365: if (cshow <= 0)
366: printf ("%s", zline);
367: else
368: {
369: ubuffree ((pointer) pzshow[ishow]);
370: pzshow[ishow] = zbufcpy (zline);
371: ishow = (ishow + 1) % cshow;
372: }
373: }
374:
375: /* Output the number of lines requested by the -n option. */
376: if (cshow > 0)
377: {
378: for (i = 0; i < cshow; i++)
379: {
380: if (pzshow[ishow] != NULL)
381: printf ("%s", pzshow[ishow]);
382: ishow = (ishow + 1) % cshow;
383: }
384: }
385:
386: /* If -f was not specified, or an error occurred while reading
387: the file, get out. */
388: if (! fforever || ferror (e))
389: break;
390:
391: clearerr (e);
392: cshow = 0;
393:
394: /* Sleep 1 second before going around the loop again. */
395: usysdep_sleep (1);
396: }
397:
398: (void) fclose (e);
399:
400: ulog_close ();
401:
402: usysdep_exit (TRUE);
403:
404: /* Avoid errors about not returning a value. */
405: return 0;
406: }
407:
408: /* Print a usage message and die. */
409:
410: static void
411: ulusage ()
412: {
413: fprintf (stderr,
414: "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n",
415: VERSION);
416: fprintf (stderr,
417: "Usage: uulog [-n #] [-sf system] [-u user] [-xDSF] [-I file] [-X debug]\n");
418: fprintf (stderr,
419: " -n: show given number of lines from end of log\n");
420: fprintf (stderr,
421: " -s: print entries for named system\n");
422: fprintf (stderr,
423: " -f: follow entries for named system\n");
424: fprintf (stderr,
425: " -u: print entries for named user\n");
426: #if HAVE_HDB_LOGGING
427: fprintf (stderr,
428: " -x: print uuxqt log rather than uucico log\n");
429: #else
430: fprintf (stderr,
431: " -F: follow entries for any system\n");
432: #endif
433: fprintf (stderr,
434: " -S: show statistics file\n");
435: fprintf (stderr,
436: " -D: show debugging file\n");
437: fprintf (stderr,
438: " -X debug: Set debugging level (0 for none, 9 is max)\n");
439: #if HAVE_TAYLOR_CONFIG
440: fprintf (stderr,
441: " -I file: Set configuration file to use\n");
442: #endif /* HAVE_TAYLOR_CONFIG */
443: exit (EXIT_FAILURE);
444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.