[comp.unix.xenix] Pcomm patches for Xenix 2.3.1

jbayer@ispi.UUCP (Jonathan Bayer) (11/20/88)

Due to demand I am re-posting these patches to Pcomm 1.1.


THIS IS NOT AN OFFICIAL PATCH


These are the local mods made to Pcomm with all five official patches
applied first.  It includes all of my previous patches as described below:

****************************

The enclosed patches fix two problems with pcomm 1.1, with the first
patch applied.

The first bug is that after pcomm sets the CLOCAL mode it doesn't
re-open the tty port.  This is important if the program is sharing a
dial-out port with uucp and you have to specify a port which has modem
control.  In this case the program would just chug merrily along
sending characters to the modem, while the OS would not pass them along
to the modem.

The addition to port.c allows Pcomm to be able to access the modem if
the port was originally opened with modem control.  line_set() removes
the modem control, but the open file still has it.  By re-opening the
port here, and then closing the old file descriptor, Pcomm can access
the port correctly.

The second bug is not with Pcomm directly, but with some stupid modems
which are on the market.  Some modems cannot receive the AT commands at
the full baud rate they are set at.  The sent_str() routine is the
problem here.  The modifications force Pcomm to send characters to the
modem at a rate of 10 chars per second.  Each character is sent at the
correct baud rate, there is just a delay of 1/10 sec inserted between
each character.  The modem commands in port.c which use the send_str()
function now call slow_send_str().  See the changes in both port.c and
dial.c.  The function do_pause() is dial.c does the delay.  do_pause()
depends on the environment variable HZ to store the number of clock
ticks per second.  


A few features I would like to see added to pcomm are:
1.	VERY IMPORTANT: Please add a patchlevel.h file indicating
	the patchlevel of the current system.
2.	a local dialing directory, probably with a name like:
		.pcomm.phone
	in the user's home directory

3.	zmodem support built in, possibly using external programs
4.	Compuserve B protocol
5.	Adding the lock file format and location to the configuration file.
6.	A possible check of long distance numbers is to limit the number
	of digits in a phone number.  Also, specify which digit would be
	the SECOND digit of the area code; if it is a zero or a 1 then
	it is an area code and therefore a long-distance number.  I have
	not done any work on this since I don't have that problem.

*********************

Adds option to control what happens when a hang up command is given

*********************

	A word of explanation;  I use rz/sz almost exclusively, and
having to type in the external command every time is a small pain. 
These patches add a line to the up/download menu called zmodem.  The
patches are set up so that a compile time option called ZMODM must be
defined for them to take effect.  The only file you have to worry about
in these patches is "config.h".  The options are set up for my system,
and they probably are a little different from the options in the
distribution files.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*** Makefile	Wed Oct 19 12:12:44 1988
--- ../src/Makefile	Wed Oct 19 12:24:16 1988
***************
*** 6,17 ****
  #GETCWD = getcwd.o
  #GETOPT = getopt.o
  
! CFLAGS = -O
  #CURSES = -ltermlib -lcurses
  CURSES = -lcurses
! LDFLAGS = -s
  SHAR = shar -a
  BIN = /usr/local/bin
  
  PCOMM = $(GETCWD) $(GETOPT) admin.o chg_dir.o curses.o d_delete.o \
  	d_lib.o d_manual.o d_menu.o d_print.o d_prompt.o d_revise.o \
--- 6,18 ----
  #GETCWD = getcwd.o
  #GETOPT = getopt.o
  
! CFLAGS = -Ox -DM_TERMINFO 
  #CURSES = -ltermlib -lcurses
  CURSES = -lcurses
! LDFLAGS = -s -ltinfo -lx
  SHAR = shar -a
  BIN = /usr/local/bin
+ CC = mcc
  
  PCOMM = $(GETCWD) $(GETOPT) admin.o chg_dir.o curses.o d_delete.o \
  	d_lib.o d_manual.o d_menu.o d_print.o d_prompt.o d_revise.o \
*** config.h	Wed Oct 19 12:12:46 1988
--- ../src/config.h	Wed Oct 19 12:21:04 1988
***************
*** 13,25 ****
  #define	SHAREDMEM
  
  /* Should a missing video attribute be promoted to standout? */
! #define NOPROMOTE
  
  /* Use extra precautions if Pcomm is set-user-id or set-group-id */
