Initial import package mingetty: A compact getty program for virtual consoles only
[external/mingetty.git] / mingetty-0.9.4-autologin.patch
1 --- mingetty-0.9.4/mingetty.c.autologin Sun Nov 26 10:54:13 2000
2 +++ mingetty-0.9.4/mingetty.c   Sun Nov 26 10:28:29 2000
3 @@ -49,6 +49,20 @@
4  #endif
5  
6  #ifdef linux
7 +/* Autologin stuff.  Currently Linux-specific, since there's no
8 +   standard way of getting the system boot time.  The kernel.h and the
9 +   sysinfo prototype are used to get the system uptime under Linux. */
10 +#include <linux/kernel.h>
11 +int sysinfo(struct sysinfo *info);
12 +
13 +/* AUTO_LAST points to a timestamp file used to limit autologins to
14 +   one per system boot. */
15 +#define AUTO_LAST "/var/log/autologin"
16 +
17 +/* AUTO_TTY is the tty on which autologins will be accepted.  If set
18 +   to an empty string, autologins will be accepted on any tty. */
19 +#define AUTO_TTY "tty1"
20 +
21  #include <sys/param.h>
22  #define USE_SYSLOG
23  #endif
24 @@ -80,7 +94,8 @@
25  static int noclear = 0;
26  /* Print the whole string of gethostname() instead of just until the next "." */
27  static int longhostname = 0;
28 -
29 +/* If supplied, attempt an automatic login with this username. */
30 +static char *autologin_name = NULL;
31  
32  /*
33   * output error messages
34 @@ -385,6 +400,62 @@
35         return logname;
36  }
37  
38 +/*
39 + * autologin_ok -- returns 1 if it's okay to auto-login when:
40 + *   this login is from /dev/tty1; and
41 + *   there was a login name passed with the --autologin option; and
42 + *   the autologin_name contains only "nice" characters; and
43 + *   this is the first autologin attempt since the last boot; 
44 + * return 0 otherwise.
45 + */
46 +static int autologin_ok(void)
47 +{
48 +       char c, *cp;
49 +       int stat_err, fd;
50 +       struct sysinfo info;
51 +       struct stat sbuf;
52 +
53 +       /* Autologins are restricted to AUTO_TTY if non-empty. */
54 +       if (AUTO_TTY[0] && strcmp(tty, AUTO_TTY))
55 +               return 0;
56 +
57 +       /* An all-alphanumeric autologin name must be supplied. */
58 +       if (autologin_name == NULL || autologin_name[0] == '\0')
59 +               return 0;
60 +       for (cp = autologin_name; (c = *cp); cp++)
61 +               if (!isalnum(c) && c != '_')
62 +                       return 0;
63 +
64 +       /* Get the uptime in info.uptime, and the last autologin time
65 +           in sbuf.st_mtime. */
66 +       sysinfo(&info);
67 +       stat_err = stat(AUTO_LAST, &sbuf);
68 +
69 +       /* If a stat error other than "no such file" occurs, I don't
70 +           know what went wrong, so I'll proceed with caution by
71 +           denying the autologin request. */
72 +       if (stat_err && errno != ENOENT)
73 +               return 0;
74 +
75 +       /* If there's been an autologin granted since the last boot,
76 +           deny this and any subsequent attempts.  Note that this test
77 +           is skipped if the AUTO_LAST file doesn't exist. */
78 +       if (!stat_err && time(NULL) - info.uptime < sbuf.st_mtime)
79 +               return 0;
80 +
81 +       /* Create the AUTO_LAST file.  The mtime of this file provides
82 +           a persistent record of the last time that an autologin
83 +           request was granted.  Deny the autologin request if either
84 +           the file open or file close fails. */
85 +       if ((fd=open(AUTO_LAST, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
86 +               return 0;
87 +       if (close(fd) != 0)
88 +               return 0;
89 +
90 +       /* All tests are okay, so grant the autologin request. */
91 +       return 1;
92 +}
93 +
94  static void usage (void)
95  {
96         error ("usage: '%s tty' with e.g. tty=tty1", progname);
97 @@ -393,6 +464,7 @@
98  static struct option const long_options[] = {
99         { "noclear", no_argument, &noclear, 1},
100         { "long-hostname", no_argument, &longhostname, 1},
101 +       { "autologin", required_argument, NULL, 'a'},
102         { 0, 0, 0, 0 }
103  };
104  
105 @@ -418,6 +490,9 @@
106                 switch (c) {
107                         case 0:
108                                 break;
109 +                       case 'a':
110 +                               autologin_name = optarg;
111 +                               break;
112                         default:
113                                 usage ();
114                 }
115 @@ -438,9 +513,12 @@
116         /* flush input and output queues, important for modems */
117         ioctl (0, TCFLSH, 2);
118  
119 -       while ((logname = get_logname ()) == 0);
120 -
121 -       execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
122 +       if (autologin_ok()) {
123 +               execl (_PATH_LOGIN, _PATH_LOGIN, "-f", autologin_name, NULL);
124 +       } else {
125 +               while ((logname = get_logname ()) == 0) ;
126 +               execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
127 +       }
128         error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
129         exit (0);
130  }