home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3340 / faillog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-17  |  4.9 KB  |  254 lines

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