! #undef	SETUGID
  
  /* Should Pcomm make a log of all phone calls? */
  #undef	LOG_CALLS
  
  /* The name of the log file (if used).  */
  #define	LOGFILE		"/usr/adm/phone.calls"
--- 13,27 ----
  #define	SHAREDMEM
  
  /* Should a missing video attribute be promoted to standout? */
! #undef  NOPROMOTE
  
  /* Use extra precautions if Pcomm is set-user-id or set-group-id */
! /* #undef	SETUGID */
! #define	SETUGID
  
  /* Should Pcomm make a log of all phone calls? */
  #undef	LOG_CALLS
+ /* #define	LOG_CALLS */
  
  /* The name of the log file (if used).  */
  #define	LOGFILE		"/usr/adm/phone.calls"
***************
*** 46,55 ****
  #undef	ASCII_PID
  
  /* Should Pcomm optimize redialing by keeping the TTY port open */
! #define	KEEP_PORT
  
  /* Does the status line scroll up on "magic cookie" terminals? */
  #undef	XMC_BROKE
  
  /* Does the alarm() system call work correctly with the wgetch() function? */
  #undef	WGETCH_BROKE
--- 48,63 ----
  #undef	ASCII_PID
  
  /* Should Pcomm optimize redialing by keeping the TTY port open */
! /* #define	KEEP_PORT */
  
  /* Does the status line scroll up on "magic cookie" terminals? */
  #undef	XMC_BROKE
  
  /* Does the alarm() system call work correctly with the wgetch() function? */
  #undef	WGETCH_BROKE
+ 
+ /* are the rz/sz zmodem routines available ? */
+ #define	ZMODM
+ 
+ /* Disconnect from port when hang up command given? */
+ #undef	D_ON_HUP
*** dial.c	Wed Oct 19 12:12:50 1988
--- ../src/dial.c	Wed Oct 19 12:14:36 1988
***************
*** 123,133 ****
--- 123,182 ----
  	return;
  }
  
+ 
+ /* The following routines was added by J. Bayer to slow down the transmission
+ ** of commands to the modem.  Some modems choke if the commands are sent
+ ** at full speed.  This code is designed to send the commands at a speed
+ ** of app. 10 characters per second.  This is different from the baud rate
+ */
+ int	slow_send = 0;
+ 
+ /*	do_pause	depends on the environment variable HZ to store
+ **			the number of clock ticks per second.  If it is
+ **			not there then it will default to 50, which is
+ **			a reasonable number for Xenix
+ */
+ 
+ void do_pause()
+ {
+ #include	<sys/types.h>
+ #include	<sys/times.h>
+ struct	tms	t;
+ long		t1;
+ int		hz = 0;
+ char		*home;
+ 	unsigned int sleep();
+ 
+ 	if ((home = getenv("HZ")) != NULL)
+ 		hz = atoi(home);
+ 	if (!hz) hz = 50;
+ 
+ 	t1 = times(&t);
+ 	while ( (times(&t) - t1) < hz/10); 
+ } /* do_pause */
+ 
+ 
+ void
+ slow_send_str(s)
+ char *s;
+ {
+ void	send_str();
+ 
+ 	slow_send++;
+ 	send_str(s);
+ 	slow_send--;
+ } /* slow_send_str */
+ 
+ 
+ 
+ 
+ 
  /*
   * Send a string to the modem.  Performs all the character synonym
   * translations.  No sanity checking on the "m_cur" value.
   */
  
+ 
  void
  send_str(s)
  char *s;
***************
*** 151,156 ****
--- 200,206 ----
  		if (skip) {
  			skip = 0;
  			write(fd, s, 1);
+ 			if (slow_send) do_pause();
  			ioctl(fd, TCSBRK, 1);
  #ifdef DEBUG
  			fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s);
***************
*** 197,202 ****
--- 247,254 ----
  		}
  
  		write(fd, s, 1);
+ 		if (slow_send) do_pause();
+ 		
  #ifdef DEBUG
  		fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s);
  #endif /* DEBUG */
***************
*** 209,214 ****
--- 261,268 ----
  	}
  	return;
  }
