home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / shadow / patch04a < prev    next >
Encoding:
Text File  |  1992-04-03  |  45.4 KB  |  2,090 lines

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F Haugh II)
  3. Subject:  v29i047:  shadow - Shadow Login Suite, Patch04a/3
  4. Message-ID: <csm-v29i047=shadow.142525@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 99fd634501ccdecc9d773b63c7e01497
  6. Date: Fri, 3 Apr 1992 20:27:23 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jfh@rpp386.cactus.org (John F Haugh II)
  10. Posting-number: Volume 29, Issue 47
  11. Archive-name: shadow/patch04a
  12. Environment: UNIX
  13. Patch-To: shadow: Volume 26, Issue 54-64
  14.  
  15. This is the first part of a three part patch.  It brings the shadow password
  16. suite from version 3.1.3 to 3.1.4 (patchlevel 17).  You must collect all
  17. three parts before attempting to re-compile everything.  The most significant
  18. change, other than the usual collection of incremental bug fixes, is the
  19. addition of initial support for SVR4.
  20.  
  21. Here is a summary of the other changes -
  22.  
  23. Correct problems which prevent code from compiling on SunOS 4.1.1
  24.  
  25. Login sets UID to user's value before executing /bin/passwd when password
  26.     had expired.  Forces user to adhere to password policy.
  27.  
  28. chage command now accepts account expiration and last password changed
  29.     dates in MM/DD/YY format (optionally compilable for DD/MM/YY or YY/MM/DD
  30.     as well)
  31.  
  32. chage command is now installed set-uid root with non-root users only being
  33.     able to view password aging information.  Intended to aid in knowing
  34.     when account or password is due to expire.
  35.  
  36. Added concept of a "tty" group.  Allows login to set the group ownership of
  37.     user's TTY at login time.
  38.  
  39. Added support to define value of arg[0] after su.  Fixes problems with
  40.     certain shells.
  41. --
  42. Prereq: "3.1.3"
  43. Index: patchlevel.h
  44. *** rel3/patchlevel.h    Fri Mar 27 10:25:49 1992
  45. --- patchlevel.h    Fri Mar 27 10:26:02 1992
  46. ***************
  47. *** 1,5 ****
  48.   /*
  49. !  * Copyright 1991, John F. Haugh II
  50.    * All rights reserved.
  51.    *
  52.    * Permission is granted to copy and create derivative works for any
  53. --- 1,5 ----
  54.   /*
  55. !  * Copyright 1991, 1992, John F. Haugh II
  56.    * All rights reserved.
  57.    *
  58.    * Permission is granted to copy and create derivative works for any
  59. ***************
  60. *** 15,22 ****
  61.    *        Bugs found by users
  62.    *    12/28/91    3.1.3    patchlevel 16
  63.    *        Changes for SunOS 4.1.1
  64.    */
  65.   
  66.   #define    RELEASE        3
  67. ! #define    PATCHLEVEL    16
  68. ! #define    VERSION        "3.1.3"
  69. --- 15,24 ----
  70.    *        Bugs found by users
  71.    *    12/28/91    3.1.3    patchlevel 16
  72.    *        Changes for SunOS 4.1.1
  73. +  *    02/08/92    3.1.4    patchlevel 17
  74. +  *        Changes for SVR4, plus bug fixes
  75.    */
  76.   
  77.   #define    RELEASE        3
  78. ! #define    PATCHLEVEL    17
  79. ! #define    VERSION        "3.1.4"
  80. Index: age.c
  81. *** rel3/age.c    Fri Mar 27 10:22:37 1992
  82. --- age.c    Fri Mar 27 10:26:12 1992
  83. ***************
  84. *** 1,5 ****
  85.   /*
  86. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  87.    * All rights reserved.
  88.    *
  89.    * Permission is granted to copy and create derivative works for any
  90. --- 1,5 ----
  91.   /*
  92. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  93.    * All rights reserved.
  94.    *
  95.    * Permission is granted to copy and create derivative works for any
  96. ***************
  97. *** 17,23 ****
  98.   #include "shadow.h"
  99.   
  100.   #ifndef    lint
  101. ! static    char    sccsid[] = "@(#)age.c    3.5    07:43:04    9/17/91";
  102.   #endif
  103.   
  104.   #define    DAY    (24L*3600L)
  105. --- 17,23 ----
  106.   #include "shadow.h"
  107.   
  108.   #ifndef    lint
  109. ! static    char    sccsid[] = "@(#)age.c    3.6    11:09:33    2/8/92";
  110.   #endif
  111.   
  112.   #define    DAY    (24L*3600L)
  113. ***************
  114. *** 228,236 ****
  115.        */
  116.   
  117.       if ((pid = fork ()) == 0) {
  118.           execl ("/bin/passwd", "passwd", pw->pw_name, (char *) 0);
  119.           puts ("Can't execute /bin/passwd");
  120. !         exit (errno);
  121.       } else if (pid == -1) {
  122.           perror ("passwd");
  123.           exit (errno);
  124. --- 228,248 ----
  125.        */
  126.   
  127.       if ((pid = fork ()) == 0) {
  128. +         /*
  129. +          * Set the UID to be that of the user.  This causes
  130. +          * passwd to work just like it would had they executed
  131. +          * it from the command line while logged in.
  132. +          */
  133. +         if (setuid (pw->pw_uid))
  134. +             _exit (errno);
  135.           execl ("/bin/passwd", "passwd", pw->pw_name, (char *) 0);
  136.           puts ("Can't execute /bin/passwd");
  137. !         fflush (stdout);
  138. !         _exit (errno);
  139.       } else if (pid == -1) {
  140.           perror ("passwd");
  141.           exit (errno);
  142. Index: faillog.c
  143. *** rel3/faillog.c    Fri Mar 27 10:22:58 1992
  144. --- faillog.c    Fri Mar 27 10:26:14 1992
  145. ***************
  146. *** 1,5 ****
  147.   /*
  148. !  * Copyright 1989, 1990, John F. Haugh II
  149.    * All rights reserved.
  150.    *
  151.    * Permission is granted to copy and create derivative works for any
  152. --- 1,5 ----
  153.   /*
  154. !  * Copyright 1989, 1990, 1992, John F. Haugh II
  155.    * All rights reserved.
  156.    *
  157.    * Permission is granted to copy and create derivative works for any
  158. ***************
  159. *** 22,45 ****
  160.   #define    strchr    index
  161.   #define    strrchr    rindex
  162.   #endif
  163.   #include "config.h"
  164.   #include "faillog.h"
  165.   
  166.   #ifndef    lint
  167. ! static    char    _sccsid[] = "@(#)faillog.c    3.2    08:44:11    9/12/91";
  168.   #endif
  169.   
  170.   FILE    *fail;        /* failure file stream */
  171. ! off_t    user;        /* one single user, specified on command line */
  172.   int    days;        /* number of days to consider for print command */
  173.   time_t    seconds;    /* that number of days in seconds */
  174.   int    max;        /* maximum failure count for fail_max */
  175.   
  176.   int    uflg;        /* set if user is a valid user id */
  177.   int    tflg;        /* print is restricted to most recent days */
  178. - struct    faillog    faillog; /* scratch structure to play with ... */
  179.   struct    stat    statbuf; /* fstat buffer for file size */
  180.   
  181.   extern    int    optind;
  182.   extern    char    *optarg;
  183.   extern    char    *asctime ();
  184. --- 22,52 ----
  185.   #define    strchr    index
  186.   #define    strrchr    rindex
  187.   #endif
  188. + #ifdef    STDLIB_H
  189. + #include <stdlib.h>
  190. + #endif
  191. + #ifdef    UNISTD_H
  192. + #include <unistd.h>
  193. + #endif
  194.   #include "config.h"
  195.   #include "faillog.h"
  196.   
  197.   #ifndef    lint
  198. ! static    char    _sccsid[] = "@(#)faillog.c    3.3    20:36:23    3/7/92";
  199.   #endif
  200.   
  201.   FILE    *fail;        /* failure file stream */
  202. ! uid_t    user;        /* one single user, specified on command line */
  203.   int    days;        /* number of days to consider for print command */
  204.   time_t    seconds;    /* that number of days in seconds */
  205.   int    max;        /* maximum failure count for fail_max */
  206.   
  207. + int    aflg;        /* set if all users are to be printed always */
  208.   int    uflg;        /* set if user is a valid user id */
  209.   int    tflg;        /* print is restricted to most recent days */
  210.   struct    stat    statbuf; /* fstat buffer for file size */
  211.   
  212. + #if !defined(UNISTD_H) && !defined(STDLIB_H)
  213.   extern    int    optind;
  214.   extern    char    *optarg;
  215.   extern    char    *asctime ();
  216. ***************
  217. *** 47,56 ****
  218. --- 54,81 ----
  219.   extern    struct    passwd    *getpwnam ();
  220.   extern    struct    passwd    *getpwent ();
  221.   extern    struct    tm    *localtime ();
  222. + #endif
  223. + #if    __STDC__
  224. + void    print(void);
  225. + void    print_one(struct faillog *faillog, uid_t uid);
  226. + void    reset(void);
  227. + int    reset_one(uid_t uid);
  228. + void    setmax(void);
  229. + void    setmax_one(uid_t uid);
  230. + #else
  231. + void    print();
  232. + void    print_one();
  233. + void    reset();
  234. + int    reset_one();
  235. + void    setmax();
  236. + void    setmax_one();
  237. + #endif /* __STDC__ */
  238.   
  239.   #define    DAY    (24L*3600L)
  240.   #define    NOW    (time ((time_t *) 0))
  241.   
  242. + void
  243.   main (argc, argv)
  244.   int    argc;
  245.   char    **argv;
  246. ***************
  247. *** 68,75 ****
  248.           perror (FAILFILE);
  249.           exit (1);
  250.       }
  251. !     while ((c = getopt (argc, argv, "m:pru:t:")) != EOF) {
  252.           switch (c) {
  253.               case 'm':
  254.                   max = atoi (optarg);
  255.                   setmax ();
  256. --- 93,104 ----
  257.           perror (FAILFILE);
  258.           exit (1);
  259.       }
  260. !     while ((c = getopt (argc, argv, "am:pru:t:")) != EOF) {
  261.           switch (c) {
  262. +             case 'a':
  263. +                 aflg++;
  264. +                 uflg = 0;
  265. +                 break;
  266.               case 'm':
  267.                   max = atoi (optarg);
  268.                   setmax ();
  269. ***************
  270. *** 87,92 ****
  271. --- 116,122 ----
  272.                       exit (1);
  273.                   }
  274.                   uflg++;
  275. +                 aflg = 0;
  276.                   user = pwent->pw_uid;
  277.                   break;
  278.               case 't':
  279. ***************
  280. *** 101,110 ****
  281.       /*NOTREACHED*/
  282.   }
  283.   
  284.   print ()
  285.   {
  286. !     int    uid;
  287.       off_t    offset;
  288.   
  289.       if (uflg) {
  290.           offset = user * sizeof faillog;
  291. --- 131,142 ----
  292.       /*NOTREACHED*/
  293.   }
  294.   
  295. + void
  296.   print ()
  297.   {
  298. !     uid_t    uid;
  299.       off_t    offset;
  300. +     struct    faillog    faillog;
  301.   
  302.       if (uflg) {
  303.           offset = user * sizeof faillog;
  304. ***************
  305. *** 122,131 ****
  306.               fread ((char *) &faillog, sizeof faillog, 1, fail) == 1;
  307.                   uid++) {
  308.   
  309. !             if (faillog.fail_cnt == 0)
  310.                   continue;
  311.   
  312. !             if (tflg && NOW - faillog.fail_time > seconds)
  313.                   continue;
  314.   
  315.               print_one (&faillog, uid);
  316. --- 154,167 ----
  317.               fread ((char *) &faillog, sizeof faillog, 1, fail) == 1;
  318.                   uid++) {
  319.   
  320. !             if (aflg == 0 && faillog.fail_cnt == 0)
  321. !                 continue;
  322. !             if (aflg == 0 && tflg &&
  323. !                     NOW - faillog.fail_time > seconds)
  324.                   continue;
  325.   
  326. !             if (aflg && faillog.fail_time == 0)
  327.                   continue;
  328.   
  329.               print_one (&faillog, uid);
  330. ***************
  331. *** 133,140 ****
  332.       }
  333.   }
  334.   
  335. ! print_one (uid)
  336. ! int    uid;
  337.   {
  338.       static    int    once;
  339.       char    *cp;
  340. --- 169,178 ----
  341.       }
  342.   }
  343.   
  344. ! void
  345. ! print_one (faillog, uid)
  346. ! struct    faillog    *faillog;
  347. ! uid_t    uid;
  348.   {
  349.       static    int    once;
  350.       char    *cp;
  351. ***************
  352. *** 146,165 ****
  353.           once++;
  354.       }
  355.       pwent = getpwuid (uid);
  356. !     tm = localtime (&faillog.fail_time);
  357.       cp = asctime (tm);
  358.       cp[24] = '\0';
  359.   
  360.       if (pwent) {
  361.           printf ("%-16s    %4d       %4d",
  362. !             pwent->pw_name, faillog.fail_cnt, faillog.fail_max);
  363. !         if (faillog.fail_time)
  364. !             printf ("     %s on %s\n", cp, faillog.fail_line);
  365.           else
  366.               putchar ('\n');
  367.       }
  368.   }
  369.   
  370.   reset ()
  371.   {
  372.       int    uid = 0;
  373. --- 184,204 ----
  374.           once++;
  375.       }
  376.       pwent = getpwuid (uid);
  377. !     tm = localtime (&faillog->fail_time);
  378.       cp = asctime (tm);
  379.       cp[24] = '\0';
  380.   
  381.       if (pwent) {
  382.           printf ("%-16s    %4d       %4d",
  383. !             pwent->pw_name, faillog->fail_cnt, faillog->fail_max);
  384. !         if (faillog->fail_time)
  385. !             printf ("     %s on %s\n", cp, faillog->fail_line);
  386.           else
  387.               putchar ('\n');
  388.       }
  389.   }
  390.   
  391. + void
  392.   reset ()
  393.   {
  394.       int    uid = 0;
  395. ***************
  396. *** 171,180 ****
  397.               ;
  398.   }
  399.   
  400.   reset_one (uid)
  401. ! int    uid;
  402.   {
  403.       off_t    offset;
  404.   
  405.       offset = uid * sizeof faillog;
  406.       fstat (fileno (fail), &statbuf);
  407. --- 210,221 ----
  408.               ;
  409.   }
  410.   
  411. + int
  412.   reset_one (uid)
  413. ! uid_t    uid;
  414.   {
  415.       off_t    offset;
  416. +     struct    faillog    faillog;
  417.   
  418.       offset = uid * sizeof faillog;
  419.       fstat (fileno (fail), &statbuf);
  420. ***************
  421. *** 206,211 ****
  422. --- 247,253 ----
  423.       return (0);
  424.   }
  425.   
  426. + void
  427.   setmax ()
  428.   {
  429.       struct    passwd    *pwent;
  430. ***************
  431. *** 219,228 ****
  432.       }
  433.   }
  434.   
  435.   setmax_one (uid)
  436. ! int    uid;
  437.   {
  438.       off_t    offset;
  439.   
  440.       offset = uid * sizeof faillog;
  441.   
  442. --- 261,272 ----
  443.       }
  444.   }
  445.   
  446. + void
  447.   setmax_one (uid)
  448. ! uid_t    uid;
  449.   {
  450.       off_t    offset;
  451. +     struct    faillog    faillog;
  452.   
  453.       offset = uid * sizeof faillog;
  454.   
  455. ***************
  456. *** 235,241 ****
  457.               perror (FAILFILE);
  458.       } else {
  459.   #ifndef    BSD
  460. !         memset ((char *) &faillog, '\0', sizeof faillog);
  461.   #else
  462.           bzero ((char *) &faillog, sizeof faillog);
  463.   #endif
  464. --- 279,285 ----
  465.               perror (FAILFILE);
  466.       } else {
  467.   #ifndef    BSD
  468. !         memset ((char *) &faillog, 0, sizeof faillog);
  469.   #else
  470.           bzero ((char *) &faillog, sizeof faillog);
  471.   #endif
  472. Index: faillog.h
  473. *** rel3/faillog.h    Fri Mar 27 10:23:24 1992
  474. --- faillog.h    Fri Mar 27 10:26:15 1992
  475. ***************
  476. *** 1,22 ****
  477.   /*
  478. !  * Copyright 1989, 1990, John F. Haugh II
  479.    * All rights reserved.
  480.    *
  481. !  * Use, duplication, and disclosure prohibited without
  482. !  * the express written permission of the author.
  483.    */
  484.   
  485.   /*
  486.    * faillog.h - login failure logging file format
  487.    *
  488. !  *    @(#)faillog.h    2.2    19:23:46    7/29/90
  489.    *
  490. !  * The login failure file is maintained by login(1) and fail(1L)
  491.    * Each record in the file represents a separate UID and the file
  492.    * is indexed in that fashion.
  493.    */
  494.   
  495.   #define    FAILFILE    "/usr/adm/faillog"
  496.   
  497.   struct    faillog {
  498.       short    fail_cnt;    /* failures since last success */
  499. --- 1,29 ----
  500.   /*
  501. !  * Copyright 1989, 1990, 1992, John F. Haugh II
  502.    * All rights reserved.
  503.    *
  504. !  * Permission is granted to copy and create derivative works for any
  505. !  * non-commercial purpose, provided this copyright notice is preserved
  506. !  * in all copies of source code, or included in human readable form
  507. !  * and conspicuously displayed on all copies of object code or
  508. !  * distribution media.
  509.    */
  510.   
  511.   /*
  512.    * faillog.h - login failure logging file format
  513.    *
  514. !  *    @(#)faillog.h    3.1    20:36:28    3/7/92
  515.    *
  516. !  * The login failure file is maintained by login(1) and faillog(8)
  517.    * Each record in the file represents a separate UID and the file
  518.    * is indexed in that fashion.
  519.    */
  520.   
  521. + #ifdef    SVR4
  522. + #define    FAILFILE    "/var/adm/faillog"
  523. + #else
  524.   #define    FAILFILE    "/usr/adm/faillog"
  525. + #endif
  526.   
  527.   struct    faillog {
  528.       short    fail_cnt;    /* failures since last success */
  529. Index: failure.c
  530. *** rel3/failure.c    Fri Mar 27 10:23:47 1992
  531. --- failure.c    Fri Mar 27 10:26:16 1992
  532. ***************
  533. *** 1,5 ****
  534.   /*
  535. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  536.    * All rights reserved.
  537.    *
  538.    * Permission is granted to copy and create derivative works for any
  539. --- 1,5 ----
  540.   /*
  541. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  542.    * All rights reserved.
  543.    *
  544.    * Permission is granted to copy and create derivative works for any
  545. ***************
  546. *** 12,17 ****
  547. --- 12,18 ----
  548.   #include <sys/types.h>
  549.   #include <fcntl.h>
  550.   #include <time.h>
  551. + #include <stdio.h>
  552.   #ifndef    BSD
  553.   #include <string.h>
  554.   #include <memory.h>
  555. ***************
  556. *** 20,25 ****
  557. --- 21,29 ----
  558.   #define    strchr    index
  559.   #define    strrchr    rindex
  560.   #endif
  561. + #ifdef    UNISTD_H
  562. + #include <unistd.h>
  563. + #endif
  564.   #include "faillog.h"
  565.   #include "config.h"
  566.   
  567. ***************
  568. *** 26,32 ****
  569.   #include <utmp.h>
  570.   
  571.   #ifndef    lint
  572. ! static    char    _sccsid[] = "@(#)failure.c    3.1    08:26:45    9/17/91";
  573.   #endif
  574.   
  575.   #define    DAY    (24L*3600L)
  576. --- 30,36 ----
  577.   #include <utmp.h>
  578.   
  579.   #ifndef    lint
  580. ! static    char    _sccsid[] = "@(#)failure.c    3.2    20:36:32    3/7/92";
  581.   #endif
  582.   
  583.   #define    DAY    (24L*3600L)
  584. ***************
  585. *** 57,63 ****
  586.       if (read (fd, (char *) faillog, sizeof *faillog)
  587.               != sizeof *faillog)
  588.   #ifndef    BSD
  589. !         memset ((void *) faillog, '\0', sizeof *faillog);
  590.   #else
  591.           bzero ((char *) faillog, sizeof *faillog);
  592.   #endif
  593. --- 61,67 ----
  594.       if (read (fd, (char *) faillog, sizeof *faillog)
  595.               != sizeof *faillog)
  596.   #ifndef    BSD
  597. !         memset ((void *) faillog, 0, sizeof *faillog);
  598.   #else
  599.           bzero ((char *) faillog, sizeof *faillog);
  600.   #endif
  601. ***************
  602. *** 83,88 ****
  603. --- 87,93 ----
  604.   failcheck (uid, faillog, failed)
  605.   int    uid;
  606.   struct    faillog    *faillog;
  607. + int    failed;
  608.   {
  609.       int    fd;
  610.       int    okay = 1;
  611. ***************
  612. *** 118,129 ****
  613.   struct    faillog    *fail;
  614.   {
  615.       struct    tm    *tp;
  616.       char    *lasttime;
  617.   
  618.       if (fail->fail_cnt == 0)
  619.           return;
  620.   
  621. !     tp = localtime (&fail->fail_time);
  622.       lasttime = asctime (tp);
  623.       lasttime[24] = '\0';
  624.   
  625. --- 123,158 ----
  626.   struct    faillog    *fail;
  627.   {
  628.       struct    tm    *tp;
  629. + #ifdef    SVR4
  630. +     char    lasttime[32];
  631. + #else
  632.       char    *lasttime;
  633. + #endif
  634.   
  635.       if (fail->fail_cnt == 0)
  636.           return;
  637.   
  638. !     tp = localtime (&(fail->fail_time));
  639. ! #if __STDC__
  640. !     /*
  641. !      * Only print as much date and time info as it needed to
  642. !      * know when the failure was.
  643. !      */
  644. !     if (NOW - fail->fail_time >= YEAR)
  645. !         strftime(lasttime, sizeof lasttime, NULL, tp);
  646. !     else if (NOW - fail->fail_time >= DAY)
  647. !         strftime(lasttime, sizeof lasttime, "%A %T", tp);
  648. !     else
  649. !         strftime(lasttime, sizeof lasttime, "%T", tp);
  650. ! #else
  651. !     /*
  652. !      * Do the same thing, but don't use strftime since it
  653. !      * probably doesn't exist on this system
  654. !      */
  655.       lasttime = asctime (tp);
  656.       lasttime[24] = '\0';
  657.   
  658. ***************
  659. *** 134,140 ****
  660.   
  661.       if (*lasttime == ' ')
  662.           lasttime++;
  663.       printf ("%d %s since last login.  Last was %s on %s.\n",
  664.           fail->fail_cnt, fail->fail_cnt > 1 ? "failures":"failure",
  665.           lasttime, fail->fail_line);
  666. --- 163,169 ----
  667.   
  668.       if (*lasttime == ' ')
  669.           lasttime++;
  670. ! #endif    /* __STDC__ */
  671.       printf ("%d %s since last login.  Last was %s on %s.\n",
  672.           fail->fail_cnt, fail->fail_cnt > 1 ? "failures":"failure",
  673.           lasttime, fail->fail_line);
  674. Index: grent.c
  675. *** rel3/grent.c    Fri Mar 27 10:23:42 1992
  676. --- grent.c    Fri Mar 27 10:26:19 1992
  677. ***************
  678. *** 1,5 ****
  679.   /*
  680. !  * Copyright 1990, 1991, John F. Haugh II
  681.    * All rights reserved.
  682.    *
  683.    * Permission is granted to copy and create derivative works for any
  684. --- 1,5 ----
  685.   /*
  686. !  * Copyright 1990, 1991, 1992, John F. Haugh II
  687.    * All rights reserved.
  688.    *
  689.    * Permission is granted to copy and create derivative works for any
  690. ***************
  691. *** 32,38 ****
  692.   #endif    /* NDBM */
  693.   
  694.   #ifndef    lint
  695. ! static    char    sccsid[] = "@(#)grent.c    3.10    08:45:25    9/12/91";
  696.   #endif    /* !lint */
  697.   
  698.   #define    NFIELDS    4
  699. --- 32,38 ----
  700.   #endif    /* NDBM */
  701.   
  702.   #ifndef    lint
  703. ! static    char    sccsid[] = "@(#)grent.c    3.11    20:36:44    3/7/92";
  704.   #endif    /* !lint */
  705.   
  706.   #define    NFIELDS    4
  707. ***************
  708. *** 176,181 ****
  709. --- 176,183 ----
  710.       return 0;
  711.   }
  712.   
  713. + #ifdef    GETGRENT
  714.   /*
  715.    * fgetgrent - get a group file entry from a stream
  716.    *
  717. ***************
  718. *** 204,215 ****
  719.    * endgrent() closes the group file if open.
  720.    */
  721.   
  722. ! int    endgrent ()
  723.   {
  724.       if (grpfp)
  725.           if (fclose (grpfp))
  726.               return -1;
  727.       grpfp = 0;
  728.   #ifdef    NDBM
  729.       if (dbmopened && gr_dbm) {
  730. --- 206,225 ----
  731.    * endgrent() closes the group file if open.
  732.    */
  733.   
  734. ! #ifdef    SVR4
  735. ! void
  736. ! #else
  737. ! int
  738. ! #endif
  739. ! endgrent ()
  740.   {
  741.       if (grpfp)
  742.           if (fclose (grpfp))
  743. + #ifdef    SVR4
  744. +             return;
  745. + #else
  746.               return -1;
  747. ! #endif
  748.       grpfp = 0;
  749.   #ifdef    NDBM
  750.       if (dbmopened && gr_dbm) {
  751. ***************
  752. *** 219,225 ****
  753. --- 229,237 ----
  754.       dbmopened = 0;
  755.       dbmerror = 0;
  756.   #endif    /* NDBM */
  757. + #ifndef    SVR4
  758.       return 0;
  759. + #endif
  760.   }
  761.   
  762.   /*
  763. ***************
  764. *** 232,240 ****
  765.   
  766.   struct    group    *getgrent ()
  767.   {
  768.       if (! grpfp && setgrent ())
  769.           return 0;
  770.       return fgetgrent (grpfp);
  771.   }
  772.   
  773. --- 244,256 ----
  774.   
  775.   struct    group    *getgrent ()
  776.   {
  777. + #ifdef    SVR4
  778. +     if (! grpfp)
  779. +         setgrent ();
  780. + #else
  781.       if (! grpfp && setgrent ())
  782.           return 0;
  783. ! #endif
  784.       return fgetgrent (grpfp);
  785.   }
  786.   
  787. ***************
  788. *** 263,271 ****
  789.       struct    sgrp    *sgrp;
  790.   #endif    /* AUTOSHADOW */
  791.   
  792.       if (setgrent ())
  793.           return 0;
  794.   #ifdef NDBM
  795.   
  796.       /*
  797. --- 279,290 ----
  798.       struct    sgrp    *sgrp;
  799.   #endif    /* AUTOSHADOW */
  800.   
  801. + #ifdef    SVR4
  802. +     setgrent ();
  803. + #else
  804.       if (setgrent ())
  805.           return 0;
  806. ! #endif
  807.   #ifdef NDBM
  808.   
  809.       /*
  810. ***************
  811. *** 360,368 ****
  812.       struct    sgrp    *sgrp;
  813.   #endif    /* AUTOSHADOW */
  814.   
  815.       if (setgrent ())
  816.           return 0;
  817.   #ifdef NDBM
  818.   
  819.       /*
  820. --- 379,390 ----
  821.       struct    sgrp    *sgrp;
  822.   #endif    /* AUTOSHADOW */
  823.   
  824. + #ifdef    SVR4
  825. +     setgrent ();
  826. + #else
  827.       if (setgrent ())
  828.           return 0;
  829. ! #endif
  830.   #ifdef NDBM
  831.   
  832.       /*
  833. ***************
  834. *** 446,452 ****
  835. --- 468,478 ----
  836.    * open already.
  837.    */
  838.   
  839. + #ifdef    SVR4
  840. + void
  841. + #else
  842.   int
  843. + #endif
  844.   setgrent ()
  845.   {
  846.   #ifdef    NDBM
  847. ***************
  848. *** 455,464 ****
  849. --- 481,498 ----
  850.   
  851.       if (! grpfp) {
  852.           if (! (grpfp = fopen (grpfile, "r")))
  853. + #ifdef    SVR4
  854. +             return;
  855. + #else
  856.               return -1;
  857. + #endif
  858.       } else {
  859.           if (fseek (grpfp, 0L, 0) != 0)
  860. + #ifdef    SVR4
  861. +             return;
  862. + #else
  863.               return -1;
  864. + #endif
  865.       }
  866.   
  867.       /*
  868. ***************
  869. *** 485,489 ****
  870. --- 519,527 ----
  871.               dbmopened = 1;
  872.       }
  873.   #endif    /* NDBM */
  874. + #ifndef    SVR4
  875.       return 0;
  876. + #endif
  877.   }
  878. + #endif    /* GRENT */
  879. Index: id.c
  880. *** rel3/id.c    Fri Mar 27 10:22:40 1992
  881. --- id.c    Fri Mar 27 10:26:20 1992
  882. ***************
  883. *** 1,5 ****
  884.   /*
  885. !  * Copyright 1991, John F. Haugh II
  886.    * All rights reserved.
  887.    *
  888.    * Permission is granted to copy and create derivative works for any
  889. --- 1,5 ----
  890.   /*
  891. !  * Copyright 1991, 1992, John F. Haugh II
  892.    * All rights reserved.
  893.    *
  894.    * Permission is granted to copy and create derivative works for any
  895. ***************
  896. *** 23,29 ****
  897.   #include "pwd.h"
  898.   
  899.   #ifndef    lint
  900. ! static    char    sccsid[] = "@(#)id.c    3.4    08:43:37    9/12/91";
  901.   #endif
  902.   
  903.   usage ()
  904. --- 23,29 ----
  905.   #include "pwd.h"
  906.   
  907.   #ifndef    lint
  908. ! static    char    sccsid[] = "@(#)id.c    3.5    20:36:50    3/7/92";
  909.   #endif
  910.   
  911.   usage ()
  912. ***************
  913. *** 114,119 ****
  914. --- 114,120 ----
  915.        */
  916.   
  917.       if (aflg && (ngroups = getgroups (0, 0)) != -1) {
  918. +         int    i;
  919.   
  920.   #if NGROUPS > 100
  921.           /*
  922. Index: lmain.c
  923. *** rel3/lmain.c    Fri Mar 27 10:25:54 1992
  924. --- lmain.c    Fri Mar 27 10:26:23 1992
  925. ***************
  926. *** 30,36 ****
  927.   #else
  928.   #include <sgtty.h>
  929.   #endif
  930. ! #include <lastlog.h>
  931.   #include "faillog.h"
  932.   #include "shadow.h"
  933.   
  934. --- 30,43 ----
  935.   #else
  936.   #include <sgtty.h>
  937.   #endif
  938. ! #ifdef    STDLIB_H
  939. ! #include <stdlib.h>
  940. ! #endif
  941. ! #ifdef    UNISTD_H
  942. ! #include <unistd.h>
  943. ! #endif
  944. ! #include "lastlog.h"
  945.   #include "faillog.h"
  946.   #include "shadow.h"
  947.   
  948. ***************
  949. *** 47,53 ****
  950.   #endif
  951.   
  952.   #ifndef    lint
  953. ! static    char    sccsid[] = "@(#)lmain.c    3.18    21:49:57    1/19/92";
  954.   #endif
  955.   
  956.                       /* danger - side effects */
  957. --- 54,60 ----
  958.   #endif
  959.   
  960.   #ifndef    lint
  961. ! static    char    sccsid[] = "@(#)lmain.c    3.19    20:36:55    3/7/92";
  962.   #endif
  963.   
  964.                       /* danger - side effects */
  965. ***************
  966. *** 150,155 ****
  967. --- 157,163 ----
  968.    * login -f name    (for pre-authenticated login: datakit, xterm, etc.)
  969.    */
  970.   
  971. + void
  972.   usage ()
  973.   {
  974.       fprintf (stderr, "usage: login [ -p ] [ name ]\n");
  975. ***************
  976. *** 249,254 ****
  977. --- 257,264 ----
  978.       int    subroot = 0;
  979.       char    *fname;
  980.       char    *cp;
  981. +     char    *tmp;
  982. +     char    buff[128];
  983.       struct    passwd    *pwd;
  984.       struct    spwd    *spwd;
  985.       struct    spwd    *getspnam();
  986. ***************
  987. *** 350,360 ****
  988.   
  989.       termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b');
  990.       termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025');
  991. !     (void) ioctl (0, TCSETAF, &termio);
  992.   #endif    /* !BSD */
  993.       umask (getdef_num("UMASK", 0));
  994.   #ifdef HAVE_ULIMIT
  995. !     ulimit (2, getdef_long("ULIMIT", 2097152L));
  996.   #endif
  997.   
  998.       /*
  999. --- 360,391 ----
  1000.   
  1001.       termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b');
  1002.       termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025');
  1003. ! #ifdef SVR4
  1004. !     /*
  1005. !      * ttymon invocation prefers this, but these settings won't come into
  1006. !      * effect after the first username login 
  1007. !      */
  1008. !     (void) ioctl (0, TCSETA, &termio);
  1009. ! #else
  1010. !      (void) ioctl (0, TCSETAF, &termio);
  1011. ! #endif
  1012.   #endif    /* !BSD */
  1013.       umask (getdef_num("UMASK", 0));
  1014.   #ifdef HAVE_ULIMIT
  1015. !     {
  1016. !         /* 
  1017. !          * Use the ULIMIT in the login.defs file, and if
  1018. !          * there isn't one, use the default value.  The
  1019. !          * user may have one for themselves, but otherwise,
  1020. !          * just take what you get.
  1021. !          */
  1022. !         long limit = getdef_long("ULIMIT", -1L);
  1023. !         if (limit != -1)
  1024. !             ulimit (2, limit);
  1025. !     }
  1026.   #endif
  1027.   
  1028.       /*
  1029. ***************
  1030. *** 370,378 ****
  1031.       if (term[5] != '\0')        /* see if anything after "TERM=" */
  1032.           addenv (term);
  1033.   #endif
  1034. !     if (! getenv("TZ") && (cp = getdef_str("ENV_TZ")))
  1035. !         addenv (*cp == '/' ? tz(cp) : cp);
  1036. !     if (! getenv("HZ") && (cp = getdef_str("ENV_HZ")))
  1037.           addenv (cp);
  1038.   
  1039.       if (optind < argc) {        /* get the user name */
  1040. --- 401,426 ----
  1041.       if (term[5] != '\0')        /* see if anything after "TERM=" */
  1042.           addenv (term);
  1043.   #endif
  1044. !     /*
  1045. !      * Add the timezone environmental variable so that time functions
  1046. !      * work correctly.
  1047. !      */
  1048. !     if (tmp = getenv ("TZ")) {
  1049. !         strcat (strcpy (buff, "TZ="), tmp);
  1050. !         addenv (buff);
  1051. !     } else if (cp = getdef_str ("ENV_TZ"))
  1052. !         addenv (*cp == '/' ? tz (cp):cp);
  1053. !     /* 
  1054. !      * Add the clock frequency so that profiling commands work
  1055. !      * correctly.
  1056. !      */
  1057. !     if (tmp = getenv("HZ")) {
  1058. !         strcat (strcpy (buff, "HZ="), tmp);
  1059. !         addenv (buff);
  1060. !     } else if (cp = getdef_str("ENV_HZ"))
  1061.           addenv (cp);
  1062.   
  1063.       if (optind < argc) {        /* get the user name */
  1064. ***************
  1065. *** 382,387 ****
  1066. --- 430,449 ----
  1067.           STRFCPY (name, argv[optind]);
  1068.           ++optind;
  1069.       }
  1070. + #ifdef SVR4
  1071. +     /*
  1072. +      * check whether ttymon has done the prompt for us already
  1073. +      */
  1074. +     {
  1075. +         char *ttymon_prompt;
  1076. +         if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL &&
  1077. +             (*ttymon_prompt != 0)) {
  1078. +         login(name, 0);    /* read name, without prompt */
  1079. +         }
  1080. +     }
  1081. + #endif /* SVR4 */
  1082.       if (optind < argc)        /* now set command line variables */
  1083.               setenv (argc - optind, &argv[optind]);
  1084.   
  1085. ***************
  1086. *** 403,409 ****
  1087.   #ifdef    RLOGIN
  1088.               preauth_flag = 0;
  1089.   #endif
  1090. !             login (name);
  1091.               continue;
  1092.           }
  1093.           if (! (pwd = getpwnam (name)))
  1094. --- 465,471 ----
  1095.   #ifdef    RLOGIN
  1096.               preauth_flag = 0;
  1097.   #endif
  1098. !             login (name, "login: ");
  1099.               continue;
  1100.           }
  1101.           if (! (pwd = getpwnam (name)))
  1102. Index: log.c
  1103. *** rel3/log.c    Fri Mar 27 10:23:41 1992
  1104. --- log.c    Fri Mar 27 10:26:25 1992
  1105. ***************
  1106. *** 1,5 ****
  1107.   /*
  1108. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1109.    * All rights reserved.
  1110.    *
  1111.    * Permission is granted to copy and create derivative works for any
  1112. --- 1,5 ----
  1113.   /*
  1114. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1115.    * All rights reserved.
  1116.    *
  1117.    * Permission is granted to copy and create derivative works for any
  1118. ***************
  1119. *** 25,35 ****
  1120.   #include "config.h"
  1121.   
  1122.   #ifndef    lint
  1123. ! static    char    sccsid[] = "@(#)log.c    3.2    07:43:10    9/17/91";
  1124.   #endif
  1125.   
  1126.   #include "lastlog.h"
  1127.   
  1128.   extern    struct    utmp    utent;
  1129.   extern    struct    passwd    pwent;
  1130.   extern    struct    lastlog    lastlog;
  1131. --- 25,43 ----
  1132.   #include "config.h"
  1133.   
  1134.   #ifndef    lint
  1135. ! static    char    sccsid[] = "@(#)log.c    3.3    20:37:03    3/7/92";
  1136.   #endif
  1137.   
  1138.   #include "lastlog.h"
  1139.   
  1140. + #ifndef    LASTLOG_FILE
  1141. + #ifdef    SVR4
  1142. + #define    LASTLOG_FILE    "/var/adm/lastlog"
  1143. + #else
  1144. + #define    LASTLOG_FILE    "/usr/adm/lastlog"
  1145. + #endif    /* SVR4 */
  1146. + #endif    /* LASTLOG_FILE */
  1147.   extern    struct    utmp    utent;
  1148.   extern    struct    passwd    pwent;
  1149.   extern    struct    lastlog    lastlog;
  1150. ***************
  1151. *** 44,50 ****
  1152.       off_t    offset;
  1153.       struct    lastlog    newlog;
  1154.   
  1155. !     if ((fd = open ("/usr/adm/lastlog", O_RDWR)) == -1)
  1156.           return;
  1157.   
  1158.       offset = pwent.pw_uid * sizeof lastlog;
  1159. --- 52,58 ----
  1160.       off_t    offset;
  1161.       struct    lastlog    newlog;
  1162.   
  1163. !     if ((fd = open (LASTLOG_FILE, O_RDWR)) == -1)
  1164.           return;
  1165.   
  1166.       offset = pwent.pw_uid * sizeof lastlog;
  1167. Index: login.c
  1168. *** rel3/login.c    Fri Mar 27 10:23:33 1992
  1169. --- login.c    Fri Mar 27 10:26:26 1992
  1170. ***************
  1171. *** 1,5 ****
  1172.   /*
  1173. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1174.    * All rights reserved.
  1175.    *
  1176.    * Permission is granted to copy and create derivative works for any
  1177. --- 1,5 ----
  1178.   /*
  1179. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1180.    * All rights reserved.
  1181.    *
  1182.    * Permission is granted to copy and create derivative works for any
  1183. ***************
  1184. *** 21,27 ****
  1185.   #endif
  1186.   
  1187.   #ifndef    lint
  1188. ! static    char    sccsid[] = "@(#)login.c    3.1    20:54:10    9/18/91";
  1189.   #endif
  1190.   
  1191.   void    setenv ();
  1192. --- 21,27 ----
  1193.   #endif
  1194.   
  1195.   #ifndef    lint
  1196. ! static    char    sccsid[] = "@(#)login.c    3.2    20:37:17    3/7/92";
  1197.   #endif
  1198.   
  1199.   void    setenv ();
  1200. ***************
  1201. *** 35,42 ****
  1202.    */
  1203.   
  1204.   void
  1205. ! login (name)
  1206.   char    *name;
  1207.   {
  1208.       char    buf[BUFSIZ];
  1209.       char    *envp[32];
  1210. --- 35,43 ----
  1211.    */
  1212.   
  1213.   void
  1214. ! login (name, prompt)
  1215.   char    *name;
  1216. + char    *prompt;
  1217.   {
  1218.       char    buf[BUFSIZ];
  1219.       char    *envp[32];
  1220. ***************
  1221. *** 47,71 ****
  1222.   
  1223.       /*
  1224.        * See if the user has configured the /etc/issue file to
  1225. !      * be displayed.
  1226.        */
  1227.   
  1228. !     if (getdef_bool ("ISSUE_FILE_ENAB")) {
  1229. !         if (fp = fopen ("/etc/issue", "r")) {
  1230. !             while ((i = getc (fp)) != EOF)
  1231. !                 putc (i, stdout);
  1232.   
  1233. !             fflush (stdout);
  1234. !             fclose (fp);
  1235.           }
  1236.       }
  1237.   #ifndef    BSD
  1238.       (void) memset (buf, '\0', sizeof buf);
  1239.   #else
  1240.       bzero (buf, sizeof buf);
  1241.   #endif
  1242. -     fputs ("login: ", stdout);
  1243.       if (fgets (buf, BUFSIZ, stdin) != buf)
  1244.           exit (1);
  1245.   
  1246. --- 48,79 ----
  1247.   
  1248.       /*
  1249.        * See if the user has configured the /etc/issue file to
  1250. !      * be displayed and display it before the prompt.
  1251.        */
  1252.   
  1253. !     if (prompt) {
  1254. !         if (getdef_bool ("ISSUE_FILE_ENAB")) {
  1255. !             if (fp = fopen ("/etc/issue", "r")) {
  1256. !                 while ((i = getc (fp)) != EOF)
  1257. !                     putc (i, stdout);
  1258.   
  1259. !                 fflush (stdout);
  1260. !                 fclose (fp);
  1261. !             }
  1262.           }
  1263. +         fputs (prompt, stdout);
  1264.       }
  1265. +     /* 
  1266. +      * Read the user's response.  The trailing newline will be
  1267. +      * removed.
  1268. +      */
  1269.   #ifndef    BSD
  1270.       (void) memset (buf, '\0', sizeof buf);
  1271.   #else
  1272.       bzero (buf, sizeof buf);
  1273.   #endif
  1274.       if (fgets (buf, BUFSIZ, stdin) != buf)
  1275.           exit (1);
  1276.   
  1277. Index: obscure.c
  1278. *** rel3/obscure.c    Fri Mar 27 10:22:36 1992
  1279. --- obscure.c    Fri Mar 27 10:26:27 1992
  1280. ***************
  1281. *** 1,5 ****
  1282.   /*
  1283. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1284.    * All rights reserved.
  1285.    *
  1286.    * Permission is granted to copy and create derivative works for any
  1287. --- 1,5 ----
  1288.   /*
  1289. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1290.    * All rights reserved.
  1291.    *
  1292.    * Permission is granted to copy and create derivative works for any
  1293. ***************
  1294. *** 21,27 ****
  1295.   #include "config.h"
  1296.   
  1297.   #ifndef    lint
  1298. ! static    char    sccsid[] = "@(#)obscure.c    3.5    07:43:55    9/17/91";
  1299.   #endif
  1300.   
  1301.   extern    int    getdef_bool();
  1302. --- 21,27 ----
  1303.   #include "config.h"
  1304.   
  1305.   #ifndef    lint
  1306. ! static    char    sccsid[] = "@(#)obscure.c    3.6    20:37:32    3/7/92";
  1307.   #endif
  1308.   
  1309.   extern    int    getdef_bool();
  1310. ***************
  1311. *** 201,206 ****
  1312.       if (size <= i)
  1313.           return 0;
  1314.   
  1315. !     printf ("Too Simple.  ");
  1316.       return 1;
  1317.   }
  1318. --- 201,207 ----
  1319.       if (size <= i)
  1320.           return 0;
  1321.   
  1322. !     printf ("Too Simple.  Use a longer password, or a mix of upper\n");
  1323. !     printf ("and lower case letters and numerics.  ");
  1324.       return 1;
  1325.   }
  1326. Index: passwd.c
  1327. *** rel3/passwd.c    Fri Mar 27 10:25:45 1992
  1328. --- passwd.c    Fri Mar 27 10:26:29 1992
  1329. ***************
  1330. *** 1,5 ****
  1331.   /*
  1332. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1333.    * All rights reserved.
  1334.    *
  1335.    * Permission is granted to copy and create derivative works for any
  1336. --- 1,5 ----
  1337.   /*
  1338. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1339.    * All rights reserved.
  1340.    *
  1341.    * Permission is granted to copy and create derivative works for any
  1342. ***************
  1343. *** 17,23 ****
  1344.   #include <signal.h>
  1345.   
  1346.   #ifndef    lint
  1347. ! static    char    sccsid[] = "@(#)passwd.c    3.7    12:04:36    12/28/91";
  1348.   #endif
  1349.   
  1350.   /*
  1351. --- 17,23 ----
  1352.   #include <signal.h>
  1353.   
  1354.   #ifndef    lint
  1355. ! static    char    sccsid[] = "@(#)passwd.c    3.8    20:37:37    3/7/92";
  1356.   #endif
  1357.   
  1358.   /*
  1359. ***************
  1360. *** 35,40 ****
  1361. --- 35,54 ----
  1362.   #define    strrchr    rindex
  1363.   #endif
  1364.   
  1365. + #ifdef    STDLIB_H
  1366. + #include <stdlib.h>
  1367. + #endif
  1368. + #ifdef    UNISTD_H
  1369. + #include <unistd.h>
  1370. + #endif
  1371. + #ifdef    ULIMIT_H
  1372. + #include <ulimit.h>
  1373. + #endif
  1374. + #ifndef UL_SFILLIM
  1375. + #define UL_SFILLIM    2
  1376. + #endif
  1377.   #include "pwd.h"
  1378.   #include "lastlog.h"
  1379.   #include "shadow.h"
  1380. ***************
  1381. *** 60,66 ****
  1382. --- 74,82 ----
  1383.    *    SCALE - convert from clock to aging units
  1384.    */
  1385.   
  1386. + #ifndef    DAY
  1387.   #define    DAY    (24L*3600L)
  1388. + #endif
  1389.   #define    WEEK    (7L*DAY)
  1390.   
  1391.   #ifdef    ITI_AGING
  1392. ***************
  1393. *** 103,109 ****
  1394.       "       %s { -l | -d | -S } name\n"
  1395.   #define    OLDPASS        "Old Password:"
  1396.   #define    NEWPASSMSG \
  1397. ! "Enter the new password (minimum of 5 characters)\n\
  1398.   Please use a combination of upper and lower case letters and numbers.\n"
  1399.   #define    CHANGING    "Changing password for %s\n"
  1400.   #define NEWPASS        "New Password:"
  1401. --- 119,125 ----
  1402.       "       %s { -l | -d | -S } name\n"
  1403.   #define    OLDPASS        "Old Password:"
  1404.   #define    NEWPASSMSG \
  1405. ! "Enter the new password (minimum of %d characters)\n\
  1406.   Please use a combination of upper and lower case letters and numbers.\n"
  1407.   #define    CHANGING    "Changing password for %s\n"
  1408.   #define NEWPASS        "New Password:"
  1409. ***************
  1410. *** 203,209 ****
  1411.        * for initial login passwords.
  1412.        */
  1413.   
  1414. !     printf (NEWPASSMSG);
  1415.       for (i = 0;i < 3;i++) {
  1416.           if (! (cp = getpass (NEWPASS))) {
  1417.               bzero (orig, sizeof orig);
  1418. --- 219,225 ----
  1419.        * for initial login passwords.
  1420.        */
  1421.   
  1422. !     printf (NEWPASSMSG, getdef_num ("PASS_MIN_LEN", 5));
  1423.       for (i = 0;i < 3;i++) {
  1424.           if (! (cp = getpass (NEWPASS))) {
  1425.               bzero (orig, sizeof orig);
  1426. ***************
  1427. *** 556,564 ****
  1428. --- 572,586 ----
  1429.                   Sflg++;
  1430.                   break;
  1431.               case 'd':
  1432. +                 if (getuid ())
  1433. +                     usage ();
  1434.                   dflg++;
  1435.                   break;
  1436.               case 'l':
  1437. +                 if (getuid ())
  1438. +                     usage ();
  1439.                   lflg++;
  1440.                   break;
  1441.               case 'u':
  1442. ***************
  1443. *** 724,730 ****
  1444.        */
  1445.   
  1446.   #ifdef    HAVE_ULIMIT
  1447. !     ulimit (2, 30000);
  1448.   #endif
  1449.   #ifdef    HAVE_RLIMIT
  1450.       setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
  1451. --- 746,752 ----
  1452.        */
  1453.   
  1454.   #ifdef    HAVE_ULIMIT
  1455. !     ulimit (UL_SFILLIM, 30000);
  1456.   #endif
  1457.   #ifdef    HAVE_RLIMIT
  1458.       setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
  1459. Index: pwd.h.m4
  1460. *** rel3/pwd.h.m4    Fri Mar 27 10:25:42 1992
  1461. --- pwd.h.m4    Fri Mar 27 10:26:31 1992
  1462. ***************
  1463. *** 1,5 ****
  1464.   /*
  1465. !  * Copyright 1990, 1991, John F. Haugh II and Steve Simmons
  1466.    * All rights reserved.
  1467.    *
  1468.    * Permission is granted to copy and create derivative works for any
  1469. --- 1,5 ----
  1470.   /*
  1471. !  * Copyright 1990, 1991, 1992, John F. Haugh II and Steve Simmons
  1472.    * All rights reserved.
  1473.    *
  1474.    * Permission is granted to copy and create derivative works for any
  1475. ***************
  1476. *** 13,21 ****
  1477.    * Standard definitions for password files.  This is an independant
  1478.    * reimplementation of the definitions used by AT&T, BSD, and POSIX.
  1479.    * It is not derived from any of those sources.  Note that it can be
  1480. !  * site-defined to have non-POSIX features as well.
  1481.    *
  1482. !  *    @(#)pwd.h.m4    3.2    12:04:43    12/28/91
  1483.    */
  1484.   
  1485.   #ifndef    PWD_H
  1486. --- 13,23 ----
  1487.    * Standard definitions for password files.  This is an independant
  1488.    * reimplementation of the definitions used by AT&T, BSD, and POSIX.
  1489.    * It is not derived from any of those sources.  Note that it can be
  1490. !  * site-defined to have non-POSIX features as well.  Ideally this file
  1491. !  * is simply replaced by the standard system supplied /usr/include/pwd.h
  1492. !  * file.
  1493.    *
  1494. !  *    @(#)pwd.h.m4    3.4    13:22:36    3/9/92
  1495.    */
  1496.   
  1497.   #ifndef    PWD_H
  1498. ***************
  1499. *** 26,33 ****
  1500.   typedef int gid_t;
  1501.   #endif
  1502.   
  1503. ! #ifdef    SUN
  1504.   #include <sys/types.h>
  1505.   #endif
  1506.   
  1507.   ifdef(`SUN4', `#define    ATT_AGE')
  1508. --- 28,41 ----
  1509.   typedef int gid_t;
  1510.   #endif
  1511.   
  1512. ! #if defined(SUN) || defined(SUN4)
  1513.   #include <sys/types.h>
  1514. + #endif
  1515. + #ifdef    SVR4
  1516. + #include <sys/types.h>
  1517. + #include <limits.h>
  1518. + #define NGROUPS NGROUPS_MAX
  1519.   #endif
  1520.   
  1521.   ifdef(`SUN4', `#define    ATT_AGE')
  1522. Index: pwent.c
  1523. *** rel3/pwent.c    Fri Mar 27 10:25:41 1992
  1524. --- pwent.c    Fri Mar 27 10:26:33 1992
  1525. ***************
  1526. *** 1,5 ****
  1527.   /*
  1528. !  * Copyright 1989, 1990, 1991 John F. Haugh II
  1529.    * All rights reserved.
  1530.    *
  1531.    * Permission is granted to copy and create derivative works for any
  1532. --- 1,5 ----
  1533.   /*
  1534. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1535.    * All rights reserved.
  1536.    *
  1537.    * Permission is granted to copy and create derivative works for any
  1538. ***************
  1539. *** 60,66 ****
  1540.   #endif
  1541.   
  1542.   #ifndef    lint
  1543. ! static    char    sccsid[] = "@(#)pwent.c    3.7    12:04:47    12/28/91";
  1544.   #endif
  1545.   
  1546.   #define    SBUFSIZ    64
  1547. --- 60,66 ----
  1548.   #endif
  1549.   
  1550.   #ifndef    lint
  1551. ! static    char    sccsid[] = "@(#)pwent.c    3.8    20:37:54    3/7/92";
  1552.   #endif
  1553.   
  1554.   #define    SBUFSIZ    64
  1555. ***************
  1556. *** 76,82 ****
  1557.   static    char    *pwdfields[NFIELDS];
  1558.   static    struct    passwd    pwent;
  1559.   
  1560. ! #if defined(AUTOSHADOW) && defined(ATT_AGE)
  1561.   /*
  1562.    * sptopwage - convert shadow ages to AT&T-style pw_age ages
  1563.    *
  1564. --- 76,82 ----
  1565.   static    char    *pwdfields[NFIELDS];
  1566.   static    struct    passwd    pwent;
  1567.   
  1568. ! #if defined(AUTOSHADOW) && defined(ATT_AGE) && defined(GETPWENT)
  1569.   /*
  1570.    * sptopwage - convert shadow ages to AT&T-style pw_age ages
  1571.    *
  1572. ***************
  1573. *** 192,197 ****
  1574. --- 192,199 ----
  1575.       return (&pwent);
  1576.   }
  1577.   
  1578. + #ifdef    GETPWENT
  1579.   /*
  1580.    * fgetpwent - get a password file entry from a stream
  1581.    *
  1582. ***************
  1583. *** 511,513 ****
  1584. --- 513,517 ----
  1585.       return status;
  1586.   }
  1587.   #endif /* NEED_PUTPWENT */
  1588. + #endif /* GETPWENT */
  1589. Index: utmp.c
  1590. *** rel3/utmp.c    Fri Mar 27 10:25:38 1992
  1591. --- utmp.c    Fri Mar 27 10:26:36 1992
  1592. ***************
  1593. *** 1,5 ****
  1594.   /*
  1595. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1596.    * All rights reserved.
  1597.    *
  1598.    * Permission is granted to copy and create derivative works for any
  1599. --- 1,5 ----
  1600.   /*
  1601. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1602.    * All rights reserved.
  1603.    *
  1604.    * Permission is granted to copy and create derivative works for any
  1605. ***************
  1606. *** 22,29 ****
  1607. --- 22,39 ----
  1608.   #define    strrchr    rindex
  1609.   #endif
  1610.   #include <stdio.h>
  1611. + #ifdef    STDLIB_H
  1612. + #include <stdlib.h>
  1613. + #endif
  1614. + #ifdef    UNISTD_H
  1615. + #include <unistd.h>
  1616. + #endif
  1617.   #include "config.h"
  1618.   
  1619. + #ifndef    UTMP_FILE
  1620. + #define    UTMP_FILE    "/etc/utmp"
  1621. + #endif
  1622.   #if defined(SUN) || defined(BSD) || defined(SUN4)
  1623.   #ifndef    WTMP_FILE
  1624.   #define WTMP_FILE "/usr/adm/wtmp"
  1625. ***************
  1626. *** 31,37 ****
  1627.   #endif    /* SUN || BSD */
  1628.   
  1629.   #ifndef    lint
  1630. ! static    char    sccsid[] = "@(#)utmp.c    3.13    11:58:53    12/28/91";
  1631.   #endif
  1632.   
  1633.   extern    struct    utmp    utent;
  1634. --- 41,47 ----
  1635.   #endif    /* SUN || BSD */
  1636.   
  1637.   #ifndef    lint
  1638. ! static    char    sccsid[] = "@(#)utmp.c    3.15    23:57:02    3/7/92";
  1639.   #endif
  1640.   
  1641.   extern    struct    utmp    utent;
  1642. ***************
  1643. *** 92,102 ****
  1644.   
  1645.           endutent ();
  1646.   
  1647. !         if (! ut || utent.ut_pid != pid) {
  1648.                (void) puts (NO_UTENT);
  1649.               exit (1);
  1650.           }
  1651. !         if (utent.ut_line[0] == '\0') {
  1652.               if (! (line = ttyname (0))) {
  1653.                   (void) puts (NO_TTY);
  1654.                   exit (1);
  1655. --- 102,123 ----
  1656.   
  1657.           endutent ();
  1658.   
  1659. !         if (! ut) {
  1660.                (void) puts (NO_UTENT);
  1661.               exit (1);
  1662.           }
  1663. ! #ifndef    UNIXPC
  1664. !         /*
  1665. !          * If there is no ut_line value in this record, fill
  1666. !          * it in by getting the TTY name and stuffing it in
  1667. !          * the structure.  The UNIX/PC is broken in this regard
  1668. !          * and needs help ...
  1669. !          */
  1670. !         if (utent.ut_line[0] == '\0')
  1671. ! #endif
  1672. !         {
  1673.               if (! (line = ttyname (0))) {
  1674.                   (void) puts (NO_TTY);
  1675.                   exit (1);
  1676. ***************
  1677. *** 156,166 ****
  1678.   char    *name;
  1679.   char    *line;
  1680.   {
  1681.       struct    utmp    utmp;
  1682.       int    fd;
  1683.       int    found = 0;
  1684.   
  1685. !     if (! (fd = open ("/etc/utmp", O_RDWR)))
  1686.           return;
  1687.   
  1688.   #if !defined(SUN) && !defined(BSD) && !defined(SUN4)
  1689. --- 177,237 ----
  1690.   char    *name;
  1691.   char    *line;
  1692.   {
  1693. + #ifdef SVR4
  1694. +     struct    utmp    utmp;
  1695. +     struct    utmpx    *utmpx, utxline;
  1696. +     extern int gettimeofday (struct timeval *tp);
  1697. +     /*
  1698. +      * Update utmpx.  We create an empty entry in case there is
  1699. +      * no matching entry in the utmpx file.
  1700. +      */
  1701. +     utmpxname (UTMPX_FILE);
  1702. +     memset (&utxline, 0, sizeof utxline);
  1703. +     strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
  1704. +     utmpx = getutxline (&utxline);
  1705. +     if (!utmpx)
  1706. +         utmpx = &utxline;
  1707. +     /*
  1708. +      * Fill in the fields in the utmpx entry and write it out.
  1709. +      */
  1710. +     strncpy (utmpx->ut_user, name, sizeof utmpx->ut_user);
  1711. +     utmpx->ut_pid = getpid ();
  1712. +     utmpx->ut_type = USER_PROCESS;
  1713. +     gettimeofday (&(utmpx->ut_tv));
  1714. +     pututxline (utmpx);
  1715. +     /*
  1716. +      * Now fill-in the regular utmp file entry.  All the information
  1717. +      * it needs is in utmpx.  We scribble it out as well.
  1718. +      */
  1719. +     utmpname (UTMP_FILE);
  1720. +     getutmp (utmpx, &utmp);
  1721. +     pututline (&utmp);
  1722. +     endutent ();
  1723. +     /* 
  1724. +      * Update the WTMP and WTMPX files and end access to UTMPX.  The
  1725. +      * endutxent() can't be done until now since utmpx is still needed
  1726. +      * and endutext() trashes the contents.
  1727. +      */
  1728. +     updwtmpx(WTMPX_FILE, utmpx);
  1729. +     endutxent();
  1730. +      utent = utmp;
  1731. + #else /* !SVR4 */
  1732.       struct    utmp    utmp;
  1733.       int    fd;
  1734.       int    found = 0;
  1735.   
  1736. !     if (! (fd = open (UTMP_FILE, O_RDWR)))
  1737.           return;
  1738.   
  1739.   #if !defined(SUN) && !defined(BSD) && !defined(SUN4)
  1740. ***************
  1741. *** 235,238 ****
  1742. --- 306,310 ----
  1743.           (void) close (fd);
  1744.       }
  1745.        utent = utmp;
  1746. + #endif /* SVR4 */
  1747.   }
  1748. Index: faillog.8
  1749. *** rel3/faillog.8    Fri Mar 27 10:25:18 1992
  1750. --- faillog.8    Fri Mar 27 10:26:38 1992
  1751. ***************
  1752. *** 1,18 ****
  1753. ! .\" Copyright 1989, 1990, John F. Haugh II
  1754.   .\" All rights reserved.
  1755.   .\"
  1756.   .\" Use, duplication, and disclosure prohibited without
  1757.   .\" the express written permission of the author.
  1758.   .\"
  1759. ! .\"    @(#)faillog.8    3.1    09:34:20    11/21/90
  1760.   .\"
  1761.   .TH FAILLOG 8
  1762.   .SH NAME
  1763.   faillog \- examine faillog and set login failure limits
  1764.   .SH SYNOPSIS
  1765. ! /etc/faillog [ -u uid ] [ -t days ] [ -m max ] [ -pr ] 
  1766.   .SH DESCRIPTION
  1767. ! \fIPlastlog\fR formats the contents of the failure log,
  1768.   \fI/usr/adm/faillog\fR, and maintains failure counts and
  1769.   limits.
  1770.   The order of the arguments to \fIfaillog\fR is significant.
  1771. --- 1,18 ----
  1772. ! .\" Copyright 1989, 1990, 1992, John F. Haugh II
  1773.   .\" All rights reserved.
  1774.   .\"
  1775.   .\" Use, duplication, and disclosure prohibited without
  1776.   .\" the express written permission of the author.
  1777.   .\"
  1778. ! .\"    @(#)faillog.8    3.2    20:36:19    3/7/92
  1779.   .\"
  1780.   .TH FAILLOG 8
  1781.   .SH NAME
  1782.   faillog \- examine faillog and set login failure limits
  1783.   .SH SYNOPSIS
  1784. ! /etc/faillog [ -u uid ] [ -a ] [ -t days ] [ -m max ] [ -pr ] 
  1785.   .SH DESCRIPTION
  1786. ! \fIfaillog\fR formats the contents of the failure log,
  1787.   \fI/usr/adm/faillog\fR, and maintains failure counts and
  1788.   limits.
  1789.   The order of the arguments to \fIfaillog\fR is significant.
  1790. ***************
  1791. *** 25,30 ****
  1792. --- 25,34 ----
  1793.   Entering \fB-t days\fR will cause only the
  1794.   failures more recent than \fBdays\fR to be printed.
  1795.   The \fB-t\fR flag overrides the use of \fB-u\fR.
  1796. + The \fB-a\fR flag causes all users to be selected.
  1797. + When used with the \fB-p\fR flag, this option selects all users
  1798. + who have ever had a login failure.
  1799. + It is meaningless with the \fB-r\fR flag.
  1800.   .PP
  1801.   The \fB-r\fR flag is used to reset the count of login failures.
  1802.   Write access to \fI/usr/adm/faillog\fR is required for
  1803. ***************
  1804. *** 49,54 ****
  1805. --- 53,64 ----
  1806.   Options may be combined in virtually any fashion.
  1807.   Each \fB-p\fR, \fB-r\fR, and \fB-m\fR option will cause
  1808.   immediate execution using any \fB-u\fR or \fB-t\fR modifier.
  1809. + .SH Bugs
  1810. + \fIfaillog\fR only prints out users with no successful login since
  1811. + the last failure.
  1812. + To print out a user who has had a successful login since their last
  1813. + failure, you must explicitly request the user with the \fB-u\fR flag,
  1814. + or print out all users with the \fB-a\fR flag.
  1815.   .SH Files
  1816.   /usr/adm/faillog \- failure logging file
  1817.   .SH See Also
  1818. Index: chage.c
  1819. *** rel3/chage.c    Mon Mar 30 08:29:42 1992
  1820. --- chage.c    Mon Mar 30 10:09:20 1992
  1821. ***************
  1822. *** 1,5 ****
  1823.   /*
  1824. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1825.    * All rights reserved.
  1826.    *
  1827.    * Permission is granted to copy and create derivative works for any
  1828. --- 1,5 ----
  1829.   /*
  1830. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1831.    * All rights reserved.
  1832.    *
  1833.    * Permission is granted to copy and create derivative works for any
  1834. ***************
  1835. *** 17,23 ****
  1836.   #include <time.h>
  1837.   
  1838.   #ifndef    lint
  1839. ! static    char    sccsid[] = "@(#)chage.c    3.9    10:14:30    8/15/91";
  1840.   #endif
  1841.   
  1842.   /*
  1843. --- 17,23 ----
  1844.   #include <time.h>
  1845.   
  1846.   #ifndef    lint
  1847. ! static    char    sccsid[] = "@(#)chage.c    3.10    10:08:53    3/30/92";
  1848.   #endif
  1849.   
  1850.   /*
  1851. ***************
  1852. *** 98,103 ****
  1853. --- 98,111 ----
  1854.   #define    SCALE    (DAY)
  1855.   #endif
  1856.   
  1857. + #if !defined(MDY_DATE) && !defined(DMY_DATE) && !defined(YMD_DATE)
  1858. + #define    MDY_DATE    1
  1859. + #endif
  1860. + #if (defined (MDY_DATE) && (defined (DMY_DATE) || defined (YMD_DATE))) || \
  1861. +     (defined (DMY_DATE) && (defined (MDY_DATE) || defined (YMD_DATE)))
  1862. + Error: You must only define one of MDY_DATE, DMY_DATE, or YMD_DATE
  1863. + #endif
  1864.   /*
  1865.    * days and juldays are used to compute the number of days in the
  1866.    * current month, and the cummulative number of days in the preceding
  1867. ***************
  1868. *** 139,144 ****
  1869. --- 147,167 ----
  1870.   #define    OPEN_FAIL    "failed opening %s\n"
  1871.   #define    WRITE_FAIL    "failed updating %s\n"
  1872.   #define    CLOSE_FAIL    "failed rewriting %s\n"
  1873. + #ifdef    MDY_DATE
  1874. + #define    LAST_CHG    "Last Password Change (MM/DD/YY)"
  1875. + #define    ACCT_EXP    "Account Expiration Date (MM/DD/YY)"
  1876. + #define    EPOCH        "12/31/69"
  1877. + #endif
  1878. + #ifdef    DMY_DATE
  1879. + #define    LAST_CHG    "Last Password Change (DD/MM/YY)"
  1880. + #define    ACCT_EXP    "Account Expiration Date (DD/MM/YY)"
  1881. + #define    EPOCH        "31/12/69"
  1882. + #endif
  1883. + #ifdef    YMD_DATE
  1884. + #define    LAST_CHG    "Last Password Change (YY/MM/DD)"
  1885. + #define    ACCT_EXP    "Account Expiration Date (YY/MM/DD)"
  1886. + #define    EPOCH        "69/12/31"
  1887. + #endif
  1888.   
  1889.   /*
  1890.    * usage - print command line syntax and exit
  1891. ***************
  1892. *** 171,183 ****
  1893.       long    total;
  1894.   
  1895.       /*
  1896. !      * start by separating the month, day and year.  this is
  1897. !      * a chauvanistic program - it only takes date input in
  1898. !      * the standard USA format.
  1899.        */
  1900.   
  1901.       if (sscanf (str, "%d/%d/%d%c", &month, &day, &year, slop) != 3)
  1902.           return -1;
  1903.   
  1904.       /*
  1905.        * the month, day of the month, and year are checked for
  1906. --- 194,215 ----
  1907.       long    total;
  1908.   
  1909.       /*
  1910. !      * start by separating the month, day and year.  the order
  1911. !      * is compiled in ...
  1912.        */
  1913.   
  1914. + #ifdef    MDY_DATE
  1915.       if (sscanf (str, "%d/%d/%d%c", &month, &day, &year, slop) != 3)
  1916.           return -1;
  1917. + #endif
  1918. + #ifdef    DMY_DATE
  1919. +     if (sscanf (str, "%d/%d/%d%c", &day, &month, &year, slop) != 3)
  1920. +         return -1;
  1921. + #endif
  1922. + #ifdef    YMD_DATE
  1923. +     if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3)
  1924. +         return -1;
  1925. + #endif
  1926.   
  1927.       /*
  1928.        * the month, day of the month, and year are checked for
  1929. ***************
  1930. *** 253,261 ****
  1931.       value = lastday * SCALE;
  1932.       tp = gmtime (&value);
  1933.       sprintf (buf, "%02d/%02d/%02d",
  1934. !         tp->tm_mon + 1, tp->tm_mday, tp->tm_year);
  1935. !     change_field (buf, "Last Password Change (MM/DD/YY)");
  1936. !     if (strcmp (buf, "12/31/69") == 0)
  1937.           lastday = -1;
  1938.       else if ((lastday = strtoday (buf)) == -1)
  1939.           return 0;
  1940. --- 285,303 ----
  1941.       value = lastday * SCALE;
  1942.       tp = gmtime (&value);
  1943.       sprintf (buf, "%02d/%02d/%02d",
  1944. ! #ifdef    MDY_DATE
  1945. !         tp->tm_mon + 1, tp->tm_mday, tp->tm_year
  1946. ! #endif
  1947. ! #ifdef    DMY_DATE
  1948. !         tp->tm_mday, tp->tm_mon + 1, tp->tm_year
  1949. ! #endif
  1950. ! #ifdef    YMD_DATE
  1951. !         tp->tm_year, tp->tm_mon + 1, tp->tm_mday
  1952. ! #endif
  1953. !         );
  1954. !     change_field (buf, LAST_CHG);
  1955. !     if (strcmp (buf, EPOCH) == 0)
  1956.           lastday = -1;
  1957.       else if ((lastday = strtoday (buf)) == -1)
  1958.           return 0;
  1959. ***************
  1960. *** 273,281 ****
  1961.       value = expdays * SCALE;
  1962.       tp = gmtime (&value);
  1963.       sprintf (buf, "%02d/%02d/%02d",
  1964. !         tp->tm_mon + 1, tp->tm_mday, tp->tm_year);
  1965. !     change_field (buf, "Account Expiration Date (MM/DD/YY)");
  1966. !     if (strcmp (buf, "12/31/69") == 0)
  1967.           expdays = -1;
  1968.       else if ((expdays = strtoday (buf)) == -1)
  1969.           return 0;
  1970. --- 315,333 ----
  1971.       value = expdays * SCALE;
  1972.       tp = gmtime (&value);
  1973.       sprintf (buf, "%02d/%02d/%02d",
  1974. ! #ifdef    MDY_DATE
  1975. !         tp->tm_mon + 1, tp->tm_mday, tp->tm_year
  1976. ! #endif
  1977. ! #ifdef    DMY_DATE
  1978. !         tp->tm_mday, tp->tm_mon + 1, tp->tm_year
  1979. ! #endif
  1980. ! #ifdef    YMD_DATE
  1981. !         tp->tm_year, tp->tm_mon + 1, tp->tm_mday
  1982. ! #endif
  1983. !         );
  1984. !     change_field (buf, ACCT_EXP);
  1985. !     if (strcmp (buf, EPOCH) == 0)
  1986.           expdays = -1;
  1987.       else if ((expdays = strtoday (buf)) == -1)
  1988.           return 0;
  1989. ***************
  1990. *** 460,466 ****
  1991.                   break;
  1992.               case 'd':
  1993.                   dflg++;
  1994. !                 lastday = strtol (optarg, 0, 10);
  1995.                   break;
  1996.               case 'W':
  1997.                   Wflg++;
  1998. --- 512,521 ----
  1999.                   break;
  2000.               case 'd':
  2001.                   dflg++;
  2002. !                 if (strchr (optarg, '/'))
  2003. !                     lastday = strtoday (optarg);
  2004. !                 else
  2005. !                     lastday = strtol (optarg, 0, 10);
  2006.                   break;
  2007.               case 'W':
  2008.                   Wflg++;
  2009. ***************
  2010. *** 472,478 ****
  2011.                   break;
  2012.               case 'E':
  2013.                   Eflg++;
  2014. !                 expdays = strtol (optarg, 0, 10);
  2015.                   break;
  2016.               default:
  2017.                   usage ();
  2018. --- 527,536 ----
  2019.                   break;
  2020.               case 'E':
  2021.                   Eflg++;
  2022. !                 if (strchr (optarg, '/'))
  2023. !                     expdays = strtoday (optarg);
  2024. !                 else
  2025. !                     expdays = strtol (optarg, 0, 10);
  2026.                   break;
  2027.               default:
  2028.                   usage ();
  2029. -- 
  2030. John F. Haugh II        | Every 56 days.   | UUCP: ...!cs.utexas.edu!rpp386!jfh
  2031. Ma Bell: (512) 251-2151 | Give Blood, often.    | Domain: jfh@rpp386.cactus.org
  2032. "A countryman between two lawyers is like a fish between two cats."
  2033.         -- Benjamin Franklin
  2034.  
  2035. exit 0 # Just in case...
  2036.