天天看點

給gkermit添加序列槽通信功能 2

原本的程式不支援選擇序列槽,自己添加一個參數 “l”來指定使用哪一個序列槽。也添加了進度的顯示。

比如

發送:

gkermit -s -l /dev/ttyS2 file.bin

接收:

gkermit -r -l /dev/ttyS2

所做的工作基本就是把對stdin、stdout的操做改為對序列槽的操作。Linux<--->Linux,Win<--->Win, Win<--->Linux測試通過。

diff -uNr gku100/ANNOUNCE gku100U/ANNOUNCE

--- gku100/ANNOUNCE 1999-12-27 04:28:38.000000000 +0800

+++ gku100U/ANNOUNCE 2009-12-09 17:15:30.000000000 +0800

@@ -103,3 +103,30 @@

Release 1.00 25 Dec 99.

------------------------------

+

+Article: 10842 of comp.protocols.kermit.misc

+From: [email protected] (Frank da Cruz)

+Newsgroups: comp.protocols.kermit.misc

+Subject: Announcing G-Kermit 1.00

+Date: 27 Dec 1999 21:19:05 GMT

+Organization: Columbia University

+

+G-Kermit 1.00 is released. The web page is:

+

+ http://www.columbia.edu/kermit/gkermit.html

+

+For those who missed the Beta test, G-Kermit is small, fast, and

+portable Kermit protocol implementation for UNIX released under

+the GPL.

+

+Prebuilt binaries are available for over 40 hardware/OS/version

+combinations:

+

+ http://www.columbia.edu/kermit/gkermit.html#down

+

+If you can send in binaries that are not listed, please let me

+know. After allowing a few days for more binaries to come in,

+we'll make a wider announcement.

+

+- Frank

+------------------------------

diff -uNr gku100/README gku100U/README

--- gku100/README 1999-12-27 10:20:24.000000000 +0800

+++ gku100U/README 2009-12-09 17:15:30.000000000 +0800

@@ -36,6 +36,9 @@

University. It is free software under the GNU Public License. See the

COPYING file for details.

+ This software is OSI Certified Open Source Software.

+ OSI Certified is a certification mark of the Open Source Initiative.

+

G-Kermit is:

. Fast

. Small

@@ -1011,4 +1014,10 @@

comp.protocols.kermit.misc The unmoderated Kermit newsgroup

[email protected] Technical support

+Also visit:

+

+ http://www.columbia.edu/kermit/gkermit.html

+

+for a more up-to-date version of this file, complete with download links.

+

(End of G-Kermit README)

diff -uNr gku100/SOURCE.txt gku100U/SOURCE.txt

--- gku100/SOURCE.txt 1970-01-01 08:00:00.000000000 +0800

+++ gku100U/SOURCE.txt 2009-12-09 17:15:30.000000000 +0800

@@ -0,0 +1,288 @@

+ Gkermit代碼分析

+

+前言

+ Cygwin序列槽裝置映射

+ linux下的/dev/ttyS[n]在cygwin會映射到Windows序列槽裝置 //./COM[n + 1]

+ 例如 /dev/ttyS0 等價于 COM1

+

+

+

+一、代碼組織結構

+ ++- .

+ +- gkermit.h 程式公共頭檔案

+

+ +- gkermit.c 程式入口、字元編解碼、打包解包、有效性驗證 (main入口)

+ +- gcmdline.c 指令行分析相關的代碼

+ +- gunixio.c Unix IO 相關的操作

+

+ +- gproto.w 狀态機源代碼

+ gproto.c 自動生成的代碼

+

+ +- gwart.c 簡易的lex分析器,用于處理.w代碼,生成.c的檔案

+

+

+

+二、基本函數清單

+ ------ 字元接口 ------

+ gkermit.h ---------------------------------------------------------------------------------

+ #define tochar(ch) ((ch) + SP ) 轉換整型到可列印字元,參見标準P13頁

+ #define xunchar(ch) ((ch) - SP ) tochar的反向操作

+ #define ctl(ch) ((ch) ^ 64 ) 控制字元和可列印字元的轉換

+ #define zgetc(a) (((--zincnt)>=0) ? 如果緩沖為空則實際讀取檔案

+ ((int)(*zinptr++) & 0xff) :

+ zfillbuf(a))

+

+ ------ 函數原型 ------

+ gunixio.c ---------------------------------------------------------------------------------

+ SIGTYP doexit (int) 結束程式:正常或異常退出

+ VOID sysinit (void) 系統初始化:

+ char dopar (char) Parity奇偶校驗

+ VOID tmsg (char *) 将參數指向的字元串輸出到終端

+ VOID tmsgl (char *) 将參數指向的字元串輸出到終端(帶換行)

+ int ttopen (char *) 打開裝置

+ int ttpkt (int) 設定通信裝置工作在RAW模式

+ int ttres (void) 複位通信裝置

+ int ttinl (char *, 讀取一個包:以EOL結尾,包含逾時機制

+ int,

+ int,

+ char,

+ char,

+ int)

+ int ttol (char *, 發送一個包:原樣發送上層提供的包

+ int)

+ int ttchk (void) 檢視輸入是否正常

+ int ttflui (void) 同步緩沖到裝置

+ long zchki (char *) 檢視檔案是否可被讀取

+ int zchko (char *) 檢視檔案是否可被寫入

+ int zopeni (char *) 打開現存的檔案:就是用于發送的檔案

+ int zopeno (char *) 建立一個輸出檔案:就是用于存放接收到的檔案

+ int zclosi (void) 關閉輸入檔案句柄

+ int zcloso (int) 關閉輸出檔案句柄

+ int zfillbuf (int) 從檔案讀取到緩沖

+ VOID zltor (char *, 本地到遠端的檔案名轉換,同時處理檔案名中的特殊字元:local to remote

+ char *,

+ int)

+ int zrtol (char *, 遠端到本地的檔案名轉換,同時處理檔案名中的特殊字元:remote to local

+ char *,

+ int,

+ int)

+ int zbackup (char *) 備份已有的檔案:在檔案名後加上“.~數字~”

+

+ gkermit.c ---------------------------------------------------------------------------------

+ int input (void) 被狀态機調用:擷取輸入檔案的包

+ VOID nxtpkt (void) 初始化下一個包的序列号

+ int ack (void) 發送DATA是空的ACK回複包:調用 spacket 函數

+ int ack1 (char *) 發送含有特定串的ACK回複包

+ int nak (void) 發送拒絕包

+ VOID tinit (void) “發送”傳輸回話初始化

+ VOID errpkt (char *) 發送ERROR包

+ int sinit (char) 發送 S(Init packet)

+ int sfile (void) 發送 F(File header packet)

+ int sdata (void) 發送 Send Data packet

+ int seof (char *) 發送 Send EOF packet

+ int seot (void) 發送 Send EOT packet

+ int resend (void) 包的重發

+ int decode (int) 解析包的 data field

+ int encstr (char *) 從字元串編碼生成資料包:調用 getpkt 函數

+ int gattr (char *) 接收檔案屬性包

+ int sattr (void) 發送檔案屬性包

+ VOID ginit (void) “接收”傳輸會話初始化

+ int scmd (char, char *) 發送kermit指令到server

+ VOID rinit (void) 接收 Init 包

+ int gnfile (void) 擷取下一個發送的檔案名