+ 
+ 
  
  /*
   * Read the result codes coming back from the modem.  Test for the 6
*** port.c	Wed Oct 19 12:13:00 1988
--- ../src/port.c	Wed Oct 19 12:19:41 1988
***************
*** 31,42 ****
  	int j, k, lfd, list[NUM_TTY], cmask, tbaud, is_dev;
  	char file[80], buf[80], message[80], *strdup();
  	unsigned int sleep();
! 	void error_win(), line_set(), release_port(), send_str();
  	void free_ptr();
  #ifndef ASCII_PID
  	int progpid;
  #endif /* ASCII_PID */
  
  	is_dev = chk_index(dir->index[dir->d_cur]);
  	/*
  	 * If we already have a port, see if it is good enough for the
--- 31,44 ----
  	int j, k, lfd, list[NUM_TTY], cmask, tbaud, is_dev;
  	char file[80], buf[80], message[80], *strdup();
  	unsigned int sleep();
! 	void error_win(), line_set(), release_port(), send_str(), slow_send_str();
  	void free_ptr();
  #ifndef ASCII_PID
  	int progpid;
  #endif /* ASCII_PID */
  
+   	int	fd1;	/* added by J. Bayer  */
+  	
  	is_dev = chk_index(dir->index[dir->d_cur]);
  	/*
  	 * If we already have a port, see if it is good enough for the
***************
*** 139,145 ****
  
  					/* open the device (ignore DCD) */
  			sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
! 			if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
  				if (getty_status)
  					set_getty(modem->tty[modem->t_cur], 1);
  				sprintf(file, "Can't open port '%s' for read and write", buf);
--- 141,147 ----
  
  					/* open the device (ignore DCD) */
  			sprintf(buf, "/dev/%s", modem->tty[modem->t_cur]);
! 			if ((fd1 = fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
  				if (getty_status)
  					set_getty(modem->tty[modem->t_cur], 1);
  				sprintf(file, "Can't open port '%s' for read and write", buf);
***************
*** 147,152 ****
--- 149,173 ----
  			}
  					/* change line settings */
  			line_set();
+ 
+ 		/* This section added by J. Bayer.  It allows Pcomm to be
+ 		** able to access the modem if the port was originally opened
+ 		** with modem control.  line_set() removes the modem control,
+ 		** but the open file still has it.  By re-opening the port
+ 		** here, and then closing the old file descriptor, Pcomm
+ 		** can access the port correctly
+ 		*/
+ 		
+ 			if ((fd = open(buf, O_RDWR)) < 0) {
+ 				if (getty_status)
+ 					set_getty(modem->tty[modem->t_cur], 1);
+ 				sprintf(file, "Can't open port '%s' for read and write", buf);
+ 				error_win(1, file, "");
+ 			}
+ 			close(fd1);
+ 
+ 		/* End of addition */
+ 
  					/* turn off the "no delay" mode */
  			fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
  					/* load the modem data base */
***************
*** 167,177 ****
  				tbaud = dir->baud[dir->d_cur];
  				dir->baud[dir->d_cur] = modem->init_sp[modem->t_cur];
  				line_set();
! 				send_str(modem->init[modem->m_cur]);
  				dir->baud[dir->d_cur] = tbaud;
  			}
  			else
! 				send_str(modem->init[modem->m_cur]);
  			sleep(1);
  			return(0);
  		}
--- 188,208 ----
  				tbaud = dir->baud[dir->d_cur];
  				dir->baud[dir->d_cur] = modem->init_sp[modem->t_cur];
  				line_set();
! 				
! 		/* changed by J. Bayer to be a slow send.  See my comments
! 		** in dial.c for the reason.
! 		*/
! 		
! 				slow_send_str(modem->init[modem->m_cur]);
  				dir->baud[dir->d_cur] = tbaud;
  			}
  			else
! 				
! 		/* changed by J. Bayer to be a slow send.  See my comments
! 		** in dial.c for the reason.
! 		*/
! 		
! 				slow_send_str(modem->init[modem->m_cur]);
  			sleep(1);
  			return(0);
  		}
*** terminal.c	Wed Oct 19 12:13:04 1988
--- ../src/terminal.c	Wed Oct 19 12:20:33 1988
***************
*** 31,37 ****
  	void help_screen(), line_set(), n_shell(), load_vs(), send_str();
  	void release_port(), do_input(), list_dir(), pexit(), zap_vs();
  	void st_line(), chg_dir(), screen_dump(), input_off(), suspend();
