Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jun 1997 11:20:53 +0200
From:      j@uriah.heep.sax.de (J Wunsch)
To:        freebsd-chat@FreeBSD.ORG
Cc:        jmr@ugcs.caltech.edu, andrsn@andrsn.stanford.edu (Annelise Anderson), kevin_eliuk@sunshine.net (Kevin Eliuk), chris@bb.cc.wa.us (Chris Coleman)
Subject:   Re: learn program
Message-ID:  <19970601112053.SJ08285@uriah.heep.sax.de>
In-Reply-To: <19970601091500.HT19999@uriah.heep.sax.de>; from J Wunsch on Jun 1, 1997 09:15:00 %2B0200
References:  <199706010344.UAA27051@envy.ugcs.caltech.edu> <19970601091500.HT19999@uriah.heep.sax.de>

next in thread | previous in thread | raw e-mail | index | archive | help
I wrote:

> As jmr@ugcs.caltech.edu wrote:
> 
> > A while ago there was some discussion about a learn program on one of 
> > the mailing lists.  Well, I found this:
> > http://cm.bell-labs.com/who/bwk/learn.tar.gz on Kernighan's web page.
> 
> Oh!

> I think thanks have to go, of course, to Brian himself first, for
> freeing up this very early piece of Unix history, to Kevin Eliuk
> (who's got the idea to ask for this program), and Annelise Anderson
> (not an unknown person for us, Annelise is also in the Donor's
> gallery), for tracking this, so Brian has finally been asked to
> release it.

I fetched it, and have a look.  Please be careful, and don't run this
program as root.  I don't think it's what i would call the latest peek
in computer security. :)  (No surprise, but you should know it.)

The ar archives contained there contain pathnames with trailing
slashes, so our ar(1) can't create them (since they are required to be
directories in Posix).  Below is a quick Perl hack that converts the
pathnames in the archives.

I've also fixed all occurances of gets() in the source, as well as a
bug that could lead to calling rm(1) without a directory name (if you
hit ^C early in the game).  Also, i think the `play' subdirectory
should ultimately go under /tmp.

#!/usr/bin/perl

die "usage: arfix filename\n" unless $#ARGV == 0;

open(AR, $ARGV[0]) || die "Can't open $ARGV[0]\n";
open(NEW, ">$ARGV[0].$$") || die "Can't open tempfile.\n";

$sig = <AR>;
die "ARGV[0] is not an ar archive\n" unless $sig eq "!<arch>\n";
print NEW $sig;

while (<AR>) {
	if ($_ eq "\n") {
		# hack
		print NEW "\n";
		next;
	}
	($path, $tstamp, $uid, $gid, $mode, $len) = split;
	$path =~ s|/$||;
	printf NEW "%-15s %-11d %-5d %-5d %-7d %-9d \`\n",
		$path, $tstamp, $uid, $gid, $mode, $len;
	$r = read(AR, $b, $len);
	print NEW $b;
}
close(AR);
close(NEW);

rename($ARGV[0], "$ARGV[0].bak");
rename("$ARGV[0].$$", $ARGV[0]);
exit 0;



--- learn.c.orig	Wed May 28 20:29:56 1997
+++ learn.c	Sun Jun  1 11:11:02 1997
@@ -2,6 +2,7 @@
 #include "learn.h"
 #include "signal.h"
 #include <stdlib.h>
+#include <string.h>
 
 char	*direct	= LLIB;	/* CHANGE THIS ON YOUR SYSTEM */
 int	more;
@@ -365,12 +366,12 @@
 			wrong > 1 ? "still " : "");
 		fflush(stdout);
 		for(;;) {
-			gets(tbuff);
+			fgets(tbuff, sizeof tbuff, stdin);
 			if (tbuff[0] == 'y') {
 				printf("Try the problem again.\n");
 				fflush(stdout);
 				goto retry;
-			} else if (strcmp(tbuff, "bye") == 0) {
+			} else if (strncmp(tbuff, "bye", strlen("bye")) == 0) {
 				wrapup(1);
 			} else if (tbuff[0] == 'n') {
 				wrong = 0;
@@ -703,7 +704,7 @@
 	}
 	chknam(direct);
 	if (chdir(direct) != 0) {
-		fprintf(stderr, "can't cd to %s\,", direct);
+		fprintf(stderr, "can't cd to %s\n", direct);
 		exit(1);
 	}
 	sname = argc > 1 ? argv[1] : 0;
@@ -721,16 +722,17 @@
 		printf("type 'return'; otherwise type the name of\n");
 		printf("the course you want, followed by 'return'.\n");
 		fflush(stdout);
-		gets(sname=subname);
+		fgets(sname=subname, sizeof subname, stdin);
 		if (sname[0] == '\0') {
 			list("Xinfo");
 			do {
 				printf("\nWhich subject?  ");
 				fflush(stdout);
-				gets(sname=subname);
+				fgets(sname=subname, sizeof subname, stdin);
 			} while (sname[0] == '\0');
 		}
 	}
+	if ((cp = strchr(sname, '\n'))) *cp = 0;
 	chknam(sname);
 	if (!level) {
 		printf("If you were in the middle of this subject\n");
@@ -738,7 +740,8 @@
 		printf("the last lesson number the computer printed.\n");
 		printf("To start at the beginning, just hit return.\n");
 		fflush(stdout);
-		gets(ans2);
+		fgets(ans2, sizeof ans2, stdin);
+		if ((cp = strchr(ans2, '\n'))) *cp = 0;
 		if (ans2[0]==0)
 			strcpy(ans2,"0");
 		for (cp=ans2; *cp; cp++)
@@ -787,7 +790,7 @@
 
 selunit()
 {
-	char fnam[20], s[50];
+	char fnam[20], s[50], *cp;
 	static char dobuff[50];
 	char posslev[20][20];
 	int diff[20], i, k, m, n, best, alts;
@@ -798,7 +801,8 @@
 	while (ask) {
 		printf("What lesson? ");
 		fflush(stdout);
-		gets(dobuff);
+		fgets(dobuff, sizeof dobuff, stdin);
+		if ((cp = strchr(dobuff, '\n'))) *cp = 0;
 		if (strcmp(dobuff, "bye") == 0)
 			wrapup(0);
 		level = todo = dobuff;
@@ -971,14 +975,16 @@
 	 interrupts turned off */
 	int retval, pid, pidw;
 
-	signal(SIGINT, SIG_IGN);
-	chdir("..");
-	if ( (pid=fork()) ==0) {
-		signal(SIGHUP, SIG_IGN);
-		execl("/bin/rm", "rm", "-r", dir, 0);
-		execl("/usr/bin/rm", "rm", "-r", dir, 0);
-		fprintf(stderr, "Can't find 'rm' command.\n");
-		exit(0);
+	if (dir) {
+		signal(SIGINT, SIG_IGN);
+		chdir("..");
+		if ( (pid=fork()) ==0) {
+			signal(SIGHUP, SIG_IGN);
+			execl("/bin/rm", "rm", "-r", dir, 0);
+			execl("/usr/bin/rm", "rm", "-r", dir, 0);
+			fprintf(stderr, "Can't find 'rm' command.\n");
+			exit(0);
+		}
 	}
 	printf("Bye.\n"); /* not only does this reassure user but 
 			it stalls for time while deleting directory */


-- 
cheers, J"org

joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970601112053.SJ08285>