[comp.sources.bugs] Patch #5 for Pcomm v1.0

hood@osiris.cso.uiuc.edu (05/26/88)

This is Patch #5 to the Pcomm version 1.0 distribution package.  It fixes
a collection of minor bugs and some problems found when porting Pcomm to
other flavors of Unix.  Some of the things changed are:

	1) Variable 'modem->hangup' changed to 'modem->hang_up' to
	prevent keyword collision on SVR3.1 implementations.

	2) A lot of references to NULL vs. pointer-to-NULL were very
	sloppy...  (My machine binds a NULL at address zero).

	3) Better error recovery from opening a port.

	4) Lock files are now created with mode 666.

A lot of the performance enhancements will have to wait 'till the 1.1
version (fix the bugs first, then work on making it better).

Keeps those cards and letters coming...

Emmet P. Gray				US Army, HQ III Corps & Fort Hood
...!ihnp4!uiucuxc!fthood!egray		Attn: AFZF-DE-ENV
					Directorate of Engineering & Housing
					Environmental Management Office
					Fort Hood, TX 76544-5057
-------------------------------------------------------------------------------
*** old/admin.c	Tue May 24 14:21:16 1988
--- admin.c	Tue May 24 14:29:23 1988
***************
*** 91,95
  }
  
! #ifdef LOG_CALLS || LIMIT_LD
  /*
   * Put together the complete phone number but strip out the extraneous

--- 91,95 -----
  }
  
! #if defined(LOG_CALLS) || defined(LIMIT_LD)
  /*
   * Put together the complete phone number but strip out the extraneous
*** old/d_manual.c	Tue May 24 14:21:17 1988
--- d_manual.c	Tue May 24 14:34:54 1988
***************
*** 16,19
  	void fix_xmc(), free_ptr();
  	extern int xmc;
  	
  	m_win = newwin(5, 50, 0, 20);

--- 16,20 -----
  	void fix_xmc(), free_ptr();
  	extern int xmc;
+ 	extern char *null_ptr;
  	
  	m_win = newwin(5, 50, 0, 20);
***************
*** 47,51
  	free_ptr(dir->number[0]);
  	dir->name[0] = strdup(number);
! 	dir->number[0] = strdup(number);
  					/* it overlaps dm_win, so erase it */
  	werase(m_win);

--- 48,56 -----
  	free_ptr(dir->number[0]);
  	dir->name[0] = strdup(number);
! 					/* if space, change to null */
! 	if (!strcmp(number, " "))
! 		dir->number[0] = null_ptr;
! 	else
! 		dir->number[0] = strdup(number);
  					/* it overlaps dm_win, so erase it */
  	werase(m_win);
*** old/d_prompt.c	Tue May 24 14:21:17 1988
--- d_prompt.c	Tue May 24 14:36:17 1988
***************
*** 219,222
  		else
  			index = strdup(ans);
  		mvwattrstr(win, 2, 62, A_BOLD, index);
  	}

--- 219,224 -----
  		else
  			index = strdup(ans);
+ 		mvwaddstr(win, 2, 62, "              ");
+ 		wrefresh(win);
  		mvwattrstr(win, 2, 62, A_BOLD, index);
  	}
*** old/init.c	Tue May 24 14:21:18 1988
--- init.c	Tue May 24 14:43:18 1988
***************
*** 107,110
  				break;
  		}
  		sprintf(temp, "%s/%s", path, name);
  					/* read permission checked */

--- 107,113 -----
  				break;
  		}
+ 		if (path == NULL)
+ 			continue;
+ 
  		sprintf(temp, "%s/%s", path, name);
  					/* read permission checked */
*** old/m_lib.c	Tue May 24 14:21:19 1988
--- m_lib.c	Tue May 24 14:24:00 1988
***************
*** 137,141
  						break;
  					case 4:
! 						m.hangup[mod] = strdup(str);
  						break;
  					case 5:

--- 137,141 -----
  						break;
  					case 4:
! 						m.hang_up[mod] = strdup(str);
  						break;
  					case 5:
***************
*** 201,205
  		m.dial[mod] = null_ptr;
  		m.suffix[mod] = null_ptr;
