[comp.sources.misc] v15i098: pc-mail release 2 patch 3

wswietse@svbs01.bs.win.tue.nl (Wietse Venema) (12/17/90)

Posting-number: Volume 15, Issue 98
Submitted-by: wswietse@svbs01.bs.win.tue.nl (Wietse Venema)
Archive-name: pcmail2/patch03

This is the third patch for the pc-mail release 2 package that appeared
in comp.sources.misc january 1990. 

Sources and earlier patches can be obtained via anonymous ftp from the
comp.sources.misc archives at uunet.uu.net, or from the author's
machine at ftp.win.tue.nl (internet address 131.155.2.8). The latter
host also has a directory tree with up-to-date MS-DOS binaries.

The following four problems are taken care of by this patch:

1 - Allow UUCP control messages (S, H, etc.) to span more than one packet.
    The problem would manifest itself as garbage appearing at the
    beginning of incoming e-mail messages, but only if the g protocol
    was being used. Thanks to Jim OBrien (JEO01@albnydh2.bitnet) for
    providing the information that led to the resolution of the problem.

2 - The sscanf(3) implementations with Microsoft C and Turbo C behave 
    different from the UNIX versions that I tested the programs with. 
    This caused the displayed numbers of (new, out, in or sent) messages 
    to be wrong. The program no longer uses sscanf(3) to parse file names. 

3 - Turbo C thrashes memory when it is freed. The program no longer
    tries to access members of data structures that have been freed.
    Thanks to Richard Brittain (richard@calvin.spp.cornell.edu) for
    pointing out the problem and its solution.

4 - After the protocol negotiation has completed, the program now allows 
    the remote host some time to change its tty mode settings. The problem 
    would sometimes result in the loss of the first packet sent by the PC, 
    and could cause 'g' protocol initialization failures. Thanks to Richard
    Brittain (richard@calvin.spp.cornell.edu) for reporting the problem.