! 	void info(), term_mode();
  
  					/* if starting out in command mode */
  	if (!input_status)
--- 31,37 ----
  	void help_screen(), line_set(), n_shell(), load_vs(), send_str();
  	void release_port(), do_input(), list_dir(), pexit(), zap_vs();
  	void st_line(), chg_dir(), screen_dump(), input_off(), suspend();
! 	void info(), term_mode(), hang_up();
  
  					/* if starting out in command mode */
  	if (!input_status)
***************
*** 132,139 ****
--- 132,143 ----
  					break;
  				case 'h':
  				case 'H':	/* hang up phone */
+ #ifdef	D_ON_HUP
  					release_port(1);
  					input_off();
+ #else
+ 					hang_up(1);
+ #endif
  					break;
  				case 'l':
  				case 'L':	/* toggle printer */
*** x_menu.c	Wed Oct 19 12:13:08 1988
--- ../src/x_menu.c	Wed Oct 19 12:21:04 1988
***************
*** 31,37 ****
--- 31,42 ----
  	mvwaddstr(xm_win, 5, 3, "4) ymodem");
  	mvwaddstr(xm_win, 6, 3, "5) ymodem-g");
  	mvwaddstr(xm_win, 7, 3, "6) ASCII");
+ #ifdef	ZMODM
+ 	mvwaddstr(xm_win, 8, 3, "7) zmodem");
+ 	mvwaddstr(xm_win, 9, 3, "8) (external)");
+ #else
  	mvwaddstr(xm_win, 8, 3, "7) (external)");
+ #endif
  	mvwaddstr(xm_win, 11, 3, "<ESC> to Abort");
  	mvwaddstr(xm_win, 13, 3, "Protocol:");
  	box(xm_win, VERT, HORZ);
***************
*** 77,82 ****
--- 82,90 ----
  		case MODEM7:
  		case YMODEM:
  		case YMODEM_G:
+ #ifdef	ZMODM
+ 		case ZMODEM:
+ #endif
  			is_batch++;
  			break;
  		default:
***************
*** 106,112 ****
  }
  
  char *protocol[PROTOCOLS] = {"xmodem", "xmodem-1k", "modem7", "ymodem",
! 	"ymodem-g", "ASCII", "(external)"};
  
  /*
   * Prompt for a list of files for the transfer programs.  A NULL return
--- 114,124 ----
  }
  
  char *protocol[PROTOCOLS] = {"xmodem", "xmodem-1k", "modem7", "ymodem",
! 	"ymodem-g", "ASCII",
! #ifdef	ZMODM
! 		"zmodem",
! #endif
! 			"(external)"};
  
  /*
   * Prompt for a list of files for the transfer programs.  A NULL return
*** x_rcv.c	Wed Oct 19 12:13:09 1988
--- ../src/x_rcv.c	Wed Oct 19 12:21:06 1988
***************
*** 63,68 ****
--- 63,77 ----
  			max_block = 1024;
  			performance = 1.02;
  			break;
+ #ifdef	ZMODM
+ 		case ZMODEM:
+ 		{
+ 		void	extrnl();
+ 		
+ 			extrnl("rz");
+ 			return 0;
+ 		}
+ #endif
  		default:
  			return(1);
  	}
*** x_send.c	Wed Oct 19 12:13:10 1988
--- ../src/x_send.c	Wed Oct 19 12:21:07 1988
***************
*** 65,70 ****
--- 65,82 ----
  			max_block = 1024;
  			performance = 1.02;
  			break;
+ #ifdef	ZMODM
+ 		case ZMODEM:
+ 		{
+ 		void	extrnl();
+ 		char	str[255];
+ 
+ 			strcpy(str,"sz ");
+ 			strcat(str,list);
+ 			extrnl(str);
+ 			return(0);
+ 		}
+ #endif
  		default:
  			return(1);
  	}
*** x_win.c	Wed Oct 19 12:13:10 1988
--- ../src/x_win.c	Wed Oct 19 12:21:08 1988
***************
*** 29,34 ****
--- 29,37 ----
  	refresh();
  	st_line("");
  
+ #ifdef	ZMODM
+ 	if (type != ZMODEM) {
+ #endif
  	xf_win = newwin(15, 44, 2, 30);
  	/*
  	 * This window should be in the non-blocking mode, so we can
***************
*** 74,84 ****
--- 77,93 ----
  	if (my_speed >= dir->baud[dir->d_cur])
  		fast++;
  
+ #ifdef	ZMODM
+ 	}
+ #endif
  	if (up)
  		ret_code = send_xmodem(xf_win, list, type, fast);
  	else
  		ret_code = rcv_xmodem(xf_win, list, type, fast);
  
+ #ifdef	ZMODM
+ 	if (type != ZMODEM) {
+ #endif
  	nodelay(xf_win, 0);
  					/* prompt for a key on errors */
  	if (ret_code) {
***************
*** 91,96 ****
--- 100,108 ----
  	werase(xf_win);
  	wrefresh(xf_win);
  	delwin(xf_win);
+ #ifdef	ZMODM
+ 	}
+ #endif
  					/* undo what xmodem_mode() did */
  	line_set();
  	return;
