diff options
Diffstat (limited to 'src/util/pty/dump-utmp.c')
-rw-r--r-- | src/util/pty/dump-utmp.c | 362 |
1 files changed, 249 insertions, 113 deletions
diff --git a/src/util/pty/dump-utmp.c b/src/util/pty/dump-utmp.c index 7cc8469..d4c303f 100644 --- a/src/util/pty/dump-utmp.c +++ b/src/util/pty/dump-utmp.c @@ -1,6 +1,29 @@ -#include <stdio.h> +/* + * Copyright 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * dump-utmp.c: dump utmp and utmpx format files for debugging purposes. + */ + +#include <sys/types.h> #include <sys/file.h> #include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> #ifndef UTMPX #ifdef HAVE_UTMPX_H @@ -8,138 +31,251 @@ #endif #endif +#if defined(HAVE_UTMPNAME) || defined(HAVE_UTMPXNAME) +#define UTN /* we can set utmp or utmpx for getut*() */ +#endif + #ifdef UTMPX #include <utmpx.h> +void print_utx(int, const struct utmpx *); #endif #include <utmp.h> -extern char *ctime (); +void print_ut(int, const struct utmp *); + +void usage(const char *); #if defined (HAVE_STRUCT_UTMP_UT_TYPE) || defined (UTMPX) -char *ut_typename (t) { - switch (t) { +char *ut_typename(int); + +char * +ut_typename(int t) { + switch (t) { #define S(N) case N : return #N #define S2(N,N2) case N : return #N2 - S(EMPTY); - S(RUN_LVL); - S(BOOT_TIME); - S(OLD_TIME); - S(NEW_TIME); - S2(INIT_PROCESS,INIT); - S2(LOGIN_PROCESS,LOGIN); - S2(USER_PROCESS,USER); - S2(DEAD_PROCESS,DEAD); - S(ACCOUNTING); - default: return "??"; - } + S(EMPTY); + S(RUN_LVL); + S(BOOT_TIME); + S(OLD_TIME); + S(NEW_TIME); + S2(INIT_PROCESS,INIT); + S2(LOGIN_PROCESS,LOGIN); + S2(USER_PROCESS,USER); + S2(DEAD_PROCESS,DEAD); + S(ACCOUNTING); + default: return "??"; + } } #endif -int main (argc, argv) int argc; char *argv[]; { - int f; - char id[5], user[50], host[100]; - char *file = 0; - int all = 0; - int is_utmpx = 0; - - while (*++argv) - { - char *arg = *argv; - if (!arg) - break; - if (!strcmp ("-a", arg)) - all = 1; - else if (!strcmp ("-x", arg)) - is_utmpx = 1; - else if (arg[0] == '-') - { - fprintf (stderr, "unknown arg `%s'\n", arg); - return 1; - } - else if (file) - { - fprintf (stderr, "already got a file\n"); - return 1; +#define S2D(x) (sizeof(x) * 2.4 + 1.5) + +void +print_ut(int all, const struct utmp *u) +{ + int lu, ll; +#ifdef HAVE_STRUCT_UTMP_UT_ID + int lid; +#endif +#ifdef HAVE_STRUCT_UTMP_UT_PID + int lpid; +#endif +#ifdef PTY_UTMP_E_EXIT + int let, lee; +#endif + +#ifdef HAVE_STRUCT_UTMP_UT_TYPE + if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) + return; +#endif + + lu = sizeof(u->ut_name); + ll = sizeof(u->ut_line); + printf("%-*.*s:", lu, lu, u->ut_name); + printf("%-*.*s:", ll, ll, u->ut_line); +#ifdef HAVE_STRUCT_UTMP_UT_ID + lid = sizeof(u->ut_id); + printf("%-*.*s:", lid, lid, u->ut_id); +#endif +#ifdef HAVE_STRUCT_UTMP_UT_PID + lpid = S2D(u->ut_pid); + printf("%*ld", lpid, (long)u->ut_pid); +#endif +#ifdef PTY_UTMP_E_EXIT + let = S2D(u->ut_exit.PTY_UTMP_E_TERMINATION); + lee = S2D(u->ut_exit.PTY_UTMP_E_EXIT); + printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMP_E_TERMINATION); + printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMP_E_EXIT); +#endif +#ifdef HAVE_STRUCT_UTMP_UT_TYPE + printf(" %-9s", ut_typename(u->ut_type)); +#endif + printf(" %s", ctime(&u->ut_time) + 4); +#ifdef HAVE_STRUCT_UTMP_UT_HOST + if (u->ut_host[0]) + printf(" %.*s\n", (int) sizeof(u->ut_host), u->ut_host); +#endif + + return; +} + +#ifdef UTMPX +void +print_utx(int all, const struct utmpx *u) +{ + int lu, ll, lid, lpid; +#ifdef PTY_UTMPX_E_EXIT + int let, lee; +#endif + + if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) + return; + + lu = sizeof(u->ut_user); + ll = sizeof(u->ut_line); + lid = sizeof(u->ut_id); + printf("%-*.*s:", lu, lu, u->ut_user); + printf("%-*.*s:", ll, ll, u->ut_line); + printf("%-*.*s", lid, lid, u->ut_id); + if (lu + ll + lid >= 60) + printf("\n"); + else + printf(":"); + lpid = S2D(u->ut_pid); + printf("%*ld", lpid, (long)u->ut_pid); +#ifdef PTY_UTMPX_E_EXIT + let = S2D(u->ut_exit.PTY_UTMPX_E_TERMINATION); + lee = S2D(u->ut_exit.PTY_UTMPX_E_EXIT); + printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMPX_E_TERMINATION); + printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMPX_E_EXIT); +#endif + printf(" %-9s", ut_typename(u->ut_type)); + printf(" %s", ctime(&u->ut_tv.tv_sec) + 4); +#ifdef HAVE_STRUCT_UTMPX_UT_HOST + if (u->ut_host[0]) + printf(" %s\n", u->ut_host); +#endif + + return; +} +#endif + +#ifdef UTMPX +#define OPTX "x" +#else +#define OPTX +#endif +#ifdef UTN +#define OPTG "g" +#else +#define OPTG +#endif +#define OPTS "a" OPTX OPTG + +void +usage(const char *prog) +{ + fprintf(stderr, "usage: %s [-" OPTS "] file\n", prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + int c; + int all, is_utmpx, do_getut; + int f; + char *fn; + size_t recsize; + size_t nread; + union { + struct utmp ut; +#ifdef UTMPX + struct utmpx utx; +#endif + } u; + + all = is_utmpx = do_getut = 0; + recsize = sizeof(struct utmp); + + while ((c = getopt(argc, argv, OPTS)) != EOF) { + switch (c) { + case 'a': + all = 1; + break; +#ifdef UTMPX + case 'x': + is_utmpx = 1; + recsize = sizeof(struct utmpx); + break; +#endif +#ifdef UTN + case 'g': + do_getut = 1; + break; +#endif + default: + usage(argv[0]); } - else - file = arg; } - f = open (file, O_RDONLY); - if (f < 0) { - perror (file); - exit (1); - } - id[4] = 0; - if (is_utmpx) { + if (argc <= optind) + usage(argv[0]); + fn = argv[optind]; + if (!do_getut) { + f = open(fn, O_RDONLY); + if (f == -1) { + perror(fn); + exit(1); + } + while ((nread = read(f, &u, recsize)) > 0) { + if (nread < recsize) { + fprintf(stderr, "short read"); + close(f); + exit(1); + } + if (is_utmpx) { #ifdef UTMPX - struct utmpx u; - while (1) { - int nread = read (f, &u, sizeof (u)); - if (nread == 0) { - /* eof */ - return 0; - } else if (nread == -1) { - /* error */ - perror ("read"); - return 1; - } - if ((u.ut_type == DEAD_PROCESS - || u.ut_type == EMPTY) - && !all) - continue; - strncpy (id, u.ut_id, 4); - printf ("%-8s:%-12s:%-4s", u.ut_user, u.ut_line, id); - printf (":%5d", u.ut_pid); - printf ("(%5d,%5d)", u.ut_exit.e_termination, u.ut_exit.e_exit); - printf (" %-9s %s", ut_typename (u.ut_type), ctime (&u.ut_xtime) + 4); - if (u.ut_syslen && u.ut_host[0]) - printf (" %s\n", u.ut_host); - } - abort (); + print_utx(all, &u.utx); #else - fprintf (stderr, "utmpx support not compiled in\n"); - return 1; -#endif - } - /* else */ - { - struct utmp u; - while (read (f, &u, sizeof (u)) == sizeof (u)) { -#ifdef EMPTY - if ((u.ut_type == DEAD_PROCESS - || u.ut_type == EMPTY) - && !all) - continue; + abort(); #endif -#ifdef HAVE_STRUCT_UTMP_UT_PID - strncpy (id, u.ut_id, 4); - strncpy (user, u.ut_user, sizeof (u.ut_user)); - user[sizeof(u.ut_user)] = 0; - printf ("%-8s:%-12s:%-4s", user, u.ut_line, id); - printf (":%5d", u.ut_pid); + } else { + print_ut(all, &u.ut); + } + } + if (nread == -1) { + perror("read"); + exit(1); + } + close(f); + } else { + if (is_utmpx) { +#ifdef UTMPX +#ifdef HAVE_UTMPXNAME + struct utmpx *utxp; + utmpxname(fn); + setutxent(); + while ((utxp = getutxent()) != NULL) + print_utx(all, utxp); #else - strncpy (user, u.ut_name, sizeof (u.ut_name)); - user[sizeof(u.ut_name)] = 0; - printf ("%-8s:%-12s", user, u.ut_line); -#endif -#ifdef HAVE_STRUCT_UTMP_UT_HOST - { - char host[sizeof (u.ut_host) + 1]; - strncpy (host, u.ut_host, sizeof(u.ut_host)); - host[sizeof (u.ut_host)] = 0; - printf (":%-*s", sizeof (u.ut_host), host); - } + fprintf(stderr, "no utmpxname(); can't use getutxent()\n"); + exit(1); #endif -#ifdef HAVE_STRUCT_UTMP_UT_EXIT - printf ("(%5d,%5d)", u.ut_exit.e_termination, u.ut_exit.e_exit); +#else + abort(); #endif -#ifdef HAVE_STRUCT_UTMP_UT_TYPE - printf (" %-9s", ut_typename (u.ut_type)); + } else { +#ifdef HAVE_UTMPNAME + struct utmp *utp; + utmpname(fn); + setutxent(); + while ((utp = getutent()) != NULL) + print_ut(all, utp); +#else + fprintf(stderr, "no utmpname(); can't use getutent()\n"); + exit(1); #endif - /* this ends with a newline */ - printf (" %s", ctime (&u.ut_time) + 4); + } } - } - - return 0; + exit(0); } |