+ int rcvfil (void) 接收檔案

+ VOID spar (char *) 設定kermit運作參數:從收到的資料中獲得參數

+ char *rpar (void) 回複kermit運作參數:本地使用的參數

+ VOID usage (void) 輸出幫助資訊

+

+ ------ 隻在 gkermic.c 中使用的函數:非全局使用的函數 ------

+ int spacket (char,int,int,char *) 建構一個包并發送:調用 ttol 函數發送

+ int rpacket (void) 讀取一個包并解析:調用 ttinl 函數讀取

+ unsigned int chk1 (char *,int) 12bit 塊 校驗:調用了chksum函數

+ unsigned int chk3 (char *,int) 16bit CRC校驗

+ unsigned int chksum (char *,int) 算數校驗

+ int getpkt (int) 從檔案讀取資料并建構包

+ VOID encode (int,int) 将一個字元編碼進包

+ VOID decstr (char *) 解包并存到字元串緩沖之中:調用 decode 函數

+

+

+ gcmdline.c --------------------------------------------------------------------------------

+ int cmdlin (void) 指令行Parser,隻是處理指令行參數,并

+ 用提取的參數更新全局參數變量。

+

+ gproto.c ----------------------------------------------------------------------------------

+ int gwart (void) 狀态機排程表

+

+三、函數調用關系

+ 由于大部分系統相關的操作都在gunixio.c,于是下面的分析都是對gunixio的調用的分析。

+ 為了使用windows的本地的函數進行替換。隻要移植gunixio.c裡的函數就可以了,其他的代碼在mingw和vc中都可編譯通過

+ 以下是在gunixio的所有函數執行的時候加入輸出語句。

+ ttopen --打開序列槽

+ ttpkt --設定序列槽工作在raw模式

+

+ G-Kermit CU-1.00, Columbia University, 1999-12-25

+ * Open device /dev/ttyS0

+ * Escape back to your local Kermit and give a SEND command.

+

+ * KERMIT READY TO RECEIVE...

+

+ ttinl --讀取包:所有序列槽的讀取read都是通過這個函數,gwart調用input->rpacket->ttinl->read

+ ttflui --清空序列槽緩沖:丢棄輸入,發送輸出,結束之後進行狀态處理(狀态排程表)

+ * recv INIT

+ ttol --寫入包:所有序列槽的寫入write都是通過這個函數

+ ttinl --讀取包

+ ttflui --......

+ * recv HEADER

+ zrtol --将遠端的檔案名轉換為本地的

+ zbackup --判斷本地是否有同名的檔案,并處理備份

+ zchko --檢查輸出的檔案是否可寫

+ zchki --檢查輸出的檔案是否可讀

+ zopeno --打開輸出檔案的句柄

+ ttol --送出包

+ ttinl --讀取包

+ ttflui --......

+ * recv ATTRIBUTES

+ * will RECEIVE 1 byte

+ ttol --送出包

+ ttinl --讀取包

+ ttflui --......

+ * recv DATA [complete]

+ ttol --送出包

+ ttinl --讀取包

+ ttflui --......

+ * recv EOF

+ zcloso

+ ttol --送出包

+ ttinl --讀取包

+ ttflui --......

+ * recv EOT

+ ttol --讀取包

+ * exchange filesize 0x1 [1] bytes

+ END

+ ttres

+

+詳細輸出模式

+ G-Kermit CU-1.00, Columbia University, 1999-12-25: POSIX

+ MAXPATHLEN = 1024

+ cmdlin action = v

+ ttopen

+ ttopen __STDC__

+ ttopen SIG_V

+ ttopen nonblocking read/write

+ ttopen TINBUFSIZ = 4080

+ ttopen xonxoff = 0

+ ttopen noxonxoff = 0

+ ttopen ttflags -1

+ ttopen nomodes 0

+ ttopen nonblock = 0

+ ttpkt

+ input[v]

+ G-Kermit CU-1.00, Columbia University, 1999-12-25

+ * Open device /dev/ttyS0

+ * Escape back to your local Kermit and give a SEND command.

+

+ * KERMIT READY TO RECEIVE...

+

+ ttinl

+ ttinl read timo = 9

+ ttinl length = 25

