This patch contains the following bugfixes:
* the TIMEOUT (and -t flag) has now different effect for getty and uugetty:
with uugetty, TIMEOUT set will now cause uugetty exit no matter whether
there has been any input from the user (the counting will start immediately
after login() has been spawned - pre- getty-2.1.0 behavior), while for
getty, it will make the counter start after single input has been detected
from the user
* getty.1 manpage updated accordingly
* @F issue substitution now works as expected
* @V / VERSION functionality documentation fix in getty.1 manpage
* fixed a bunch of memleaks (if not all):
* Fputs() made strdup()-free (we now use static structs where possible)
* avoided unnecessary dual strdup() for Version in defs()
* freeing of "DEF **def" including its internals is now handled, as well as
feeing of other variables in defs() pointing to strdup()ed memory areas
Jan Rafaj
--- ./man/getty.1.orig 2002-09-13 09:05:03.000000000 +0200
+++ ./man/getty.1 2005-07-21 10:24:53.000000000 +0200
@@ -307,7 +307,18 @@
to exit (which
.I init
should then respawn), if the login is not completed within timeout seconds
-(after the login name is entered)
+(after the login name is entered). This option behaves differently for
+.I getty
+and
+.I uugetty.
+If
+.I getty
+is used, the counting will start after single input from the user has been
+detected, whileas with
+.I uugetty,
+the counting will start immediately after
+.IR login (1m)
+has been spawned, no matter the input from the user.
Giving
.B \-w
@@ -388,9 +399,12 @@
If
.I string
begins with a '/' character, it is assumed to be the full pathname of a
-file, and
+text file, and
.B @V
-is set to be the contents of that file. The default is /proc/version.
+is set to be the contents of the first line in that file (line has to be
+terminated by newline character or by end of file).
+.br
+The default is /proc/version.
.TP
LOGIN=\fIname\fR
Sets the name of the login program to
@@ -503,6 +517,14 @@
to exit if no user name is accepted before the
.I number
of seconds elapse after the login prompt is displayed.
+With
+.I getty,
+the counting will start as soon as a single character
+has been entered by the user, whileas with
+.I uugetty,
+the counting will start immediately after the login prompt
+is displayed, no matter the input from the user.
+.br
The default is to wait indefinitely for the user name.
.TP
CONNECT=\fIstring\fR
@@ -865,6 +887,11 @@
.IR cu (1)
and others). This prevents two or more processes from having conficting
use of a tty port.
+.br
+.I Uugetty
+also differs from
+.I getty
+by handling the -t parameter and TIMEOUT option.
.PP
When
.I uugetty
--- ./main.c.orig 2004-04-11 03:34:34.000000000 +0200
+++ ./main.c 2005-07-21 11:37:19.000000000 +0200
@@ -78,6 +78,8 @@
void debugstart();
#endif /* DEBUG */
+DEF **def;
+
/* trivial globals */
char buf[MAXLINE];
@@ -86,7 +88,7 @@
char tbuf[64];
#define Perror(s) { debug(D_INIT, "Line %d: %s: Error %d: %s\n", \
- __LINE__, s, errno, sys_errlist[errno]); \
+ __LINE__, s, errno, strerror(errno)); \
exit(errno); \
}
@@ -149,6 +151,50 @@
}
}
+/*
+ * Why a lot of programmers ignore the fact that memory area returned
+ * by strdup() and *alloc() has to be freed upon exit? :(( -JR
+ */
+void free_def(void)
+{
+ register DEF **deflist = def;
+
+ for (; *deflist != (DEF *)NULL; deflist++) {
+ free((*deflist)->name);
+ free((*deflist)->value);
+ free(*deflist);
+ }
+}
+
+void free_sysname(void)
+{
+ if (SysName)
+ free(SysName);
+ SysName = NULL;
+}
+
+void free_version(void)
+{
+ if (Version && defvalue(def, "VERSION"))
+ free(Version);
+ Version = NULL;
+}
+
+#ifdef UUGETTY
+void free_lock(void)
+{
+ if (lock)
+ free(lock);
+ lock = NULL;
+}
+
+void free_altlock(void)
+{
+ if (altlock)
+ free(altlock);
+ altlock = NULL;
+}
+#endif
/*
** main
@@ -320,7 +366,6 @@
char **args;
{
register int c;
- DEF **def;
char *p;
char termcap[1024];
@@ -416,22 +461,27 @@
/* now, get all that info in the defaults file */
def = defbuild(defname);
+ atexit(free_def);
#ifdef DEBUG
if ((p = defvalue(def, "DEBUG"))) (void) sscanf(p, "%o", &Debug);
if (Debug) debugstart();
#endif /* DEBUG */
SysName = strdup(getuname());
+ atexit(free_sysname);
if (p = defvalue(def, "SYSTEM")) SysName = p;
- if (p = defvalue(def, "VERSION"))
- Version = strdup(p);
- if (*Version == '/')
- { if ((fp = fopen(Version, "r")))
- { fgets(buf, MAXLINE, fp);
- fclose(fp);
- buf[strlen(buf)-1] = '\0';
- Version = strdup(buf);
+ if (p = defvalue(def, "VERSION")) {
+ if (*p == '/') {
+ if ((fp = fopen(p, "r"))) {
+ fgets(buf, MAXLINE, fp);
+ fclose(fp);
+ buf[strlen(buf)-1] = '\0';
+ Version = strdup(buf);
}
- }
+ } else {
+ Version = strdup(p);
+ }
+ atexit(free_version);
+ }
if((p = defvalue(def, "LOGIN"))) login_pgm = p;
if((p = defvalue(def, "ISSUE"))) issue = p;
if((p = defvalue(def, "CLEAR")) && (strequal(p, "NO")))
@@ -489,12 +539,15 @@
#ifdef UUGETTY
(void) sprintf(buf, LOCK, Device);
lock = strdup(buf);
+ atexit(free_lock);
if((p = defvalue(def, "ALTLOCK"))) {
(void) sprintf(buf, LOCK, p);
altlock = strdup(buf);
+ atexit(free_altlock);
} else if(! strequal(Device, InitDevice)) {
(void) sprintf(buf, LOCK, InitDevice);
altlock = strdup(buf);
+ atexit(free_altlock);
}
debug(D_LOCK, "lock = (%s), altlock = (%s)", lock, altlock);
@@ -625,8 +678,8 @@
with the uts struct filled above.
*/
- debug(D_UTMP, "adding utmp entry: type: %d, pid: %d, line: %s,
- id: %c%c, time: %d, user: %s, host: %s, addr: %d",
+ debug(D_UTMP, "adding utmp entry: type: %d, pid: %d, line: %s, "
+ "id: %c%c, time: %d, user: %s, host: %s, addr: %d",
uts.ut_type, uts.ut_pid, uts.ut_line,
(uts.ut_id[0] ? uts.ut_id[0] : ' '),
(uts.ut_id[1] ? uts.ut_id[1] : ' '),
@@ -1077,16 +1130,20 @@
login_prompt:
(void) ioctl(STDIN, TCFLSH, 0);
#ifdef FIDO
- if (emsi && (strcmp(emsi,"yes") == 0))
- (void) Fputs("**EMSI_REQA77E\r", stdout);
+ if (emsi && (strcmp(emsi,"yes") == 0))
+ (void) Fputs("**EMSI_REQA77E\r", stdout);
#endif
(void) Fputs(gtab->login, stdout);
-
+#ifndef UUGETTY
login_result=getlogname(&termio, buf, MAXLINE);
+#endif
if(TimeOut > 0) {
(void) signal(SIGALRM, timeout);
(void) alarm((unsigned) TimeOut);
}
+#ifdef UUGETTY
+ login_result=getlogname(&termio, buf, MAXLINE);
+#endif
switch(login_result) {
#ifdef FIDO
@@ -1114,6 +1171,13 @@
#ifdef SETTERM
setenv("TERM", term, TRUE);
#endif /* SETTERM */
+ free_def();
+ free_sysname();
+ free_version();
+#ifdef UUGETTY
+ free_lock();
+ free_altlock();
+#endif
debug(D_RUN, "execing login");
(void) execl(login_pgm,
"login", buf, NULLPTR);
--- ./funcs.c.orig 2002-09-25 08:43:28.000000000 +0200
+++ ./funcs.c 2005-07-20 19:01:55.000000000 +0200
@@ -87,12 +87,11 @@
register char *s;
register FILE *stream;
{
- char c, n, tbuf[20], ubuf[MAXBUF];
- char *cbuf;
+ char c, n, tbuf[20];
time_t clock;
struct tm *lt;
- struct utsname utsbuf;
- struct hostent *fqdname;
+ static struct utsname utsbuf;
+ static struct hostent *fqdname;
FILE *fp1;
char *day_name[] = { "Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat" };
@@ -119,21 +118,8 @@
return(EOF);
break;
case 'F': /* FQDName */
- cbuf = strdup(SysName);
-#if 0 /* The does a seg violation - no idea why.... */
fqdname = gethostbyname(SysName);
-#endif
-#if 0 /* So, we cheat.....! */
- /* Which also gets a seg violation! */
- if (fp1 = fopen("/etc/HOSTNAME", "r"))
- { fgets(cbuf, MAXBUF, fp1);
- fclose(fp1);
- cbuf[strlen(cbuf)] = '\0';
- }
- if (fqdname != NULL)
- cbuf = strdup(fqdname->h_name);
-#endif
- if (Fputs(cbuf, stream) == EOF)
+ if (fqdname && Fputs(fqdname->h_name, stream) == EOF)
return(EOF);
break;
case 'L': /* line */
@@ -141,18 +127,15 @@
return(EOF);
break;
case 'M': /* arch of machine */
- cbuf = strdup(utsbuf.machine);
- if (Fputs(cbuf, stream) == EOF)
+ if (Fputs(utsbuf.machine, stream) == EOF)
return(EOF);
break;
case 'O': /* O/S name */
- cbuf = strdup(utsbuf.sysname);
- if (Fputs(cbuf, stream) == EOF)
+ if (Fputs(utsbuf.sysname, stream) == EOF)
return(EOF);
break;
case 'R': /* O/S rev_id */
- cbuf = strdup(utsbuf.release);
- if (Fputs(cbuf, stream) == EOF)
+ if (Fputs(utsbuf.release, stream) == EOF)
return(EOF);
break;
case 'S': /* system node name */
@@ -166,8 +149,8 @@
return(EOF);
break;
case 'U': /* number of active users */
- (void) sprintf(ubuf, "%d", Nusers);
- if (Fputs(ubuf, stream) == EOF)
+ (void) sprintf(tbuf, "%d", Nusers);
+ if (Fputs(tbuf, stream) == EOF)
return(EOF);
break;
case 'V': /* version */
@@ -175,12 +158,10 @@
return(EOF);
break;
case 'u': /* user count str */
- cbuf = malloc(20);
(void) sprintf(tbuf, "%d User", Nusers);
if (Nusers > 1)
- cbuf = strcat(tbuf,"s");
- else cbuf=strdup(tbuf);
- if (Fputs(cbuf, stream) == EOF)
+ strcat(tbuf, "s");
+ if (Fputs(tbuf, stream) == EOF)
return(EOF);
break;
case '@': /* in case '@@' was used */