! 		m.hangup[mod] = null_ptr;
  
  		m.con_3[mod] = null_ptr;

--- 201,205 -----
  		m.dial[mod] = null_ptr;
  		m.suffix[mod] = null_ptr;
! 		m.hang_up[mod] = null_ptr;
  
  		m.con_3[mod] = null_ptr;
***************
*** 246,250
  		fprintf(fp, "MODEM_%da=%s;%s;%s;%s;%s\n", i+1, modem->mname[i],
  		 modem->init[i], modem->dial[i], modem->suffix[i],
! 		 modem->hangup[i]);
  
  		fprintf(fp, "MODEM_%db=%s;%s;%s;%s;%s;%s\n", i+1,

--- 246,250 -----
  		fprintf(fp, "MODEM_%da=%s;%s;%s;%s;%s\n", i+1, modem->mname[i],
  		 modem->init[i], modem->dial[i], modem->suffix[i],
! 		 modem->hang_up[i]);
  
  		fprintf(fp, "MODEM_%db=%s;%s;%s;%s;%s;%s\n", i+1,
***************
*** 320,324
  				free_ptr(modem->dial[j]);
  				free_ptr(modem->suffix[j]);
! 				free_ptr(modem->hangup[j]);
  
  				free_ptr(modem->con_3[j]);

--- 320,324 -----
  				free_ptr(modem->dial[j]);
  				free_ptr(modem->suffix[j]);
! 				free_ptr(modem->hang_up[j]);
  
  				free_ptr(modem->con_3[j]);
***************
*** 339,343
  				modem->dial[j] = strdup(modem->dial[j+1]);
  				modem->suffix[j] = strdup(modem->suffix[j+1]);
! 				modem->hangup[j] = strdup(modem->hangup[j+1]);
  
  				modem->con_3[j] = strdup(modem->con_3[j+1]);

--- 339,343 -----
  				modem->dial[j] = strdup(modem->dial[j+1]);
  				modem->suffix[j] = strdup(modem->suffix[j+1]);
! 				modem->hang_up[j] = strdup(modem->hang_up[j+1]);
  
  				modem->con_3[j] = strdup(modem->con_3[j+1]);
***************
*** 359,363
  			free_ptr(modem->dial[j]);
  			free_ptr(modem->suffix[j]);
! 			free_ptr(modem->hangup[j]);
  
  			free_ptr(modem->con_3[j]);

--- 359,363 -----
  			free_ptr(modem->dial[j]);
  			free_ptr(modem->suffix[j]);
! 			free_ptr(modem->hang_up[j]);
  
  			free_ptr(modem->con_3[j]);
***************
*** 378,382
  			modem->dial[j] = null_ptr;
  			modem->suffix[j] = null_ptr;
! 			modem->hangup[j] = null_ptr;
  
  			modem->con_3[j] = null_ptr;

--- 378,382 -----
  			modem->dial[j] = null_ptr;
  			modem->suffix[j] = null_ptr;
! 			modem->hang_up[j] = null_ptr;
  
  			modem->con_3[j] = null_ptr;
*** old/main.c	Tue May 24 14:21:20 1988
--- main.c	Tue May 24 15:47:20 1988
***************
*** 9,12
   *					Environmental Management Office
   *					Fort Hood, TX 76544-5057
   *	Beta release	 7 Feb 88
   *	Release 1.0	12 Mar 88

--- 9,13 -----
   *					Environmental Management Office
   *					Fort Hood, TX 76544-5057
+  *
   *	Beta release	 7 Feb 88
   *	  patch #1	 8 Feb 88
***************
*** 10,13
   *					Fort Hood, TX 76544-5057
   *	Beta release	 7 Feb 88
   *	Release 1.0	12 Mar 88
   */

--- 11,16 -----
   *
   *	Beta release	 7 Feb 88
+  *	  patch #1	 8 Feb 88
+  *	Pre-release	27 Feb 88
   *	Release 1.0	12 Mar 88
   *	  patch #1	22 Apr 88
***************
*** 11,14
   *	Beta release	 7 Feb 88
   *	Release 1.0	12 Mar 88
   */
  

--- 14,22 -----
   *	Pre-release	27 Feb 88
   *	Release 1.0	12 Mar 88
+  *	  patch #1	22 Apr 88
+  *	  patch #2	26 Mar 88
+  *	  patch #3	 3 Apr 88
+  *	  patch #4	14 Apr 88
+  *	  patch #5	25 May 88
   */
  
*** old/modem.h	Tue May 24 14:21:26 1988
--- modem.h	Tue May 24 14:26:02 1988
***************
*** 17,21
  	char	*dial[NUM_MODEM];	/* dial command */
  	char	*suffix[NUM_MODEM];	/* dialing command suffix */
! 	char	*hangup[NUM_MODEM];	/* hang up the modem */
  	char	*con_3[NUM_MODEM];	/* 300 baud connect message */
  	char	*con_12[NUM_MODEM];	/* 1200 baud connect message */

--- 17,21 -----
  	char	*dial[NUM_MODEM];	/* dial command */
  	char	*suffix[NUM_MODEM];	/* dialing command suffix */
! 	char	*hang_up[NUM_MODEM];	/* hang up the modem */
  	char	*con_3[NUM_MODEM];	/* 300 baud connect message */
  	char	*con_12[NUM_MODEM];	/* 1200 baud connect message */
*** old/port.c	Tue May 24 14:21:20 1988
--- port.c	Tue May 24 14:57:01 1988
***************
*** 26,30
  get_port()
  {
! 	int i, j, k, progpid, fd, list[NUM_TTY];
  	char file[80], buf[80], message[80], *strdup();
  	unsigned int sleep();

--- 26,30 -----
  get_port()
  {
! 	int i, j, k, progpid, fd, list[NUM_TTY], cmask;
  	char file[80], buf[80], message[80], *strdup();
  	unsigned int sleep();
***************
*** 106,109
  			getty_status = set_getty(modem->tty[list[i]], 0);
  			
  			if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
  				set_getty(modem->tty[list[i]], 1);

--- 106,110 -----
  			getty_status = set_getty(modem->tty[list[i]], 0);
  			
+ 			cmask = umask(0);
  			if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
  				if (getty_status)
***************
*** 107,111
  			
  			if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
! 				set_getty(modem->tty[list[i]], 1);
  				sprintf(buf, "'%s'", file);
  				error_win(1, "Can't create the lockfile", buf);

--- 108,113 -----
  			cmask = umask(0);
  			if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
! 				if (getty_status)
! 					set_getty(modem->tty[list[i]], 1);
  				sprintf(buf, "'%s'", file);
  				error_win(1, "Can't create the lockfile", buf);
***************
*** 111,114
  				error_win(1, "Can't create the lockfile", buf);
  			}
  #ifdef ASCII_PID
  			sprintf(buf, "%10d\n", getpid());

--- 113,117 -----
  				error_win(1, "Can't create the lockfile", buf);
  			}
+ 			umask(cmask);
  #ifdef ASCII_PID
  			sprintf(buf, "%10d\n", getpid());
***************
*** 127,131
  			sprintf(buf, "/dev/%s", modem->tty[list[i]]);
  			if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
! 				set_getty(modem->tty[list[i]], 1);
  				sprintf(file, "Can't open port '%s' for read and write", buf);
  				error_win(1, file, NULL);

--- 130,135 -----
  			sprintf(buf, "/dev/%s", modem->tty[list[i]]);
  			if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
! 				if (getty_status)
! 					set_getty(modem->tty[list[i]], 1);
  				sprintf(file, "Can't open port '%s' for read and write", buf);
  				error_win(1, file, NULL);
***************
*** 138,141
  			line_set();
  					/* load the modem data base */
  			for (j=0; j<modem->m_entries; j++) {
  				if (!strcmp(modem->tname[list[i]], modem->mname[j])) {

--- 142,146 -----
  			line_set();
  					/* load the modem data base */
+ 			modem->m_cur = -1;
  			for (j=0; j<modem->m_entries; j++) {
  				if (!strcmp(modem->tname[list[i]], modem->mname[j])) {
*** old/s_axfer.c	Tue May 24 14:21:21 1988
--- s_axfer.c	Tue May 24 15:26:38 1988
***************
*** 86,90
  				break;
  			case 7:
! 				if ((num = num_prompt(x_win, 14, 50, "Transfer timeout", NULL)) != -1) {
  					if (num > MAX_TIMER || num < MIN_TIMER) {
  						beep();

--- 86,90 -----
  				break;
  			case 7:
! 				if ((num = num_prompt(x_win, 14, 50, "Transfer timeout", "")) != -1) {
  					if (num > MAX_TIMER || num < MIN_TIMER) {
  						beep();
*** old/s_gen.c	Tue May 24 14:21:21 1988
--- s_gen.c	Tue May 24 15:27:05 1988
***************
*** 45,49
  		switch(i) {
  			case 1:
! 				if ((ans = str_prompt(g_win, 3, 50, "Default log file", NULL)) != NULL) {
  					free_ptr(param->logfile);
  					param->logfile = strdup(ans);

--- 45,49 -----
  		switch(i) {
  			case 1:
! 				if ((ans = str_prompt(g_win, 3, 50, "Default log file", "")) != NULL) {
  					free_ptr(param->logfile);
  					param->logfile = strdup(ans);
***************
*** 52,56
  				break;
  			case 2:
! 				if ((ans = str_prompt(g_win, 4, 50, "Default screen dump file", NULL)) != NULL) {
  					free_ptr(param->dumpfile);
  					param->dumpfile = strdup(ans);

--- 52,56 -----
  				break;
  			case 2:
! 				if ((ans = str_prompt(g_win, 4, 50, "Default screen dump file", "")) != NULL) {
  					free_ptr(param->dumpfile);
  					param->dumpfile = strdup(ans);
*** old/s_modem.c	Tue May 24 14:21:21 1988
--- s_modem.c	Tue May 24 15:28:04 1988
***************
*** 49,53
  				break;
  			case 3:
! 				if ((ans = str_prompt(mo_win, 5, 40, "Dialing command", NULL)) != NULL) {
  					free_ptr(modem->dial[j]);
  					modem->dial[j] = strdup(ans);

--- 49,53 -----
  				break;
  			case 3:
! 				if ((ans = str_prompt(mo_win, 5, 40, "Dialing command", "")) != NULL) {
  					free_ptr(modem->dial[j]);
  					modem->dial[j] = strdup(ans);
***************
*** 63,69
  				break;
  			case 5:
! 				if ((ans = str_prompt(mo_win, 7, 40, "Hangup string", NULL)) != NULL) {
! 					free_ptr(modem->hangup[j]);
! 					modem->hangup[j] = strdup(ans);
  					ret_code++;
  				}

--- 63,69 -----
  				break;
  			case 5:
! 				if ((ans = str_prompt(mo_win, 7, 40, "Hang up string", "")) != NULL) {
! 					free_ptr(modem->hang_up[j]);
! 					modem->hang_up[j] = strdup(ans);
  					ret_code++;
  				}
***************
*** 70,74
  				break;
  			case 6:
! 				if ((ans = str_prompt(mo_win, 8, 40, "300 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_3[j]);
  					modem->con_3[j] = strdup(ans);

--- 70,74 -----
  				break;
  			case 6:
! 				if ((ans = str_prompt(mo_win, 8, 40, "300 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_3[j]);
  					modem->con_3[j] = strdup(ans);
***************
*** 77,81
  				break;
  			case 7:
! 				if ((ans = str_prompt(mo_win, 9, 40, "1200 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_12[j]);
  					modem->con_12[j] = strdup(ans);

--- 77,81 -----
  				break;
  			case 7:
! 				if ((ans = str_prompt(mo_win, 9, 40, "1200 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_12[j]);
  					modem->con_12[j] = strdup(ans);
***************
*** 84,88
  				break;
  			case 8:
! 				if ((ans = str_prompt(mo_win, 10, 40, "2400 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_24[j]);
  					modem->con_24[j] = strdup(ans);

--- 84,88 -----
  				break;
  			case 8:
! 				if ((ans = str_prompt(mo_win, 10, 40, "2400 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_24[j]);
  					modem->con_24[j] = strdup(ans);
***************
*** 91,95
  				break;
  			case 9:
! 				if ((ans = str_prompt(mo_win, 11, 40, "4800 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_48[j]);
  					modem->con_48[j] = strdup(ans);

--- 91,95 -----
  				break;
  			case 9:
! 				if ((ans = str_prompt(mo_win, 11, 40, "4800 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_48[j]);
  					modem->con_48[j] = strdup(ans);
***************
*** 98,102
  				break;
  			case 10:
! 				if ((ans = str_prompt(mo_win, 12, 40, "9600 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_96[j]);
  					modem->con_96[j] = strdup(ans);

--- 98,102 -----
  				break;
  			case 10:
! 				if ((ans = str_prompt(mo_win, 12, 40, "9600 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_96[j]);
  					modem->con_96[j] = strdup(ans);
***************
*** 105,109
  				break;
  			case 11:
! 				if ((ans = str_prompt(mo_win, 13, 40, "19200 baud connect string", NULL)) != NULL) {
  					free_ptr(modem->con_192[j]);
  					modem->con_192[j] = strdup(ans);

--- 105,109 -----
  				break;
  			case 11:
! 				if ((ans = str_prompt(mo_win, 13, 40, "19200 baud connect string", "")) != NULL) {
  					free_ptr(modem->con_192[j]);
  					modem->con_192[j] = strdup(ans);
***************
*** 112,116
  				break;
  			case 12:
! 				if ((ans = str_prompt(mo_win, 14, 40, "No connect string 1", NULL)) != NULL) {
  					free_ptr(modem->no_con1[j]);
  					modem->no_con1[j] = strdup(ans);

--- 112,116 -----
  				break;
  			case 12:
! 				if ((ans = str_prompt(mo_win, 14, 40, "No connect string 1", "")) != NULL) {
  					free_ptr(modem->no_con1[j]);
  					modem->no_con1[j] = strdup(ans);
***************
*** 119,123
  				break;
  			case 13:
! 				if ((ans = str_prompt(mo_win, 15, 40, "No connect string 2", NULL)) != NULL) {
  					free_ptr(modem->no_con2[j]);
  					modem->no_con2[j] = strdup(ans);

--- 119,123 -----
  				break;
  			case 13:
! 				if ((ans = str_prompt(mo_win, 15, 40, "No connect string 2", "")) != NULL) {
  					free_ptr(modem->no_con2[j]);
  					modem->no_con2[j] = strdup(ans);
***************
*** 126,130
  				break;
  			case 14:
! 				if ((ans = str_prompt(mo_win, 16, 40, "No connect string 3", NULL)) != NULL) {
  					free_ptr(modem->no_con3[j]);
  					modem->no_con3[j] = strdup(ans);

--- 126,130 -----
  				break;
  			case 14:
! 				if ((ans = str_prompt(mo_win, 16, 40, "No connect string 3", "")) != NULL) {
  					free_ptr(modem->no_con3[j]);
  					modem->no_con3[j] = strdup(ans);
***************
*** 133,137
  				break;
  			case 15:
! 				if ((ans = str_prompt(mo_win, 17, 40, "No connect string 4", NULL)) != NULL) {
  					free_ptr(modem->no_con4[j]);
  					modem->no_con4[j] = strdup(ans);

--- 133,137 -----
  				break;
  			case 15:
! 				if ((ans = str_prompt(mo_win, 17, 40, "No connect string 4", "")) != NULL) {
  					free_ptr(modem->no_con4[j]);
  					modem->no_con4[j] = strdup(ans);
***************
*** 209,213
  	mvwprintw(w, 5, 12, "3) Dialing command ........ %-39.39s", modem->dial[i]);
  	mvwprintw(w, 6, 12, "4) Dialing cmd suffix ..... %-39.39s", modem->suffix[i]);
! 	mvwprintw(w, 7, 12, "5) Hangup string .......... %-39.39s", modem->hangup[i]);
  	mvwprintw(w, 8, 12, "6) 300 baud connect ....... %-39.39s", modem->con_3[i]);
  	mvwprintw(w, 9, 12, "7) 1200 baud connect ...... %-39.39s", modem->con_12[i]);

--- 209,213 -----
  	mvwprintw(w, 5, 12, "3) Dialing command ........ %-39.39s", modem->dial[i]);
  	mvwprintw(w, 6, 12, "4) Dialing cmd suffix ..... %-39.39s", modem->suffix[i]);
! 	mvwprintw(w, 7, 12, "5) Hang up string ......... %-39.39s", modem->hang_up[i]);
  	mvwprintw(w, 8, 12, "6) 300 baud connect ....... %-39.39s", modem->con_3[i]);
  	mvwprintw(w, 9, 12, "7) 1200 baud connect ...... %-39.39s", modem->con_12[i]);
*** old/s_prompt.c	Tue May 24 14:21:22 1988
--- s_prompt.c	Tue May 24 15:28:53 1988
***************
*** 132,136
  	while ((ans = wgetch(win)) != '\r') {
  		i++;
! 		if (*menu[i] == NULL)
  			i = 0;
  		if (ans == 27)

--- 132,136 -----
  	while ((ans = wgetch(win)) != '\r') {
  		i++;
! 		if (menu[i] == NULL)
  			i = 0;
  		if (ans == 27)
*** old/s_tty.c	Tue May 24 14:21:22 1988
--- s_tty.c	Tue May 24 15:36:55 1988
***************
*** 81,84
  					beep();
  					mvwaddstr(tt_win, 21, 24, "   ");
  					wrefresh(tt_win);
  					continue;

--- 81,85 -----
  					beep();
  					mvwaddstr(tt_win, 21, 24, "   ");
+ 					wmove(tt_win, 21, 24);
  					wrefresh(tt_win);
  					continue;
***************
*** 90,93
  				disp_tty(tt_win);
  				ret_code = 1;
  			}
  

--- 91,95 -----
  				disp_tty(tt_win);
  				ret_code = 1;
+ 				break;
  			}
  
***************
*** 135,139
  	void free_ptr();
  					/* get temp tty */
! 	if ((ans = str_prompt(win, i+4, 24, "TTY name", NULL)) == NULL)
  		return(1);
  

--- 137,141 -----
  	void free_ptr();
  					/* get temp tty */
! 	if ((ans = str_prompt(win, i+4, 24, "TTY name", "")) == NULL)
  		return(1);
  
***************
*** 142,146
  
  					/* get temp tname */
! 	if ((ans = str_prompt(win, i+4, 39, "Modem name", NULL)) == NULL)
  		return(1);
  

--- 144,148 -----
  
  					/* get temp tname */
! 	if ((ans = str_prompt(win, i+4, 39, "Modem name", "")) == NULL)
  		return(1);
  
*** old/terminal.c	Tue May 24 14:21:23 1988
--- terminal.c	Tue May 24 14:25:54 1988
***************
*** 357,361
  	else
  #endif /* UNIXPC */
! 		send_str(modem->hangup[modem->m_cur]);
  
  	if (verbose)

--- 357,361 -----
  	else
  #endif /* UNIXPC */
! 		send_str(modem->hang_up[modem->m_cur]);
  
  	if (verbose)

root@cca.ucsf.edu (Computer Center) (05/28/88)

In article <13900001@osiris.cso.uiuc.edu>, hood@osiris.cso.uiuc.edu writes:
> 
> This is Patch #5 to the Pcomm version 1.0 distribution package.

Well, I would probably like to have this program available but I have
no idea from the posting where to find it.

Now what coach?

Bug and discussion postings should _always_ include a sufficient
reference to identify the program and indicate where it was posted.

Thos Sumner       (thos@cca.ucsf.edu)   BITNET:  thos@ucsfcca
(The I.G.)        (...ucbvax!ucsfcgl!cca.ucsf!thos)

OS|2 -- an Operating System for puppets.

#include <disclaimer.std>

P.S. In this case, I finally found it by looking for the file name
(not found in the subject line, by the way) in the comp.sources.unix
archive.