*** xmodem.h	Wed Oct 19 12:13:11 1988
--- ../src/xmodem.h	Wed Oct 19 12:21:08 1988
***************
*** 12,25 ****
--- 12,35 ----
  #define CAN		24
  #define CTRLZ		26
  
+ #ifdef	ZMODM
+ #define PROTOCOLS	8
+ #else
  #define PROTOCOLS	7
+ #endif
  #define XMODEM		0
  #define XMODEM_1k	1
  #define MODEM7		2
  #define YMODEM		3
  #define YMODEM_G	4
  #define XASCII		5
+ 
+ #ifdef	ZMODM
+ #define	ZMODEM		6
+ #define	EXTRNL		7
+ #else
  #define EXTRNL		6
+ #endif
  
  #define ABORT		(-1)
  #define ERROR		(-2)

jbayer@ispi.UUCP (Jonathan Bayer) (11/20/88)

I have received a number of inquiries regarding my patches to pcomm to
make it work on Xenix 386, v 2.3.1.

These patches apply  to Pcomm 1.1 with all five official patches
applied.  If you are running Xenix you should apply the other patches I
posted first.


THIS IS NOT AN OFFICIAL PATCH


The following patches fixes pcomm to work properly with the version
of HDB that comes with SCO Xenix 2.3.1.  The patch will work for any
HDB system since the one line that is specific to SCO Xenix is ifdef'ed
in place.

A word of explaination:  SCO uses two device names to refer to
the same modem port, one for modem control, and one for no modem
control.  This created problems in the past since when one port was
locked the other was not.  The port names all end with a letter, with
the case of the letter indicating whether modem control is active or
not.  A capitol letter indicates modem control.  SCO has specified in
the new HDB that the last letter should be folded into lower case,
thereby ensuring that when one port is locked both of them are.  The
below patch adds this to pcomm.



- - - - - - - patch starts here - - - - - - - - - -
*** ../oldsrc/config.h	Sat Nov 19 13:13:52 1988
--- config.h	Wed Nov 16 22:42:10 1988
***************
*** 45,51 ****
  #define	LOCK_DIR	"/usr/spool/uucp"
  
  /* Do the lock files use ASCII encoded PID's? */
! #undef	ASCII_PID
  
  /* Should Pcomm optimize redialing by keeping the TTY port open */
  /* #define	KEEP_PORT */
--- 45,52 ----
  #define	LOCK_DIR	"/usr/spool/uucp"
  
  /* Do the lock files use ASCII encoded PID's? */
! /* #undef	ASCII_PID */
! #define		ASCII_PID
  
  /* Should Pcomm optimize redialing by keeping the TTY port open */
  /* #define	KEEP_PORT */
*** ../oldsrc/port.c	Sat Nov 19 13:13:53 1988
--- port.c	Fri Nov 18 23:59:07 1988
***************
*** 110,115 ****
--- 110,120 ----
  	while (list[i] != -1) {
  					/* create a lock file name */
  		sprintf(file, "%s/LCK..%s", LOCK_DIR, modem->tty[list[i]]);
+ #ifdef	ASCII_PID
+ #ifdef	M_XENIX
+ 		file[strlen(file) - 1] = tolower(file[strlen(file) - 1]);
+ #endif
+ #endif
  #ifdef DEBUG
  		fprintf(stderr, "get_port: checking '/dev/%s'\n", modem->tty[list[i]]);
  #endif /* DEBUG */