The patches are in the form of context diffs: for each block of changed
text, the old one appears first, followed by the corrected one.  The
nature of the changes is indicated in the first column:  replacements
are indicated with a `!' character, additions with  `+', and deletions
with `-'. If you don't have the patch program it should not be too hard
to apply the corrections by hand.

*** protomsg.c-	Mon Jan 22 13:04:33 1990
--- protomsg.c	Sat Oct 13 19:33:48 1990
***************
*** 45,53 ****
  /* CREATION DATE
  /*      Thu Mar 26 16:14:57 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/01/22 13:02:28
  /* VERSION/RELEASE
! /*	2.1
  /*--*/
  
  #include "defs.h"
--- 45,53 ----
  /* CREATION DATE
  /*      Thu Mar 26 16:14:57 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/10/13 19:33:46
  /* VERSION/RELEASE
! /*	2.3
  /*--*/
  
  #include "defs.h"
***************
*** 90,99 ****
  public char *hear()
  {
      register int nread;
  
!     if ((nread = CALL(Read)(ttfd,msgin,MSGBUF)) < 0)
! 	trap(E_LOST,"FAILED (link lost)");
!     msgin[nread] = '\0';
      debug(4)("got \"%s\"\n",msgin);
      return(msgin);
  }
--- 90,108 ----
  public char *hear()
  {
      register int nread;
+     register int bufpos = 0;
  
!     /* Allow a message to span multiple packets ... */
! 
!     for (;;) {
! 	if ((nread = CALL(Read)(ttfd,msgin+bufpos,MSGBUF-bufpos)) <= 0)
! 	    trap(E_LOST,"FAILED (link lost)");
! 	if ((bufpos += nread) >= MSGBUF)
! 	    trap(E_LOST,"FAILED (message buffer overflow)");
! 	msgin[bufpos] = '\0';
! 	if (strlen(msgin) < bufpos)
! 	    break;
!     }
      debug(4)("got \"%s\"\n",msgin);
      return(msgin);
  }
*** newseqno.c-	Mon Jan 29 15:50:48 1990
--- newseqno.c	Sat Oct 13 18:47:33 1990
***************
*** 30,40 ****
  /* CREATION DATE
  /*      Sat Mar 28 18:10:53 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/01/29 15:50:46
  /* VERSION/RELEASE
! /*	2.2
  /*--*/
  
  #include "defs.h"
  #include "path.h"
  #include "ndir.h"
--- 30,42 ----
  /* CREATION DATE
  /*      Sat Mar 28 18:10:53 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/10/13 18:47:32
  /* VERSION/RELEASE
! /*	2.4
  /*--*/
  
+ #include <ctype.h>
+ 
  #include "defs.h"
  #include "path.h"
  #include "ndir.h"
***************
*** 72,85 ****
  public unsigned seqno(s)
  char   *s;
  {
!     unsigned seq;
!     char    junk = 0;
  
!     /* MicroSoft C sscanf() does not terminate if assignment to seq fails */
  
!     if (strlen(s) == NAMELEN && sscanf(s + 1, "%u%c", &seq, &junk) == 1
!     && junk == 0)
! 	return (seq);
      else
  	return (0);
  }
--- 74,104 ----
  public unsigned seqno(s)
  char   *s;
  {
!     long    atol();
  
!     /*
!      * Originally, we used sscanf() to parse the string:
!      * 
!      * sscanf(s, "%u%c", &seq, &junk) == 1
!      * 
!      * but that caused problems with Microsoft C (%c conversion is done even
!      * if the %u conversion fails) and Turbo C (assigment to junk even if no
!      * %c conversion is performed). Remedy: do not try to parse the string with
!      * sscanf().
!      */
  
!     if (strlen(s) == NAMELEN && isalpha(*s) && alldig(s+1))
! 	return ((unsigned int) atol(s+1));
      else
  	return (0);
+ }
+ 
+ /* alldig - does string contain digits only? */
+ 
+ hidden int alldig(s)
+ register char *s;
+ {
+     while (*s && isascii(*s) && isdigit(*s))
+ 	s++;
+     return (*s == 0);
  }
*** pager.c-	Tue Apr 17 11:41:39 1990
--- pager.c	Tue Apr 17 11:45:53 1990
***************
*** 142,150 ****
  /* CREATION DATE
  /*      Fri Apr  3 22:06:00 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/01/22 13:02:21
  /* VERSION/RELEASE
! /*	2.1
  /*--*/
  
  #include <stdio.h>
--- 142,150 ----
  /* CREATION DATE
  /*      Fri Apr  3 22:06:00 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/04/17 11:45:48
  /* VERSION/RELEASE
! /*	2.2
  /*--*/
  
  #include <stdio.h>
***************
*** 171,183 ****
  /* close_pager - release memory in a pager file */
  
  public void close_pager(p)
! register File *p;
  {
      register Line *q;
  
      if (p) {
! 	for (q = p->head; q; q = q->next)	/* release lines */
  	    free((char *) q);
  	if (curfile == p)			/* unset current file */
  	    curfile = 0;
  	free((char *) p);			/* release header */
--- 171,186 ----
  /* close_pager - release memory in a pager file */
  
  public void close_pager(p)
! File   *p;
  {
      register Line *q;
+     register Line *next;
  
      if (p) {
! 	for (q = p->head; q; q = next) {	/* release lines */
! 	    next = q->next;			/* avoid using freed block */
  	    free((char *) q);
+ 	}
  	if (curfile == p)			/* unset current file */
  	    curfile = 0;
  	free((char *) p);			/* release header */
*** startup.c-	Mon Jan 22 13:04:38 1990
--- startup.c	Sat Oct 13 19:01:39 1990
***************
*** 40,48 ****
  /* CREATION DATE
  /*      Fri Mar 27 13:43:00 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/01/22 13:02:41
  /* VERSION/RELEASE
! /*	2.1
  /*--*/
  
  #include <stdio.h>
--- 40,48 ----
  /* CREATION DATE
  /*      Fri Mar 27 13:43:00 GMT+1:00 1987
  /* LAST MODIFICATION
! /*	90/10/13 19:01:38
  /* VERSION/RELEASE
! /*	2.2
  /*--*/
  
  #include <stdio.h>
***************
*** 129,134 ****
--- 129,138 ----
  
      log("OK (startup)");
      systrap = savetrap;				/* get here if expect wins */
+ 
+     /* Give remote host some time to switch tty modes... */
+ 
+     sleep(1);
      return (0);
  }
  
***************
*** 136,143 ****
  
  public  endproto()
  {
-     int    *savetrap = systrap;			/* save exception handler */
-     jmp_buf mytrap;
      int     status;
  
      if (Close)					/* check there is one */
--- 140,145 ----