home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1963 < prev    next >
Internet Message Format  |  1990-12-28  |  9KB

  1. From: cs00chs@unccvax.uncc.edu (charles spell)
  2. Newsgroups: alt.sources
  3. Subject: watch.c - Trash the last copy...this one passed lint...Ooops.
  4. Message-ID: <2849@unccvax.uncc.edu>
  5. Date: 17 Oct 90 00:03:52 GMT
  6.  
  7. This seems to satisfy lint and the more picky compliers...ignore any warnings.
  8. Trash last version....to compile: cc -o watch watch.c -lcurses.
  9. --cut here--
  10. /******************************************************************************
  11. *  This program is freely distributable as long as there has been no changes
  12. *  applied to this file. Bugs, comments, suggestions:uunet!mcnc!unccvax!cs00chs
  13. *     If you find this program useful in part or in whole, please send a
  14. *     contribution to John J. Ribera, Jr. If there is enough monetary interest,
  15. *     fixes and upgrades will be available (see address below).
  16. */
  17. #include <signal.h>
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <utmp.h>
  22. #include <time.h>
  23. /******************************************************************************
  24. * NAME
  25. *     watch(1-att) - watch for mail, time, and users logging in (SystemV)
  26. *
  27. * SYNOPSIS
  28. *     att watch [users...] [ttylines...] [&]
  29. *
  30. * DESCRIPTION
  31. *     watch will notify the you if there is mail, when new mail arrives,
  32. *     display the current time, and notify you of any user logging on or off
  33. *     the system. On dual universe machines this program must be compiled and
  34. *     run in the att universe. The terminal this is run on must have the tsl=
  35. *     and fsl= capabilities to work properly. It helps if ws# is in terminfo
  36. *     also. tsl= is the sequence to go to the status line, fsl= is the
  37. *     sequence to return from status line (cursor position should be restored
  38. *     by this sequence). ws# should be the maximum number of characters that
  39. *     can be displayed on the status line. See your terminal reference manual
  40. *     for these values (and TERMINFO(5) on how to apply them).
  41. *
  42. *     If there are users and/or ttylines specified on the command line, only
  43. *     those users and/or lines will be checked for logins/logouts, otherwise
  44. *     ANY login/logout will be displayed.
  45. *     To disable watch and clear the status line, use:
  46. *            kill <pid>
  47. *     where <pid> is the process id of the watch program. Do not kill
  48. *     watch(1-att) with a -9 value, i.e., the status line will not be cleared.
  49. *
  50. * EXAMPLES
  51. *     watch &
  52. *        - this watches for all users logging in or out of the system.
  53. *
  54. *     watch jjr smith tty01 tty03 &
  55. *        - this will watch for users with 'jjr' and 'smith' as well as those
  56. *          logging in tty01 and tty03.
  57. *
  58. * WARNINGS
  59. *     Be sure to run watch(1) with an att preceeding the watch command on dual
  60. *     universe systems. Be careful not to run watch in the backround more than
  61. *     once.  To compile type: cc watch.c -o watch -ltermlib (the att universe
  62. *     on dual universe machines).
  63. *
  64. * BUGS
  65. *     Most of the time you will want to execute watch in the backround. The
  66. *     logout seems to be closing the tty faster than the clear status line
  67. *     sequence can be sent in some cases.
  68. *     Try putting this in your .logout: sleep 2
  69. *
  70. * AUTHOR
  71. *
  72. *     clt2!jjr
  73. *     John J. Ribera Jr.
  74. *     9505-J University Terrace Drive
  75. *     Charlotte, NC 28262
  76. *     Voice: (704) 549-5571
  77. *
  78. *     If you find this program useful in part or in whole, please send a
  79. *     contribution to John J. Ribera, Jr. If there is enough monetary interest,
  80. *     fixes and upgrades will be available.
  81. */
  82.  
  83. #define MAX_PORT    512
  84. #define UTMP        "/etc/utmp"
  85. #define ST_MAIL     0
  86. #define ST_DATE     9
  87. #define ST_LOGIN    26
  88. #define ST_WIDTH    37
  89. #define MAIL_DIR    "/usr/spool/mail"
  90.  
  91. #define MAIL        "    MAIL"
  92. #define NEW_MAIL    "NEW MAIL"
  93. #define CLR_MAIL    "        "
  94.  
  95. char    watchfor[2048];
  96. char    St_line[256];
  97. char    Termb[1024];
  98. char    Ts[80];
  99. char    Fs[80];
  100. short   Ws;
  101. char    *tgetstr();
  102. int     tgetent();
  103. int     tgetnum();
  104. int     tputs();
  105.  
  106. main(argc, argv)
  107. int     argc;
  108. char    **argv;
  109. {
  110. struct  utmp    curr[MAX_PORT + 1];
  111. struct  utmp    last[MAX_PORT + 1];
  112. struct  stat    statb, save_mail;
  113.         long    last_mtime;
  114.         long    last_time;
  115.         char    mailfile[256];
  116.         char    *login;
  117.         char    *strcpy();
  118.         char    *getenv();
  119.         char    *getlogin();
  120.         char    *ctime();
  121.         char    *memcpy();
  122.         char    *strstr();
  123.         char    *strcat();
  124.         char    *gettstr();
  125.         char    **getpwuid();
  126.         short   i, j, k, l;
  127.         short   watchcnt;
  128.         short   read_utmp();
  129.         int     memcmp();
  130.         void    disp_utmp();
  131.         void    disp_chng();
  132.         void    disp_stat();
  133.         void    done();
  134.  
  135. signal(SIGINT, done);
  136. signal(SIGQUIT, done);
  137. signal(SIGTERM, done);
  138. signal(SIGHUP, done);
  139. for (watchfor[0] = '\0', watchcnt = --argc; argc; --argc)
  140.     strcat(strcat(watchfor, *++argv), " ");
  141. /* Initialize termcaps for going to/from status line and intensity  */
  142. if (tgetent(Termb, getenv("TERM")) != 1)
  143.     fprintf(stderr, "\nUnable to find terminfo data"), exit(1);
  144. if (!*strcpy(Ts, gettstr("tsl")) || !*strcpy(Fs, gettstr("fsl")))
  145.     fprintf(stderr, "\nNeed status line caps - tsl=, and fsl=."), exit(1);
  146. if ((Ws = tgetnum("ws")) == -1 && (Ws = tgetnum("co")) == -1)
  147.     Ws = 80;
  148. /* Initialize everything for loop below...get current utmp entries  */
  149. sprintf(St_line, "%-*.*s", Ws, Ws, "");
  150. last_time = time((long *) 0);
  151. memcpy(&St_line[ST_DATE], ctime(&last_time), 16);
  152. disp_stat(St_line);
  153. if ((login = getenv("LOGNAME")) == NULL && (login = getenv("USER")) == NULL &&
  154.     (login = getlogin()) == NULL && !*(login = *getpwuid(getuid())))
  155.     fprintf(stderr, "\nUnable to find you"), exit(1);
  156. sprintf(mailfile, "%s/%s", MAIL_DIR, login);
  157. l = read_utmp(last);
  158. if (stat(UTMP, &statb) < 0)
  159.     fprintf(stderr, "\nUnable to stat utmp file."), exit(1);
  160.  
  161. for (last_mtime = statb.st_mtime; stat(UTMP, &statb) == 0; sleep(1))
  162.     {
  163.     if (statb.st_mtime > last_mtime)
  164.         {
  165.         last_mtime = statb.st_mtime;
  166.         for (i = k = read_utmp(curr); i; i--)
  167.             for (j = l; j; j--)
  168.                 if (!watchcnt ||
  169.                     (strstr(watchfor, curr[i-1].ut_line) ||
  170.                      strstr(watchfor, curr[i-1].ut_user) ||
  171.                      strstr(watchfor, last[j-1].ut_line) ||
  172.                      strstr(watchfor, last[j-1].ut_user)))
  173.                      if (!strcmp(curr[i-1].ut_line, last[j-1].ut_line))
  174.                         if (last[j-1].ut_type != curr[i-1].ut_type)
  175.                             disp_chng(&last[j-1], &curr[j-1]);
  176.         memcpy(last, curr, sizeof(curr));
  177.         l = k;
  178.         }
  179.     if ((last_time / 60) != (time((long *) 0) / 60))
  180.         {
  181.         if (!((last_time = time((long *) 0)) % 3600))
  182.             putchar('\007');
  183.         memcpy(&St_line[ST_DATE], ctime(&last_time), 16);
  184.         disp_stat(St_line);
  185.         }
  186.     if (stat(mailfile, &statb) != 0)
  187.         fprintf(stderr, "Unable to stat %s", mailfile), exit(1);
  188.     if (memcmp(&save_mail, &statb, sizeof(statb)))
  189.         {
  190.         memcpy(&St_line[ST_MAIL], CLR_MAIL, strlen(CLR_MAIL));
  191.         disp_stat(St_line);
  192.         if (statb.st_mtime >= statb.st_atime && statb.st_size > 1)
  193.             {
  194.             memcpy(&St_line[ST_MAIL], NEW_MAIL, strlen(NEW_MAIL));
  195.             putchar('\007');
  196.             }
  197.         else if (statb.st_size > 1)
  198.             memcpy(&St_line[ST_MAIL], MAIL, strlen(MAIL));
  199.         disp_stat(St_line);
  200.         memcpy(&save_mail, &statb, sizeof(statb));
  201.         }
  202.     if (getppid() == 1)
  203.         done();
  204.     }
  205. return(0);
  206. }
  207.  
  208. void
  209. disp_chng(last, curr)
  210. struct  utmp    *last;
  211. struct  utmp    *curr;
  212. {
  213. if (last->ut_type != USER_PROCESS && curr->ut_type == USER_PROCESS)
  214.     sprintf(&St_line[ST_LOGIN], "%-8.8s on %s", curr->ut_user, curr->ut_line);
  215. if (last->ut_type == USER_PROCESS && curr->ut_type != USER_PROCESS)
  216.     sprintf(&St_line[ST_LOGIN], "%-8.8s off %s", last->ut_user, last->ut_line);
  217. memcpy(last, curr, sizeof(*last));
  218. disp_stat(St_line);
  219. }
  220.  
  221. void
  222. disp_stat(stat_line)
  223. char    *stat_line;
  224. {
  225.     int     outc();
  226.     char    hold[256];
  227.  
  228. tputs(Ts, 1, outc);
  229. strcpy(hold, stat_line);
  230. sprintf(stat_line, "%-*.*s", Ws-1, Ws-1, hold);
  231. fwrite(stat_line, strlen(stat_line), 1, stdout);
  232. tputs(Fs, 1, outc);
  233. fflush(stdout);
  234. }
  235.  
  236. short
  237. read_utmp(utmps)
  238. struct  utmp    *utmps;
  239. {
  240.         FILE    *fp;
  241.         short   i;
  242.  
  243. if ((fp = fopen(UTMP, "r")) == (FILE *) NULL)
  244.     fprintf(stderr, "\nUnable to read utmp file."), (void)exit(1);
  245. i = (short) fread(utmps, sizeof(*utmps), MAX_PORT, fp);
  246. fclose(fp);
  247. return(i);
  248. }
  249.  
  250. void
  251. done()
  252. {
  253. disp_stat("");
  254. exit(0);
  255. }
  256.  
  257. char    *
  258. gettstr(id)
  259. char    *id;
  260. {
  261. static  char    tstr[256];
  262.         char    *ptr;
  263.  
  264. ptr = tstr;
  265. strcpy(tstr, tgetstr(id, &ptr));
  266. if (ptr == tstr)
  267.     *tstr = '\0';
  268. return(tstr);
  269. }
  270.  
  271. int
  272. outc(c)
  273. char    c;
  274. {
  275. fwrite(&c, 1, 1, stdout);
  276. }
  277. --cut here--
  278. -- 
  279.  .--------------------------.  ...  |On the border of your mind lies a place
  280.  |uunet!mcnc!unccvax!cs00chs|  (")  |where dreams and reality are one...I will 
  281.  `--------------------------'-w-U-w-|take you there, for I am the subject...
  282.  \%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\|the subject of your imagination. -Aldo Nova
  283.