home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2287 / faillog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  4.7 KB  |  251 lines

  1. /*
  2.  * Copyright 1989, 1990, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Use, duplication, and disclosure prohibited without
  6.  * the express written permission of the author.
  7.  */
  8.  
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <stdio.h>
  12. #include <pwd.h>
  13. #include <time.h>
  14. #ifndef    BSD
  15. #include <string.h>
  16. #include <memory.h>
  17. #else
  18. #include <strings.h>
  19. #define    strchr    index
  20. #define    strrchr    rindex
  21. #endif
  22. #include "config.h"
  23. #include "faillog.h"
  24.  
  25. #ifndef    lint
  26. static    char    _sccsid[] = "@(#)faillog.c    2.2    19:23:44    7/29/90";
  27. #endif
  28.  
  29. FILE    *fail;        /* failure file stream */
  30. off_t    user;        /* one single user, specified on command line */
  31. int    days;        /* number of days to consider for print command */
  32. time_t    seconds;    /* that number of days in seconds */
  33. int    max;        /* maximum failure count for fail_max */
  34.  
  35. int    mflg;        /* set fail_max for a given user */
  36. int    rflg;        /* reset fail_cnt for user or all user's */
  37. int    uflg;        /* set if user is a valid user id */
  38. int    tflg;        /* print is restricted to most recent days */
  39. struct    faillog    faillog; /* scratch structure to play with ... */
  40. struct    stat    statbuf; /* fstat buffer for file size */
  41.  
  42. extern    int    optind;
  43. extern    char    *optarg;
  44. extern    char    *asctime ();
  45. extern    struct    passwd    *getpwuid ();
  46. extern    struct    passwd    *getpwnam ();
  47. extern    struct    passwd    *getpwent ();
  48. extern    struct    tm    *localtime ();
  49.  
  50. #define    DAY    (24L*3600L)
  51. #define    NOW    (time ((time_t *) 0))
  52.  
  53. main (argc, argv)
  54. int    argc;
  55. char    **argv;
  56. {
  57.     char    *mode;
  58.     int    uid = 0;
  59.     int    c;
  60.     struct    passwd    *pwent;
  61.  
  62.     if (getuid () == 0)    /* only root can update anything */
  63.         mode = "r+";
  64.     else            /* all others can only look */
  65.         mode = "r";
  66.  
  67.     if ((fail = fopen (FAILFILE, mode)) == (FILE *) 0) {
  68.         perror (FAILFILE);
  69.         exit (1);
  70.     }
  71.     while ((c = getopt (argc, argv, "m:pru:t:")) != EOF) {
  72.         switch (c) {
  73.             case 'm':
  74.                 max = atoi (optarg);
  75.                 setmax ();
  76.                 break;
  77.             case 'p':
  78.                 print ();
  79.                 break;
  80.             case 'r':
  81.                 reset ();
  82.                 break;
  83.             case 'u':
  84.                 pwent = getpwnam (optarg);
  85.                 if (! pwent) {
  86.                     fprintf (stderr, "Unknown User: %s\n", optarg);
  87.                     exit (1);
  88.                 }
  89.                 uflg++;
  90.                 user = pwent->pw_uid;
  91.                 break;
  92.             case 't':
  93.                 days = atoi (optarg);
  94.                 seconds = days * DAY;
  95.                 tflg++;
  96.                 break;
  97.         }
  98.     }
  99.     fclose (fail);
  100.     exit (0);
  101. }
  102.  
  103. print ()
  104. {
  105.     int    uid;
  106.     off_t    offset;
  107.  
  108.     if (uflg) {
  109.         offset = user * sizeof faillog;
  110.         fstat (fileno (fail), &statbuf);
  111.         if (offset >= statbuf.st_size)
  112.             return;
  113.  
  114.         fseek (fail, (off_t) user * sizeof faillog, 0);
  115.         if (fread ((char *) &faillog, sizeof faillog, 1, fail) == 1)
  116.             print_one (&faillog, user);
  117.         else
  118.             perror (FAILFILE);
  119.     } else {
  120.         for (uid = 0;
  121.             fread ((char *) &faillog, sizeof faillog, 1, fail) == 1;
  122.                 uid++) {
  123.  
  124.             if (faillog.fail_cnt == 0)
  125.                 continue;
  126.  
  127.             if (tflg && NOW - faillog.fail_time > seconds)
  128.                 continue;
  129.  
  130.             print_one (&faillog, uid);
  131.         }
  132.     }
  133. }
  134.  
  135. print_one (faillog, uid)
  136. struct    faillog    *faillog;
  137. {
  138.     static    int    once;
  139.     char    *cp;
  140.     struct    tm    *tm;
  141.     struct    passwd    *pwent;
  142.  
  143.     if (! once) {
  144.         printf ("Username        Failures    Maximum     Latest\n");
  145.         once++;
  146.     }
  147.     pwent = getpwuid (uid);
  148.     tm = localtime (&faillog->fail_time);
  149.     cp = asctime (tm);
  150.     cp[24] = '\0';
  151.  
  152.     if (pwent) {
  153.         printf ("%-16s    %4d       %4d",
  154.             pwent->pw_name, faillog->fail_cnt, faillog->fail_max);
  155.         if (faillog->fail_time)
  156.             printf ("     %s on %s\n", cp, faillog->fail_line);
  157.         else
  158.             putchar ('\n');
  159.     }
  160. }
  161.  
  162. reset ()
  163. {
  164.     int    uid = 0;
  165.  
  166.     if (uflg)
  167.         reset_one (user);
  168.     else
  169.         for (uid = 0;reset_one (uid);uid++)
  170.             ;
  171. }
  172.  
  173. reset_one (uid)
  174. int    uid;
  175. {
  176.     off_t    offset;
  177.  
  178.     offset = uid * sizeof faillog;
  179.     fstat (fileno (fail), &statbuf);
  180.     if (offset >= statbuf.st_size)
  181.         return (0);
  182.  
  183.     if (fseek (fail, offset, 0) != 0) {
  184.         perror (FAILFILE);
  185.         return (0);
  186.     }
  187.     if (fread ((char *) &faillog, sizeof faillog, 1, fail) != 1) {
  188.         if (! feof (fail))
  189.             perror (FAILFILE);
  190.  
  191.         return (0);
  192.     }
  193.     if (faillog.fail_cnt == 0)
  194.         return (1);    /* don't fill in no holes ... */
  195.  
  196.     faillog.fail_cnt = 0;
  197.  
  198.     if (fseek (fail, offset, 0) == 0
  199.         && fwrite ((char *) &faillog, sizeof faillog, 1, fail) == 1) {
  200.         fflush (fail);
  201.         return (1);
  202.     } else {
  203.         perror (FAILFILE);
  204.     }
  205.     return (0);
  206. }
  207.  
  208. setmax ()
  209. {
  210.     int    uid = 0;
  211.     struct    passwd    *pwent;
  212.  
  213.     if (uflg) {
  214.         setmax_one (user);
  215.     } else {
  216.         setpwent ();
  217.         while (pwent = getpwent ())
  218.             setmax_one (pwent->pw_uid);
  219.     }
  220. }
  221.  
  222. setmax_one (uid)
  223. int    uid;
  224. {
  225.     off_t    offset;
  226.  
  227.     offset = uid * sizeof faillog;
  228.  
  229.     if (fseek (fail, offset, 0) != 0) {
  230.         perror (FAILFILE);
  231.         return;
  232.     }
  233.     if (fread ((char *) &faillog, sizeof faillog, 1, fail) != 1) {
  234.         if (! feof (fail))
  235.             perror (FAILFILE);
  236.     } else {
  237. #ifndef    BSD
  238.         memset ((char *) &faillog, '\0', sizeof faillog);
  239. #else
  240.         bzero ((char *) &faillog, sizeof faillog);
  241. #endif
  242.     }
  243.     faillog.fail_max = max;
  244.  
  245.     if (fseek (fail, offset, 0) == 0
  246.         && fwrite ((char *) &faillog, sizeof faillog, 1, fail) == 1)
  247.         fflush (fail);
  248.     else
  249.         perror (FAILFILE);
  250. }
  251.