C-KERMIT 6.0 PATCHES -- Source-code patches for C-Kermit 6.0.192 Most recent update: Tue Mar 10 16:50:30 1998 Highest patch number: 37 You can apply these patches if you have source code and the necessary C compiler and libraries to build a new executable. There is no need to apply any patch if it does not apply to your configuration, or if the symptom does not affect you or your users. Each patch is self-contained and independent from the others, unless otherwise noted. Line numbers correspond to the source-code files of the 6.0.192 release. The patches included in this file are believed to be safe, but come with no guarantees. In particular, those submitted by users fall into the "use at your own risk" category. The patches appear in chronological order in email-message format separated by lines of equal signs (=). CONTENTS: Number Domain Description 0001 All UNIX C-Kermit mishandles timestamps on files before 1970 0002 Solaris 2.5++ Compilation error on Solaris 2.5 with Pro C 0003 All VMS CKERMIT.INI Fix for VMS 0004 VMS/VAX/UCX 2.0 C-Kermit 6.0 can't TELNET on VAX/VMS with UCX 2.0 0005 All C-Kermit Might Send Packets Outside Window 0006 All MOVE from SEND-LIST does not delete original files 0007 Solaris 2.5++ Higher serial speeds on Solaris 2.5 0008 All C-Kermit application file name can't contain spaces 0009 AT&T 7300 UNIXPC setuid and hardware flow-control problems 0010 Linux on Alpha Patch to make ckutio.c compile on Linux/Alpha 0011 OS-9/68000 2.4 Patch to make ck9con.c compile on OS-9/68000 2.4 0012 MW Coherent 4.2 Patches for successful build on Coherent 4.2 0013 SINIX-Y 5.43 "delay" variable conflicts with 0014 VMS/VAX/CMU-IP Subject: Patches for VAX/VMS 5.x + CMU-IP 0015 All XECHO doesn't flush its output 0016 VMS CD and other directory operations might not work 0017 Linux 1.2.x++ Use standard POSIX interface for high serial speeds 0018 UNIX SET WILDCARD-EXPANSION SHELL dumps core 0019 All Hayes V.34 modem init string problem 0020 All READ command does not fail if file not open 0021 All Problems with long function arguments 0022 All Certain \function()s can misbehave 0023 All X MOD 0 crashes program 0024 All Internal bulletproofing for lower() function 0025 OpenBSD Real OpenBSD support for C-Kermit 6.0 0026 All Incorrect checks for macro/command-file nesting depth 0027 All ANSWER doesn't automatically CONNECT 0028 All Overzealous EXIT warning 0029 All OUTPUT doesn't echo when DUPLEX is HALF 0030 All Minor problems with REMOTE DIRECTORY/DELETE/etc 0031 All CHECK command broken 0032 All Problem with SET TRANSMIT ECHO 0033 UNIX, VMS, etc HELP SET SERVER says too much 0034 All READ and !READ too picky about line terminators 0035 All END from inside SWITCH doesn't work 0036 All Problem telnetting to multihomed hosts 0037 All Redirection failures in REMOTE xxx > file Legend: ++ means "and above" ---------------------------------------------------------------------------- PATCH-LEVEL ANNOUNCEMENT If you install any patches, you should also install an indicator of which patches were installed. This is done as follows: 1. In ckcmai.c, after the line: char *ck_ver = "C-Kermit 6.0.192"; /* C-Kermit Version */ add a new line such as: char *ck_patch = "1 2 3 4 8 10"; /* Patches */ The string contains the patch number of each patch that has been installed, separated by spaces. A range of patches can be indicated in the customary hyphenated notation: char *ck_patch = "1-4 8 10"; /* Patches */ 2. Make the following change to the VERSION command in ckuusr.c: *** /w/pub/ftp/kermit/f/ckuusr.c Sun Nov 24 19:20:51 1996 --- ./ckuusr.c Sat Jan 11 11:58:14 1997 *************** *** 3677,3694 **** #endif /* NOCSETS */ if (cx == XXVER) { /* VERSION */ + extern char * ck_patch; if ((y = cmcfm()) < 0) return(y); printf("%s, for%s\n Numeric: %ld",versio,ckxsys,vernum); if (xvernum) printf("C-Kermit %s",ck_ver); if (verwho) printf("-%d\n",verwho); else printf("\n"); + if (*ck_patch) + printf(" Patches: %s\n", ck_patch); hmsga(copyright); #ifdef OS2 shoreg(); #endif /* OS2 */ return(success = 1); } 3. And make a similar change to the shover() routine in ckuus5.c: *** /w/pub/ftp/kermit/f/ckuus5.c Sun Nov 24 19:20:50 1996 --- ./ckuus5.c Sat Jan 11 12:03:41 1997 *************** *** 2663,2673 **** --- 2663,2675 ---- shover() { extern long xvernum; extern char *ck_ver; + extern char *ck_patch; printf("\nVersions:\n %s\n Numeric: %ld",versio,vernum); if (verwho) printf("-%d",verwho); printf("\n"); if (xvernum) printf("C-Kermit %s\n",ck_ver); + if (*ck_patch) printf(" Patches: %s\n", ck_patch); printf(xxdiff(ckxv,ckxsys) ? " %s for%s\n" : " %s\n",ckxv,ckxsys); printf(xxdiff(ckzv,ckzsys) ? " %s for%s\n" : " %s\n",ckzv,ckzsys); printf(" %s\n",protv); ... Whenever you install a new patch, be sure to update the ck_patch string in ckcmai.c, and then the VERSION and SHOW VERSION commands will indicate the patch level. ==================== X-Patch-Number: 0001 Date: Sun, 1 Dec 1996 22:16:56 -0800 From: Paul Eggert To: kermit-support@columbia.edu Subject: C-Kermit mishandles timestamps on files before 1970 C-Kermit 6.0.192 rejects files whose timestamps are before 1970-01-01 local time. But every Unix can represent files with timestamps before that. It's common, for example, in the US/Pacific time zone to have a file with timestamp 1969-12-31 16:00:00 local time, since this equals 1970-01-01 00:00:00 UTC. And many Unixes can represent times before the epoch, e.g. on Solaris 2.5.1: $ uname -a SunOS shade 5.5.1 Generic_103640-03 sun4u sparc SUNW,Ultra-1 $ echo $TZ UTC0 $ ls -l test -rw-rw-r-- 1 eggert eggert 0 Dec 13 1901 test It is certainly not a requirement of the ANSI C Library, or of Posix, that timestamps before 1970 cannot be represented. Here is a patch: RCS file: RCS/ckufio.c,v retrieving revision 6.0.192.0 retrieving revision 6.0.192.1 diff -c -r6.0.192.0 -r6.0.192.1 *** ckufio.c 1996/11/23 19:27:13 6.0.192.0 --- ckufio.c 1996/12/02 06:07:54 6.0.192.1 *************** *** 2659,2666 **** yy = time_stamp->tm_year; /* Year - 1900 */ yy += 1900; debug(F101,"zdatstr year","",yy); - if (yy < 1970) /* By definition of C library */ - return(""); if (time_stamp->tm_mon < 0 || time_stamp->tm_mon > 11) return(""); --- 2659,2664 ---- [It is not known if this patch is safe on all UNIX platforms.] ==================== X-Patch-Number: 0002 Date: Mon, 02 Dec 1996 13:47:13 -0500 To: kermit-support@columbia.edu Subject: Compilation error on Solaris 2.5 with Pro C From: "David J. Fiander" I defined CK_ENVIRONMENT and found that the prototype for tn_snenv() in ckcnet.h conflicted with the function definition in ckcnet.c. the former declared the first parameter to be a CHAR * (i.e. an unsigned char *), while the latter declared to be a char * (i.e. signed char *). The Pro C compiler treats this as an error. I changed the function definition in ckcnet.c to declare the parameter as a CHAR * and the problem was resolved. - David [Note: This problem does not occur with standard builds. Resolution: CK_ENVIRONMENT, which controls the use of TELNET NEW-ENVIRONMENT protocol, is not supported in the UNIX version of C-Kermit 6.0.192. The type mismatch is a mistake, however.] ==================== X-Patch-Number: 0003 Date: Tue, 3 Dec 96 10:56:50 EST From: Mike Freeman Subject: CKERMIT.INI Fix for VMS A minor fix to CKERMIT.INI from the 6-Sep release is shown below. Needed to get C-Kermit 6(192) to run on my Vax/VMS system with VmS V5.5-2 and VAX C V3.1. *** $ker:ckermit.ini;-1 --- $ker:ckermit.ini; ************** *** 680,686 ; In VMS and OpenVMS, allow for system-wide site customizations ! if equal "\v(system)" "VMS" { xif exist CKERMIT_INI:CKERMIT.SYS { echo Executing CKERMIT_INI:CKERMIT.SYS take CKERMIT_INI:CKERMIT.SYS --- 680,686 ----- ; In VMS and OpenVMS, allow for system-wide site customizations ! xif equal "\v(system)" "VMS" { xif exist CKERMIT_INI:CKERMIT.SYS { echo Executing CKERMIT_INI:CKERMIT.SYS take CKERMIT_INI:CKERMIT.SYS MIke Freeman | Internet: freeman@watsun.cc.columbia.edu Amateur Radio Calsign: K7UIJ | */ PGP Public Key Available */ ==================== X-Patch-Number: 0004 Date: Thu, 5 Dec 1996 15:20:00 EST From: Frank da Cruz Subject: C-Kermit 6.0 can't TELNET on VAX/VMS with UCX 2.0 PROBLEM: On VAX/VMS systems with early versions of DEC TCP/IP (UCX), "set host" and "telnet" commands might fail with "Connection refused", even though the system (UCX) TELNET program to the same host works correctly. DIAGNOSIS: If you don't specify a port, Kermit substitutes the service name "telnet" and then asks UCX to look it up; similary, if you specify a port by name, rather than number, Kermit asks UCX to look it up. On VAX/VMS with DEC TCP/IP UCX 2.0, 2.0A, 2.0B, or 2.0C, the getservbyname() function fails to return the port number in network byte order as it should, and instead returns the number with its bytes swapped (e.g. 5888 instead of 23). Then Kermit tries to connect to port 5888 on the host; most hosts will refuse the connection; if they don't, you probably didn't reach a Telnet port anyway. This bug was fixed in UCX 2.0D and thereafter. However, there is no way for Kermit to know which version of UCX is being used. WORKAROUND: Specify the port number (not name) in your SET HOST or TELNET command, e.g.: set host xyzcorp.com 23 CURE: A new command: SET TCP UCX-PORT-BUG { ON, OFF } It is OFF by default, so UCX versions of VMS C-Kermit will work with all latter-day versions of UCX with no special effort. But if you have an old UCX system, and you tell C-Kermit to "set host" or "telnet" and it says "Connection refused", tell it to SET TCP UCX-PORT-BUG ON and try again. If this works, then put this command into your (or the system-wide) CKERMIT.INI file. The following patch adds this command to VMS versions of C-Kermit that were built for UCX support. It has already been applied to the CKVV55-UCX20 binary in the Kermit archive. PATCH: *** /w/pub/ftp/kermit/f/ckcnet.c Wed Nov 27 19:54:46 1996 --- ./ckcnet.c Wed Dec 4 17:14:41 1996 *************** *** 1,4 **** ! char *cknetv = "Network support, 6.0.078, 6 Sep 1996"; /* C K C N E T -- Network support */ --- 1,4 ---- ! char *cknetv = "Network support, 6.0.079, 4 Dec 1996"; /* C K C N E T -- Network support */ *************** *** 960,965 **** --- 960,967 ---- extern VOID C$$SOCK_TRANSLATE(); #endif /* CK_ANSIC */ + int ucx_port_bug = 0; /* Explained below */ + struct servent * my_getservbyname (service, proto) char *service, *proto; { static struct servent sent; *************** *** 1007,1035 **** C$$SOCK_TRANSLATE(&s.sb.st[0]); return NULL; } - /* sent.s_port is returned by UCX in network byte order. */ - /* Calling htons here swaps the bytes, which ruins everything. */ - - /* Oh yeah? WHICH VERSION of UCX??? Let's try this... */ - - #ifndef __alpha /* Maybe it should be __DECC, or some version thereof... */ /* ! Hunter says: "In fact, the "#ifndef __alpha" isn't even needed, since ! my_getservbyname() isn't included if "__DECC" is defined, and that's ! always defined on Alpha." But if it doesn't hurt either, better not risk ! taking it out. */ ! #ifndef TCPWARE ! #define DO_HTONS ! #endif /* TCPWARE */ ! #endif /* __alpha */ ! ! #ifdef DO_HTONS sent.s_port = htons(sent.s_port); ! debug(F111,"UCX getservbyname","port",ntohs(sent.s_port)); ! #else ! debug(F111,"UCX getservbyname","port",sent.s_port); ! #endif /* DO_HTONS */ return &sent; } #endif /* __DECC */ --- 1009,1028 ---- C$$SOCK_TRANSLATE(&s.sb.st[0]); return NULL; } /* ! sent.s_port is supposed to be returned by UCX in network byte order. ! However, UCX 2.0 through 2.0C did not do this; 2.0D and later do it. ! But there is no way of knowing which UCX version, so we have a user-settable ! runtime variable. Note: UCX 2.0 was only for the VAX. */ ! debug(F101,"UCX getservbyname port","",sent.s_port); ! debug(F101,"UCX getservbyname ntohs(port)","",ntohs(sent.s_port)); ! if (ucx_port_bug) { sent.s_port = htons(sent.s_port); ! debug(F100,"UCX-PORT-BUG ON: swapping bytes","",0); ! debug(F101,"UCX swapped port","",sent.s_port); ! debug(F101,"UCX swapped ntohs(port)","",ntohs(sent.s_port)); ! } return &sent; } #endif /* __DECC */ *** /w/pub/ftp/kermit/f/ckuus3.c Sun Nov 24 19:20:50 1996 --- ./ckuus3.c Wed Dec 4 16:58:49 1996 *************** *** 3031,3036 **** --- 3031,3046 ---- success = recvbuf(z); return(success); #endif /* SO_RCVBUF */ + + #ifdef VMS + #ifdef DEC_TCPIP + case XYTCP_UCX: { /* UCX 2.0 port swabbing bug */ + extern int ucx_port_bug; + return(success = seton(&ucx_port_bug)); + } + #endif /* DEC_TCPIP */ + #endif /* VMS */ + default: return(0); } *** /w/pub/ftp/kermit/f/ckuusr.c Sun Nov 24 19:20:51 1996 --- ./ckuusr.c Wed Dec 4 17:12:50 1996 *************** *** 1098,1103 **** --- 1098,1108 ---- #ifdef SO_SNDBUF "sendbuf", XYTCP_SENDBUF, 0, #endif /* SO_SNDBUF */ + #ifdef VMS + #ifdef DEC_TCPIP + "ucx-port-bug", XYTCP_UCX, 0, + #endif /* DEC_TCPIP */ + #endif /* VMS */ "",0,0 }; int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab)); *** /w/pub/ftp/kermit/f/ckuusr.h Sun Nov 24 19:20:52 1996 --- ./ckuusr.h Wed Dec 4 16:59:18 1996 *************** *** 803,808 **** --- 803,809 ---- #define XYTCP_LINGER 3 /* Linger */ #define XYTCP_RECVBUF 4 /* Receive Buffer Size */ #define XYTCP_KEEPALIVE 5 /* Keep Alive packets */ + #define XYTCP_UCX 6 /* UCX 2.0 port swabbing bug */ #define XYMSK 83 /* MS-DOS Kermit compatibility options */ #define MSK_COLOR 0 /* Terminal color handling */ ==================== X-Patch-Number: 0005 Date: Mon, 9 Dec 1996 17:00:56 EST From: Frank da Cruz Subject: C-Kermit Might Send Packets Outside Window PROBLEM: When sending a file with a window size greater than 1 under conditions of packet loss, C-Kermit might send packets outside the current window. This should not cause file corruption, and in many cases (depending on the Kermit implementation on the receiving end), it won't even cause a noticable problem, but in other cases it might cause the transfer to stop unnecessarily. CURE: In the ckcfn2.c module, replace the nxtpkt() function with this new one: /* N X T P K T -- Next Packet */ /* Get packet number of next packet to send and allocate a buffer for it. Returns: 0 on success, with global pktnum set to the packet number; -1 on failure to allocate buffer (fatal); -2 if resulting packet number is outside the current window. */ int nxtpkt() { /* Called by file sender */ int j, n, x; debug(F101,"nxtpkt pktnum","",pktnum); debug(F101,"nxtpkt winlo ","",winlo); n = (pktnum + 1) % 64; /* Increment packet number mod 64 */ debug(F101,"nxtpkt n","",n); x = chkwin(n,winlo,wslots); /* Don't exceed window boundary */ debug(F101,"nxtpkt chkwin","",x); if (x) return(-2); j = getsbuf(n); /* Get a buffer for packet n */ if (j < 0) { debug(F101,"nxtpkt getsbuf failure","",j); return(-1); } pktnum = n; return(0); } ==================== X-Patch-Number: 0006 Date: Wed, 11 Dec 1996 12:26:00 EST From: Frank da Cruz Subject: MOVE from SEND-LIST does not delete original files If you build up a list of files to be sent using ADD SEND-LIST and then give a SEND command with no operands, it sends the files in the send list. If you give a MOVE command with no operands, it does the same thing. But unlike SEND, MOVE should delete each original after sending it successfully; in C-Kermit 6.0.192, it does not. Here's the patch: *** /w/pub/ftp/kermit/f/ckuusr.c Sun Nov 24 19:20:51 1996 --- ckuusr.c Wed Dec 11 12:39:01 1996 *************** *** 2863,2868 **** --- 2863,2870 ---- sndsrc = nfils; /* Like MSEND */ addlist = 1; /* But using a different list... */ filenext = filehead; + if (cx == XXMOVE) + moving = 1; sstate = 's'; goto sendend; } else { /* Oops, no list. */ ==================== X-Patch-Number: 0007 Date: Thu, 12 Dec 1996 21:11:47 -0500 From: "Richard L. Hamilton" Subject: Higher serial speeds on Solaris 2.5 Here's how I hacked up C-Kermit 6.0 for more of the speeds that Solaris >= 2.5 supports. This was with the following make command, to get rid of references to unsupported speeds as well as to help get some of the additional speeds. POSIX is a must, 'cause setting speeds > 38400 without the cfsetospeed() and similar functions is a pain. The #ifndef VANILLA was just so I could turn off all my hacks real easily, and it and the corresponding #endif should probably be removed. make solaris2xg KFLAGS="-DCK_DSYSINI -DCK_INI_B -DCK_WREFRESH -DPOSIX -DNOB_3600 -DNOB_7200 -DBPS_134 -DBPS_1800 -DBPS_57K -DBPS_76K -DBPS_115K -DBPS_230K" diff ckutio.c.orig ckutio.c 4605c4605,4616 < --- > #ifndef VANILLA > #ifdef SOLARIS > #ifdef POSIX > #ifdef BPS_76K > case 7680: s = B76800; break; > #endif /* BPS_76K */ > #ifdef BPS_230K > case 23040: s = B230400; break; > #endif /* BPS_230K */ > #endif /* POSIX */ > #endif /* SOLARIS */ > #endif /* VANILLA */ 4951a4963,4974 > #ifndef VANILLA > #ifdef SOLARIS > #ifdef POSIX > #ifdef BPS_76K > case B76800: ss = 76800L; break; > #endif /* BPS_76K */ > #ifdef BPS_230K > case B230400: ss = 230400L; break; > #endif /* BPS_230K */ > #endif /* POSIX */ > #endif /* SOLARIS */ > #endif /* VANILLA */ diff ckuus3.c.orig ckuus3.c 328a329,331 > #ifdef BPS_1800 > "1800", 180, 0, > #endif /* BPS_1800 */ ==================== X-Patch-Number: 0008 Date: Wed, 18 Dec 1996 11:42:00 EST From: Frank da Cruz Subject: C-Kermit application file name can't contain spaces When the first command-line argument to C-Kermit is a filename, C-Kermit should execute the commands from the file, e.g. kermit filename But if the filename contains spaces, this doesn't work in version 6.0, even if the filename is properly quoted to the shell: kermit "this is a file name" Here is the patch: *** /w/pub/ftp/kermit/f/ckuus4.c Sun Nov 24 19:20:50 1996 --- ckuus4.c Wed Dec 18 11:40:46 1996 *************** *** 636,642 **** */ cmdini(); /* Allocate command buffers etc */ cmini(0); /* Initialize them */ ! strcpy(cmdbuf,yargv[1]); /* Stuff filename into command buf */ strcat(cmdbuf,"\r\r"); /* And some carriage returns */ if ((y = cmifip("","",&s,&x,0,takepath,xxstring)) < 0) doexit(BAD_EXIT,xitsta); --- 636,642 ---- */ cmdini(); /* Allocate command buffers etc */ cmini(0); /* Initialize them */ ! sprintf(cmdbuf,"{%s}",yargv[1]); /* Put filename in command buf */ strcat(cmdbuf,"\r\r"); /* And some carriage returns */ if ((y = cmifip("","",&s,&x,0,takepath,xxstring)) < 0) doexit(BAD_EXIT,xitsta); ==================== X-Patch-Number: 0009 Subject: cku192 on an AT&T 3B1/7300 Date: Sun, 5 Jan 97 16:12:40 CST (-0600) From: "Randolph J. Herber" I used the sys3upcx entry in the makefile. It works. I noticed the following problems: 1. kermit needs to run setuid uucp if it is sharing a line with HDB uucp. If you set kermit setuid uucp and attempt to run it as user root, it fails because the AT&T 3B1 UNIX operating system is System V Release 0 and does not have save uid in the kernel. The following code snippet in priv_ini() of ckutio.c shows the change I made to address this situation: if (realuid == UID_ROOT) { /* If real id is root, */ privuid = (UID_T) -1; /* stay root at all times. */ err &= ~1; /* and remove any setuid err */ } /* added RJH 31DEC1996 */ 2. AT&T UNIX 3.51m does have hardware flow control which can set but not tested for. I added the following in tthflow() of ckutio.c after the #ifdef ATTSV to address this situation: #ifdef ATT7300 #define RTSFLOW CTSCD #define CTSFLOW CTSCD #endif With these present, then cku192 can be generated with CK_RTSCTS. I have observed that it can make a 30% difference in performance by avoiding hangs while kermit times out when the other system is expecting hardware flow control. Please note that version 3.51m was released as a patch on fix disk 2 and not everyone has it. Randolph J. Herber, (Speaking for myself and not US, USDOE, Fermilab or URA.) (Trademarks belong to their respective owners.) ==================== X-Patch-Number: 0010 Date: Sat, 11 Jan 1997 00:06:01 -0600 (CST) From: "Patrick J. Volkerding" To: fdc@watsun.cc.columbia.edu Subject: C-Kermit for Linux on Alpha ************************************************************************ NOTE: This patch (Patch 0010) and Patch 0017 are mutually exclusive. Patch 0017 includes same fix for Linux/Alpha as Patch 0010 does. If you wish to use the higher serial speeds available with the standard POSIX interface, apply Patch 0017 instead of Patch 0010. ************************************************************************ There was one little snag in the compile, but it looks like this patch fixes it: --- ckutio.c.orig Fri Jan 10 23:55:38 1997 +++ ckutio.c Fri Jan 10 23:55:38 1997 @@ -671,6 +671,9 @@ #ifdef LINUXHISPEED #include #endif /* LINUXHISPEED */ +#ifdef __alpha__ /* Linux on DEC Alpha */ +#include +#endif /* __alpha__ */ #else #ifdef AIXRS /* IBM AIX */ #include ==================== X-Patch-Number: 0011 Date: Sat, 11 Jan 1997 00:06:01 -0600 (CST) From: ... Subject: Patch to make ck9con.c compile on OS-9/68000 2.4 *** /w/pub/ftp/kermit/f/ck9con.c Thu Aug 22 19:50:45 1996 --- ./ck9con.c Sat Jan 11 12:57:23 1997 *************** *** 935,941 **** --- 935,945 ---- else if (n < 0) { debug(F101, "conect comm errno", NULL, errno); if (!quiet) + #ifdef OSK + printf("\n\012Communications disconnect "); + #else printf("\n\lCommunications disconnect "); + #endif if (network) ttclos(0); dohangup = 1; active = 0; ==================== X-Patch-Number: 0012 Date: Sat, 25 Jan 1997 20:46:22 -0500 (EST) From: Fred Smith Subject: Patches for Coherent 4.2 You've now got TWO new Coherent executables in your /pub/kermit/incoming directory. Both were compiled using the coherent42 target in the makefile, without any changes to the target. In both cases, however, I needed to make some changes in the code. I'll append some patches here with the changes. NOTE that I'll also embed some commentary in the patches (I'll add a "FRANK" to my commentary so you can easily find it) describing WHY I made that change. One of the executables, cku192.coherent42-mw-uucp is compiled with as few changes as possible, using the default lockfile naming rules that were in effect in older revs of Coherent. The other, cku192.coherent42-taylor-uucp was slightly modified to use a naming convention matching that used by the Taylor UUCP in use in Coherent 4.2 (and as an add-on by some people to the 4.0.x systems). So, in theory, the cku192.coherent42-mw-uucp ought to be usable on older 4.x releases that do not use Taylor UUCP. But who knows if it really will work. It was compiled on 4.2.10. I believe there have been numerous changes in the system internals and in the libraries across each of the (many) revs between 4.0.0 and 4.2.10, so each person who tries it has my sincere wishes for good luck! OTOH, MWC (as far as I know) did not ship Taylor UUCP as an official part of the distribution prior to 4.2.x (though they had an update available for earlier revs), and beginning at 4.2.x shipped ONLY Taylor UUCP. So, I believe that the cku192.coherent42-taylor-uucp executable is quite likely to work on any 4.2.x release. Both executables were tested (on my 4.2.10 system) by uploading themselves to our ISP, so at least to the extent that that exercises the program, they do appear to work. I noticed that the old bug remains where on Coherent the full-screen display is drawn twice. OK, here's the patches, with some additional commentary: ------------------------------------------------------------------------------- *** ../src/ckufio.c Sat Nov 23 14:27:13 1996 --- ckufio.c Sat Jan 25 20:28:18 1997 *************** *** 211,216 **** --- 211,221 ---- #endif /* BSD4 */ #endif /* BSD44 */ FRANK This is needed for cku192 to avoid fatal compiler errors. I didn't track down the reason, but it must be something that changed since 190. + /* FCS */ + #ifdef COHERENT + #include + #endif /* COHERENT */ + /* Is `y' a leap year? */ #define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) *** ../src/ckutio.c Mon Nov 18 12:10:44 1996 --- ckutio.c Sat Jan 25 20:28:19 1997 *************** *** 993,1000 **** --- 993,1003 ---- #else #ifdef SELECT #ifndef BELLV10 FRANK Also needed on 192 but not on 190. + /* FCS */ + #ifndef COHERENT static struct timeval tv; static struct timezone tz; + #endif /* COHERENT */ #endif /* BELLV10 */ #endif /* SELECT */ #endif /* OXOS */ *************** *** 2999,3004 **** --- 3002,3008 ---- #endif /* LFDEVNO */ /* ... define it here or on CC */ #endif /* SVR4 */ /* command line. */ FRANK This, if NOT commented out, builds the cku192.coherent42.MWC-uucp executable. If commented out you get the cku192.coherent42.TAYLOR-uucp. + /* FCS #ifdef COHERENT #define LFDEVNO #endif /* COHERENT */ *************** *** 4272,4277 **** --- 4276,4286 ---- flow == FLO_DTRC || flow == FLO_DTRT) { tthflow(flow, 1, &ttraw); FRANK This is needed only for cku192.coherent42-taylor-uucp. + /* FCS */ + #ifdef COHERENT + #define SVORPOSIX + #endif /* COHERENT */ + #ifndef SVORPOSIX ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */ #else *************** *** 4317,4322 **** --- 4326,4336 ---- #endif /* BSD44ORPOSIX */ #endif /* SVORPOSIX */ return(0); FRANK ditto. + + /* FCS */ + #ifdef COHERENT + #undef SYSVORPOSIX + #endif /* COHERENT */ } /* T T V T -- Condition communication line for use as virtual terminal */ *** ../src/ckuus3.c Sun Nov 24 12:51:52 1996 --- ckuus3.c Sat Jan 25 20:28:18 1997 *************** *** 3334,3340 **** FRANK without this one MWC's C compiler takes a fatal error, complaining something like redefining a function to null.?? #ifdef CK_ANSIC xxstring = y ? zzstring : (xx_strp) NULL; #else ! xxstring = y ? zzstring : NULL; #endif /* CK_ANSIC */ #endif /* datageneral */ return(success = 1); --- 3334,3341 ---- #ifdef CK_ANSIC xxstring = y ? zzstring : (xx_strp) NULL; #else ! /* FCS */ ! xxstring = y ? zzstring : (xx_strp)NULL; #endif /* CK_ANSIC */ #endif /* datageneral */ return(success = 1); ==================== X-Patch-Number: 0013 From: Stephan Hoffmann-Emden Date: Tue, 4 Feb 1997 06:00:49 -0500 (EST) To: fdc@watsun.cc.columbia.edu Subject: SINIX-RM BINARIES this is the result of our porting-works for a SINIX-Y rm600 5.43 B0045 RM600 3/512 R4000 We've got problems with the declaration of variable 'delay' caused by include-file /usr/include/sys/clock.h Therefore the variables were renamed in the following modules: ckcfns.c ckcmai.c ckuus3.c ckuus4.c ckuusy.c Patch: *** /w/pub/ftp/kermit/c-kermit/ckcfns.c Sun Nov 24 19:20:48 1996 --- ./ckcfns.c Mon Feb 3 11:46:51 1997 *************** *** 44,46 **** extern int parity, turn, network, what, whatru, fsecs, justone, slostart, ! delay, displa, xflg, mypadn, remfile, moving; extern long filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize, sendstart, rs_len; --- 44,46 ---- extern int parity, turn, network, what, whatru, fsecs, justone, slostart, ! ckdelay, displa, xflg, mypadn, remfile, moving; extern long filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize, sendstart, rs_len; *************** *** 1305,1308 **** } ! if (!local && !server && delay > 0) /* OS-9 sleep(0) == infinite */ ! sleep(delay); /* Delay if requested */ #ifdef datageneral --- 1305,1308 ---- } ! if (!local && !server && ckdelay > 0) /* OS-9 sleep(0) == infinite */ ! sleep(ckdelay); /* Delay if requested */ #ifdef datageneral *** /w/pub/ftp/kermit/c-kermit/ckcmai.c Fri Nov 29 08:52:13 1996 --- ./ckcmai.c Mon Feb 3 11:35:33 1997 *************** *** 893,895 **** escape = DFESC, /* Escape character for connect */ ! delay = DDELAY, /* Initial delay before sending */ tnlm = 0, /* Terminal newline mode */ --- 893,895 ---- escape = DFESC, /* Escape character for connect */ ! ckdelay = DDELAY, /* Initial delay before sending */ tnlm = 0, /* Terminal newline mode */ *** /w/pub/ftp/kermit/c-kermit/ckuus3.c Sun Nov 24 19:20:50 1996 --- ./ckuus3.c Mon Feb 3 11:45:18 1997 *************** *** 75,77 **** local, server, success, dest, ! flow, autoflow, binary, xfermode, delay, parity, escape, what, srvdis, turn, duplex, backgrd, --- 75,77 ---- local, server, success, dest, ! flow, autoflow, binary, xfermode, ckdelay, parity, escape, what, srvdis, turn, duplex, backgrd, *************** *** 3550,3552 **** if (x < 0) x = 0; ! return(success = setnum(&delay,x,y,999)); --- 3550,3552 ---- if (x < 0) x = 0; ! return(success = setnum(&ckdelay,x,y,999)); *** /w/pub/ftp/kermit/c-kermit/ckuus4.c Sun Nov 24 19:20:50 1996 --- ./ckuus4.c Mon Feb 3 11:45:24 1997 *************** *** 234,236 **** atcapr, autopar, bctr, bctu, bgset, bigrbsiz, bigsbsiz, binary, carrier, ! cdtimo, cmask, crunched, delay, duplex, ebq, ebqflg, flow, fmask, fncact, fncnv, inecho, keep, local, lscapr, lscapu, xfermode, --- 234,236 ---- atcapr, autopar, bctr, bctu, bgset, bigrbsiz, bigsbsiz, binary, carrier, ! cdtimo, cmask, crunched, ckdelay, duplex, ebq, ebqflg, flow, fmask, fncact, fncnv, inecho, keep, local, lscapr, lscapu, xfermode, *************** *** 2487,2489 **** printf( " Pad Character:%11d%9d", padch, mypadc); ! printf(" Delay: %6d\n",delay); printf( " Packet Start: %11d%9d", mystch, stchr); --- 2487,2489 ---- printf( " Pad Character:%11d%9d", padch, mypadc); ! printf(" Delay: %6d\n",ckdelay); printf( " Packet Start: %11d%9d", mystch, stchr); *** /w/pub/ftp/kermit/c-kermit/ckuusy.c Sun Nov 10 18:37:33 1996 --- ./ckuusy.c Mon Feb 3 11:45:30 1997 *************** *** 116,118 **** urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow, ! fncact, clfils, noinit, stayflg, nettype, cfilef, delay, noherald, cmask, cmdmsk, backgrd, exitonclose; --- 116,118 ---- urpsiz, wslotr, swcapr, binary, warn, parity, turn, turnch, duplex, flow, ! fncact, clfils, noinit, stayflg, nettype, cfilef, ckdelay, noherald, cmask, cmdmsk, backgrd, exitonclose; *************** *** 321,323 **** if (z > -1) /* If in range */ ! delay = z; /* set it */ else { --- 321,323 ---- if (z > -1) /* If in range */ ! ckdelay = z; /* set it */ else { ==================== X-Patch-Number: 0014 From: Wolfgang J. Moeller Date: Tue 4 Feb 1997 09:10:11 +0100 To: fdc@watsun.cc.columbia.edu Subject: Patches for VAX/VMS 5.x + CMU-IP Note: The missing argument to ttclos() applies to all builds, not just this one. *** /w/pub/ftp/kermit/f/ckcnet.c Wed Nov 27 19:54:46 1996 --- ./ckcnet.c Thu Jan 23 01:02:52 1997 *************** *** 2513,2519 **** x = read(ttyfd,&dummy,0); /* Try to read nothing */ if (x < 0) { /* "Connection reset by peer" */ perror("TCP/IP"); /* or somesuch... */ ! ttclos(); /* Close our end too. */ return(-1); } } --- 2513,2519 ---- x = read(ttyfd,&dummy,0); /* Try to read nothing */ if (x < 0) { /* "Connection reset by peer" */ perror("TCP/IP"); /* or somesuch... */ ! ttclos(0); /* Close our end too. */ return(-1); } } *************** *** 2663,2669 **** x = read(ttyfd,&dummy,0); /* Try to read nothing */ if (x < 0) { /* "Connection reset by peer" */ perror("TCP/IP"); /* or somesuch... */ ! ttclos(); /* Close our end too. */ return(-1); } } --- 2663,2669 ---- x = read(ttyfd,&dummy,0); /* Try to read nothing */ if (x < 0) { /* "Connection reset by peer" */ perror("TCP/IP"); /* or somesuch... */ ! ttclos(0); /* Close our end too. */ return(-1); } } *** /w/pub/ftp/kermit/f/ckvtio.c Sun Nov 24 19:20:55 1996 --- ./ckvtio.c Sun Feb 2 15:54:12 1997 *************** *** 2557,2562 **** --- 2557,2563 ---- #ifdef CMU_TCPIP mask = 1; exceptfds = mask; + #ifdef CMU_TCPIP_BOGUS_SELECT if (select(1, &mask, 0, &exceptfds, &timeout) == 1) if (FD_ISSET(0,&exceptfds)) return(*c = -1); *************** *** 2564,2569 **** --- 2565,2589 ---- *c = (unsigned)(concc & 0xff); *src = 0; return(1); + #else /* CMU_TCPIP_BOGUS_SELECT (wjm 02-feb-1997) */ + /* non-blocking select() - zero timeout */ + switch(select(1, &mask, 0, &exceptfds, &timeout)) { + case 1: /* console ready */ + netcon_queued = 0; /* QIO completed */ + *src = 0; + if (!(FD_ISSET(0,&exceptfds))) { /* o.k. */ + *c = (unsigned)(concc & 0xff); + return(1); + } else /* I/O error */ + return(*c = -1); + + case 0: /* timeout (no console input) */ + break; + + default: /* select() error */ + return(*c = -1); /* shouldn't get here */ + } + #endif /* CMU_TCPIP_BOGUS_SELECT (wjm 02-feb-1997) */ #else (void) sys$readef(CON_EFN, &mask); if (mask & (1 << CON_EFN)) { *************** *** 2887,2892 **** --- 2907,2913 ---- net_chan = GET_SDC(ttyfd); if (nettty_queued) (void) sys$cancel(net_chan); + nettty_queued = 0; /*+wjm*/ #else /* DEC_TCPIP */ #ifdef CMU_TCPIP /* not going to do this when CMU is the network transport. *************** *** 2896,2907 **** */ #else /* !CMU_TCPIP */ if (nettty_queued) (void) sys$cancel(ttyfd); #endif /* CMU_TCPIP */ #endif /* DEC_TCPIP */ if (netcon_queued) (void) sys$cancel(conchn); - netcon_queued = 0; ! nettty_queued = 0; return(0); #else /* Not TCPIPLIB */ return(0); --- 2917,2929 ---- */ #else /* !CMU_TCPIP */ if (nettty_queued) (void) sys$cancel(ttyfd); + nettty_queued = 0; /*+wjm*/ #endif /* CMU_TCPIP */ #endif /* DEC_TCPIP */ if (netcon_queued) (void) sys$cancel(conchn); netcon_queued = 0; ! ! /*-wjm nettty_queued = 0; */ return(0); #else /* Not TCPIPLIB */ return(0); ==================== X-Patch-Number: 0015 From: "Melissa O'Neill" Subject: XECHO doesn't flush its output... To: kermit-support@columbia.edu Date: Tue, 4 Feb 1997 18:20:51 -0800 (PST) CKermit 6.0.192 has a small problem with the XECHO command, which doesn't doesn't flush it's output. This means that a display from an XECHO command may not be seen a timely way. Enclosed is a simple patch to fix the problem. --- ckuusr.c.orig Tue Jan 28 11:55:50 1997 +++ ckuusr.c Tue Jan 28 11:56:20 1997 @@ -2071,6 +2071,7 @@ printf("%s\n",s); } else if (cx == XXXECH) { /* XECHO */ printf("%s",s); + fflush(stdout); } else { /* APC */ #ifdef CK_APC if (apcactive == APC_LOCAL || ==================== X-Patch-Number: 0016 Date: Mon, 17 Feb 1997 17:16:56 -0800 From: Frank da Cruz Subject: CD and other directory operations might not work In the VMS-specific file i/o module, CKVFIO.C, routine isdir(), a struct that contained a pointer to a malloc'd buffer was being used after the buffer was freed. In many cases this does not cause a problem because the material is still actually there, but in some cases the free() implementation actually wipes the buffer clean, causing the operation to fail. The most common symptom was failure of CD / SET DEFAULT in OpenVMS Alpha 6.2 or later that has been updated with ALPLIBR04_070, "Fix realloc fragmentation problem," LIBRTL patch (this was discovered by Lucas Hart). The fix is to postpone the free() call till after we are finished using the struct: *** /w/pub/ftp/kermit/f/ckvfio.c Sun Nov 24 19:20:54 1996 --- ./ckvfio.c Mon Feb 17 17:23:23 1997 *************** *** 18,22 **** #endif /* __ALPHA */ ! char *ckzv = "File support, 6.0.130, 6 Sep 96"; char *ckzsys = CKVFIO_OS_ARCH_STRING; --- 18,22 ---- #endif /* __ALPHA */ ! char *ckzv = "File support, 6.0.131, 17 Feb 1997"; char *ckzsys = CKVFIO_OS_ARCH_STRING; *************** *** 31,35 **** Columbia University Academic Information Systems, New York City. ! Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New York. The C-Kermit software may not be, in whole or in part, licensed or sold for profit as a software product itself, nor may it be included in or --- 31,35 ---- Columbia University Academic Information Systems, New York City. ! Copyright (C) 1985, 1997, Trustees of Columbia University in the City of New York. The C-Kermit software may not be, in whole or in part, licensed or sold for profit as a software product itself, nor may it be included in or *************** *** 255,258 **** --- 255,259 ---- * 129 06-Sep-96 fdc Fix zchki() to return -2 if blah.DIR;n is a directory. * 130 06-Sep-96 fdc Fixes to isdir(), zstrip(), zchdir(). + * 131 17-Feb-97 fdc Another fix to isdir() (free() was called too early). */ *************** *** 628,633 **** #endif /* COMMENT */ - free(full_name); - if (new_len == 0) { /* Could still be a device name. */ --- 629,632 ---- *************** *** 644,647 **** --- 643,647 ---- i, i, serial_num, new_len); #endif /* COMMENT */ + free(full_name); return(((i & 1) == 1 && new_len > 0) ? 1: 0); *************** *** 657,666 **** --- 657,669 ---- name_buf[new_len-1] = '\0'; } + free(full_name); return( isdir(name_buf) ); } else { /* Logical name is just a random string signifying nothing */ + free(full_name); return(0); } } return(1); } ==================== X-Patch-Number: 0017 Date: Wed, 22 Jan 1997 18:57:18 -0500 To: kermit@columbia.edu Subject: Patches to C-Kermit 6.0.192 for better Linux support From: tytso@mit.edu ************************************************************************ NOTE: This patch (Patch 0017) and Patch 0010 are mutually exclusive. Patch 0017 includes same fix for Linux/Alpha as Patch 0010 does. If do not wish to use the higher serial speeds available with the standard POSIX interface, apply Patch 0010 instead of Patch 0017. ************************************************************************ I'm the tty and serial driver maintainer for Linux, and I've recently made some changes so that kermit can better support Linux serial ports. The current kermit code uses a non-standard Linux specific ioctl to use the 57600 and 115200 baud rates. These ioctl's have not been required for two major versions (2.0, 1.2). Indeed, Linux at this point can support 230K bps and 460K bps. These patches do allow the use of the old ioctl's, but most Linux systems really don't need them anymore. I've added support for 230 or 460 kbaud, using the standard POSIX interface. I hope you find this useful, and these patches will find their way into the next version of C-kermit. Please let me know if you have any problems with them. Thanks!! - Ted Patch generated: on Wed Jan 22 15:18:08 EST 1997 by tytso@rsts-11.mit.edu against Kermit version 6.0.192 ---------------------------------------------------------------- RCS file: RCS/makefile,v retrieving revision 1.1 diff -u -r1.1 makefile --- makefile 1996/12/07 17:12:55 1.1 +++ makefile 1996/12/07 21:49:22 @@ -2800,13 +2800,35 @@ $(MAKE) wermit \ "CFLAGS = -DATTSV -DNOFILEH -DCIE $(KFLAGS) -O" "LNKFLAGS =" -# Linux 0.99.14 or later with gcc, dynamic libraries, curses, TCP/IP. -# -# -DLINUXFSSTND (Linux File System Standard) gives UUCP lockfil /var/lock with -# string pid. Remove this and get /usr/spool/uucp with int pid, which was used -# in early Linux versions. +# Linux 1.2 and later (1.3, 2.0, 2.1) with gcc, dynamic libraries, TCP/IP +# +# Most modern Linux systems use ncurses (with curses.h and an ncurses +# shared library. Modern Linux systems also generally use FSSTND 1.2. +# So, you don't need most of the compatibility hair described below. +# +# If your Linux system does not have ncurses, remove -DCK_CURSES +# and the entire LIBS= clause. +# +# NOTE: Remove -DBIGBUFOK for small-memory or limited-resource systems. # -# If you get compiler errors regarding , add -DNOHISPEED. +# +# For very old (ancient) Linux systems, mainly systems with pre-1.0 and +# 1.0 kernel versions, and various odd-ball Linux distributions, read on.... +# +# -DLINUXFSSTND (Linux File System Standard 1.2) gives UUCP lockfil /var/lock +# with string pid. Remove this and get /usr/spool/uucp with int pid, +# which was used in early Linux versions. +# +# Add -DFSSTND10 to support the version 1.0 of the FSSTND. In the earlier +# version of the FSSTND, the PID string in the UUCP lock file had leading +# zeros. In FSSTND 1.2 this was changed to be be leading spaces instead. +# To use the older standard, add define FSSTND10. +# +# Add -DOLINUXHISPEED (Old Linux High Speed support) to turn on an ugly kludge +# which was used in Linux 1.0 systems to support speeds of 57600 and 115200. +# Really, really, old Linux systems (pre-0.99pl15) will not support this. +# If OLINUXHISPEED is not defined, then only the standard termios methods +# of setting the port speed will be used. # # -DCK_POSIX_SIG (POSIX signal handling) is good for Linux releases back to at # least 0.99.14; if it causes trouble for you, just remove it. @@ -2825,23 +2847,14 @@ # But wait, there's more. On most Linux systems, -ltermcap must be included # in LIBS. But on others, the linker complains that libtermcap can't be # found. In that case, try removing -ltermcap from LIBS=. -# -# But wait, there's more. The format of the PID string in the UUCP lockfile -# changed between Linux FSSTND 1.0 and 1.2. In the earlier standard, it had -# leading zeros; in the second, it has leading spaces. By default this entry -# uses the newer standard. To force the second one, add -DFSSTND10. -# -# "The nice thing about the Linux standard is there are so many to choose from" -# -# NOTE: Remove -DBIGBUFOK for small-memory or limited-resource systems. linux: @echo 'Making C-Kermit $(CKVER) for Linux...' @echo 'IMPORTANT: Read the comments in the linux section of the' @echo 'makefile if you get compilation or link errors.' $(MAKE) wermit "CC = gcc" "CC2 = gcc" \ "CFLAGS = -O -DPOSIX -DDYNAMIC -DCK_CURSES -DCK_POSIX_SIG \ - -DBIGBUFOK -DTCPSOCKET -DLINUXFSSTND $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap" + -DBIGBUFOK -DTCPSOCKET -DLINUXFSSTND -DCK_DSYSINI $(KFLAGS)" \ + "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lncurses -ltermcap" #This version was used for Linux prior to C-Kermit 6.0.192. #Now the "Linux File System Standard" is considered standard, ditto TCP/IP. ---------------------------------------------------------------- RCS file: RCS/ckuusr.h,v retrieving revision 1.1 diff -u -r1.1 ckuusr.h --- ckuusr.h 1996/12/07 21:31:08 1.1 +++ ckuusr.h 1996/12/07 21:33:08 @@ -104,7 +104,11 @@ #ifdef CU_ACIS #define CK_SYSINI "/usr/share/lib/kermit/ckermit.ini" #else +#ifdef __linux__ +#define CK_SYSINI "/usr/share/kermit/ckermit.ini" +#else #define CK_SYSINI "/usr/local/bin/ckermit.ini" +#endif /* linux */ #endif /* CU_ACIS */ #endif /* HPUX10 */ /* Fill in #else..#ifdef's here for VMS, OS/2, etc. */ ---------------------------------------------------------------- RCS file: RCS/ckcdeb.h,v retrieving revision 1.1 diff -u -r1.1 ckcdeb.h --- ckcdeb.h 1996/12/07 17:12:53 1.1 +++ ckcdeb.h 1996/12/07 18:33:35 @@ -1513,18 +1513,6 @@ #define BPS_38K /* 38400 bps */ #endif -/* - Speeds of 57600 and higher are supported in Linux 0.99.15 and later, but - it seems to do no harm to enable them for earlier releases too, in which - case commands like "set speed 57600" simply fail with an "Unsupported line - speed" message. -*/ -#ifndef NOHISPEED -#ifdef __linux__ -#define LINUXHISPEED -#endif /* __linux__ */ -#endif /* NOHISPEED */ - #ifndef NOB_57K #ifdef Plan9 #define BPS_57K @@ -1536,9 +1524,7 @@ #define BPS_57K #else #ifdef __linux__ -#ifdef LINUXHISPEED #define BPS_57K -#endif /* LINUXHISPEED */ #else #ifdef HPUX #define BPS_57K @@ -1607,9 +1593,7 @@ #define BPS_115K #else #ifdef __linux__ -#ifdef LINUXHISPEED #define BPS_115K -#endif /* LINUXHISPEED */ #else #ifdef __386BSD__ #define BPS_115K @@ -1643,11 +1627,26 @@ #ifdef __32BIT__ #define BPS_230K #endif /* __32BIT__ */ -#else +#else +#ifdef __linux__ +#define BPS_230K +#else #undef BPS_230K +#endif /* Linux */ #endif /* OS2 */ #endif /* NOB_230K */ +#ifndef NOB_460K /* 460800 bps */ +#ifdef __linux__ +#define BPS_460K +#else +#undef BPS_460K +#endif /* Linux */ +#endif /* NOB_460K */ + +#ifdef BPS_460K +#define MAX_SPD 460800L /* Maximum speed defined */ +#else #ifdef BPS_230K /* Maximum speed defined */ #define MAX_SPD 230400L #else @@ -1673,6 +1672,7 @@ #define MAX_SPD 14400L #else #define MAX_SPD 9600L +#endif #endif #endif #endif ---------------------------------------------------------------- RCS file: RCS/ckutio.c,v retrieving revision 1.1 diff -u -r1.1 ckutio.c --- ckutio.c 1996/12/07 17:12:53 1.1 +++ ckutio.c 1996/12/07 19:32:28 @@ -668,9 +668,9 @@ #include #include #include -#ifdef LINUXHISPEED +#ifdef OLINUXHISPEED #include -#endif /* LINUXHISPEED */ +#endif /* OLINUXHISPEED */ #else #ifdef AIXRS /* IBM AIX */ #include @@ -4167,11 +4167,10 @@ ttraw.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */ ttraw.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */ /* NOTE: We should also handle hardware flow control here! */ -#ifdef __linux__ -/* In Linux case, we do this, which is unlikely to be portable */ +#ifdef POSIX_CRTSCTS ttraw.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */ ttraw.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */ -#endif /* __linux__ */ +#endif /* POSIX_CRTSCTS */ } else if (flow == FLO_RTSC || /* Hardware */ flow == FLO_DTRC || flow == FLO_DTRT) { @@ -4419,10 +4418,10 @@ tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */ tttvt.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */ /* NOTE: We should also handle hardware flow control here! */ -#ifdef __linux__ +#ifdef POSIX_CRTSCTS tttvt.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */ tttvt.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */ -#endif /* __linux__ */ +#endif /* POSIX_CRTSCTS */ } else if (flow == FLO_NONE) { /* NONE */ tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */ tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff */ @@ -4524,12 +4523,10 @@ s, s2; int ok = 1; /* Speed check result, assume ok */ -#ifdef __linux__ /* Linux... */ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED /* Linux... */ unsigned int spd_flags = 0; struct serial_struct serinfo; -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ debug(F101,"ttsspd cps","",cps); debug(F101,"ttsspd ttyfd","",ttyfd); @@ -4591,11 +4588,9 @@ #endif /* B28800 */ #ifdef B38400 case 3840: s = B38400; -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED spd_flags = ~ASYNC_SPD_MASK; /* Nonzero, but zero flags */ -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ break; #else /* B38400 not defined... */ #ifdef EXTB @@ -4611,8 +4606,7 @@ case 11520: s = _B115200; break; #endif /* _B115200 */ #else -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED /* This bit from : "Only note to make is maybe this: When the ASYNC_SPD_CUST flags are set then @@ -4623,9 +4617,7 @@ */ case 5760: s = B38400; spd_flags = ASYNC_SPD_HI; break; case 11520: s = B38400; spd_flags = ASYNC_SPD_VHI; break; -#endif /* ASYNC_SPD_MASK */ #else -#ifdef QNX #ifdef B57600 case 5760: s = B57600; break; #endif /* B57600 */ @@ -4635,15 +4627,13 @@ #ifdef B115200 case 11520: s = B115200; break; #endif /* B115200 */ -#else -#ifdef B57600 - case 5760: s = B57600; break; -#endif /* B57600 */ -#ifdef B115200 - case 11520: s = B115200; break; -#endif /* B115200 */ -#endif /* QNX */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ +#ifdef B230400 + case 23040: s = B230400; break; +#endif /* B230400 */ +#ifdef B460800 + case 46080: s = B460800; break; +#endif /* 460800 */ #endif /* HPUX */ default: ok = 0; /* Good speed not found, so not ok */ @@ -4672,8 +4662,7 @@ debug(F101,"ttsspd tcgetattr","",x); if (x < 0) return(-1); -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED debug(F101,"ttsspd spd_flags","",spd_flags); if (spd_flags && spd_flags != ASYNC_SPD_CUST) { if (ioctl(ttyfd, TIOCGSERIAL, &serinfo) < 0) { @@ -4685,8 +4674,7 @@ if (ioctl(ttyfd, TIOCSSERIAL, &serinfo) < 0) return(-1); } -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ cfsetospeed(&ttcur,s); cfsetispeed(&ttcur,s2); cfsetospeed(&ttraw,s); @@ -4783,12 +4771,10 @@ #endif /* POSIX */ s; long ss; -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED unsigned int spd_flags = 0; struct serial_struct serinfo; -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ #ifdef NETCONN if (netconn) return(-1); /* -1 if network connection */ @@ -4801,13 +4787,9 @@ else ss = ttylastspeed; #else -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK - debug(F100,"ttgspd Linux ASYNC_SPD_MASK defined","",0); -#else - debug(F100,"ttgspd Linux ASYNC_SPD_MASK not defined","",0); -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#ifdef OLINUXHISPEED + debug(F100,"ttgspd Linux OLINUXHISPEED","",0); +#endif /* OLINUXHISPEED */ if (ttyfd < 0) { #ifdef BSD44ORPOSIX @@ -4828,13 +4810,11 @@ if (tcgetattr(ttyfd,&ttcur) < 0) return(-1); s = cfgetospeed(&ttcur); debug(F101,"ttgspd cfgetospeed 2 BSDORPOSIX","",s); -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED if (ioctl(ttyfd,TIOCGSERIAL,&serinfo) > -1) spd_flags = serinfo.flags & ASYNC_SPD_MASK; debug(F101,"ttgspd spd_flags","",spd_flags); -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ #else #ifdef ATTSV if (ioctl(ttyfd,TCGETA,&ttcur) < 0) return(-1); @@ -4854,11 +4834,9 @@ #endif /* BSD44ORPOSIX */ } debug(F101,"ttgspd code","",s); -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED debug(F101,"ttgspd spd_flags","",spd_flags); -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ switch (s) { #ifdef B0 case B0: ss = 0L; break; @@ -4934,14 +4912,12 @@ #ifdef B38400 case B38400: ss = 38400L; -#ifdef __linux__ -#ifdef ASYNC_SPD_MASK +#ifdef OLINUXHISPEED switch(spd_flags) { case ASYNC_SPD_HI: ss = 57600L; break; case ASYNC_SPD_VHI: ss = 115200L; break; } -#endif /* ASYNC_SPD_MASK */ -#endif /* __linux__ */ +#endif /* OLINUXHISPEED */ break; #else #ifdef EXTB @@ -4958,7 +4934,6 @@ case _B115200: ss = 115200L; break; #endif /* _B115200 */ #else -#ifdef QNX #ifdef B57600 case B57600: ss = 57600L; break; #endif /* B57600 */ @@ -4968,14 +4943,12 @@ #ifdef B115200 case B115200: ss = 115200L; break; #endif /* B115200 */ -#else -#ifdef B57600 - case B57600: ss = 57600L; break; -#endif /* B57600 */ -#ifdef B115200 - case B115200: ss = 115200L; break; -#endif /* B115200 */ -#endif /* QNX */ +#ifdef B230400 + case B230400: ss = 230400L; break; +#endif /* B230400 */ +#ifdef B460800 + case B460800: ss = 460800L; break; +#endif /* B460800 */ #endif /* HPUX */ default: ---------------------------------------------------------------- RCS file: RCS/ckuus3.c,v retrieving revision 1.1 diff -u -r1.1 ckuus3.c --- ckuus3.c 1996/12/07 17:12:54 1.1 +++ ckuus3.c 1996/12/07 18:30:44 @@ -346,6 +346,9 @@ #ifdef BPS_38K "38400", 3840, 0, #endif /* BPS_38K */ +#ifdef BPS_460K + "460800", 46080, 0, +#endif /* BPS_460K */ "4800", 480, 0, #ifdef BPS_50 "50", 5, 0, ---------------------------------------------------------------- RCS file: RCS/ckuusx.c,v retrieving revision 1.1 diff -u -r1.1 ckuusx.c ------------------------------------------------------------------------ Date: Tue Feb 18 16:28:45 EST 1997 From: Jim Knoble Subject: linux-posix-hispeed+linux-alpha patch Here's the patch that ought to be used to build ckermit for Linux/Alpha systems *after* Ted Tso's POSIX-hispeed patch has been applied (his patch breaks if patch #10 for Linux/Alpha is applied, and patch #10 breaks if Ted's patch is applied first). Seems like the thing to do is put Ted's patch in the PATCHES file, then this one right after it (or even combine them ... it won't hurt Linux on Intel or SPARC platforms to have this in there). --- ckutio.c.orig Wed Jan 29 00:10:16 1997 +++ ckutio.c Wed Jan 29 00:12:17 1997 @@ -671,6 +671,9 @@ #ifdef OLINUXHISPEED #include #endif /* OLINUXHISPEED */ +#ifdef __alpha__ /* Linux on DEC Alpha */ +#include +#endif /* __alpha__ */ #else #ifdef AIXRS /* IBM AIX */ #include ==================== X-Patch-Number: 0018 Date: Thu Feb 20 12:25:11 1997 From: Frank da Cruz Subject: SET WILDCARD-EXPANSION SHELL dumps core In UNIX, SET WILDCARD-EXPANSION SHELL causes C-Kermit to dump core whenever a command was given that had to parse the name of an existing file or file group. Diagnosis: storage wasn't being allocated for the file list. Here's the patch: *** /w/pub/ftp/kermit/f/ckufio.c Sun Nov 24 19:20:49 1996 --- ./ckufio.c Thu Feb 20 12:22:58 1997 *************** *** 2259,2265 **** #endif /* DTILDE */ #ifndef NOPUSH if (!nopush && wildxpand) /* Who is expanding wildcards? */ ! fcount = shxpand(fn,mtchs,MAXWLD); /* Shell */ else #endif /* NOPUSH */ fcount = (mtchs == NULL && /* Kermit */ --- 2259,2268 ---- #endif /* DTILDE */ #ifndef NOPUSH if (!nopush && wildxpand) /* Who is expanding wildcards? */ ! fcount = (mtchs == NULL && /* Shell */ ! (mtchs = (char **)malloc(MAXWLD * sizeof(*mtchs))) == NULL) ! ? 0 ! : shxpand(fn,mtchs,MAXWLD); else #endif /* NOPUSH */ fcount = (mtchs == NULL && /* Kermit */ ==================== X-Patch-Number: 0019 Date: Sat Mar 8 13:02:07 1997 From: Frank da Cruz Subject: Hayes V.34 modem init string problem A user writes: > I replaced the Accura 144 with and Accura 288 on our 3B2. I used the same > kermit script to configure the new modem as I had with the old one. But I > can no longer use the dial command. I get the message "Error initializing > modem." What signal is kermit getting from the modem to cause this? > It seems that Hayes removed an S register (S82) from the new model. Workaround: In your .mykermrc file, or wherever else you are setting up your modem, right after it says: set modem type hayes-high-speed Add: set modem command init-string ATQ0X4N1Y0&S0&C1&D2S37=0\13 Patch: *** /w/pub/ftp/kermit/f/ckudia.c Sun Nov 24 19:20:49 1996 --- ./ckudia.c Sat Mar 8 13:04:15 1997 *************** *** 896,904 **** ",", /* pause_chars */ 2, /* pause_time */ #ifdef OS2 ! "ATQ0X4N1Y0&S0&C1&D2S37=0S82=128\015", /* wake_str */ #else ! "ATQ0X4N1Y0S37=0S82=128\015", /* wake_str */ #endif /* OS2 */ 0, /* wake_rate */ "OK\015", /* wake_prompt */ --- 896,904 ---- ",", /* pause_chars */ 2, /* pause_time */ #ifdef OS2 ! "ATQ0X4N1Y0&S0&C1&D2S37=0\015", /* wake_str */ #else ! "ATQ0X4N1Y0S37=0\015", /* wake_str */ #endif /* OS2 */ 0, /* wake_rate */ "OK\015", /* wake_prompt */ ==================== X-Patch-Number: 0020 Date: Sun Mar 23 19:25:18 1997 From: Frank da Cruz Subject: READ command does not fail if file not open IF FAILURE does not work after a READ command that is executed before the READ file is opened. Here's the patch: *** /w/pub/ftp/kermit/f/ckuus6.c Sun Nov 24 19:20:51 1996 --- ./ckuus6.c Sun Mar 23 19:23:24 1997 *************** *** 338,348 **** return(y); if (chkfn(ZRFILE) < 1) { /* File open? */ printf("?Read file not open\n"); ! return(0); } if (!(s = (char *)readbuf)) { /* Where to read into. */ printf("?Oops, no READ buffer!\n"); ! return(0); } #ifdef BINREAD if (cx == XXRDBL) { /* READBLOCK */ --- 338,348 ---- return(y); if (chkfn(ZRFILE) < 1) { /* File open? */ printf("?Read file not open\n"); ! return(success = 0); } if (!(s = (char *)readbuf)) { /* Where to read into. */ printf("?Oops, no READ buffer!\n"); ! return(success = 0); } #ifdef BINREAD if (cx == XXRDBL) { /* READBLOCK */ ==================== X-Patch-Number: 0021 Date: Sun Mar 23 19:25:18 1997 From: Frank da Cruz Subject: Problems with long function arguments The 1023-byte limit on function arguments is overly restrictive on platforms where memory is not tight. Patch: *** /w/pub/ftp/kermit/f/ckuusr.h Sun Nov 24 19:20:52 1996 --- ckuusr.h Sun Mar 23 19:48:59 1997 *************** *** 19,24 **** --- 19,33 ---- /* Sizes of things */ + #ifdef BIGBUFOK + #define FNVALL 10238 /* Function return value */ + #define MAXARGLEN 8191 /* Function arg length after eval */ + #else + #define FNVALL 1022 + #define MAXARGLEN 1023 + #endif /* BIGBUFOK */ + #define FSPECL 300 /* Max length for MSEND/GET string */ #define VNAML 64 /* Max length for variable name */ #define ARRAYREFLEN 128 /* Max length for array reference */ *** /w/pub/ftp/kermit/f/ckuus4.c Sun Nov 24 19:20:50 1996 --- ckuus4.c Sun Mar 23 19:46:01 1997 *************** *** 3138,3144 **** } #endif /* NOFRILLS */ - #define FNVALL 1024 char fnval[FNVALL+2]; /* Return value */ static char ipabuf[16] = { NUL }; /* IP address buffer */ ==================== X-Patch-Number: 0022 Date: Sun Mar 23 19:25:18 1997 From: Frank da Cruz Subject: Certain \function()s can misbehave Certain \f...() functions return incorrect values, or even cause crashes or core dumps, when arguments are missing (especially the first one), or when they are too long. Also: . The \fverify() function did not work right when given a starting position as the third argument. . \fbreak() did not pay attention to the SET CASE setting . fverify() did not pay attention to the SET CASE setting . fverify() would crash if given a huge number as the 3rd argument . \flpad() and \frpad() erroneously truncated their arguments if they were longer than the padding length . \ftrim() and \fltrim() erroneously returned "0" if given an empty argument . \ttrim() and \fltrim() ignored SET CASE Also, some of the string functions were inconsistent as to whether they allowed a starting position -- e.g. \fverify() did, but \fbreak() didn't. So an optional starting position was added as the 3rd argument to \fbreak() and \fspan(). These are not documented in manual. There were numerous problems in the code. The fixes involve a complete replacement of the fneval() function in ckuus4.c. Note: this patch depends on Patch 0021. static char * /* Evaluate builtin functions */ fneval(fn,argp,argn,xp) char *fn, *argp[]; int argn; char * xp; { int i, j, k, len1, len2, len3, n, x, y; char *bp[FNARGS + 1]; /* Pointers to malloc'd strings */ char c; char *p, *s; char *val1, *val2; /* Pointers to numeric string values */ /* IMPORTANT: Note that argn is not an accurate count of the number of arguments. We can't really tell if an argument is null until after we execute the code below. So argn is really the maximum number of arguments we might have. In particular note that argn is always at least 1, even if the function is called with empty parentheses (but don't count on it). */ if (!fn) fn = ""; /* Protect against null pointers */ debug(F111,"fneval",fn,argn); debug(F110,"fneval",argp[0],0); if (argn > FNARGS) argn = FNARGS; /* And too many arguments */ y = lookup(fnctab,fn,nfuncs,&x); if (y < 0) /* bad function name */ return(""); /* so value is null */ #ifdef DEBUG if (deblog) { int j; for (j = 0; j < argn; j++) debug(F111,"fneval function arg",argp[j],j); } #endif /* DEBUG */ /* \fliteral() and \fcontents() are special functions that do not evaluate their arguments, and are treated specially here. After these come the functions whose arguments are evaluated in the normal way. */ if (y == FN_LIT) { /* literal(arg1) */ debug(F110,"flit",xp,0); return(xp ? xp : ""); /* return a pointer to arg itself */ } if (y == FN_CON) { /* Contents of variable, unexpanded. */ char c; if (!(p = argp[0]) || !*p) return(""); p = brstrip(p); if (*p == CMDQ) p++; if ((c = *p) == '%') { /* Scalar variable. */ c = *++p; /* Get ID character. */ p = ""; /* Assume definition is empty */ if (!c) return(p); /* Double paranoia */ if (c >= '0' && c <= '9') { /* Digit for macro arg */ if (maclvl < 0) /* Digit variables are global */ p = g_var[c]; /* if no macro is active */ else /* otherwise */ p = m_arg[maclvl][c - '0']; /* they're on the stack */ } else { if (isupper(c)) c -= ('a'-'A'); p = g_var[c]; /* Letter for global variable */ } return(p ? p : ""); } if (c == '&') { /* Array reference. */ int vbi, d; if (arraynam(p,&vbi,&d) < 0) /* Get name and subscript */ return(""); if (chkarray(vbi,d) > 0) { /* Array is declared? */ vbi -= ARRAYBASE; /* Convert name to index */ if (a_dim[vbi] >= d) { /* If subscript in range */ char **ap; ap = a_ptr[vbi]; /* get data pointer */ if (ap) { /* and if there is one */ return(ap[d]); /* return what it points to */ } } } else return(""); } } for (i = 0; i < FNARGS; i++) /* Initialize all argument pointers */ bp[i] = NULL; for (i = 0; i < argn; i++) { /* Loop to expand each argument */ n = MAXARGLEN; /* Allow plenty of space */ bp[i] = s = malloc(n+1); /* Allocate space for this argument */ if (bp[i] == NULL) { /* handle failure to get space */ for (k = 0; k < i; k++) if (bp[k]) free(bp[k]); debug(F101,"fneval malloc failure, arg","",i); return(""); } p = argp[i] ? argp[i] : ""; /* Point to this argument */ /* Trim leading and trailing spaces from the original argument, before evaluation. This code new to edit 184. */ { int x, j; x = strlen(p); if (*p == '{' && *(p+x-1) == '}') { p[x-1] = NUL; p++; x -= 2; } else { j = x - 1; /* Trim trailing whitespace */ while (j > 0 && (*(p + j) == SP || *(p + j) == HT)) *(p + j--) = NUL; while (*p == SP || *p == HT) /* Strip leading whitespace */ p++; } } /* Now evaluate the argument */ if (zzstring(p,&s,&n) < 0) { /* Expand arg into new space */ debug(F101,"fneval xxstring fails, arg","",i); for (k = 0; k <= i; k++) /* Free up previous space on error */ if (bp[k]) free(bp[k]); return(""); /* and return null string. */ } debug(F111,"fneval arg",bp[i],i); } #ifdef DEBUG if (deblog) { int j; for (j = 0; j < argn; j++) { debug(F111,"fneval arg post eval",argp[j],j); debug(F111,"fneval evaluated arg",bp[j],j); } } #endif /* DEBUG */ /* At this point bp[0..argn-1] are not NULL and all must be freed before returning. */ switch (y) { /* Do function on expanded args */ case FN_DEF: /* \fdefinition(arg1) */ if (!bp[0]) return(""); k = mlook(mactab,bp[0],nmac); p = (k > -1) ? mactab[k].mval : ""; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p ? p : ""); case FN_EVA: /* \fevaluate(arg1) */ p = ""; if (argn > 0) p = *(bp[0]) ? evala(bp[0]) : ""; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p ? p : ""); case FN_EXE: /* \fexecute(arg1) */ if (argn < 1) return(""); j = (int)strlen(s = bp[0]); /* Length of macro invocation */ p = ""; /* Initialize return value to null */ if (j) { /* If there is a macro to execute */ while (*s == SP) s++,j--; /* strip leading spaces */ p = s; /* remember beginning of macro name */ for (i = 0; i < j; i++) { /* find end of macro name */ if (*s == SP) break; s++; } if (*s == SP) { /* if there was a space after */ *s++ = NUL; /* terminate the macro name */ while (*s == SP) s++; /* skip past any extra spaces */ } else s = ""; /* maybe there are no arguments */ if (p && *p) k = mlook(mactab,p,nmac); /* Look up the macro name */ else k = -1; /* This is just a WEE bit dangerous because we are copying up to 9 arguments into the space reserved for one. It won't overrun the buffer, but if there are lots of long arguments we might lose some. The other problem is that if the macro has more than 3 arguments, the 4th through last are all concatenated onto the third. (The workaround is to use spaces rather than commas to separate them.) Leaving it like this to avoid having to allocate tons more buffers. */ if (argn > 1) { /* Commas used instead of spaces */ int i; char *p = bp[0]; /* Reuse this space */ *p = NUL; /* Make into dodo() arg list */ for (i = 1; i < argn; i++) { strncat(p,bp[i],MAXARGLEN); strncat(p," ",MAXARGLEN); } s = bp[0]; /* Point to new list */ } p = ""; /* Initialize return value */ if (k >= 0) { /* If macro found in table */ /* Go set it up (like DO cmd) */ if ((j = dodo(k,s,cmdstk[cmdlvl].ccflgs)) > 0) { if (cmpush() > -1) { /* Push command parser state */ extern int ifc; int ifcsav = ifc; /* Push IF condition on stack */ k = parser(1); /* Call parser to execute the macro */ cmpop(); /* Pop command parser */ ifc = ifcsav; /* Restore IF condition */ if (k == 0) { /* No errors, ignore action cmds. */ p = mrval[maclvl+1]; /* If OK, set return value. */ if (p == NULL) p = ""; } } else { /* Can't push any more */ debug(F100,"fexec pushed too deep","",0); printf("\n?\\fexec() too deeply nested\n"); while (cmpop() > -1) ; p = ""; } } } } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p ? p : ""); case FN_FC: /* \ffiles() - File count. */ if (argn < 1) return("0"); if (*(bp[0])) { k = zxpand(bp[0]); sprintf(fnval,"%d",k); p = fnval; } else p = "0"; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_FIL: /* \fnextfile() - Next file in list. */ p = fnval; /* (no args) */ *p = NUL; znext(p); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p ? p : ""); case FN_IND: /* \findex(arg1,arg2,arg3) */ case FN_RIX: /* \frindex(arg1,arg2,arg3) */ p = "0"; if (argn > 1) { /* Only works if we have 2 or 3 args */ int start; len1 = (int)strlen(bp[0]); /* length of string to look for */ len2 = (int)strlen(s = bp[1]); /* length of string to look in */ if (len1 < 1 || len2 < 1) /* Watch out for empty strings */ goto indexfin; j = len2 - len1; /* length difference */ start = (y == FN_IND) ? 0 : j; /* Starting position */ if (argn > 2) { val1 = *(bp[2]) ? evala(bp[2]) : ""; if (chknum(val1)) { int t; t = atoi(val1) - 1; if (t < 0) t = 0; start = (y == FN_IND) ? t : start - t - 1; if (start < 0) start = 0; } } start = ckindex(bp[0],bp[1],start,(y==FN_IND)?0:1,inpcas[cmdlvl]); sprintf(fnval,"%d",start); p = fnval; } indexfin: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_RPL: /* \freplace(s1,s2,s3) */ /* s = bp[0] = source string bp[1] = match string bp[2] = replacement string p = fnval = destination (result) string */ if (argn < 1) return(""); p = fnval; if (argn < 2) { /* Only works if we have 2 or 3 args */ strcpy(p,bp[0]); } else { len1 = (int)strlen(bp[0]); /* length of string to look in */ len2 = (int)strlen(bp[1]); /* length of string to look for */ len3 = (argn < 3) ? 0 : (int)strlen(bp[2]); /* Len of replacemnt */ j = len1 - len2 + 1; if (j < 1 || len1 == 0 || len2 == 0) { /* Args out of whack */ strcpy(p,bp[0]); /* so just return original string */ } else { s = bp[0]; /* Point to beginning of string */ while (j--) { /* For each character */ if (inpcas[cmdlvl] ? !strncmp(bp[1],s,len2) : !xxstrcmp(bp[1],s,len2) ) { /* To be replaced? */ if (len3) { /* Yes, */ strncpy(p,bp[2],len3); /* replace it */ p += len3; } s += len2; /* and skip past it. */ } else { /* No, */ *p++ = *s++; /* just copy this character */ } } *p = NUL; while (*p++ = *s++); } } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p = fnval); case FN_CHR: /* \fcharacter(arg1) */ if (argn < 1) return(""); val1 = *(bp[0]) ? evala(bp[0]) : ""; if (chknum(val1)) { /* Must be numeric */ i = atoi(val1); if (i >= 0 && i < 256) { /* Must be an 8-bit value */ p = fnval; *p++ = (char) i; *p = NUL; p = fnval; } else p = ""; /* Otherwise return empty string */ } else p = ""; /* Otherwise return empty string */ for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_COD: /* \fcode(char) */ if (argn < 1) return(""); if ((int)strlen(bp[0]) > 0) { p = fnval; i = *bp[0]; sprintf(p,"%d",(i & 0xff)); } else p = ""; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_LEN: /* \flength(arg1) */ if (argn > 0) { p = fnval; sprintf(p,"%d",(int)strlen(bp[0])); } else p = "0"; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_LOW: /* \flower(arg1) */ if (argn < 1) return(""); s = bp[0]; p = fnval; while (*s) { if (isupper(*s)) *p = (char) tolower(*s); else *p = *s; p++; s++; } *p = NUL; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); p = fnval; return(p); case FN_MAX: /* \fmax(arg1,arg2) */ case FN_MIN: /* \fmin(arg1,arg2) */ case FN_MOD: /* \fmod(arg1,arg2) */ if (argn < 2) return(""); val1 = *(bp[0]) ? evala(bp[0]) : ""; free(bp[0]); /* Copy this because evala() returns */ bp[0] = malloc((int)strlen(val1)+1); /* pointer to same */ strcpy(bp[0],val1); val1 = bp[0]; /* buffer next time. */ val2 = *(bp[1]) ? evala(bp[1]) : ""; if (chknum(val1) && chknum(val2)) { i = atoi(val1); j = atoi(val2); switch (y) { case FN_MAX: if (j < i) j = i; break; case FN_MIN: if (j > i) j = i; break; case FN_MOD: if (j == 0) { p = ""; goto modfin; } j = i % j; break; } p = fnval; sprintf(p,"%d",j); } else p = ""; modfin: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_SUB: /* \fsubstr(arg1,arg2,arg3) */ case FN_RIG: /* \fright(arg1,arg2) */ if (argn < 1) return(""); val1 = ""; if (argn > 1) if (*(bp[1])) val1 = evala(bp[1]); free(bp[1]); /* Have to copy this */ bp[1] = malloc((int)strlen(val1)+1); strcpy(bp[1],val1); val1 = bp[1]; val2 = ""; if (argn > 2) if (*(bp[2])) val2 = evala(bp[2]); if ( ((argn > 1) && (int)strlen(val1) && !rdigits(val1)) || ((y == FN_SUB) && ((argn > 2) && (int)strlen(val2) && !rdigits(val2))) ) { p = ""; /* if either, return null */ } else { int lx; p = fnval; /* pointer to result */ lx = strlen(bp[0]); /* length of arg1 */ if (y == FN_SUB) { /* substring */ k = (argn > 2) ? atoi(val2) : MAXARGLEN; /* length */ j = (argn > 1) ? atoi(val1) : 1; /* start pos for substr */ } else { /* right */ k = (argn > 1) ? atoi(val1) : lx; /* length */ j = lx - k + 1; /* start pos for right */ if (j < 1) j = 1; } if (k > 0 && j <= lx) { /* if start pos in range */ s = bp[0]+j-1; /* point to source string */ for (i = 0; (i < k) && (*p++ = *s++); i++) ; /* copy */ } *p = NUL; /* terminate the result */ p = fnval; /* and point to it. */ } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); /* Free temp mem */ return(p); case FN_UPP: /* \fupper(arg1) */ s = bp[0] ? bp[0] : ""; p = fnval; while (*s) { if (islower(*s)) *p = (char) toupper(*s); else *p = *s; p++; s++; } *p = NUL; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); p = fnval; return(p); case FN_REP: /* \frepeat(text,number) */ if (argn < 1) return(""); p = fnval; /* Return value */ *p = NUL; val1 = "1"; if (argn > 1) if (*(bp[1])) val1 = evala(bp[1]); if (chknum(val1)) { /* Repeat count */ n = atoi(val1); if (n > 0) { /* Make n copies */ p = fnval; *p = '\0'; k = (int)strlen(bp[0]); /* Make sure string has some length */ if (k > 0) { for (i = 0; i < n; i++) { s = bp[0]; for (j = 0; j < k; j++) { if ((p - fnval) >= FNVALL) { /* Protect against */ p = ""; /* core dumps... */ break; } else *p++ = *s++; } } *p = NUL; } } } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); p = fnval; return(p); #ifndef NOFRILLS case FN_REV: /* \freverse() */ if (argn < 1) return(""); p = fnval; yystring(bp[0],&p); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); #endif /* NOFRILLS */ case FN_RPA: /* \frpad() and \flpad() */ case FN_LPA: if (argn < 1) return(""); *fnval = NUL; /* Return value */ val1 = ""; if (argn > 1) if (*(bp[1])) val1 = evala(bp[1]); if (argn == 1 || !*val1) { /* If a number wasn't given */ p = fnval; /* just return the original string */ strncpy(p,bp[0],FNVALL); } else if (chknum(val1)) { /* Repeat count */ char pc; n = atoi(val1); if (n >= 0) { p = fnval; k = (int)strlen(bp[0]); /* Length of string to be padded */ if (k >= n) { /* It's already long enough */ strncpy(p,bp[0],FNVALL); } else { if (n + k <= FNVALL) { pc = (char) ((argn < 3) ? SP : *bp[2]); if (!pc) pc = SP; if (y == FN_RPA) { /* RPAD */ strncpy(p,bp[0],k); p += k; for (i = k; i < n; i++) *p++ = pc; } else { /* LPAD */ n -= k; for (i = 0; i < n; i++) *p++ = pc; strncpy(p,bp[0],k); p += k; } } *p = NUL; } } } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); p = fnval; return(p); #ifdef ZFCDAT case FN_FD: /* \fdate(filename) */ p = fnval; *p = NUL; if (argn > 0) sprintf(fnval,"%s",*(bp[0]) ? zfcdat(bp[0]) : ""); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); #endif /* ZFCDAT */ case FN_FS: /* \fsize(filename) */ p = fnval; *p = NUL; if (argn > 0) sprintf(fnval,"%ld",*(bp[0]) ? zchki(bp[0]) : 0L); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_VER: /* \fverify() */ p = "0"; if (argn > 1) { /* Only works if we have 2 or 3 args */ int start; char *s2, ch1, ch2; start = 0; if (argn > 2) { /* Starting position specified */ val1 = *(bp[2]) ? evala(bp[2]) : ""; if (chknum(val1)) { start = atoi(val1) /* - 1 */; if (start < 0) start = 0; if (start > (int)strlen(bp[1])) goto verfin; } } i = start; p = "0"; for (s = bp[1] + start; *s; s++,i++) { ch1 = *s; if (!inpcas[cmdlvl]) if (islower(ch1)) ch1 = toupper(ch1); j = 0; for (s2 = bp[0]; *s2; s2++) { ch2 = *s2; if (!inpcas[cmdlvl]) if (islower(ch2)) ch2 = toupper(ch2); if (ch1 == ch2) { j = 1; break; } } if (j == 0) { sprintf(fnval,"%d",i+1); p = fnval; break; } } } verfin: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_IPA: /* Find and return IP address */ if (argn > 0) { /* in argument string. */ int start; char *s2; start = 0; if (argn > 1) { /* Starting position specified */ if (chknum(bp[1])) { start = atoi(bp[1]) - 1; if (start < 0) start = 0; } } p = getip(bp[0]+start); } else p = ""; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_HEX: /* \fhexify(arg1) */ if (argn < 1) return(""); p = ""; if ((int)strlen(bp[0]) < (FNVALL / 2)) { s = bp[0]; p = fnval; while (*s) { x = (*s >> 4) & 0x0f; *p++ = hexdigits[x]; x = *s++ & 0x0f; *p++ = hexdigits[x]; } *p = NUL; p = fnval; } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_UNH: { /* \funhex(arg1) */ int c[2], i; if (argn < 1) return(""); p = ""; if ((int)strlen(bp[0]) < (FNVALL * 2)) { s = bp[0]; p = fnval; while (*s) { for (i = 0; i < 2; i++) { c[i] = *s++; if (!c[i]) { p = ""; goto unhexfin; } if (islower(c[i])) c[i] = toupper(c[i]); if (c[i] >= '0' && c[i] <= '9') c[i] -= 0x30; else if (c[i] >= 'A' && c[i] <= 'F') c[i] -= 0x37; else { p = ""; goto unhexfin; } } *p++ = ((c[0] << 4) & 0xf0) | (c[1] & 0x0f); } *p = NUL; p = fnval; } unhexfin: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); } case FN_BRK: { /* \fbreak() */ char * c; /* Characters to break on */ char c2, s2; int start = 0; int done = 0; if (argn < 1) return(""); p = fnval; /* Destination pointer */ *p = NUL; if (argn > 2) { s = bp[2] ? bp[2] : ""; if (chknum(s)) { start = atoi(s); if (start < 0) start = 0; if (start > (int)strlen(bp[0])) goto brkfin; } } s = bp[0] + start; /* Source pointer */ while (*s && !done) { s2 = *s; if (!inpcas[cmdlvl] && islower(s2)) s2 = toupper(s2); c = bp[1] ? bp[1] : ""; /* Character to break on */ while (*c) { c2 = *c; if (!inpcas[cmdlvl] && islower(c2)) c2 = toupper(c2); if (c2 == s2) { done = 1; break; } c++; } if (done) break; *p++ = *s++; } *p = NUL; /* terminate the result */ p = fnval; /* and point to it. */ brkfin: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); } case FN_SPN: { /* \fspan() */ char *q; char c1, c2; int start = 0; if (argn < 1) return(""); p = fnval; /* Result pointer */ *p = NUL; if (argn > 2) { /* Starting position */ s = bp[2] ? bp[2] : ""; if (chknum(s)) { start = atoi(s); if (start < 0) start = 0; } } s = bp[0] + start; /* Source pointer */ if (argn > 1 && (int)strlen(bp[1]) > 0 && start <= (int)strlen(bp[0])) { while (*s) { /* Loop thru source string */ q = bp[1]; /* Span string */ c1 = *s; if (!inpcas[cmdlvl]) if (islower(c1)) c1 = toupper(c1); x = 0; while (c2 = *q++) { if (!inpcas[cmdlvl]) if (islower(c2)) c2 = toupper(c2); if (c1 == c2) { x = 1; break; } } if (!x) break; *p++ = *s++; } *p = NUL; /* Terminate and return the result */ p = fnval; } for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); } case FN_TRM: /* \ftrim(s1[,s2]) */ case FN_LTR: /* \fltrim(s1[,s2]) */ if (argn < 1) return(""); if ((len1 = (int)strlen(bp[0])) > 0) { if (len1 > FNVALL) len1 = FNVALL; s = " \t"; if (argn > 1) /* Trim list given */ s = bp[1]; len2 = (int)strlen(s); if (len2 < 1) { /* or not... */ s = " \t"; /* Default is to trim whitespace */ len2 = 2; } if (y == FN_TRM) { /* Trim from right */ char * q, p2, q2; strncpy(fnval,bp[0],FNVALL); /* Copy string to output */ p = fnval + len1 - 1; /* Point to last character */ while (p >= (char *)fnval) { /* Go backwards */ q = s; /* Point to trim list */ p2 = *p; if (!inpcas[cmdlvl]) if (islower(p2)) p2 = toupper(p2); while (*q) { /* Is this char in trim list? */ q2 = *q; if (!inpcas[cmdlvl]) if (islower(q2)) q2 = toupper(q2); if (p2 == q2) { /* Yes, null it out */ *p = NUL; break; } q++; } if (!*q) /* Trim list exhausted */ break; /* So we're done. */ p--; /* Else keep trimming */ } } else { /* Trim from left */ char * q, p2, q2; p = bp[0]; /* Source */ while (*p) { p2 = *p; if (!inpcas[cmdlvl]) if (islower(p2)) p2 = toupper(p2); q = s; while (*q) { /* Is this char in trim list? */ q2 = *q; if (!inpcas[cmdlvl]) if (islower(q2)) q2 = toupper(q2); if (p2 == q2) { /* Yes, point past it */ p++; /* and try next source character */ break; } q++; /* No, try next trim character */ } if (!*q) /* Trim list exhausted */ break; /* So we're done. */ } strncpy(fnval,p,FNVALL); } p = fnval; } else p = ""; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_CAP: /* \fcapitalize(arg1) */ if (argn < 1) return(""); s = bp[0]; p = fnval; x = 0; while (c = *s++) { if (isalpha(c)) { if (x == 0) { x = 1; if (islower(c)) c = toupper(c); } else if (isupper(c)) c = tolower(c); } *p++ = c; } *p = NUL; for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); p = fnval; return(p); case FN_TOD: /* Time of day to secs since midnite */ if (argn < 1) return(""); p = fnval; sprintf(p,"%ld",tod2sec(bp[0])); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); case FN_FFN: /* Full pathname of file */ p = fnval; *p = NUL; if (argn > 0) #ifdef ZFNQFP zfnqfp(bp[0],FNVALL,p); #else strcpy(p,bp[0]); #endif /* ZFNQFP */ for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p ? p : ""); case FN_CHK: { /* \fchecksum() */ long chk = 0; p = (argn > 0) ? bp[0] : ""; while (*p) chk += *p++; sprintf(fnval,"%lu",chk); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return((char *)fnval); } case FN_CRC: /* \fcrc16() */ *fnval = NUL; if (argn > 0) sprintf(fnval,"%u",chk3((CHAR *)bp[0],0)); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return((char *)fnval); case FN_BSN: /* \fbasename() */ if (argn > 0) zstrip(bp[0],&p); for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(p); default: for (k = 0; k < argn; k++) if (bp[k]) free(bp[k]); return(""); } } ==================== X-Patch-Number: 0023 Date: Sun Mar 23 19:25:18 1997 From: Frank da Cruz Subject: X MOD 0 crashes program "\feval(number%0)", "\fmod(number,0)", or "EVALUATE number % 0" would crash C-Kermit. Also, dividing by zero would return -1 without issuing any kind of warning. Now both return -1 and always print a "?Divide by zero" warning. Patch: *** /w/pub/ftp/kermit/f/ckuus5.c Tue Feb 18 09:31:55 1997 --- ./ckuus5.c Thu Mar 27 19:54:55 1997 *************** *** 5532,5540 **** switch(op) { case '*': expval = oldval * expval; break; case '/': ! if (expval == 0) expval = -1; /* don't divide by 0 */ ! else expval = oldval / expval; break; ! case '%': expval = oldval % expval; break; case '&': expval = oldval & expval; break; } } --- 5532,5545 ---- switch(op) { case '*': expval = oldval * expval; break; case '/': ! case '%': ! if (expval == 0) { ! if (!x_ifnum) ! printf("?Divide by zero\n"); ! expval = -1; /* No way to return a null integer */ ! } else ! expval = (op == '/') ? (oldval / expval) : (oldval % expval); ! break; case '&': expval = oldval & expval; break; } } ==================== X-Patch-Number: 0024 Date: Mon Mar 31 19:02:32 1997 From: Frank da Cruz Subject: Internal bulletproofing for lower() function. The lower() function did not check if called with a null pointer. Patch: *** /w/pub/ftp/kermit/f/ckucmd.c Sun Nov 24 19:20:49 1996 --- ckucmd.c Mon Mar 31 19:00:40 1997 *************** *** 3875,3880 **** --- 3875,3881 ---- int lower(s) char *s; { int n = 0; + if (!s) return(0); while (*s) { if (isupper(*s)) *s = (char) tolower(*s); s++, n++; } return(n); } ==================== X-Patch-Number: 0025 To: kermit@columbia.edu Subject: Real OpenBSD support for C-Kermit 6.0 Date: Tue, 01 Apr 1997 11:56:01 -0700 From: "Todd C. Miller" Below is a diff to add a real OpenBSD entry. OpenBSD uses ncurses as its curses and has terminfo so must link with -ltermlib (-ltermcap is for termcap-compatibility). --- makefile.DIST Wed Dec 18 21:57:53 1996 +++ makefile Tue Apr 1 11:51:23 1997 @@ -402,7 +402,7 @@ # + for OSF/1 (vanilla, from OS/F), "make posix" # + for OkiStation 7300 Series, "make sys5r4sxtcp" # + for Olivetti LSX-3020 with X/OS R.2.3, "make xos23" or "make xos23c" -# ? for OpenBSD, "make netbsd"? +# + for OpenBSD, "make openbsd" # + for Perkin-Elmer (Concurrent) 3200 series, "make sys5". # + for Perkin-Elmer (Concurrent) 3200 series with , "make ccop1" # + for Perkin-Elmer/Concurrent 3200 with Xelos R02, "make ccop1" @@ -888,6 +888,14 @@ $(MAKE) wermit \ "CFLAGS= -DBSD44 -DCK_CURSES -DDYNAMIC -DTCPSOCKET $(KFLAGS) -O" \ "LIBS= -lcurses -ltermcap" + +#OpenBSD +#Note that OpenBSD uses ncurses as its curses so use -ltermlib, not -ltermcap +openbsd: + @echo Making C-Kermit $(CKVER) for OpenBSD with curses... + $(MAKE) wermit \ + "CFLAGS= -DBSD44 -DCK_CURSES -DDYNAMIC -DTCPSOCKET $(KFLAGS) -O" \ + "LIBS= -lcurses -ltermlib" #NetBSD netbsd: ==================== X-Patch-Number: 0026 Date: Tue Apr 1 18:02:15 1997 From: Frank da Cruz Subject: Incorrect checks for macro/command-file nesting depth *** /w/pub/ftp/kermit/f/ckuusr.c Tue Feb 18 09:31:40 1997 --- ckuusr.c Tue Apr 1 18:00:56 1997 *************** *** 3405,3411 **** #endif /* OS2 */ char takepath[1024]; ! if (tlevel > MAXTAKE-1) { printf("?Take files nested too deeply\n"); return(-2); } --- 3405,3411 ---- #endif /* OS2 */ char takepath[1024]; ! if (tlevel >= MAXTAKE-1) { printf("?Take files nested too deeply\n"); return(-2); } *** /w/pub/ftp/kermit/f/ckuus5.c Tue Feb 18 09:31:55 1997 --- ckuus5.c Tue Apr 1 18:08:25 1997 *************** *** 2526,2534 **** --- 2526,2536 ---- debug(F111,"popclvl mac 3",macp[maclvl],maclvl); *cmdbuf = '\0'; /* clear the command buffer */ debug(F111,"popclvl mac 4",mrval[maclvl+1],maclvl); + if (maclvl+1 < MACLEVEL) { if (mrval[maclvl+1]) { /* Free any deeper return values. */ free(mrval[maclvl+1]); mrval[maclvl+1] = NULL; + } } debug(F111,"popclvl mac 6",mrval[maclvl+1],maclvl); maclvl--; /* Pop macro level */ ==================== X-Patch-Number: 0027 Date: Tue Apr 1 18:34:55 1997 From: Frank da Cruz Subject: ANSWER doesn't automatically CONNECT The DIAL and REDIAL commands, if given from top level with DIAL CONNECT set to ON or AUTO, and if they succeed, cause C-Kermit to enter CONNECT mode automatically. ANSWER should behave the same way. Patch: *** /w/pub/ftp/kermit/f/ckuusr.c Tue Feb 18 09:31:40 1997 --- ckuusr.c Tue Apr 1 18:31:48 1997 *************** *** 1928,1934 **** cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */ x = dodial(cx); debug(F101,"dodial returns","",x); ! if ((cx == XXDIAL || cx == XXRED) && (x > 0) && /* If DIAL or REDIAL succeeded */ (dialcon > 0)) { if ( dialcon == 1 || /* And DIAL CONNECT is ON, */ --- 1928,1934 ---- cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */ x = dodial(cx); debug(F101,"dodial returns","",x); ! if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) && (x > 0) && /* If DIAL or REDIAL succeeded */ (dialcon > 0)) { if ( dialcon == 1 || /* And DIAL CONNECT is ON, */ ==================== X-Patch-Number: 0028 Date: Tue Apr 1 19:39:51 1997 From: Frank da Cruz Subject: Overzealous EXIT warning When SET EXIT WARNING is ON, C-Kermit can sometimes warn you about a connection being open when it couldn't possibly be open. This can happen, for example, if you SET LINE to a serial device and then HANGUP, but the serial device is still getting the Carrier Detect signal (e.g. because it is connected to a modem that never drops CD). However, if C-Kermit has been told to HANGUP, or to close the connection via SET HOST or SET LINE with no argument, then it knows the connection is closed and so it should not warn. Here's the patch: *** /w/pub/ftp/kermit/f/ckcmai.c Tue Feb 18 09:31:26 1997 --- ./ckcmai.c Tue Apr 1 19:35:59 1997 *************** *** 969,974 **** --- 969,975 ---- extern int ttyfd, tn_exit; #endif /* NETCONN */ int exitonclose = 0; /* Exit on close */ + int haveline = 0; /* SET LINE or SET HOST in effect */ int tlevel = -1; /* Take-file command level */ #ifdef NOLOCAL *** /w/pub/ftp/kermit/f/ckuus3.c Sun Nov 24 19:20:50 1996 --- ./ckuus3.c Tue Apr 1 19:35:04 1997 *************** *** 85,90 **** --- 85,92 ---- xfrcan, xfrchr, xfrnum, pacing, xitwarn, xitsta, cmd_cols, cmd_rows, ckxech, xaskmore, xfrbel; + extern int haveline; + #ifdef TCPSOCKET extern int tn_exit; #endif /* TCPSOCKET */ *************** *** 4428,4433 **** --- 4430,4436 ---- debug(F101,"hupok x","",x); debug(F101,"hupok xitwarn","",xitwarn); debug(F101,"hupok network","",network); + debug(F101,"hupok haveline","",haveline); #ifdef CK_TTYFD debug(F101,"hupok ttyfd","",ttyfd); #endif /* CK_TTYFD */ *************** *** 4450,4455 **** --- 4453,4460 ---- ttchk() >= 0 ) needwarn = 1; + /* A connection seems to be open but it can't possibly be */ + if (!haveline) needwarn = 0; if (needwarn) { if (strcmp(ttname,"*")) printf( *************** *** 4474,4479 **** --- 4479,4486 ---- 1 /* or can't check ttyfd, then warn */ #endif /* CK_TTYFD */ ; + /* A connection seems to be open but it can't possibly be */ + if (!haveline) needwarn = 0; if (needwarn) printf( " A serial connection might still be active on %s.\n", *** /w/pub/ftp/kermit/f/ckuus7.c Wed Nov 27 19:54:46 1996 --- ./ckuus7.c Tue Apr 1 19:38:36 1997 *************** *** 129,134 **** --- 129,135 ---- extern int tnlm, sosi, tlevel, lf_opts, backgrd, flow, fdispla, b_save, f_save; extern int fnrpath, fnspath, debses, parity, pktpaus, ttnproto, ckxech; extern int x_ifnum; + extern int haveline; extern int atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso; *************** *** 5243,5248 **** --- 5244,5250 ---- mdmhup(); #endif /* NODIAL */ ttclos(0); /* Close old connection, if any */ + haveline = 0; if (oldplex > -1) /* Restore duplex setting. */ duplex = oldplex; if (*s) { /* They gave a hostname */ *************** *** 5273,5278 **** --- 5275,5281 ---- if (zz) { if (autoflow) /* Maybe change flow control */ setflow(); + haveline = 1; return(success = 1); } } *** /w/pub/ftp/kermit/f/ckuusr.c Tue Feb 18 09:31:40 1997 --- ./ckuusr.c Tue Apr 1 19:37:07 1997 *************** *** 127,132 **** --- 127,133 ---- extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg, escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho, ckxech, carrier, deblog, sendmode, epktflg, what, moving, protocol; + extern int haveline; extern int bye_active; extern long sendstart; #ifdef CK_TTYFD *************** *** 2417,2422 **** --- 2418,2424 ---- if (x) DialerSend(OPT_KERMIT_HANGUP, 0); #endif /* OS2 */ + if (x) haveline = 0; return(success = x); } ==================== X-Patch-Number: 0029 Date: Sat Apr 5 13:50:08 1997 From: Frank da Cruz Subject: OUTPUT doesn't echo when DUPLEX is HALF If INPUT ECHO is ON and DUPLEX is HALF, OUTPUT should echo locally. Patch: *** /w/pub/ftp/kermit/f/ckuus5.c Tue Feb 18 09:31:55 1997 --- ckuus5.c Sat Apr 5 13:48:46 1997 *************** *** 1734,1739 **** --- 1734,1740 ---- msleep(pacing); } } + if (inecho && duplex && local) conxo(obsize,obuf); rc = 0; /* Success */ xxout_x: obn = 0; /* Reset count */ ==================== X-Patch-Number: 0030 Date: Sat Apr 5 14:33:39 1997 From: Frank da Cruz Subject: Minor problems with REMOTE DIRECTORY/DELETE/etc The replies to REMOTE DIRECTORY, REMOTE DELETE, and REMOTE SPACE generated by the C-Kermit server in UNIX and AOS/VS contained double carriage returns. The responses generated by the OS-9 or Mac server contained double linefeeds. Also, the REMOTE DELETE summary report counted files as being deleted when they actually were not (e.g. if write-protected). Patch: *** /w/pub/ftp/kermit/f/ckcfns.c Sun Nov 24 19:20:48 1996 --- ./ckcfns.c Sat Apr 5 14:29:25 1997 *************** *** 2631,2640 **** /* The following bunch of routines feed internally generated data to the server to send to the client in response to REMOTE commands like DIRECTORY, DELETE, ! and so on. Note that in writing this data to buffers, we do not use "\n". ! Instead we use "\15\12", i.e. LITERAL carriage return and linefeed, because ! that it was is required by the Kermit protocol in text mode. */ static char funcbuf[512]; static int --- 2636,2663 ---- /* The following bunch of routines feed internally generated data to the server to send to the client in response to REMOTE commands like DIRECTORY, DELETE, ! and so on. We have to write these lines in the format appropriate to our ! platform, so they can be converted to generic (CRLF) text format by the ! packetizer. */ + #ifdef UNIX + char * endline = "\12"; + #else + #ifdef datageneral + char * endline = "\12"; + #else + #ifdef MAC + char * endline = "\15"; + #else + #ifdef OSK + char * endline = "\15"; + #else + char * endline = "\15\12"; + #endif /* OSK */ + #endif /* MAC */ + #endif /* datageneral */ + #endif /* UNIX */ + static char funcbuf[512]; static int *************** *** 2792,2817 **** if (len > -1L) { nfiles++; nbytes += len; ! sprintf(funcbuf," %04d-%02d-%02d %02d:%02d %11ld %s\15\12", ! year, month, date, hour, minute, len, p); } else { ndirs++; sprintf(funcbuf, ! " %04d-%02d-%02d %02d:%02d %11s %s\15\12", ! year, month, date, hour, minute, "(directory)", p); } funcnxt = 0; funclen = strlen(funcbuf); } else if (nxpnd == 0) { /* Done, send summary */ char *blankline = ""; /* At beginning of summary */ - char *endline = "\15\12"; /* At end of summary */ /* The idea is to prevent (a) unnecessary multiple blanklines, and (b) prompt-stomping. Preventing (b) is practically impossible, because it depends on the client so for now always include that final CRLF. */ if (!ndirs || !nbytes || !nfiles) ! blankline = "\15\12"; sprintf(funcbuf, "%sSummary: %ld director%s, %ld file%s, %ld byte%s%s", blankline, --- 2815,2840 ---- if (len > -1L) { nfiles++; nbytes += len; ! sprintf(funcbuf," %04d-%02d-%02d %02d:%02d %11ld %s%s", ! year, month, date, hour, minute, len, p, endline); } else { ndirs++; sprintf(funcbuf, ! " %04d-%02d-%02d %02d:%02d %11s %s%s", ! year, month, date, hour, minute, ! "(directory)", p, endline); } funcnxt = 0; funclen = strlen(funcbuf); } else if (nxpnd == 0) { /* Done, send summary */ char *blankline = ""; /* At beginning of summary */ /* The idea is to prevent (a) unnecessary multiple blanklines, and (b) prompt-stomping. Preventing (b) is practically impossible, because it depends on the client so for now always include that final CRLF. */ if (!ndirs || !nbytes || !nfiles) ! blankline = endline; sprintf(funcbuf, "%sSummary: %ld director%s, %ld file%s, %ld byte%s%s", blankline, *************** *** 2887,2893 **** ndirs = 0L; nfiles = 0L; nbytes = 0L; ! sprintf(funcbuf,"Listing files: \"%s\"\15\12\15\12",name); funcnxt = 0; funclen = strlen(funcbuf); --- 2910,2916 ---- ndirs = 0L; nfiles = 0L; nbytes = 0L; ! sprintf(funcbuf,"Listing files: \"%s\"%s%s",name,endline,endline); funcnxt = 0; funclen = strlen(funcbuf); *************** *** 2951,2965 **** if (*p == '/') p++; if (len > -1L) { nfiles++; nbytes += len; ! sprintf(funcbuf, ! " %10s: %s\15\12", ! zdelet(name) ? "skipping" : "deleted", ! p ! ); } else ! sprintf(funcbuf," directory: %s\15\12", p); funcnxt = 0; funclen = strlen(funcbuf); } else --- 2974,2988 ---- if (*p == '/') p++; if (len > -1L) { + if (zdelet(name)) { + sprintf(funcbuf," %10s: %s%s","skipping",p,endline); + } else { nfiles++; nbytes += len; ! sprintf(funcbuf," %10s: %s%s","deleted",p,endline); ! } } else ! sprintf(funcbuf," directory: %s%s", p, endline); funcnxt = 0; funclen = strlen(funcbuf); } else *************** *** 2968,2978 **** if (nxpnd == 0) { sprintf(funcbuf, ! "\15\12%ld file%s deleted, %ld byte%s freed\15\12", nfiles, (nfiles == 1) ? "" : "s", nbytes, ! (nbytes == 1) ? "" : "s" ); nxpnd--; funcnxt = 0; --- 2991,3003 ---- if (nxpnd == 0) { sprintf(funcbuf, ! "%s%ld file%s deleted, %ld byte%s freed%s", ! endline, nfiles, (nfiles == 1) ? "" : "s", nbytes, ! (nbytes == 1) ? "" : "s", ! endline ); nxpnd--; funcnxt = 0; *************** *** 3018,3024 **** #endif /* OS2 */ nfiles = nbytes = 0L; ! sprintf(funcbuf,"Deleting \"%s\"\15\12",name); funcnxt = 0; funclen = strlen(funcbuf); --- 3043,3049 ---- #endif /* OS2 */ nfiles = nbytes = 0L; ! sprintf(funcbuf,"Deleting \"%s\"%s",name,endline); funcnxt = 0; funclen = strlen(funcbuf); *************** *** 3044,3053 **** static char spctext[64]; if (drive) sprintf(spctext, ! " Drive %c: %ldK free\15\12", drive, ! zdskspace(drive - 'A' + 1) / 1024L); else ! sprintf(spctext, " Free space: %ldK\15\12", zdskspace(0) / 1024L); nfils = 0; /* No files, no lists. */ xflg = 1; /* Flag we must send X packet. */ strcpy(cmdstr,"free space"); /* Data for X packet. */ --- 3069,3081 ---- static char spctext[64]; if (drive) sprintf(spctext, ! " Drive %c: %ldK free%s", ! drive, ! zdskspace(drive - 'A' + 1) / 1024L, ! endline ! ); else ! sprintf(spctext, " Free space: %ldK%s", zdskspace(0) / 1024L, endline); nfils = 0; /* No files, no lists. */ xflg = 1; /* Flag we must send X packet. */ strcpy(cmdstr,"free space"); /* Data for X packet. */ ==================== X-Patch-Number: 0031 Date: Sat Apr 5 15:19:46 1997 From: Frank da Cruz Subject: CHECK command broken Patch: *** /w/pub/ftp/kermit/f/ckuus3.c Sun Nov 24 19:20:50 1996 --- ckuus3.c Sat Apr 5 15:18:40 1997 *************** *** 1465,1471 **** if ((y = cmcfm()) < 0) return(y); #ifndef NOPUSH ! if (!xxstrcmp(atmbuf,"push",(int)strlen(atmbuf))) { if (msgflg) /* If at top level... */ printf(" push%s available\n", nopush ? " not" : ""); else if (nopush && !backgrd) --- 1465,1471 ---- if ((y = cmcfm()) < 0) return(y); #ifndef NOPUSH ! if (!xxstrcmp(line,"push",(int)strlen(line))) { if (msgflg) /* If at top level... */ printf(" push%s available\n", nopush ? " not" : ""); else if (nopush && !backgrd) ==================== X-Patch-Number: 0032 Date: Sat Apr 5 16:34:57 1997 From: Frank da Cruz Subject: Problem with SET TRANSMIT ECHO SET TRANSMIT ECHO ON didn't work when PARITY was NONE. Patch: *** /w/pub/ftp/kermit/f/ckuus4.c Sun Nov 24 19:20:50 1996 --- ckuus4.c Sat Apr 5 16:33:36 1997 *************** *** 1285,1294 **** *s &= 0x7f; s++; } if (conoll(p) < 0) { z = 0; goto xmitexit; - } } } if (xmitw) /* Give receiver time to digest. */ --- 1285,1294 ---- *s &= 0x7f; s++; } + } if (conoll(p) < 0) { z = 0; goto xmitexit; } } if (xmitw) /* Give receiver time to digest. */ ==================== X-Patch-Number: 0033 Date: Sun Apr 6 14:24:24 1997 From: Frank da Cruz Subject: HELP SET SERVER says too much SET SERVER IDLE-TIMEOUT is only available in Kermit 95. Patch: *** /w/pub/ftp/kermit/f/ckuus2.c Wed Nov 27 19:54:46 1996 --- ckuus2.c Sun Apr 6 14:23:03 1997 *************** *** 1127,1134 **** --- 1127,1136 ---- "Tells the C-Kermit server where to search for files whose names it receives", "from client GET commands when the names are not fully specified pathnames.", "Default is no GET-PATH, so C-Kermit looks only in its current directory.\n", + #ifdef OS2 "SET SERVER IDLE-TIMEOUT seconds", "Idle time limit while in server mode, 0 for no limit.\n", + #endif /* OS2 */ "SET SERVER LOGIN [ username [ password [ account ] ] ]", "Sets up a username and optional password which must be supplied before", "the server will respond to any commands other than REMOTE LOGIN. The", ==================== X-Patch-Number: 0034 Date: Thu May 29 11:50:52 1997 From: Frank da Cruz Subject: READ and !READ too picky about line terminators The READ and !READ commands do not return the last or only line of the input file (or command) if it does not end with a proper line terminator. Patch: *** /w/pub/ftp/kermit/f/ckuus6.c Sun Nov 24 19:20:51 1996 --- ./ckuus6.c Thu May 29 11:49:41 1997 *************** *** 358,364 **** { y = zsinl(ZRFILE, s, readblock); /* Read a line. */ debug(F111,"read zsinl",s,y); ! if (y < 0) { /* On EOF or other error, */ zclose(ZRFILE); /* close the file, */ delmac(vnp); /* delete the variable, */ return(success = 0); /* and return failure. */ --- 358,364 ---- { y = zsinl(ZRFILE, s, readblock); /* Read a line. */ debug(F111,"read zsinl",s,y); ! if (y < 0 && !*s) { /* On EOF or other error, */ zclose(ZRFILE); /* close the file, */ delmac(vnp); /* delete the variable, */ return(success = 0); /* and return failure. */ ==================== X-Patch-Number: 0035 Date: Thu Jul 3 13:35:08 1997 From: Frank da Cruz Subject: END from inside SWITCH doesn't work Instead of terminating the current macro or command file, the END command, when given in a SWITCH statement, just exits from the SWITCH statement. Patch: *** /w/pub/ftp/kermit/f/ckuusr.c Tue Feb 18 09:31:40 1997 --- ./ckuusr.c Thu Jul 3 13:34:10 1997 *************** *** 3372,3378 **** (cmdstk[cmdlvl].src == CMD_MD) && (!strncmp(m_arg[maclvl-1][0],"_xif",4) || !strncmp(m_arg[maclvl-1][0],"_for",4) || ! !strncmp(m_arg[maclvl-1][0],"_whi",4))) { debug(F110,"END popping",m_arg[maclvl-1][0],0); dogta(XXPTA); /* Put args back */ popclvl(); /* Pop up two levels */ --- 3372,3379 ---- (cmdstk[cmdlvl].src == CMD_MD) && (!strncmp(m_arg[maclvl-1][0],"_xif",4) || !strncmp(m_arg[maclvl-1][0],"_for",4) || ! !strncmp(m_arg[maclvl-1][0],"_whi",4) || ! !strncmp(m_arg[maclvl-1][0],"_swi",4))) { debug(F110,"END popping",m_arg[maclvl-1][0],0); dogta(XXPTA); /* Put args back */ popclvl(); /* Pop up two levels */ ==================== X-Patch-Number: 0036 Date: Sat Sep 20 10:50:49 1997 From: Frank da Cruz Subject: Problem telnetting to multihomed hosts Problems can occur telnetting to multihomed hosts by IP number. If the address given is an IP address (rather than a hostname), the gethostbyname call should be skipped. This was already done for Windows, but it should be done everywhere. Cure: apply this patch: *** /w/pub/ftp/kermit/f/ckcnet.c Wed Nov 27 19:54:46 1996 --- ./ckcnet.c Sat Sep 20 11:38:57 1997 *************** *** 1940,1958 **** bzero((char *)&saddr, sizeof(saddr)); debug(F100,"netopen bzero ok","",0); if ( ! #ifdef NT ! /* we found that Win95 tries to call the DNS */ ! /* when a numeric IP Address is specified. */ ! /* and of course the lookup fails resulting */ ! /* in a long delay. So we test for the IP */ ! /* numeric value before calling gethostbyname */ ! /* but only in Win32 so as not to */ ! /* alter current code that works properly */ ! /* everywhere else. */ ! inet_addr(namecopy) == INADDR_NONE && ! #endif /* NT */ ! (host = gethostbyname(namecopy)) != NULL) { debug(F100,"netopen gethostbyname != NULL","",0); #ifdef OS2 strncpy(name,host->h_name,80); --- 1940,1961 ---- bzero((char *)&saddr, sizeof(saddr)); debug(F100,"netopen bzero ok","",0); + /* + NOTE: Originally the inet_addr() check was #ifdef NT, but is enabled for + all as of 20 Sep 97, to allow people to "set host" to a specific numeric IP + address without going through the multihomed host sequence and winding up + at a different place than the one requested. + */ + x = inet_addr(namecopy); + debug(F111,"netopen inet_addr",namecopy,x); if ( ! #ifdef INADDR_NONE ! x == INADDR_NONE ! #else ! x < 0 ! #endif /* INADDR_NONE */ ! ! && (host = gethostbyname(namecopy)) != NULL) { debug(F100,"netopen gethostbyname != NULL","",0); #ifdef OS2 strncpy(name,host->h_name,80); ==================== X-Patch-Number: 0037 Date: Tue Mar 10 16:50:51 1998 From: Frank da Cruz Subject: Redirection failures in REMOTE xxx > file If the server replies to a REMOTE command with a short-form reply (i.e. in the data field of an ACK), any redirection specified in the REMOTE command fails to take place, but the file is left open. Fix: *** /w/pub/ftp/kermit/f/ckcpro.w Sun Nov 10 18:37:30 1996 --- ./ckcpro.w Tue Mar 10 14:55:14 1998 *************** *** 1018,1033 **** querybuf[0] = NUL; } #endif /* NOSPL */ ! decode(rdatap,puttrm,0); /* Text is in ACK Data field */ if (rdatap) /* If we had data */ ! if (*rdatap) ! conoll(""); /* Then add a CRLF */ if (bye_active && network) { /* I sent a BYE command and got */ msleep(500); /* the ACK... */ tthang(); } success = 1; RESUME; #endif /* NOSERVER */ } --- 1018,1074 ---- querybuf[0] = NUL; } #endif /* NOSPL */ ! rf_err = "Can't open file"; ! x = 1; ! if (remfile) { /* Response redirected to file */ ! if (rempipe) /* or pipe */ ! x = zxcmd(ZOFILE,remdest); /* Pipe: Start command */ ! else ! x = opena(remdest,&iattr); /* File: Open with attributes */ ! } else { ! x = opent(&iattr); /* "open" the screen */ ! } ! if (x) { /* If file was opened ok */ ! if (decode(rdatap, ! #ifndef NOSPL ! (query || !remfile) ? puttrm : ! #else ! !remfile ? puttrm : ! #endif /* NOSPL */ ! putfil, 1) < 0) { ! errpkt((CHAR *)"Error writing data"); ! RESUME; ! } else { if (rdatap) /* If we had data */ ! if (*rdatap) /* add a line terminator */ ! if (remfile) { /* Can't use zsout("") for this... */ ! extern char * zoutptr; ! extern int zoutcnt; ! #ifndef UNIX ! #ifndef datageneral ! zmchout('\015'); /* Carriage return */ ! #endif /* datageneral */ ! #endif /* UNIX */ ! #ifndef MAC ! #ifndef OSK ! zmchout('\012'); /* Linefeed */ ! #endif /* OSK */ ! #endif /* MAC */ ! } else { /* To screen, easy. */ ! conoll(""); ! } if (bye_active && network) { /* I sent a BYE command and got */ msleep(500); /* the ACK... */ tthang(); } + clsof(0); success = 1; RESUME; + } + } else { /* otherwise */ + errpkt((CHAR *) rf_err); /* send error message */ + RESUME; /* and quit. */ + } #endif /* NOSERVER */ } ==================== __________________________________ (End of C-Kermit 6.0 PATCHES file)