home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / A / PS / PROCPS-0.000 / PROCPS-0 / procps-0.97 / xproc / XConsole.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-15  |  7.3 KB  |  261 lines

  1. /*************************************************************************
  2.  * 
  3.  * A short X-windows program to display kernel messages in a window.
  4.  * Created because xterm -C doesn't work in linux, and its nice to
  5.  * see error messages when a mount or mtools operation fails, etc.
  6.  *
  7.  * Written by Robert Nation (nation@rocket.sanders.lockheed.com) 2/93.
  8.  *
  9.  * This file Copyright 1992 Robert J. Nation 
  10.  * It may be distributed under the GNU Public License, version 2, or
  11.  * any higher version.  See section COPYING of the GNU Public license
  12.  * for conditions under which this file may be redistributed.
  13.  *
  14.  * Note: this is my first X-windows program. If I did it all wrong, please
  15.  * tell me.
  16.  *************************************************************************/
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/utsname.h>
  21. #include <unistd.h>
  22. #include <time.h>
  23.  
  24. #include <fcntl.h>
  25. #include <X11/Intrinsic.h>
  26. #include <X11/StringDefs.h>
  27. #include <X11/Xaw/Form.h>
  28. #include <X11/Xaw/Text.h>
  29. #include <X11/Xaw/AsciiText.h>
  30. #include <X11/Xaw/Label.h>
  31. #include <X11/Xaw/Command.h>
  32.  
  33. Widget toplevel;
  34. Widget logwindow,compwindow,timewindow,quitbutton;
  35. XtAppContext app_con;
  36.  
  37. /* file descriptor for the kernel /proc/kmsg file */
  38. int kmsg=0;
  39.  
  40. /* Items used to retrieve the system name */
  41. #define UTSLENGTH 64
  42. char line[UTSLENGTH*3+10];
  43. struct utsname name;
  44. char tbuf[50];
  45.  
  46. /* file descriptor for the log file */
  47. FILE *logfd = (FILE *)0;
  48.  
  49.  
  50. /***************************************************************************
  51.  * 
  52.  * This subroutine gets called at most once per minute to update the time.
  53.  * It is called by a time-out callback 
  54.  *
  55.  **************************************************************************/
  56. void print_date(client_data, id)
  57. XtPointer client_data;
  58. XtIntervalId *id;
  59. {
  60.   time_t tp;
  61.   struct tm *curtime;
  62.   Arg arg[10];
  63.   int nargs;
  64.  
  65.   time(&tp);
  66.   curtime = localtime(&tp);
  67.   strftime(tbuf,49,"%a %b %d %H:%M %Y",curtime);
  68.   nargs=0;
  69.   XtSetArg( arg[nargs], XtNlabel, tbuf);nargs++;
  70.   XtSetValues( timewindow, (ArgList)arg, nargs);
  71.   XtAppAddTimeOut(app_con,60000,print_date,NULL);
  72. }
  73.  
  74. /***************************************************************************
  75.  * 
  76.  * This subroutine gets called when the user presses the quit button.
  77.  * It closes the open files and exits.
  78.  *
  79.  **************************************************************************/
  80. void quit_callback(widget,closure,callData)
  81.      Widget widget;
  82.      caddr_t closure;
  83.      caddr_t callData;
  84. {
  85.   close(kmsg);
  86.   fclose(logfd);
  87.   exit(0);
  88. }
  89.  
  90.  
  91. /***************************************************************************
  92.  * 
  93.  * This subroutine gets called when there is some input waiting in 
  94.  * /proc/kmsg 
  95.  *
  96.  **************************************************************************/
  97. void handle_kmsg_input(client_data, source, id)
  98. caddr_t client_data;
  99. int source;
  100. XtInputId id;
  101. {
  102.    XawTextPosition pos1;
  103.    XawTextBlock tt;
  104.    int chars_read,nargs,i;
  105.    Arg arg[10];
  106.  
  107.    /* read the input */
  108.    chars_read =read(kmsg,line,99);
  109.    /* make sure that there really was something to read */
  110.    if(chars_read < 1)
  111.      return;
  112.  
  113.    /* Get rid of Carriage returns, since they cause double-spacing */
  114.    for(i=0;i<chars_read;i++)
  115.      if(line[i]==13)
  116.        {
  117.      strcpy(&line[i],&line[i+1]);
  118.      chars_read--;
  119.        }
  120.    line[chars_read]=0;
  121.    tt.firstPos = 0;
  122.    tt.ptr = line;
  123.    tt.length = strlen(tt.ptr);
  124.    if(line[0]=='\r')
  125.      {
  126.        tt.length--;
  127.        tt.ptr++;
  128.      }
  129.  
  130.    tt.format = FMT8BIT;
  131.  
  132.    /* decide where to put the text */
  133.    pos1 = XawTextGetInsertionPoint(logwindow);
  134.    pos1 += tt.length;
  135.  
  136.    /* display it */
  137.    nargs=0;
  138.    XtSetArg( arg[nargs], XtNinsertPosition, pos1); nargs++;
  139.    XtSetValues( logwindow, (ArgList)arg, nargs);
  140.    XawTextReplace(logwindow, pos1, pos1, &tt);
  141.  
  142.    /* if the log file is open, send message there, too */
  143.    if(logfd != (FILE *)0)
  144.      {
  145.        fprintf(logfd,line);
  146.        fflush(logfd);
  147.      }
  148. }
  149.  
  150. /***************************************************************************
  151.  * 
  152.  * Main routine. Opens windows and files, sets up callback routines
  153.  *
  154.  **************************************************************************/
  155. void main(int argc, char **argv)
  156. {
  157.   int nargs,i;
  158.   Arg arg[10];
  159.   time_t tp;
  160.   struct tm *curtime;
  161.   static XtCallbackRec callback[2];
  162.  
  163.   /* open /proc/kmsg. Exit if the open fails */
  164.   kmsg = open("/proc/kmsg",O_RDONLY);
  165.   if(kmsg < 0)
  166.     {
  167.       fprintf(stderr,"Unable to open /proc/kmsg\n");
  168.       exit(1);
  169.     }
  170.  
  171.   /* check to see if a log file was specified.
  172.    * If specified, try to open it. If the open fails, print a warning and 
  173.    * continue */
  174.   for(i=1;i<argc;i++)
  175.     {
  176.       if(strcmp(argv[i],"-log")==0)
  177.     {
  178.       if(i<argc-1)
  179.         {
  180.           logfd=fopen(argv[i+1],"a");
  181.           if(logfd==(FILE *)0)
  182.         {
  183.           fprintf(stderr,"Unable to open log file %s\n",argv[i+1]);
  184.           exit(1);
  185.         }
  186.         }
  187.       else
  188.         {
  189.           fprintf(stderr,"Log file name not found in command line\n");
  190.           exit(1);
  191.         }
  192.     }
  193.     }
  194.       
  195.   /* get the system name and kernel release number */
  196.   uname(&name);
  197.   sprintf(line,"%s Console (%s %s)",name.nodename,name.sysname,name.release);
  198.  
  199.   /* By replacing argv[0] with the system name line, it shows up in the 
  200.    * window's title bar. The must be a better way to do this */
  201.   argv[0]=line;
  202.   
  203.  
  204.   toplevel = XtAppInitialize( &app_con, "Linux Console", NULL, 0, &argc, argv,
  205.               NULL,NULL,0);
  206.  
  207.   /* create a window to hold all the sub-windows */
  208.   compwindow = XtCreateManagedWidget( "Composite", formWidgetClass,
  209.                      toplevel,(ArgList)0,0);
  210.  
  211.   /* create a window to display the time, and put the current
  212.    * time in it*/
  213.   time(&tp);
  214.   curtime = localtime(&tp);
  215.   strftime(tbuf,49,"%a %b %d %H:%M %Y",curtime);
  216.   nargs=0;
  217.   XtSetArg( arg[nargs], XtNwidth, 180 );nargs++;
  218.   XtSetArg( arg[nargs], XtNlabel, tbuf);nargs++;
  219.   XtSetArg( arg[nargs], XtNvertDistance, 2);nargs++;
  220.   XtSetArg( arg[nargs], XtNhorizDistance, 2);nargs++;
  221.   timewindow = XtCreateManagedWidget( "Composite", labelWidgetClass,
  222.                      compwindow,arg, nargs);
  223.  
  224.   /* create a quit button */
  225.   nargs=0;
  226.   callback[0].callback = quit_callback;
  227.   callback[0].closure = (caddr_t)toplevel;
  228.   XtSetArg( arg[nargs], XtNcallback, callback );nargs++;
  229.   XtSetArg( arg[nargs], XtNfromHoriz, timewindow );nargs++;
  230.   XtSetArg( arg[nargs], XtNvertDistance, 2);nargs++;
  231.   XtSetArg( arg[nargs], XtNhorizDistance, 2);nargs++;
  232.   quitbutton =
  233.     XtCreateManagedWidget("quit ", commandWidgetClass, compwindow, arg, nargs);
  234.  
  235.   /* create a window, with a scroll-bar, to display the kernel messages in */
  236.   nargs=0;
  237.   XtSetArg( arg[nargs], XtNeditType, XtEtextEdit );nargs++;
  238.   XtSetArg( arg[nargs], XtNwidth, 495 );nargs++;
  239.   XtSetArg( arg[nargs], XtNheight, 44);nargs++;
  240.   XtSetArg( arg[nargs], XtNscrollVertical,XawtextScrollAlways);nargs++;
  241.   XtSetArg( arg[nargs], XtNfromVert,timewindow);nargs++;
  242.   XtSetArg( arg[nargs], XtNvertDistance, 2);nargs++;
  243.   XtSetArg( arg[nargs], XtNhorizDistance, 2);nargs++;
  244.   logwindow = XtCreateManagedWidget( "Console", asciiTextWidgetClass, 
  245.                      compwindow, arg, nargs);
  246.   
  247.   /* display the whole thing */
  248.   XtRealizeWidget(toplevel);
  249.  
  250.   /* add a callback for when there is input in /proc/kmsg */
  251.   XtAppAddInput(app_con,kmsg, (XtPointer)XtInputReadMask, 
  252.         handle_kmsg_input, NULL);
  253.  
  254.   /* add a time-out callback once a minute for the time
  255.    * when the system is heavily loaded, the callbacks can
  256.    * become less frequent. */
  257.   XtAppAddTimeOut(app_con,60000,print_date,NULL);
  258.  
  259.   XtAppMainLoop(app_con);
  260. }
  261.