+ PKT<-[^A9 S~' @-#Y3~*!J*0+++B"U1@G](27) rc=0

+ rpacket type=S, seq=00, len=22

+ chksum=1445

+ ttflui

+ ttflui = 0, errno = 0

+ input[S]

+ * recv INIT

+ spar attributes=1 longpackets=1

+ spar whatami = 0x22

+ spar streamok = -1

+ spar sysid [U1]

+ spar recognizes peer

+ rpar streamok=-1 whatami=38

+ chksum=1455

+ ttol

+ PKT->[^A9 Y~' @-#Y3~*!J*0+++F"U1@Q](28)

+ ttinl

+ ttinl read timo = 7

+ ttinl length = 13

+ PKT<-[^A-!Ftest.txt&4;](15) rc=0

+ rpacket type=F, seq=01, len=8

+ crc=25883

+ ttflui

+ ttflui = 0, errno = 0

+ input[F]

+ * recv HEADER

+ zrtol

+ zbackup

+ zbackup A test.txt: 8

+ zbackup B test.txt

+ zbackup test.txt.~2~: OK

+ rcvfil filename [test.txt]

+ zchko

+ zchki

+ zchko(.) x = 0 errno = 0

+ zopeno

+ zopeno test.txt: 0

+ crc=3239

+ ttol

+ PKT->[^A-!Ytest.txt RG](16)

+ ttinl

+ ttinl read timo = 7

+ ttinl length = 12

+ PKT<-[^A,"A""B81!1)R0](14) rc=0

+ rpacket type=A, seq=02, len=7

+ crc=40080

+ ttflui

+ ttflui = 0, errno = 0

+ input[A]

+ * recv ATTRIBUTES

+ * will RECEIVE 1 byte

+ crc=58689

+ ttol

+ PKT->[^A%"Y.5!](8)

+ ttinl

+ ttinl read timo = 7

+ ttinl length = 7

+ PKT<-[^A'#D#J'O!](9) rc=0

+ rpacket type=D, seq=03, len=2

+ crc=31681

+ ttflui

+ ttflui = 0, errno = 0

+ input[D]

+ * recv DATA [complete]

+ crc=64665

+ ttol

+ PKT->[^A%#Y/R9](8)

+ ttinl

+ ttinl read timo = 7

+ ttinl length = 5

+ PKT<-[^A%$Z(,*](7) rc=0

+ rpacket type=Z, seq=04, len=0

+ crc=33546

+ ttflui

+ ttflui = 0, errno = 0

+ input[Z]

+ * recv EOF

+ zcloso

+ zcloso(test.txt) cx = 0 keep = 0

+ crc=45457

+ ttol

+ PKT->[^A%$Y+&1](8)

+ ttinl

+ ttinl read timo = 7

+ ttinl length = 5

+ PKT<-[^A%%B 8;](7) rc=0

+ rpacket type=B, seq=05, len=0

+ crc=1563

+ ttflui

+ ttflui = 0, errno = 0

+ input[B]

+ * recv EOT

+ crc=43081

+ ttol

+ PKT->[^A%%Y*A)](8)

+ * exchange filesize 0x1 [1] bytes

+ END

+ ttres

+ exit 0

+

diff -uNr gku100/gcmdline.c gku100U/gcmdline.c

--- gku100/gcmdline.c 1999-12-27 04:05:38.000000000 +0800

+++ gku100U/gcmdline.c 2009-12-09 17:15:30.000000000 +0800

@@ -29,6 +29,8 @@

*/

#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

#include "gkermit.h"

/* Externals */

@@ -53,7 +55,7 @@

_MYPROTOTYPE( VOID usage, (void) );

#ifndef NOGETENV

-_MYPROTOTYPE( char * getenv, (char *) );

+/* _MYPROTOTYPE( char * getenv, (char *) ); */

#define GARGC 32

#define GBUFSIZ 256

static char gbuf[GBUFSIZ], *gargs[GARGC], *gptr = NULL;

@@ -150,6 +152,16 @@

xp = *xargv+1; /* Pointer for bundled args */

while (x) {

switch (x) {

+ case 'l':

+ if (*(xp+1)) fatal("invalid argument bundling after -l");

+ if (xargc > 1)

+ {

+ strcpy(ttname,*(xargv + 1));

+ xargc--;

+ xargv++;

+ }

+ break;

+

case 'r': /* Receive */

if (action) fatal("conflicting actions");

action = 'v';

@@ -163,12 +175,12 @@

if (zchki(*cmlist) < 0)

fatal("file not found or not accessible");

while (--xargc > 0) { /* Traverse the list */

- *xargv++;

+ xargv++;

if (**xargv == '-')

break;

nfils++;

}

- xargc++, *xargv--; /* Adjust argv/argc */

+ xargc++, xargv--; /* Adjust argv/argc */

if (nfils < 1) fatal("missing filename for -s");

action = 's';

break;

@@ -176,7 +188,7 @@

case 'g': /* get */

if (action) fatal("conflicting actions");

if (*(xp+1)) fatal("invalid argument bundling after -g");

- *xargv++, xargc--;

+ xargv++, xargc--;

if ((xargc == 0) || (**xargv == '-'))

fatal("missing filename for -g");

cmarg = *xargv;

@@ -200,7 +212,7 @@

case 'p': /* Parity */

if (*(xp+1)) fatal("invalid argument bundling");

- *xargv++, xargc--;

+ xargv++, xargc--;

if ((xargc < 1) || (**xargv == '-'))

fatal("missing parity");

switch(x = **xargv) {

@@ -219,12 +231,16 @@

case 'd': /* Debug */

p = xargv;

- *p++;

+ p++;

if ((xargc < 2) || (**p == '-')) {

db = fopen("debug.log","w");

} else {

- *xargv++, xargc--;

+ xargv++, xargc--;

+ if (strcmp(*xargv,"stdout") == 0) {

+ db = stdout;

+ } else {

db = fopen(*xargv,"w");

+ }

}

if (db) {

extern char * versio, * build;

@@ -243,7 +259,7 @@

case 'a': /* As-name */

if (*(xp+1)) fatal("invalid argument bundling after -a");

- *xargv++, xargc--;

+ xargv++, xargc--;

if ((xargc == 0) || (**xargv == '-'))

fatal("missing name for -a");

cmarg2 = *xargv;

@@ -342,6 +358,7 @@

fprintf(stderr,"%s: %s./n",versio,build);

fprintf(stderr,"Usage: gkermit [ options ]/n");

fprintf(stderr,"Options:/n");

+ fprintf(stderr," -l Device to use,such as /dev/ttyS0/n");

fprintf(stderr," -r Receive files/n");

fprintf(stderr," -s fn Send files/n");

fprintf(stderr," -g fn Get files from server/n");

diff -uNr gku100/gkermit.c gku100U/gkermit.c

--- gku100/gkermit.c 1999-12-27 10:11:20.000000000 +0800

+++ gku100U/gkermit.c 2009-12-09 17:15:30.000000000 +0800

@@ -56,6 +56,10 @@

#define _GKERMIT_C

#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+#include <unistd.h>

+#include <errno.h>

#include "gkermit.h"

/* Forward declarations of functions used within this module... */

@@ -76,6 +80,9 @@

extern char * zinptr;

extern FILE * ofp; /* Output file pointer */

+extern long tfilelength;

+extern long sfilelength;

+

/* Global variables declared here */

char *cmarg, *cmarg2 = NULL; /* Send filename pointers */

@@ -190,7 +197,7 @@

usage(); /* give usage message */

doexit(1); /* and quit. */

}

- sysinit(); /* Set up interrupt handlers, etc */

+ //sysinit(); /* Set up interrupt handlers, etc */

if (urpsiz > MAXRP) /* In case MAXRP < DEFRP... */

urpsiz = MAXRP;

if (maxrp > 9020)

@@ -212,8 +219,12 @@

if (start == 's' || start == 'r') /* If sending or getting*/

ttflui(); /* flush comm line input buffer */

gwart(); /* Do the protocol */

+ if (sfilelength == tfilelength)

+ printf(" * exchange filesize 0x%lx [%ld] bytes/n",tfilelength,tfilelength);

+ printf("END/n");

}

doexit(failure); /* Done, exit. */

+

return(failure); /* To shut up picky compilers. */

}

@@ -327,11 +338,14 @@

s = rpar(); /* Get our protocol parameters */

if (c == 'S') { /* Sending a file... */

tmsgl(versio);

- tmsgl("Escape back to your local Kermit and give a RECEIVE command.");

+ printf(" * Open device %s/n",ttname);

+ tmsgl(" * Escape back to your local Kermit and give a RECEIVE command.");

+ tmsgl("");

+ tmsgl(" * KERMIT READY TO SEND...");

tmsgl("");

- tmsgl("KERMIT READY TO SEND...");

sleep(delay);

}

+ printf(" * send INIT/n");

return(spacket(c,seq,strlen(s),s)); /* Send S or I packet */

}

@@ -360,6 +374,7 @@

maxsiz = spsiz - (bctr + 3); /* Maximum packet data field length */

if (spsiz > 94) maxsiz -= 4; /* Long packet has more fields */

nxtpkt(); /* Get next packet number */

+ printf(" * send HEADER/n");

return(spacket('F',seq,x,xdata)); /* Send filename */

}

@@ -367,7 +382,7 @@

sattr() { /* Build and send A packet */

int i, aln;

int binary;

- extern long filelength;

+ extern long tfilelength;

nxtpkt(); /* Get next packet sequence number */

if (debug) fprintf(db,"sattr seq %d/n",seq);

@@ -388,9 +403,9 @@

xdata[i++] = tochar(1); /* Length of value is 1 */

xdata[i++] = 'A'; /* A for ASCII */

}

- if (filelength > -1L) {

+ if (tfilelength > -1L) {

xdata[i] = '1'; /* File length in bytes */

- sprintf((char *) &xdata[i+2],"%ld",filelength);

+ sprintf((char *) &xdata[i+2],"%ld",tfilelength);

aln = (int)strlen((char *)(xdata+i+2));

xdata[i+1] = tochar(aln);

i += aln + 2;

@@ -398,6 +413,7 @@

xdata[i] = NUL; /* Terminate last good field */

aln = (int)strlen((char *)xdata); /* Get overall length of attributes */

if (debug) fprintf(db,"sattr data %s/n",xdata);

+ printf(" * send ATTRIBUTES/n");

return(spacket('A',seq,aln,xdata)); /* Send it */

}

#define FTBUFL 10 /* File type buffer */

@@ -428,7 +444,14 @@

text = 0;

}

break;

-

+ case '1':

+ for (i =0; (i < aln) && (i < FTBUFL);i++)

+ ftbuf[i] = *s++;

+ ftbuf[i] = '/0';

+ if (i < aln) s += (aln - i);

+ printf(" * will RECEIVE %s byte/n",ftbuf);

+ tfilelength = atol(ftbuf);

+ break;

default: /* Unknown attribute */

s += aln; /* Just skip past it */

break;

@@ -441,6 +464,9 @@

int

sdata() { /* Send a data packet */

int x;

+

+ int havesend = 0;

+

if (cx || cz) { /* Interrupted... */

if (debug)

fprintf(db,"sdata interrupted cx = %d cz = %d/n",cx,cz);

@@ -454,11 +480,27 @@

return(0);

}

nxtpkt(); /* Get next packet number */

- return(spacket('D',seq,x,xdata)); /* Send the packet */

+

+ havesend = spacket('D',seq,x,xdata);/* Send the packet */

+

+ if (sfilelength >= tfilelength)

+ {

+ sfilelength = tfilelength;

+ printf(" * send DATA [complete]");

+ printf(" /n");

+ }

+ else

+ {

+ printf(" * send DATA %3ld%%/r",(sfilelength * 100 / tfilelength));

+ }

+ fflush(stdout);

+

+ return(havesend);

}

int

seof(s) char *s; { /* Send end-of-file packet */

+ printf(" * send EOF/n");

if (debug) fprintf(db,"seof [%s]/n",s);

if (zclosi() < 0) { /* Close the file */

if (debug)

@@ -478,6 +520,7 @@

int

seot() { /* Send end-of-transmission packet */

nxtpkt();

+ printf(" * send EOT/n");

return(spacket('B',seq,0,""));

}

@@ -658,7 +701,7 @@

chksum(p,len) char *p; int len; { /* Generate arithmetic checksum */

register unsigned int k, m;

m = (parity) ? 0177 : 0377;

- for (k = 0; len-- > 0; *p++)

+ for (k = 0; len-- > 0; p++)

k += (unsigned)*p & m;

return(k);

}

@@ -701,6 +744,7 @@

if (!c) c = -1;

} else { /* or file... */

c = zgetc(text);

+ sfilelength++;

}

if (c < 0) { /* Watch out for empty file. */

first = -1;

@@ -721,6 +765,7 @@

if (!next) next = -1;

} else {

next = zgetc(text);

+ sfilelength++;

}

if (next < 0) first = -1; /* If none, we're at EOF. */

osize = size; /* Remember current size. */

@@ -860,6 +905,7 @@

*osp++ = a; /* the repeat count. */

} else {

putc((char)a,ofp); /* Use putc macro here to avoid */

+ sfilelength++;

if (ferror(ofp)) { /* function-call overhead. */

if (debug)

fprintf(db,"decode putc a=%u errno=%u/n",a,errno);

@@ -1025,28 +1071,35 @@

rinit() { /* RECEIVE initialization */

if (quiet) return;

tmsgl(versio);

- tmsgl("Escape back to your local Kermit and give a SEND command.");

+ printf(" * Open device %s/n",ttname);

+ tmsgl(" * Escape back to your local Kermit and give a SEND command.");

tmsgl("");

- tmsgl("KERMIT READY TO RECEIVE...");

+ tmsgl(" * KERMIT READY TO RECEIVE...");

+ tmsgl("");

}

VOID

ginit() { /* GET initialization */

if (quiet) return;

tmsgl(versio);

- tmsgl("Escape back to your local Kermit and give a SERVER command.");

+ printf(" * Open device %s/n",ttname);

+ tmsgl(" * Escape back to your local Kermit and give a SERVER command.");

tmsgl("");

- tmsgl("KERMIT READY TO GET...");

+ tmsgl("* KERMIT READY TO GET...");

+ tmsgl("");

}

int

gnfile() { /* Get name of next file to send */

+ long filesize = 0;

if (cz) /* Batch was canceled */

return(0);

while (nfils-- > 0) { /* Otherwise continue thru list */

strncpy(filnam,*cmlist++,MAXPATHLEN);

filnam[MAXPATHLEN-1] = NUL;

- if (zchki(filnam) > -1) /* Skip files that can't be read */

+ filesize = zchki(filnam);

+ if (filesize > -1) /* Skip files that can't be read */

+ printf(" * file %s | HEX: 0x%lx | DEC: %ld/n",filnam,filesize,filesize);

return(1);

}

return(0); /* None left */

diff -uNr gku100/gkermit.h gku100U/gkermit.h

--- gku100/gkermit.h 2003-05-27 23:30:14.000000000 +0800

+++ gku100U/gkermit.h 2009-12-09 17:15:30.000000000 +0800

@@ -233,11 +233,7 @@

/* Externs */

-#ifdef ERRNO_H

-#include <errno.h>

-#else

extern int errno;

-#endif /* ERRNO_H */

#ifndef _GKERMIT_C

extern int debug;

#endif /* _GKERMIT_C */

diff -uNr gku100/gkermit.nr gku100U/gkermit.nr

--- gku100/gkermit.nr 1999-12-27 23:27:52.000000000 +0800

+++ gku100U/gkermit.nr 1970-01-01 08:00:00.000000000 +0800

@@ -1,343 +0,0 @@

-./" @(#) gkermit.1 1.00 Columbia University 1999/12/25

-.TH GKERMIT 1C "25 Dec 1999" "UNIX G-Kermit"

-.SH NAME

-gkermit /- G-Kermit (GNU Kermit) 1.00 file transfer software.

-.ll 80

-.SH SYNOPSIS

-.nf

-.sp

-gkermit [ options ] -s file(s) Send files

-gkermit [ options ] -g file(s) Get files

-gkermit [ options ] -r Receive files

-.PP

-.SH DESCRIPTION

-G-Kermit is a UNIX program for transferring files using the

-Kermit protocol. G-Kermit is a product of Kermit Project at Columbia

-University. It is free software under the GNU Public License. See the

-COPYING file for details.

-.PP

-.SS INVOKING G-KERMIT

-.PP

-The G-Kermit binary is called "gkermit". It should be stored someplace

-in your UNIX PATH; normally it is available as /usr/local/bin/gkermit.

-To run G-Kermit, just type "gkermit" followed by command-line options that

-tell it what to do. If no options are given, it prints a usage message

-listing the available options.

-.PP

-If an option takes an argument, the argument is required; if an option does

-not take an argument, no argument may be given (exception: -d). The action

-options are -r, -s, and -g. Only one action option may be given. If no

-action options are given, G-Kermit does nothing (except possibly to print its

-usage message or create a debug.log file). Here are some examples ("$ " is

-the shell prompt):

-.nf

-.sp

- $ gkermit -s hello.c <-- Send the hello.c file

- $ gkermit -s hello.* <-- Send all hello.* files

- $ gkermit -r <-- Wait to receive files

- $ gkermit -g hello.c <-- Get hello.c file

- $ gkermit -g hello.//* <-- Get all hello.* files

-.sp

-.fi

-Options that do not take arguments can be "bundled" with other options.

-An option that takes an argument must always be followed by a space and

-then its argument(s). Examples:

-.nf

-.sp

- $ gkermit -is hello.o <-- Send hello.o in binary mode

- $ gkermit -dr <-- Receive with debugging

-.sp

-.fi

-.SS COMMAND-LINE OPTIONS

-.sp

-.nf

- -r RECEIVE. Wait for incoming files.

- -s fn SEND. Send file(s) specified by fn.

- -g fn GET. Get specified file(s) from server.

- -a fn AS-NAME. Alternative name for file.

- -i IMAGE. Binary-mode transfer (default).

- -T TEXT. Text-mode transfer.

- -P PATH (filename) conversion disabled.

- -w WRITEOVER when filenames collide.

- -K KEEP incompletely received files.

- -p x PARITY. x = e,o,m,s,n; default = n(one).

- -e n PACKET LENGTH. n = 40-9000; default=4000.

- -b n TIMEOUT. Per-packet timeout, seconds.

- -x XON/XOFF. Set Xon/Xoff in the tty driver.

- --x Unset Xon/Xoff in the tty driver.

- -S STREAMING disabled.

- -X EXTERNAL. G-Kermit is an external protocol.

- -q QUIET. Suppress messages.

- -d DEBUG. Write debugging info to ./debug.log.

- -d fn DEBUG. Write debugging info to given file.

- -h HELP. Display brief usage message.

-.fi

-.PP

-You may supply options to G-Kermit on the command line or through the

-GKERMIT environment variable, which can contain any valid gkermit

-command-line options. These are processed before the actual command-line

-options and so can be overridden by them. Example for bash or ksh, which you

-can put in your profile if you want to always keep incomplete files, suppress

-streaming, suppress messages, and use Space parity:

-.nf

-.sp

- export GKERMIT="-K -S -q -p s"

-.fi

-.PP

-.SS MECHANICS OF FILE TRANSFER

-.PP

-To transfer files with G-Kermit you must be connected through a terminal

-emulator to the UNIX system where G-Kermit is running, meaning you are

-online to UNIX and have access to the shell prompt (or to a menu that has

-an option to invoke G-Kermit). The connection can be serial (direct or

-dialed) or network (Telnet, Rlogin, X.25, etc).

-.PP

-When you tell G-Kermit to SEND a file (or files), e.g. with:

-.nf

-.sp

- $ gkermit -Ts oofa.txt

-.sp

-.fi

-it pauses for a second and then sends its first packet. What happens next

-depends on the capabilities of your terminal emulator:

-.PP

-.in +0.5i

-.ll -0.5i

-.ta +0.2i

-.ti -0.2i

-/(bu If your emulator supports Kermit "autodownloads" then it receives the

-file automatically and puts you back in the terminal screen when done.

-.sp

-.ti -0.2i

-/(bu Otherwise, you'll need to take whatever action is required by your

-emulator to get its attention: a mouse action, a keystroke like Alt-x,

-or a character sequence like Ctrl-// or Ctrl-] followed by the letter

-"c" (this is called "escaping back") and then tell it to receive the

-file. When the transfer is complete, you must instruct your emulator

-to go back to its terminal screen.

-.ll +0.5i

-.in -0.5i

-.fi

-.PP

-During file transfer, most terminal emulators put up some kind of running

-display of the file transfer progress.

-.PP

-When you tell G-Kermit to RECEIVE (with "gkermit -r"), this requires you to

-escape back to your terminal emulator and instruct it to send the desired

-file(s).

-.PP

-If your terminal emulator supports Kermit autodownloads AND Kermit server

-mode, then you can use GET ("gkermit -g files...") rather than RECEIVE

-("gkermit -r"), and the rest happens automatically, as when G-Kermit is

-sending.

-.SS INTERRUPTING FILE TRANSFER

-.PP

-G-Kermit supports file and group interruption. The method for interrupting

-a transfer depends on your terminal emulator. For example, while the

-file-transfer display is active, you might type the letter 'x' to cancel the

-current file and go on to the next one (if any), and the letter 'z' to

-cancel the group. Or there might be buttons you can click with your mouse.

-.PP

-When G-Kermit is in packet mode and your terminal emulator is in its

-terminal screen, you can also type three (3) Ctrl-C characters in a row to

-make G-Kermit exit and restore the normal terminal modes.

-.PP

-.SS TEXT AND BINARY TRANSFER MODE

-.PP

-When sending files in binary mode, G-Kermit sends every byte exactly as it

-is stored on the disk. This mode is appropriate for program binaries,

-graphics files, tar archives, compressed files, etc, and is G-Kermit's

-default file transfer mode when sending. When receiving files in binary

-mode, G-Kermit simply copies each byte to disk. (Obviously the bytes are

-encoded for transmission, but the encoding and decoding procedures give a

-replica of the original file after transfer.)

-.PP

-When sending files in text mode, G-Kermit converts the record format to the

-common one that is defined for the Kermit protocol, namely lines terminated

-by carriage return and linefeed (CRLF); the receiver converts the CRLFs to

-whatever line-end or record-format convention is used on its platform. When

-receiving files in text mode, G-Kermit simply strips carriage returns,

-leaving only a linefeed at the end of each line, which is the UNIX

-convention.

-.PP

-When receiving files, the sender's transfer mode (text or binary)

-predominates if the sender gives this information to G-Kermit in a Kermit

-File Attribute packet, which of course depends on whether your terminal

-emulator's Kermit protocol has this feature. Otherwise, if you gave a -i or

--T option on the gkermit command line, the corresponding mode is used;

-otherwise the default mode (binary) is used.

-.PP

-Furthermore, when either sending or receiving, G-Kermit and your terminal

-emulator's Kermit can inform each other of their OS type (UNIX in G-Kermit's

-case). If your emulator supports this capability, which is called

-"automatic peer recognition", and it tells G-Kermit that its platform is

-also UNIX, G-Kermit and the emulator's Kermit automatically switch into

-binary mode, since no record-format conversion is necessary in this case.

-Automatic peer recognition is disabled automatically if you include the -i

-(image) or -T (text) option.

-.PP

-When sending, G-Kermit sends all files in the same mode, text or binary.

-There is no automatic per-file mode switching. When receiving, however,

-per-file switching occurs automatically based on the incoming Attribute

-packets, if any (explained below), that accompany each file.

-.PP

-.SS PATHNAMES

-.PP

-When SENDING a file, G-Kermit obtains the filenames from the command line.

-It depends on the shell to expand metacharacters (wildcards and tilde).

-.PP

-G-Kermit uses the full pathname given to find and open the file, but then

-strips the pathname before sending the name to the receiver. For example:

-.nf

-.sp

- $ gkermit -s /etc/hosts

-.sp

-.fi

-results in the receiver getting a file called "HOSTS" or "hosts" (the

-directory part, "/etc/", is stripped).

-.PP

-However, if a pathname is included in the -a option, the directory part

-is not stripped:

-.nf

-.sp

- $ gkermit -s /etc/hosts -a /tmp/hosts

-.sp

-.fi

-This example sends the /etc/hosts file but tells the receiver that its name

-is "/tmp/hosts". What the receiver does with the pathname is, of course, up

-to the receiver, which might have various options for dealing with incoming

-pathnames.

-.PP

-When RECEIVING a file, G-Kermit does NOT strip the pathname. If the

-incoming filename includes a path, G-Kermit tries to store the file in the

-specified place. If the path does not exist, the transfer fails. The

-incoming pathname can, of course, be overridden with the -a option.

-.PP

-.SS FILENAME CONVERSION

-.PP

-When sending a file, G-Kermit normally converts outbound filenames to

-common form: uppercase, no more than one period, and no funny characters.

-So, for example, gkermit.tar.gz would be sent as GKERMIT_TAR.GZ.

-.PP

-When receiving a file, if the name is all uppercase, G-Kermit converts it

-to all lowercase. If the name contains any lowercase letters, G-Kermit

-leaves the name alone.

-.PP

-If the automatic peer recognition feature is available in the terminal

-emulator, and G-Kermit recognizes the emulator's platform as UNIX, G-Kermit

-automatically disables filename conversion and sends and accepts filenames

-literally.

-.PP

-You can force literal filenames by including the -P option on the command

-line.

-.PP

-.SS FILENAME COLLISIONS

-.PP

-When G-Kermit receives a file whose name is the same as that of an existing

-file, G-Kermit "backs up" the existing file by adding a unique suffix to its

-name. The suffix is ".~n~", where n is a number. This kind of backup suffix

-is compatible with GNU EMACS and various other popular applications.

-.PP

-To defeat the backup feature and have incoming files overwrite existing

-files of the same name, include the -w (writeover) option on the command

-line.

-.PP

-.SH RETURN VALUES

-G-Kermit resturns an exit status code of 0 if all actions succeeded

-and 1 if any actions failed.

-.PP

-.SH IMPLEMENTATION NOTES

-G-Kermit is designed to be small, portable, and stable, and is intended for

-use only on the "far end" of a connection; it does not make connections

-itself, although it can be used as an external protocol by other programs that

-do make connections. To keep it small and stable, it does not include sliding

-windows, a command or scripting language or character-set translation. To

-keep it portable and stable, it avoids use of system services that are not

-standardized across all UNIX varieties and therefore, in particular, does not

-support file timestamps, internal wildcard expansion, and other features that

-are not implemented consistently (or at all) across all UNIXes.

-.PP

-.SH ENVIRONMENT

-A GKERMIT environment variable may be defined (for example in your shell

-profile) to include G-Kermit command-line options; these are processed by

-G-Kermit before any options that are specified on the command line, and

-therefore are overriden by command-line options.

-.PP

-.SH DIAGNOSTICS

-If an error occurs during file

-transfer G-Kermit sends an error packet to your terminal emulator to cancel

-the transfer; an appropriate error message should be displayed on your

-screen.

-.PP

-.SH ERRORS

-File transfers can fail for a number of reasons:

-.sp

-.in +0.5i

-.ll -0.5i

-.ta +0.2i

-.ti -0.2i

-/(bu Lack of read access to a source file.

-.ti -0.2i

-/(bu Lack of write access to a target directory.

-.ti -0.2i

-/(bu Lack of adequate flow control.

-.ti -0.2i

-/(bu Use of streaming on an unreliable connection.

-.ti -0.2i

-/(bu Excessive unprefixing of control characters.

-.ti -0.2i

-/(bu Sending bare 8-bit data on a 7-bit connection.

-.ti -0.2i

-/(bu Packets too long for receiver's buffers.

-.ti -0.2i

-/(bu Timeout interval too short for connection.

-.ti -0.2i

-.ll +0.5i

-.in -0.5i

-.fi

-.sp

-and many others; these are covered in the references.

-.PP

-.SH REFERENCES

-.PP

-The Kermit protocol is specified in "Kermit, A File Transfer Protocol" by

-Frank da Cruz, Digital Press (1987). A correctness proof of the Kermit

-protocol appears in "Specification and Validation Methods", edited by Egon

-Boerger, Oxford University Press (1995). "Using C-Kermit" by Frank da Cruz

-and Christine M. Gianone, Digital Press (1997, or later edition) explains many

-of the terms and techniques referenced here in case you are not familiar with

-them, and also includes tutorials on data communications, extensive

-troubleshooting and performance tips, etc. Various other books on Kermit are

-available from Digital Press. Online resources include:

-.nf

-.sp

- Web: http://www.columbia.edu/kermit/

- FTP: ftp://kermit.columbia.edu/kermit/g/

- News: comp.protocols.kermit.misc

- Email: [email protected]

-.fi

-.sp

-Also see the README file distributed with G-Kermit for further detail. It

-can also be found at ftp://kermit.columbia.edu/kermit/g/README.

-.PP

-.SH BUGS

-The speed of a file transfer depends not only on the speed of the two

-computers involved and the characteristics of the connection, but also on the

-capabilities and configuration of the two Kermit programs. Kermit is a fast

-and reliable protocol, but not all implementations of it are necessarily fast

-or reliable.

-.PP

-Nonstreaming transfers on a TCP/IP connection might be inordinately slow

-if one or both of the TCP/IP stacks uses the Nagle or Delayed ACK tricks.

-Streaming is used automatically if the other Kermit supports it.

-.PP

-When receiving files in text mode, G-Kermit strips all carriage returns,

-even if they aren't followed by linefeed.

-.PP

-A backups files are not guaranteed to have the highest number in their

-backup suffix.

-.PP

-.SH AUTHOR

-Frank da Cruz, the Kermit Project, Columbia University, New York City,

-December 1999.

-.br

diff -uNr gku100/gproto.c gku100U/gproto.c

--- gku100/gproto.c 1999-12-27 10:20:24.000000000 +0800

+++ gku100U/gproto.c 2009-12-09 17:15:30.000000000 +0800

@@ -35,6 +35,10 @@

#include <stdio.h>

#include "gkermit.h"

+extern long tfilelength;

+extern long sfilelength;

+extern int maxsiz;

+

_MYPROTOTYPE( int closof, (void) ); /* Close output file */

_MYPROTOTYPE( VOID errpkt, (char *) ); /* Send Error packet */

@@ -95,6 +99,7 @@

break;

case 2:

{ /* Receive ACK to I packet */

+ printf(" * recv INIT ACK/n");

spar(rdatap); /* Set parameters from it */

bctu = bctr; /* Switch to negotiated block check */

if (gnfile() > 0) { /* Is there a file to send? */

@@ -112,6 +117,7 @@

break;

case 3:

{ /* Receive ACK to File header packet */

+ printf(" * recv HEADER ACK/n");

if (attributes) { /* If attributes negotiated */

if (sattr() < 0) { /* Send file attributes */

errpkt("sattr");

@@ -132,6 +138,7 @@

break;

case 4:

{ /* Receive ACK to Attribute packet */

+ printf(" * recv ATTRIBUTES ACK/n");

if (*rdatap == 'N') { /* Check for refusal */

seof("D");

BEGIN sseof;

@@ -150,6 +157,13 @@

break;

case 5:

{ /* Receive ACK to Data packet */

+ if (sfilelength >= tfilelength) {

+ //printf(" * recv DATA ACK /n");

+ }

+ else {

+ //printf(" * recv DATA ACK /r");

+ //fflush(stdout);

+ }

if (*rdatap == 'X') /* Check for file cancellation */

cx = 1;

else if (*rdatap == 'Z') /* Check for batch cancellation */

@@ -166,6 +180,13 @@

break;

case 6:

{ /* Receive ACK to EOF */

+ if (sfilelength >= tfilelength) {

+ printf(" * recv EOF ACK /n");

+ }

+ else {

+ printf("/n");

+ printf(" * recv EOF ACK /n");

+ }

if (gnfile() > 0) { /* Get next file from list */

if (sfile() > 0)

BEGIN ssfil;

@@ -177,13 +198,17 @@

}

break;

case 7:

- { return(failure); }

+ {

+ printf(" * recv EOT ACK/n");

+ return(failure);

+}

break;

case 8:

{ tinit(); rinit(); BEGIN srini; }

break;

case 9:

{ /* Receive S packet */

+ printf(" * recv INIT/n");

spar(rdatap); /* Set parameters from it */

ack1(rpar()); /* ACK with our parameters */

bctu = bctr; /* Switch to negotiated block check */

@@ -192,10 +217,14 @@

}

break;

case 10:

- { ack(); return(failure); }

+ {

+ printf(" * recv EOT/n");

+ ack(); return(failure);

+}

break;

case 11:

{ /* Receive File header packet */

+ printf(" * recv HEADER/n");

if (rcvfil() < 0) {

errpkt("rcvfil");

} else {

@@ -208,6 +237,7 @@

break;

case 12:

{ /* Receive Attribute packet */

+ printf(" * recv ATTRIBUTES/n");

if (gattr(rdatap) == 0) {

ack();

} else {

@@ -220,6 +250,14 @@

if (decode(datalen) < 0) {

errpkt("Packet decoding error");

} else {

+ if (sfilelength >= tfilelength) {

+ sfilelength = tfilelength;

+ printf(" * recv DATA [complete]/n");

+ }

+ else {

+ printf(" * recv DATA %3ld%%/r",(sfilelength * 100 / tfilelength));

+ fflush(stdout);

+ }

ack();

BEGIN srdat;

}

@@ -241,12 +279,22 @@

{ /* Receive Data packet */

if (decode(datalen) < 0)

errpkt("Packet decoding error");

- else

+ else {

+ if (sfilelength >= tfilelength) {

+ sfilelength = tfilelength;

+ printf(" * recv DATA [complete]/n");

+ }

+ else {

+ printf(" * recv DATA %3ld%%/r",(sfilelength * 100 / tfilelength));

+ fflush(stdout);

+ }

ack();

+ }

}

break;

case 16:

{ /* Receive EOF packet */

+ printf(" * recv EOF/n");

if (*rdatap == 'D') /* Check for Discard directive */

cx = 1;

if (closof() < 0) { /* Close the output file */

diff -uNr gku100/gunixio.c gku100U/gunixio.c

--- gku100/gunixio.c 1999-12-27 07:32:26.000000000 +0800

+++ gku100U/gunixio.c 2009-12-09 17:15:30.000000000 +0800

@@ -58,6 +58,7 @@

*/

#include <stdio.h> /* Standard input/output */

+#include <stdlib.h>

#ifdef POSIX

#include <termios.h> /* Terminal modes */

@@ -75,6 +76,8 @@

#include <setjmp.h> /* Longjumps */

#include <sys/stat.h> /* File exist, file size */

#include <errno.h> /* Error symbols */

+#include <unistd.h>

+#include <string.h>

#include "gkermit.h" /* gkermit definitions */

/* All versions of HP-UX need Xon/Xoff */

@@ -212,6 +215,7 @@

static jmp_buf jbuf; /* Longjump buffer for timeouts */

+int handle = 0;

/* Functions... */

SIGTYP

@@ -221,19 +225,21 @@

ttres(); /* Reset the communication device */

#ifdef F_SETFL

if (ttflags > -1) /* Restore its flags */

- fcntl(0,F_SETFL,ttflags);

+ fcntl(handle,F_SETFL,ttflags);

#endif /* F_SETFL */

if (debug) {

fprintf(db,"exit %d/n",x);

fclose(db);

}

+ if (handle != -1)

+ close(handle);

exit(x);

}

VOID

sysinit() { /* To be run first thing */

#ifdef F_SETFL

- ttflags = fcntl(0,F_GETFL,0); /* Get and save stdin flags */

+ ttflags = fcntl(handle,F_GETFL,0); /* Get and save stdin flags */

#endif /* F_SETFL */

#ifdef SIGINT

signal(SIGINT,SIG_IGN); /* Ignore interrupts */

@@ -305,6 +311,14 @@

int

ttopen(ttname) char *ttname; { /* "Open" the communication device */

+ handle = open(ttname,O_RDWR|O_NOCTTY);

+ if (handle == -1)

+ {

+ printf(" * Error open device %s/n",ttname);

+ logerr("ttopen fcntl(handle,F_SETFL,O_NDELAY)");

+ return -1;

+ }

+

if (debug) { /* Vital statistics for debug log */

#ifdef __STDC__

fprintf(db,"ttopen __STDC__/n");

@@ -362,8 +376,8 @@

#ifdef F_SETFL

if (ttflags != -1) { /* Set nonbocking i/o on stdin */

errno = 0;

- if (fcntl(0, F_SETFL,ttflags|O_NDELAY) == -1)

- logerr("ttopen fcntl(0,F_SETFL,O_NDELAY)");

+ if (fcntl(handle, F_SETFL,ttflags|O_NDELAY) == -1)

+ logerr("ttopen fcntl(handle,F_SETFL,O_NDELAY)");

else

nonblock = 1;

}

@@ -377,16 +391,16 @@

if (debug)

fprintf(db,"ttopen nonblock = %d/n", nonblock);

#ifdef POSIX

- tcgetattr(0,&ttold); /* Get stdin device attributes */

- tcgetattr(0,&ttraw);

+ tcgetattr(handle,&ttold); /* Get stdin device attributes */

+ tcgetattr(handle,&ttraw);

#else

#ifdef SYSV

- ioctl(0,TCGETA,&ttold);

- ioctl(0,TCGETA,&ttraw);

+ ioctl(handle,TCGETA,&ttold);

+ ioctl(handle,TCGETA,&ttraw);

#else

#ifdef BSD

- gtty(0,&ttold);

- gtty(0,&ttraw);

+ gtty(handle,&ttold);

+ gtty(handle,&ttraw);

#endif /* BSD */

#endif /* SYSV */

#endif /* POSIX */

@@ -453,10 +467,10 @@

#endif /* VINTR */

#ifdef POSIX

- if (tcsetattr(0,TCSADRAIN,&ttraw) < 0)

+ if (tcsetattr(handle,TCSADRAIN,&ttraw) < 0)

return(-1);

#else

- if (ioctl(0,TCSETAW,&ttraw) < 0)

+ if (ioctl(handle,TCSETAW,&ttraw) < 0)

return(-1);

#ifdef SYSV

#endif /* SYSV */

@@ -478,7 +492,7 @@

}

#endif /* SETXONXOFF */

ttraw.sg_flags &= ~(ECHO|CRMOD); /* No echo, etc */

- if (stty(0,&ttraw) < 0) return(-1); /* Set modes */

+ if (stty(handle,&ttraw) < 0) return(-1); /* Set modes */

#else

system("stty raw -echo");

#endif /* BSD */

@@ -492,22 +506,22 @@

int x = 0;

if (havemodes) { /* Restore old modes */

#ifdef POSIX

- x = tcsetattr(0,TCSADRAIN,&ttold);

+ x = tcsetattr(handle,TCSADRAIN,&ttold);

#else

#ifdef SYSV

sleep(1); /* Let output finish */

- x = ioctl(0,TCSETAW,&ttold);

+ x = ioctl(handle,TCSETAW,&ttold);

#else

#ifdef BSD

sleep(1); /* Let output finish */

- x = stty(0,&ttold);

+ x = stty(handle,&ttold);

#else

x = system("stty -raw echo");

#endif /* BSD */

#endif /* SYSV */

#endif /* POSIX */

}

- write(1,"/015/012",2);

+ write(handle,"/015/012",2);

raw = 0;

return(x);

}

@@ -517,7 +531,7 @@

int x = 0;

if (nonblock) { /* Try to read */

errno = 0;

- x = read(0,&tinbuf[tlast],TINBUFSIZ-tlast);

+ x = read(handle,&tinbuf[tlast],TINBUFSIZ-tlast);

#ifdef EXTRADEBUG

fprintf(db,"ttchk read %d errno = %d/n",x,errno);

#endif /* EXTRADEBUG */

@@ -544,13 +558,13 @@

tinptr = tinbuf;

errno = 0;

#ifdef POSIX

- x = tcflush(0,TCIFLUSH); /* kernel/driver buffers */

+ x = tcflush(handle,TCIFLUSH); /* kernel/driver buffers */

#else

#ifdef SYSV

- x = ioctl(0,TCFLSH,0);

+ x = ioctl(handle,TCFLSH,0);

#else

#ifdef BSD

- x = ioctl(0,TIOCFLUSH,&n);

+ x = ioctl(handle,TIOCFLUSH,&n);

#endif /* BSD */

#endif /* SYSV */

#endif /* POSIX */

@@ -607,7 +621,7 @@

} else { /* Otherwise... */

while (1) { /* Read until we have a packet */

#ifdef DUMBIO

- x = read(0,&c,1); /* Dumb blocking read byte loop */

+ x = read(handle,&c,1); /* Dumb blocking read byte loop */

if (x < 0) {

logerr("ttinl XX read 1");

rc = -2;

@@ -629,7 +643,7 @@

int x;

if (tincnt < 1) { /* Need to fill our buffer */

errno = 0;

- tincnt = read(0,tinbuf,TINBUFSIZ);

+ tincnt = read(handle,tinbuf,TINBUFSIZ);

if (tincnt > -1) tlast = tincnt;

if (debug)

fprintf(db,"ttinl nonblock tincnt=%d errno=%d/n",

@@ -639,15 +653,15 @@

/* Go back to blocking and wait for 1 char */

if (ttflags != -1) {

errno = 0;

- x = fcntl(0, F_SETFL, ttflags & ~O_NDELAY);

+ x = fcntl(handle, F_SETFL, ttflags & ~O_NDELAY);

if (x == -1 || errno)

logerr("ttinl fcntl O_NDELAY off");

errno = 0;

- tincnt = read(0,tinbuf,1);

+ tincnt = read(handle,tinbuf,1);

if (tincnt < 1 || errno)

logerr("ttinl BL read");

errno = 0;

- fcntl(0, F_SETFL, ttflags | O_NDELAY);

+ fcntl(handle, F_SETFL, ttflags | O_NDELAY);

if (x == -1 || errno)

logerr("ttinl fcntl O_NDELAY on");

}

@@ -675,7 +689,7 @@

tincnt--;

} else {

#endif /* O_NDELAY */

- x = read(0,&c,1); /* Dumb read byte loop */

+ x = read(handle,&c,1); /* Dumb read byte loop */

if (x < 0) {

logerr("ttinl XX read 1");

rc = -2;

@@ -820,7 +834,7 @@

return(n);

#else

while (n > 0) { /* Send the packet with write() */

- i = write(1,&s[m],n); /* Allowing for partial results */

+ i = write(handle,&s[m],n); /* Allowing for partial results */

if (i < 0) {

if (errno == EWOULDBLOCK) /* and even no results at all.. */

continue;

@@ -849,7 +863,8 @@

/* File Functions */

char ofile[MAXPATHLEN]; /* Output filename */

-long filelength = -1L;

+long tfilelength = -1L; /* Input File length */

+long sfilelength = 0L; /* Bytes of File have send */

long

zchki(fn) char * fn; { /* Check if file is readable */

@@ -908,9 +923,9 @@

zopeni(name) char *name; { /* Open existing file for input */

ifp = fopen(name,"r");

if (debug) fprintf(db,"zopeni %s: %d/n",name, ifp ? 0 : errno);

- filelength = zchki(name);

- if (filelength < 0)

- return((int)filelength);

+ tfilelength = zchki(name);

+ if (tfilelength < 0)

+ return((int)tfilelength);

zincnt = 0;

zinptr = zinbuf;

return((ifp == NULL) ? -1 : 0);

@@ -1142,7 +1157,7 @@

zfillbuf(text) int text; { /* Refill input file buffer */

if (zincnt < 1) { /* Nothing in buffer - must refill */

if (text) { /* Text mode needs LF/CRLF handling */

- int c; /* Current character */

+ int c = 0; /* Current character */

for (zincnt = 0; /* Read a line */

zincnt < MAXRECORD - 1 && (c = getc(ifp)) != EOF && c != '/n';

zincnt++

diff -uNr gku100/gwart.c gku100U/gwart.c

--- gku100/gwart.c 1999-12-18 01:04:22.000000000 +0800

+++ gku100U/gwart.c 2009-12-09 17:15:30.000000000 +0800

@@ -40,6 +40,8 @@

#include <stdio.h>

#include <ctype.h>

+#include <stdlib.h>

+#include <string.h>

#include "gkermit.h"

#define TBL_TYPE "short" /* C data type of state table */

diff -uNr gku100/makefile gku100U/makefile

--- gku100/makefile 1999-12-27 04:28:38.000000000 +0800

+++ gku100U/makefile 2009-12-09 17:15:30.000000000 +0800

@@ -28,17 +28,22 @@

# See README and COPYING for further information.

# Sample installation values - change or override as needed.

+prefix = /usr/local

-BINDIR = /usr/local/bin

-MANDIR = /usr/man/manl

-TEXTDIR = /usr/local/doc

-INFODIR = /usr/local/info

-MANEXT = l

+BINDIR = ${prefix}/bin

+MANDIR = ${prefix}/share/man/man1

+TEXTDIR = ${prefix}/share/doc/gkermit

+INFODIR = ${prefix}/share/info

+MANEXT = 1

# Default compiler and flags

CC=cc

-CFLAGS= -DPOSIX -O $(KFLAGS)

+CFLAGS= -Wall -DPOSIX -O $(KFLAGS)

+

+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))

+ CFLAGS += -g

+endif

# Object files

@@ -94,7 +99,7 @@

cc -o gkermit $(OBJECTS)

clean:

- rm -f $(OBJECTS) gproto.o gproto.c gwart.o gwart

+ rm -f $(OBJECTS) gproto.o gwart.o gwart gkermit

install:

@if test -f ./gkermit; then /