summaryrefslogblamecommitdiffstats
path: root/source/a/getty-ps/getty.bugfixes.diff
blob: 6a1ed29e9d8313e805635e68e9913015ee003e8b (plain) (tree)



































































































































































































































































































































































                                                                             
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)
+		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 */