/*+ * $Header: /home/vikas/src/nocol/netconsole/RCS/netconsole.c,v 2.8 1999/11/01 05:39:37 vikas Exp $ */ /* * * To DISPLAY the output from various NOCOL monitoring programs. * Uses curses for screen management and display. * * The design of the program is such that it displays ALL the files in * the DATA directory one after another in a cycle. As an option , the * data directory can be displayed on the command line. * * A separate window for the events and another for the messages are * created. The message window can scroll and is for sending debug or * any other messages that might be needed in the future. A separate * routine 'msg_dpy' is called for the message 's display. * * AUTHOR: * * Vikas Aggarwal, vikas@navya.com * */ /* Copyright 1992 JvNCnet */ /* Copyright 1994 Vikas Aggarwal, vikas@navya.com */ /* * $Log: netconsole.c,v $ * Revision 2.8 1999/11/01 05:39:37 vikas * Added -T cmd line option to specify terminal type. * * Revision 2.7 1998/08/13 15:30:16 vikas * Added environment variable NOCOL_SEVERITY checking (jonz@netrail.net) * * Revision 2.6 1998/07/31 18:22:48 vikas * Added INTSIGNALS * * Revision 2.5 1994/11/29 20:40:34 vikas * Updated as netconsole for v4.0 * * Revision 2.4 1994/06/12 18:09:35 vikas * Deleted the 'options' variable and set debug/quiet/emode to * be simple integers instead. * * Revision 2.2 1994/01/18 18:01:38 aggarwal * Added 'silent' option to prevent *any* form of beeping. Command line * flag only. * * Revision 2.1 1993/10/30 03:53:11 aggarwal * Fixed the definitions of the signal handlers * * Revision 2.0 1992/06/18 21:05:21 aggarwal * Additional features for releasing: * o window resizing * o terminal setup * * Revision 1.8 1992/05/14 12:34:41 aggarwal * Number of major fixes: * - moved get_reply() to above main so types were defined * before being called in 'main()' * - setuserenviron() sprintf was missing terminal '\0' * - set_terminal() extensively modified. * * Revision 1.4 1990/04/05 17:47:02 aggarwal * Was doing a 'endwin()' in Error even though initscr() had not been * called. Got rid of that. Extended the help a bit. * * Revision 1.1 90/03/09 13:06:18 aggarwal * Initial revision * */ #ifndef lint static char rcsid[] = "$RCSfile: netconsole.c,v $ $Revision: 2.8 $ $Date: 1999/11/01 05:39:37 $" ; #endif /*+ ** INCLUDES */ #include "netconsole.h" /* application specific */ /* * global variables */ char *good_terminals[] = { GOODTERMINALS, "" } ; char *bad_terminals[] = { BADTERMINALS, "" } ; main (ac, av) int ac; char **av; { extern char *optarg; extern int optind; register int i ; /* temporary counter */ void done(), wsizechange(); /* for signals */ char *envlevel; char term[MAXLINE]; #ifdef _NOCOLVERSION_ fprintf (stderr, "NOCOL version %s\n\n", nocol_version); fflush (stderr); #endif /* * Set the initial values of variables */ prognm = av[0] ; /* program name */ datadir = DATADIR ; msgsdir = MSGSDIR ; helpfile = HELPFILE ; eventsz = 0; /* Init value important */ page = 1; /* init value */ level = E_CRITICAL; /* default severity */ term[0] = '\0'; /* allow environment variable to set the default display level */ if ( (envlevel = (char *)getenv("NOCOL_SEVERITY")) != NULL) { switch (*envlevel) { case 'C': case 'c': level = E_CRITICAL ; break; case 'E': case 'e': level = E_ERROR; break; case 'W': case 'w': level = E_WARNING; break; case 'I': case 'i': level = E_INFO; break; } } while ((i = getopt(ac, av, "dewl:qsT:")) != EOF) switch (i) { case 'd': debug = 1; /* debug */ break ; case 'w': case 'e': /* expanded/wide display */ emode = 1; break; case 'l': /* level */ sscanf(optarg, "%d", &level) ; break; case 'q': /* no initial beep */ quiet = 1; break ; case 's': /* never beep */ silent = 1; break; case 'T': strncpy(term, optarg, sizeof(term)); /* cmd line term type */ break; case '?': default: fprintf(stderr, "%s: unknown flag: %c\n", prognm, i); goto Error ; } /* end switch */ switch ( ac - optind ) { case 0: /* default data dir */ break ; case 1: datadir = av[optind] ; /* alternate data dir */ break ; default: goto Error; /* more than one data dir */ } /* * Setup to catch ALL signals except SIGUSR1/SIGUSR2 for security * purposes. */ for (i = 0 ; i < SIGUSR1 ; ++i ) signal (i, done); if (setuserenviron(term) == -1) /* check the user environment */ { /* .. specifically for TERM */ perror ("setuserenv"); exit (1); } all_doer(); /* the main do'er */ if (entered_curses) endwin (); /* This point never reached */ perror (prognm); exit (1); Error: usage (); /* No 'endwin' here */ exit (1); } /* end 'main' */ /*+ usage ** FUNCTION ** Display short message on usage of the program **/ #ifndef Fprintf #define Fprintf(s) fprintf(stderr, s ) #endif usage() { static char usage[]="[-d (debug)] [-q (quiet)] [-l level] [-w (wide)] [-s (silent)] [-T termtype] [data dir]"; fprintf (stderr, "\nUSAGE: %s %s\n\n", prognm, usage); fprintf(stderr, "Data directory is: %s\n", datadir); Fprintf("To verify terminal type, turn debug mode on and\n"); Fprintf("then toggle between wide display mode (using w)\n"); Fprintf("You can set your shell environment variable NOCOL_SEVERITY \n"); Fprintf("to the initial desired level (Critical, Error, Warning, Info)\n"); Fprintf("\n"); return (0); } /* end usage() */ /*+ wsizechange ** FUNCTION: ** Function to catch window size change signals (in xterm, etc.) ** After getting the signal, the system blocks all further occurences of ** the signal until the function returns. However, if calling all_doer, ** this function never really returns, but calls all_doer() directly. ** So remember to unblock the SIGWINCH in case calling all_doer directly. **/ void wsizechange() { #ifdef TIOCGWINSZ static struct winsize win ; /* 4.3 BSD window sizing */ #endif #ifdef TIOCGWINSZ if (ioctl(1, TIOCGWINSZ, (char *) &win) == 0 ) { if (win.ws_row > 0) LINES = win.ws_row ; if (win.ws_col > 0) COLS = win.ws_col ; } #endif if (entered_curses) { endwin() ; /* get out of curses and start over */ tputs(clscr, 1, outchar); /* clear the screen */ fflush(stdout); } /* * Now reset any special variables for setup_display() and return. * If calling 'all_doer' (doesn't return), remember to reset signal */ eventsz = 0 ; /* so that new size is reset */ setup_display() ; display_screenful() ; /* put stuff back on screen */ } /* end wsizechange */ /*+ all_doer ** FUNCTION: ** This is the main doer. It creates all the necessary windows ** and then repeatedly calls the 'build_display()' routine to display ** all the data. This is made as a separate routine from main so that ** options can be changed and this function can be called directly ** without going thru main() again. **/ all_doer() { entered_curses = 1 ; /* so done can call endwin() */ #ifdef SIGWINCH /* catch window size change signals */ # ifdef INTSIGNALS if (signal(SIGWINCH, wsizechange) == (void *)-1) perror("couldn't set signal for SIGWINCH- "); # else signal(SIGWINCH, wsizechange); # endif #endif setup_display(); /* Just creates all the windows */ return (build_display()); /* Display all files forever */ } /* end: all_doer() */ /*+ done ** FUNCTION ** Close up and die. **/ void done() { echo(); if (entered_curses) /* else kills the login window */ endwin(); printf ("\n\n"); exit(0); }