xref: /OK3568_Linux_fs/u-boot/common/lrz.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun   lrz - receive files with x/y/zmodem
3*4882a593Smuzhiyun   Copyright (C) until 1988 Chuck Forsberg (Omen Technology INC)
4*4882a593Smuzhiyun   Copyright (C) 1994 Matt Porter, Michael D. Black
5*4882a593Smuzhiyun   Copyright (C) 1996, 1997 Uwe Ohse
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun   This program is free software; you can redistribute it and/or modify
8*4882a593Smuzhiyun   it under the terms of the GNU General Public License as published by
9*4882a593Smuzhiyun   the Free Software Foundation; either version 2, or (at your option)
10*4882a593Smuzhiyun   any later version.
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun   This program is distributed in the hope that it will be useful,
13*4882a593Smuzhiyun   but WITHOUT ANY WARRANTY; without even the implied warranty of
14*4882a593Smuzhiyun   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*4882a593Smuzhiyun   GNU General Public License for more details.
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun   You should have received a copy of the GNU General Public License
18*4882a593Smuzhiyun   along with this program; if not, write to the Free Software
19*4882a593Smuzhiyun   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20*4882a593Smuzhiyun   02111-1307, USA.
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun   originally written by Chuck Forsberg
23*4882a593Smuzhiyun */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #include "zglobal.h"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define SS_NORMAL 0
28*4882a593Smuzhiyun #include <stdio.h>
29*4882a593Smuzhiyun #include <stdlib.h>
30*4882a593Smuzhiyun //#include <signal.h>
31*4882a593Smuzhiyun //#include <ctype.h>
32*4882a593Smuzhiyun #include <errno.h>
33*4882a593Smuzhiyun //#include <getopt.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #ifdef HAVE_UTIME_H
36*4882a593Smuzhiyun #include <utime.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun //#include "timing.h"
40*4882a593Smuzhiyun //#include "long-options.h"
41*4882a593Smuzhiyun //#include "error.h"
42*4882a593Smuzhiyun //#include "xstrtol.h"
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #ifndef STRICT_PROTOTYPES
45*4882a593Smuzhiyun //extern time_t time();
46*4882a593Smuzhiyun //extern char *strerror();
47*4882a593Smuzhiyun //extern char *strstr();
48*4882a593Smuzhiyun #endif
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #ifndef HAVE_ERRNO_DECLARATION
51*4882a593Smuzhiyun extern int errno;
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define MAX_BLOCK 8192
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /*
57*4882a593Smuzhiyun  * Max value for HOWMANY is 255 if NFGVMIN is not defined.
58*4882a593Smuzhiyun  *   A larger value reduces system overhead but may evoke kernel bugs.
59*4882a593Smuzhiyun  *   133 corresponds to an XMODEM/CRC sector
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun #ifndef HOWMANY
62*4882a593Smuzhiyun #ifdef NFGVMIN
63*4882a593Smuzhiyun #define HOWMANY MAX_BLOCK
64*4882a593Smuzhiyun #else
65*4882a593Smuzhiyun #define HOWMANY 255
66*4882a593Smuzhiyun #endif
67*4882a593Smuzhiyun #endif
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun unsigned Baudrate = 2400;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun //FILE *fout;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun int Lastrx;
75*4882a593Smuzhiyun int Crcflg;
76*4882a593Smuzhiyun int Firstsec;
77*4882a593Smuzhiyun int errors;
78*4882a593Smuzhiyun int Restricted=1;	/* restricted; no /.. or ../ in filenames */
79*4882a593Smuzhiyun int Readnum = HOWMANY;	/* Number of bytes to ask for in read() from modem */
80*4882a593Smuzhiyun int skip_if_not_found;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun char *Pathname;
83*4882a593Smuzhiyun const char *program_name="rz";		/* the name by which we were called */
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun int Topipe=0;
86*4882a593Smuzhiyun int MakeLCPathname=TRUE;	/* make received pathname lower case */
87*4882a593Smuzhiyun int Verbose=0;
88*4882a593Smuzhiyun int Quiet=0;		/* overrides logic that would otherwise set verbose */
89*4882a593Smuzhiyun int Nflag = 0;		/* Don't really transfer files */
90*4882a593Smuzhiyun int Rxclob=TRUE;;	/* Clobber existing file */
91*4882a593Smuzhiyun int Rxbinary=FALSE;	/* receive all files in bin mode */
92*4882a593Smuzhiyun int Rxascii=FALSE;	/* receive files in ascii (translate) mode */
93*4882a593Smuzhiyun int Thisbinary;		/* current file is to be received in bin mode */
94*4882a593Smuzhiyun int try_resume=FALSE;
95*4882a593Smuzhiyun int allow_remote_commands=FALSE;
96*4882a593Smuzhiyun int junk_path=FALSE;
97*4882a593Smuzhiyun int no_timeout=FALSE;
98*4882a593Smuzhiyun enum zm_type_enum protocol=ZM_ZMODEM;
99*4882a593Smuzhiyun int	under_rsh=FALSE;
100*4882a593Smuzhiyun int zmodem_requested=FALSE;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun #ifdef SEGMENTS
103*4882a593Smuzhiyun int chinseg = 0;	/* Number of characters received in this data seg */
104*4882a593Smuzhiyun char secbuf[1+(SEGMENTS+1)*MAX_BLOCK];
105*4882a593Smuzhiyun #else
106*4882a593Smuzhiyun char secbuf[MAX_BLOCK + 1];
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
110*4882a593Smuzhiyun int timesync_flag=0;
111*4882a593Smuzhiyun int in_timesync=0;
112*4882a593Smuzhiyun #endif
113*4882a593Smuzhiyun int in_tcpsync=0;
114*4882a593Smuzhiyun int tcpsync_flag=1;
115*4882a593Smuzhiyun int tcp_socket=-1;
116*4882a593Smuzhiyun int tcp_flag=0;
117*4882a593Smuzhiyun char *tcp_server_address=NULL;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun char tcp_buf[256]="";
120*4882a593Smuzhiyun #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
121*4882a593Smuzhiyun static int o_sync = 0;
122*4882a593Smuzhiyun #endif
123*4882a593Smuzhiyun static int rzfiles __P ((struct zm_fileinfo *));
124*4882a593Smuzhiyun static int tryz __P ((void));
125*4882a593Smuzhiyun static void checkpath __P ((const char *name));
126*4882a593Smuzhiyun //static void chkinvok __P ((const char *s));
127*4882a593Smuzhiyun static void report __P ((int sct));
128*4882a593Smuzhiyun static void uncaps __P ((char *s));
129*4882a593Smuzhiyun static int IsAnyLower __P ((const char *s));
130*4882a593Smuzhiyun static int putsec __P ((struct zm_fileinfo *zi, char *buf, size_t n));
131*4882a593Smuzhiyun //static int make_dirs __P ((char *pathname));
132*4882a593Smuzhiyun static int procheader __P ((char *name, struct zm_fileinfo *));
133*4882a593Smuzhiyun static int wcgetsec __P ((size_t *Blklen, char *rxbuf, unsigned int maxtime));
134*4882a593Smuzhiyun static int wcrx __P ((struct zm_fileinfo *));
135*4882a593Smuzhiyun static int wcrxpn __P ((struct zm_fileinfo *, char *rpn));
136*4882a593Smuzhiyun static int wcreceive __P ((int argc, char **argp));
137*4882a593Smuzhiyun static int rzfile __P ((struct zm_fileinfo *));
138*4882a593Smuzhiyun static void usage __P ((int exitcode, const char *what));
139*4882a593Smuzhiyun //static void usage1 __P ((int exitcode));
140*4882a593Smuzhiyun static void exec2 __P ((const char *s));
141*4882a593Smuzhiyun static int closeit __P ((struct zm_fileinfo *));
142*4882a593Smuzhiyun static void ackbibi __P ((void));
143*4882a593Smuzhiyun static int sys2 __P ((const char *s));
144*4882a593Smuzhiyun static void zmputs __P ((const char *s));
145*4882a593Smuzhiyun static size_t getfree __P ((void));
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun static long buffersize=1024*128;
148*4882a593Smuzhiyun static unsigned long min_bps=0;
149*4882a593Smuzhiyun static long min_bps_time=120;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun extern int CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c);
152*4882a593Smuzhiyun extern void CYGACC_COMM_IF_PUTC (char x, char y);
153*4882a593Smuzhiyun extern int CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun char Lzmanag;		/* Local file management request */
156*4882a593Smuzhiyun char zconv;		/* ZMODEM file conversion request */
157*4882a593Smuzhiyun char zmanag;		/* ZMODEM file management request */
158*4882a593Smuzhiyun char ztrans;		/* ZMODEM file transport request */
159*4882a593Smuzhiyun int Zctlesc;		/* Encode control characters */
160*4882a593Smuzhiyun int Zrwindow = 1400;	/* RX window size (controls garbage count) */
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun int tryzhdrtype=ZRINIT;	/* Header type to send corresponding to Last rx close */
163*4882a593Smuzhiyun time_t stop_time;
164*4882a593Smuzhiyun void *zmodem_addr;
165*4882a593Smuzhiyun unsigned int zmodem_offset;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
168*4882a593Smuzhiyun #  if defined(ENABLE_SYSLOG_FORCE) || defined(ENABLE_SYSLOG_DEFAULT)
169*4882a593Smuzhiyun int enable_syslog=TRUE;
170*4882a593Smuzhiyun #  else
171*4882a593Smuzhiyun int enable_syslog=FALSE;
172*4882a593Smuzhiyun #  endif
173*4882a593Smuzhiyun #define DO_SYSLOG_FNAME(message) do { \
174*4882a593Smuzhiyun 	if (enable_syslog) { \
175*4882a593Smuzhiyun 		const char *shortname; \
176*4882a593Smuzhiyun 		if (!zi->fname) \
177*4882a593Smuzhiyun 			shortname="no.name"; \
178*4882a593Smuzhiyun 		else { \
179*4882a593Smuzhiyun 			shortname=strrchr(zi->fname,'/'); \
180*4882a593Smuzhiyun 			if (!shortname) \
181*4882a593Smuzhiyun 				shortname=zi->fname; \
182*4882a593Smuzhiyun 			else \
183*4882a593Smuzhiyun 				shortname++; \
184*4882a593Smuzhiyun 		} \
185*4882a593Smuzhiyun         lsyslog message ; \
186*4882a593Smuzhiyun 	} \
187*4882a593Smuzhiyun } while(0)
188*4882a593Smuzhiyun #define DO_SYSLOG(message) do { \
189*4882a593Smuzhiyun 	if (enable_syslog) { \
190*4882a593Smuzhiyun         lsyslog message ; \
191*4882a593Smuzhiyun 	} \
192*4882a593Smuzhiyun } while(0)
193*4882a593Smuzhiyun #else
194*4882a593Smuzhiyun #define DO_SYSLOG_FNAME(message) do { } while(0)
195*4882a593Smuzhiyun #define DO_SYSLOG(message) do { } while(0)
196*4882a593Smuzhiyun #endif
197*4882a593Smuzhiyun #ifdef __STDC__
198*4882a593Smuzhiyun #  define WAYTOGO
199*4882a593Smuzhiyun #  include <stdarg.h>
200*4882a593Smuzhiyun #  define VA_START(args, lastarg) va_start(args, lastarg)
201*4882a593Smuzhiyun #else
202*4882a593Smuzhiyun #  include <varargs.h>
203*4882a593Smuzhiyun #  define VA_START(args, lastarg) va_start(args)
204*4882a593Smuzhiyun #endif
205*4882a593Smuzhiyun #define error(x,y,z,a)
206*4882a593Smuzhiyun /*********************************************************/
207*4882a593Smuzhiyun /****************  PORTING FUNTIONS **********************/
208*4882a593Smuzhiyun /*********************************************************/
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun // Send one character
sendline(int c)211*4882a593Smuzhiyun void sendline(int c)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	CYGACC_COMM_IF_PUTC(0, c);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun //read data with timeout
216*4882a593Smuzhiyun //ret value: how many bytes read, 0=timeout, <0=error
217*4882a593Smuzhiyun //read data is store at buf
read_data(int tout_in_100ms,char * buf,int size)218*4882a593Smuzhiyun int read_data(int tout_in_100ms, char *buf, int size)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	extern int xyzModem_CHAR_TIMEOUT;
221*4882a593Smuzhiyun 	char c;
222*4882a593Smuzhiyun 	int wait_msec = tout_in_100ms * 100;
223*4882a593Smuzhiyun 	int ret;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	while(1) {
226*4882a593Smuzhiyun 		ret = CYGACC_COMM_IF_GETC_TIMEOUT(0, &c);
227*4882a593Smuzhiyun 		if(ret != 0) {
228*4882a593Smuzhiyun 			buf[0] = c;
229*4882a593Smuzhiyun 			return 1;
230*4882a593Smuzhiyun 		}
231*4882a593Smuzhiyun 		if(wait_msec > xyzModem_CHAR_TIMEOUT)
232*4882a593Smuzhiyun 			wait_msec -= xyzModem_CHAR_TIMEOUT;
233*4882a593Smuzhiyun 		else
234*4882a593Smuzhiyun 			wait_msec = 0;
235*4882a593Smuzhiyun 		if(wait_msec == 0)
236*4882a593Smuzhiyun 			return 0;
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun //send data in a buffer
send_data(int fd,char * buf,int size)242*4882a593Smuzhiyun void send_data(int fd, char *buf, int size)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	int i;
245*4882a593Smuzhiyun 	for(i=0;i<size;i++)
246*4882a593Smuzhiyun 		CYGACC_COMM_IF_PUTC(0, buf[i]);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun //flush tx data
flushmo(void)250*4882a593Smuzhiyun void flushmo(void)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	//flush tx
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun //return seconds elapsed between reset=1 & reset=0. float allowed
timing(int reset,time_t * nowp)255*4882a593Smuzhiyun ulong timing (int reset, time_t *nowp)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun 	static unsigned long start;
258*4882a593Smuzhiyun 	if(reset) {
259*4882a593Smuzhiyun 		start = get_timer(0);
260*4882a593Smuzhiyun 		return 0;
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 	else {
263*4882a593Smuzhiyun 		return get_timer(start)/ 1000;
264*4882a593Smuzhiyun 	}
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun /***************************************************/
268*4882a593Smuzhiyun /************** END PORTING FUNCTIONS **************/
269*4882a593Smuzhiyun /***************************************************/
xsendline(int c)270*4882a593Smuzhiyun void xsendline(int c)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	sendline(c);
273*4882a593Smuzhiyun }
printable(int c)274*4882a593Smuzhiyun int printable(int c)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	if((c>=' ') && (c <= '~'))
277*4882a593Smuzhiyun 		return c;
278*4882a593Smuzhiyun 	return '?';
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun void
282*4882a593Smuzhiyun #ifdef WAYTOGO
zperr(const char * fmt,...)283*4882a593Smuzhiyun zperr(const char *fmt, ...)
284*4882a593Smuzhiyun #else
285*4882a593Smuzhiyun zperr(fmt, va_alist)
286*4882a593Smuzhiyun 	const char *fmt;
287*4882a593Smuzhiyun 	va_dcl
288*4882a593Smuzhiyun #endif
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun #if 0
291*4882a593Smuzhiyun     va_list ap;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	if (Verbose<=0)
294*4882a593Smuzhiyun 		return;
295*4882a593Smuzhiyun 	fprintf(stderr,_("Retry %d: "),errors);
296*4882a593Smuzhiyun     VA_START(ap, fmt);
297*4882a593Smuzhiyun     vfprintf(stderr,fmt, ap);
298*4882a593Smuzhiyun     va_end(ap);
299*4882a593Smuzhiyun     putc('\n',stderr);
300*4882a593Smuzhiyun #endif
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun void
304*4882a593Smuzhiyun #ifdef WAYTOGO
zpfatal(const char * fmt,...)305*4882a593Smuzhiyun zpfatal(const char *fmt, ...)
306*4882a593Smuzhiyun #else
307*4882a593Smuzhiyun zpfatal(fmt, va_alist)
308*4882a593Smuzhiyun 	const char *fmt;
309*4882a593Smuzhiyun 	va_dcl
310*4882a593Smuzhiyun #endif
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun #if 0
313*4882a593Smuzhiyun     va_list ap;
314*4882a593Smuzhiyun     int err=errno;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	if (Verbose<=0)
317*4882a593Smuzhiyun 		return;
318*4882a593Smuzhiyun 	fprintf(stderr,"%s: ",program_name);
319*4882a593Smuzhiyun     VA_START(ap, fmt);
320*4882a593Smuzhiyun     vfprintf(stderr,fmt, ap);
321*4882a593Smuzhiyun     va_end(ap);
322*4882a593Smuzhiyun 	fprintf(stderr,": %s\n",strerror(err));
323*4882a593Smuzhiyun #endif
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun void
327*4882a593Smuzhiyun #ifdef WAYTOGO
vfile(const char * format,...)328*4882a593Smuzhiyun vfile(const char *format, ...)
329*4882a593Smuzhiyun #else
330*4882a593Smuzhiyun vfile(format, va_alist)
331*4882a593Smuzhiyun 	const char *format;
332*4882a593Smuzhiyun 	va_dcl
333*4882a593Smuzhiyun #endif
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun #if 0
336*4882a593Smuzhiyun     va_list ap;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	if (Verbose < 3)
339*4882a593Smuzhiyun 		return;
340*4882a593Smuzhiyun     VA_START(ap, format);
341*4882a593Smuzhiyun     vfprintf(stderr,format, ap);
342*4882a593Smuzhiyun     va_end(ap);
343*4882a593Smuzhiyun     putc('\n',stderr);
344*4882a593Smuzhiyun #endif
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun #ifndef vstringf
348*4882a593Smuzhiyun /* if using gcc this function is not needed */
349*4882a593Smuzhiyun void
350*4882a593Smuzhiyun #ifdef WAYTOGO
vstringf(const char * format,...)351*4882a593Smuzhiyun vstringf(const char *format, ...)
352*4882a593Smuzhiyun #else
353*4882a593Smuzhiyun vstringf(format, va_alist)
354*4882a593Smuzhiyun 	const char *format;
355*4882a593Smuzhiyun 	va_dcl
356*4882a593Smuzhiyun #endif
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun     va_list ap;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun     VA_START(ap, format);
361*4882a593Smuzhiyun     vfprintf(stderr,format, ap);
362*4882a593Smuzhiyun     va_end(ap);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun long cr3tab[] = { /* CRC polynomial 0xedb88320 */
366*4882a593Smuzhiyun 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
367*4882a593Smuzhiyun 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
368*4882a593Smuzhiyun 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
369*4882a593Smuzhiyun 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
370*4882a593Smuzhiyun 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
371*4882a593Smuzhiyun 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
372*4882a593Smuzhiyun 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
373*4882a593Smuzhiyun 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
374*4882a593Smuzhiyun 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
375*4882a593Smuzhiyun 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
376*4882a593Smuzhiyun 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
377*4882a593Smuzhiyun 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
378*4882a593Smuzhiyun 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
379*4882a593Smuzhiyun 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
380*4882a593Smuzhiyun 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
381*4882a593Smuzhiyun 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
382*4882a593Smuzhiyun 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
383*4882a593Smuzhiyun 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
384*4882a593Smuzhiyun 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
385*4882a593Smuzhiyun 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
386*4882a593Smuzhiyun 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
387*4882a593Smuzhiyun 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
388*4882a593Smuzhiyun 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
389*4882a593Smuzhiyun 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
390*4882a593Smuzhiyun 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
391*4882a593Smuzhiyun 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
392*4882a593Smuzhiyun 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
393*4882a593Smuzhiyun 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
394*4882a593Smuzhiyun 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
395*4882a593Smuzhiyun 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
396*4882a593Smuzhiyun 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
397*4882a593Smuzhiyun 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun unsigned short crctab[256] = {
400*4882a593Smuzhiyun     0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
401*4882a593Smuzhiyun     0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
402*4882a593Smuzhiyun     0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
403*4882a593Smuzhiyun     0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
404*4882a593Smuzhiyun     0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
405*4882a593Smuzhiyun     0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
406*4882a593Smuzhiyun     0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
407*4882a593Smuzhiyun     0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
408*4882a593Smuzhiyun     0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
409*4882a593Smuzhiyun     0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
410*4882a593Smuzhiyun     0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
411*4882a593Smuzhiyun     0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
412*4882a593Smuzhiyun     0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
413*4882a593Smuzhiyun     0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
414*4882a593Smuzhiyun     0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
415*4882a593Smuzhiyun     0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
416*4882a593Smuzhiyun     0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
417*4882a593Smuzhiyun     0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
418*4882a593Smuzhiyun     0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
419*4882a593Smuzhiyun     0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
420*4882a593Smuzhiyun     0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
421*4882a593Smuzhiyun     0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
422*4882a593Smuzhiyun     0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
423*4882a593Smuzhiyun     0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
424*4882a593Smuzhiyun     0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
425*4882a593Smuzhiyun     0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
426*4882a593Smuzhiyun     0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
427*4882a593Smuzhiyun     0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
428*4882a593Smuzhiyun     0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
429*4882a593Smuzhiyun     0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
430*4882a593Smuzhiyun     0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
431*4882a593Smuzhiyun     0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
432*4882a593Smuzhiyun };
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun void
canit(int fd)435*4882a593Smuzhiyun canit (int fd)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun 	static char canistr[] =
438*4882a593Smuzhiyun 	{
439*4882a593Smuzhiyun 		24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0
440*4882a593Smuzhiyun 	};
441*4882a593Smuzhiyun 	purgeline(fd);
442*4882a593Smuzhiyun 	//write(fd,canistr,strlen(canistr));
443*4882a593Smuzhiyun 	send_data(fd, canistr, strlen(canistr));
444*4882a593Smuzhiyun 	if (fd==0) {
445*4882a593Smuzhiyun 		//write(1,canistr,strlen(canistr));
446*4882a593Smuzhiyun 		send_data(1,canistr,strlen(canistr));
447*4882a593Smuzhiyun 	}
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun const char *
protname(void)451*4882a593Smuzhiyun protname(void)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	const char *prot_name;
454*4882a593Smuzhiyun 	switch(protocol) {
455*4882a593Smuzhiyun 	case ZM_XMODEM:
456*4882a593Smuzhiyun 		prot_name="XMODEM";
457*4882a593Smuzhiyun 		break;
458*4882a593Smuzhiyun 	case ZM_YMODEM:
459*4882a593Smuzhiyun 		prot_name="YMODEM";
460*4882a593Smuzhiyun 		break;
461*4882a593Smuzhiyun 	default:
462*4882a593Smuzhiyun 		prot_name="ZMODEM";
463*4882a593Smuzhiyun 		break;
464*4882a593Smuzhiyun 	}
465*4882a593Smuzhiyun 	return prot_name;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun /* called by signal interrupt or terminate to clean things up */
469*4882a593Smuzhiyun RETSIGTYPE
bibi(int n)470*4882a593Smuzhiyun bibi(int n)
471*4882a593Smuzhiyun {
472*4882a593Smuzhiyun 	if (zmodem_requested)
473*4882a593Smuzhiyun 		zmputs(Attn);
474*4882a593Smuzhiyun 	canit(0);
475*4882a593Smuzhiyun 	io_mode(0,0);
476*4882a593Smuzhiyun 	//error(128+n,0,_("caught signal %d; exiting"), n);
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun #if 0
480*4882a593Smuzhiyun static struct option const long_options[] =
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun 	{"append", no_argument, NULL, '+'},
483*4882a593Smuzhiyun 	{"ascii", no_argument, NULL, 'a'},
484*4882a593Smuzhiyun 	{"binary", no_argument, NULL, 'b'},
485*4882a593Smuzhiyun 	{"bufsize", required_argument, NULL, 'B'},
486*4882a593Smuzhiyun 	{"allow-commands", no_argument, NULL, 'C'},
487*4882a593Smuzhiyun 	{"allow-remote-commands", no_argument, NULL, 'C'},
488*4882a593Smuzhiyun 	{"escape", no_argument, NULL, 'e'},
489*4882a593Smuzhiyun 	{"rename", no_argument, NULL, 'E'},
490*4882a593Smuzhiyun 	{"help", no_argument, NULL, 'h'},
491*4882a593Smuzhiyun 	{"crc-check", no_argument, NULL, 'H'},
492*4882a593Smuzhiyun 	{"junk-path", no_argument, NULL, 'j'},
493*4882a593Smuzhiyun 	{"errors", required_argument, NULL, 3},
494*4882a593Smuzhiyun 	{"disable-timeouts", no_argument, NULL, 'O'},
495*4882a593Smuzhiyun 	{"disable-timeout", no_argument, NULL, 'O'}, /* i can't get it right */
496*4882a593Smuzhiyun 	{"min-bps", required_argument, NULL, 'm'},
497*4882a593Smuzhiyun 	{"min-bps-time", required_argument, NULL, 'M'},
498*4882a593Smuzhiyun 	{"newer", no_argument, NULL, 'n'},
499*4882a593Smuzhiyun 	{"newer-or-longer", no_argument, NULL, 'N'},
500*4882a593Smuzhiyun 	{"protect", no_argument, NULL, 'p'},
501*4882a593Smuzhiyun 	{"resume", no_argument, NULL, 'r'},
502*4882a593Smuzhiyun 	{"restricted", no_argument, NULL, 'R'},
503*4882a593Smuzhiyun 	{"quiet", no_argument, NULL, 'q'},
504*4882a593Smuzhiyun 	{"stop-at", required_argument, NULL, 's'},
505*4882a593Smuzhiyun 	{"timesync", no_argument, NULL, 'S'},
506*4882a593Smuzhiyun 	{"timeout", required_argument, NULL, 't'},
507*4882a593Smuzhiyun 	{"keep-uppercase", no_argument, NULL, 'u'},
508*4882a593Smuzhiyun 	{"unrestrict", no_argument, NULL, 'U'},
509*4882a593Smuzhiyun 	{"verbose", no_argument, NULL, 'v'},
510*4882a593Smuzhiyun 	{"windowsize", required_argument, NULL, 'w'},
511*4882a593Smuzhiyun 	{"with-crc", no_argument, NULL, 'c'},
512*4882a593Smuzhiyun 	{"xmodem", no_argument, NULL, 'X'},
513*4882a593Smuzhiyun 	{"ymodem", no_argument, NULL, 1},
514*4882a593Smuzhiyun 	{"zmodem", no_argument, NULL, 'Z'},
515*4882a593Smuzhiyun 	{"overwrite", no_argument, NULL, 'y'},
516*4882a593Smuzhiyun 	{"null", no_argument, NULL, 'D'},
517*4882a593Smuzhiyun 	{"syslog", optional_argument, NULL , 2},
518*4882a593Smuzhiyun 	{"delay-startup", required_argument, NULL, 4},
519*4882a593Smuzhiyun 	{"o-sync", no_argument, NULL, 5},
520*4882a593Smuzhiyun 	{"o_sync", no_argument, NULL, 5},
521*4882a593Smuzhiyun 	{"tcp-server", no_argument, NULL, 6},
522*4882a593Smuzhiyun 	{"tcp-client", required_argument, NULL, 7},
523*4882a593Smuzhiyun 	{NULL,0,NULL,0}
524*4882a593Smuzhiyun };
525*4882a593Smuzhiyun #endif
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun void
show_version(void)528*4882a593Smuzhiyun show_version(void)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun 	printf ("%s (%s) %s\n", program_name, PACKAGE, VERSION);
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun int
534*4882a593Smuzhiyun //main(int argc, char *argv[])
zmodem_rx(unsigned long addr,int * rxsize)535*4882a593Smuzhiyun zmodem_rx(unsigned long addr, int *rxsize)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun 	__maybe_unused register char *cp;
538*4882a593Smuzhiyun 	//register int npats;
539*4882a593Smuzhiyun 	//char **patts=NULL; /* keep compiler quiet */
540*4882a593Smuzhiyun 	int exitcode=0;
541*4882a593Smuzhiyun 	__maybe_unused int c;
542*4882a593Smuzhiyun 	__maybe_unused unsigned int startup_delay=0;
543*4882a593Smuzhiyun 	__maybe_unused int argc = 1;
544*4882a593Smuzhiyun 	__maybe_unused char *argv[] = { "rz" };
545*4882a593Smuzhiyun 	zmodem_addr = (void *)addr;
546*4882a593Smuzhiyun 	zmodem_offset = 0;
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 	Rxtimeout = 100;
549*4882a593Smuzhiyun #if 0
550*4882a593Smuzhiyun 	setbuf(stderr, NULL);
551*4882a593Smuzhiyun 	if ((cp=getenv("SHELL")) && (strstr(cp, "rsh") || strstr(cp, "rksh")
552*4882a593Smuzhiyun 		|| strstr(cp,"rbash") || strstr(cp, "rshell")))
553*4882a593Smuzhiyun 		under_rsh=TRUE;
554*4882a593Smuzhiyun 	if ((cp=getenv("ZMODEM_RESTRICTED"))!=NULL)
555*4882a593Smuzhiyun 		Restricted=2;
556*4882a593Smuzhiyun #endif
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	/* make temporary and unfinished files */
559*4882a593Smuzhiyun 	//umask(0077);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	//from_cu();
562*4882a593Smuzhiyun 	//chkinvok(argv[0]);	/* if called as [-]rzCOMMAND set flag */
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
565*4882a593Smuzhiyun 	openlog(program_name,LOG_PID,ENABLE_SYSLOG);
566*4882a593Smuzhiyun #endif
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	//setlocale (LC_ALL, "");
569*4882a593Smuzhiyun 	//bindtextdomain (PACKAGE, LOCALEDIR);
570*4882a593Smuzhiyun 	//textdomain (PACKAGE);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun #if 0
573*4882a593Smuzhiyun     parse_long_options (argc, argv, show_version, usage1);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	while ((c = getopt_long (argc, argv,
576*4882a593Smuzhiyun 		"a+bB:cCDeEhm:M:OprRqs:St:uUvw:XZy",
577*4882a593Smuzhiyun 		long_options, (int *) 0)) != EOF)
578*4882a593Smuzhiyun 	{
579*4882a593Smuzhiyun 		unsigned long int tmp;
580*4882a593Smuzhiyun 		char *tmpptr;
581*4882a593Smuzhiyun 		enum strtol_error s_err;
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 		switch (c)
584*4882a593Smuzhiyun 		{
585*4882a593Smuzhiyun 		case 0:
586*4882a593Smuzhiyun 			break;
587*4882a593Smuzhiyun 		case '+': Lzmanag = ZF1_ZMAPND; break;
588*4882a593Smuzhiyun 		case 'a': Rxascii=TRUE;  break;
589*4882a593Smuzhiyun 		case 'b': Rxbinary=TRUE; break;
590*4882a593Smuzhiyun 		case 'B':
591*4882a593Smuzhiyun 			if (strcmp(optarg,"auto")==0)
592*4882a593Smuzhiyun 				buffersize=-1;
593*4882a593Smuzhiyun 			else
594*4882a593Smuzhiyun 				buffersize=strtol(optarg,NULL,10);
595*4882a593Smuzhiyun 			break;
596*4882a593Smuzhiyun 		case 'c': Crcflg=TRUE; break;
597*4882a593Smuzhiyun 		case 'C': allow_remote_commands=TRUE; break;
598*4882a593Smuzhiyun 		case 'D': Nflag = TRUE; break;
599*4882a593Smuzhiyun 		case 'E': Lzmanag = ZF1_ZMCHNG; break;
600*4882a593Smuzhiyun 		case 'e': Zctlesc = 1; break;
601*4882a593Smuzhiyun 		case 'h': usage(0,NULL); break;
602*4882a593Smuzhiyun 		case 'H': Lzmanag= ZF1_ZMCRC; break;
603*4882a593Smuzhiyun 		case 'j': junk_path=TRUE; break;
604*4882a593Smuzhiyun 		case 'm':
605*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, &tmpptr, 0, &tmp, "km");
606*4882a593Smuzhiyun 			min_bps = tmp;
607*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
608*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("min_bps"), s_err);
609*4882a593Smuzhiyun 			break;
610*4882a593Smuzhiyun 		case 'M':
611*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
612*4882a593Smuzhiyun 			min_bps_time = tmp;
613*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
614*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("min_bps_time"), s_err);
615*4882a593Smuzhiyun 			if (min_bps_time<=1)
616*4882a593Smuzhiyun 				usage(2,_("min_bps_time must be > 1"));
617*4882a593Smuzhiyun 			break;
618*4882a593Smuzhiyun 		case 'N': Lzmanag = ZF1_ZMNEWL;  break;
619*4882a593Smuzhiyun 		case 'n': Lzmanag = ZF1_ZMNEW;  break;
620*4882a593Smuzhiyun 		case 'O': no_timeout=TRUE; break;
621*4882a593Smuzhiyun 		case 'p': Lzmanag = ZF1_ZMPROT;  break;
622*4882a593Smuzhiyun 		case 'q': Quiet=TRUE; Verbose=0; break;
623*4882a593Smuzhiyun 		case 's':
624*4882a593Smuzhiyun 			if (isdigit((unsigned char) (*optarg))) {
625*4882a593Smuzhiyun 				struct tm *tm;
626*4882a593Smuzhiyun 				time_t t;
627*4882a593Smuzhiyun 				int hh,mm;
628*4882a593Smuzhiyun 				char *nex;
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 				hh = strtoul (optarg, &nex, 10);
631*4882a593Smuzhiyun 				if (hh>23)
632*4882a593Smuzhiyun 					usage(2,_("hour to large (0..23)"));
633*4882a593Smuzhiyun 				if (*nex!=':')
634*4882a593Smuzhiyun 					usage(2, _("unparsable stop time\n"));
635*4882a593Smuzhiyun 				nex++;
636*4882a593Smuzhiyun                 mm = strtoul (optarg, &nex, 10);
637*4882a593Smuzhiyun 				if (mm>59)
638*4882a593Smuzhiyun 					usage(2,_("minute to large (0..59)"));
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 				t=time(NULL);
641*4882a593Smuzhiyun 				tm=localtime(&t);
642*4882a593Smuzhiyun 				tm->tm_hour=hh;
643*4882a593Smuzhiyun 				tm->tm_min=hh;
644*4882a593Smuzhiyun 				stop_time=mktime(tm);
645*4882a593Smuzhiyun 				if (stop_time<t)
646*4882a593Smuzhiyun 					stop_time+=86400L; /* one day more */
647*4882a593Smuzhiyun 				if (stop_time - t <10)
648*4882a593Smuzhiyun 					usage(2,_("stop time to small"));
649*4882a593Smuzhiyun 			} else {
650*4882a593Smuzhiyun 				s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
651*4882a593Smuzhiyun 				stop_time = tmp + time(0);
652*4882a593Smuzhiyun 				if (s_err != LONGINT_OK)
653*4882a593Smuzhiyun 					STRTOL_FATAL_ERROR (optarg, _("stop-at"), s_err);
654*4882a593Smuzhiyun 				if (tmp<10)
655*4882a593Smuzhiyun 					usage(2,_("stop time to small"));
656*4882a593Smuzhiyun 			}
657*4882a593Smuzhiyun 			break;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 		case 'r':
661*4882a593Smuzhiyun 			if (try_resume)
662*4882a593Smuzhiyun 				Lzmanag= ZF1_ZMCRC;
663*4882a593Smuzhiyun 			else
664*4882a593Smuzhiyun 				try_resume=TRUE;
665*4882a593Smuzhiyun 			break;
666*4882a593Smuzhiyun 		case 'R': Restricted++;  break;
667*4882a593Smuzhiyun 		case 'S':
668*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
669*4882a593Smuzhiyun 			timesync_flag++;
670*4882a593Smuzhiyun 			if (timesync_flag==2) {
671*4882a593Smuzhiyun #ifdef HAVE_SETTIMEOFDAY
672*4882a593Smuzhiyun 				//error(0,0,_("don't have settimeofday, will not set time\n"));
673*4882a593Smuzhiyun #endif
674*4882a593Smuzhiyun 				//if (getuid()!=0)
675*4882a593Smuzhiyun 				//	error(0,0,
676*4882a593Smuzhiyun 				//_("not running as root (this is good!), can not set time\n"));
677*4882a593Smuzhiyun 			}
678*4882a593Smuzhiyun #endif
679*4882a593Smuzhiyun 			break;
680*4882a593Smuzhiyun 		case 't':
681*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
682*4882a593Smuzhiyun 			Rxtimeout = tmp;
683*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
684*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("timeout"), s_err);
685*4882a593Smuzhiyun 			if (Rxtimeout<10 || Rxtimeout>1000)
686*4882a593Smuzhiyun 				usage(2,_("timeout out of range 10..1000"));
687*4882a593Smuzhiyun 			break;
688*4882a593Smuzhiyun 		case 'w':
689*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
690*4882a593Smuzhiyun 			Zrwindow = tmp;
691*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
692*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("window size"), s_err);
693*4882a593Smuzhiyun 			break;
694*4882a593Smuzhiyun 		case 'u':
695*4882a593Smuzhiyun 			MakeLCPathname=FALSE; break;
696*4882a593Smuzhiyun 		case 'U':
697*4882a593Smuzhiyun 			if (!under_rsh)
698*4882a593Smuzhiyun 				Restricted=0;
699*4882a593Smuzhiyun 			else  {
700*4882a593Smuzhiyun 				DO_SYSLOG((LOG_INFO,"--unrestrict option used under restricted shell"));
701*4882a593Smuzhiyun 				//error(1,0,
702*4882a593Smuzhiyun 	//_("security violation: can't do that under restricted shell\n"));
703*4882a593Smuzhiyun 			}
704*4882a593Smuzhiyun 			break;
705*4882a593Smuzhiyun 		case 'v':
706*4882a593Smuzhiyun 			++Verbose; break;
707*4882a593Smuzhiyun 		case 'X': protocol=ZM_XMODEM; break;
708*4882a593Smuzhiyun 		case 1:   protocol=ZM_YMODEM; break;
709*4882a593Smuzhiyun 		case 'Z': protocol=ZM_ZMODEM; break;
710*4882a593Smuzhiyun 		case 'y':
711*4882a593Smuzhiyun 			Rxclob=TRUE; break;
712*4882a593Smuzhiyun 		case 2:
713*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
714*4882a593Smuzhiyun #  ifndef ENABLE_SYSLOG_FORCE
715*4882a593Smuzhiyun 			if (optarg && (!strcmp(optarg,"off") || !strcmp(optarg,"no"))) {
716*4882a593Smuzhiyun 				if (under_rsh)
717*4882a593Smuzhiyun 					;//error(0,0, _("cannot turnoff syslog"));
718*4882a593Smuzhiyun 				else
719*4882a593Smuzhiyun 					enable_syslog=FALSE;
720*4882a593Smuzhiyun 			}
721*4882a593Smuzhiyun 			else
722*4882a593Smuzhiyun 				enable_syslog=TRUE;
723*4882a593Smuzhiyun #  else
724*4882a593Smuzhiyun 			//error(0,0, _("cannot turnoff syslog"));
725*4882a593Smuzhiyun #  endif
726*4882a593Smuzhiyun #endif
727*4882a593Smuzhiyun 		case 3:
728*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, NULL, 0, &tmp, "km");
729*4882a593Smuzhiyun 			bytes_per_error = tmp;
730*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
731*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("bytes_per_error"), s_err);
732*4882a593Smuzhiyun 			if (bytes_per_error<100)
733*4882a593Smuzhiyun 				usage(2,_("bytes-per-error should be >100"));
734*4882a593Smuzhiyun 			break;
735*4882a593Smuzhiyun         case 4:
736*4882a593Smuzhiyun 			s_err = xstrtoul (optarg, NULL, 0, &tmp, NULL);
737*4882a593Smuzhiyun 			startup_delay = tmp;
738*4882a593Smuzhiyun 			if (s_err != LONGINT_OK)
739*4882a593Smuzhiyun 				STRTOL_FATAL_ERROR (optarg, _("startup delay"), s_err);
740*4882a593Smuzhiyun 			break;
741*4882a593Smuzhiyun 		case 5:
742*4882a593Smuzhiyun #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
743*4882a593Smuzhiyun 			o_sync=1;
744*4882a593Smuzhiyun #else
745*4882a593Smuzhiyun 			//error(0,0, _("O_SYNC not supported by the kernel"));
746*4882a593Smuzhiyun #endif
747*4882a593Smuzhiyun 			break;
748*4882a593Smuzhiyun 		case 6:
749*4882a593Smuzhiyun 			tcp_flag=2;
750*4882a593Smuzhiyun 			break;
751*4882a593Smuzhiyun 		case 7:
752*4882a593Smuzhiyun 			tcp_flag=3;
753*4882a593Smuzhiyun 			tcp_server_address=(char *)strdup(optarg);
754*4882a593Smuzhiyun 			if (!tcp_server_address)
755*4882a593Smuzhiyun 				;//error(1,0,_("out of memory"));
756*4882a593Smuzhiyun 			break;
757*4882a593Smuzhiyun 		default:
758*4882a593Smuzhiyun 			usage(2,NULL);
759*4882a593Smuzhiyun 		}
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	}
762*4882a593Smuzhiyun #endif
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun #if 0
765*4882a593Smuzhiyun 	if (getuid()!=geteuid()) {
766*4882a593Smuzhiyun 		error(1,0,
767*4882a593Smuzhiyun 		_("this program was never intended to be used setuid\n"));
768*4882a593Smuzhiyun 	}
769*4882a593Smuzhiyun #endif
770*4882a593Smuzhiyun 	/* initialize zsendline tab */
771*4882a593Smuzhiyun 	zsendline_init();
772*4882a593Smuzhiyun #ifdef HAVE_SIGINTERRUPT
773*4882a593Smuzhiyun 	siginterrupt(SIGALRM,1);
774*4882a593Smuzhiyun #endif
775*4882a593Smuzhiyun 	//if (startup_delay)
776*4882a593Smuzhiyun 	//	sleep(startup_delay);
777*4882a593Smuzhiyun 
778*4882a593Smuzhiyun 	//npats = argc - optind;
779*4882a593Smuzhiyun 	//patts=&argv[optind];
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun #if 0
782*4882a593Smuzhiyun 	if (npats > 1)
783*4882a593Smuzhiyun 		usage(2,_("garbage on commandline"));
784*4882a593Smuzhiyun 	if (protocol!=ZM_XMODEM && npats)
785*4882a593Smuzhiyun 		usage(2, _("garbage on commandline"));
786*4882a593Smuzhiyun 	if (Restricted && allow_remote_commands) {
787*4882a593Smuzhiyun 		allow_remote_commands=FALSE;
788*4882a593Smuzhiyun 	}
789*4882a593Smuzhiyun #endif
790*4882a593Smuzhiyun 	allow_remote_commands=FALSE;
791*4882a593Smuzhiyun 	if (Fromcu && !Quiet) {
792*4882a593Smuzhiyun 		if (Verbose == 0)
793*4882a593Smuzhiyun 			Verbose = 2;
794*4882a593Smuzhiyun 	}
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	vfile("%s %s\n", program_name, VERSION);
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun #if 0
799*4882a593Smuzhiyun 	if (tcp_flag==2) {
800*4882a593Smuzhiyun 		char buf[256];
801*4882a593Smuzhiyun #ifdef MAXHOSTNAMELEN
802*4882a593Smuzhiyun 		char hn[MAXHOSTNAMELEN];
803*4882a593Smuzhiyun #else
804*4882a593Smuzhiyun 		char hn[256];
805*4882a593Smuzhiyun #endif
806*4882a593Smuzhiyun 		char *p,*q;
807*4882a593Smuzhiyun 		int d;
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 		/* tell receiver to receive via tcp */
810*4882a593Smuzhiyun 		d=tcp_server(buf);
811*4882a593Smuzhiyun 		p=strchr(buf+1,'<');
812*4882a593Smuzhiyun 		p++;
813*4882a593Smuzhiyun 		q=strchr(p,'>');
814*4882a593Smuzhiyun 		*q=0;
815*4882a593Smuzhiyun 		if (gethostname(hn,sizeof(hn))==-1) {
816*4882a593Smuzhiyun 			error(1,0, _("hostname too long\n"));
817*4882a593Smuzhiyun 		}
818*4882a593Smuzhiyun 		fprintf(stdout,"connect with lrz --tcp-client \"%s:%s\"\n",hn,p);
819*4882a593Smuzhiyun 		fflush(stdout);
820*4882a593Smuzhiyun 		/* ok, now that this file is sent we can switch to tcp */
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 		tcp_socket=tcp_accept(d);
823*4882a593Smuzhiyun 		dup2(tcp_socket,0);
824*4882a593Smuzhiyun 		dup2(tcp_socket,1);
825*4882a593Smuzhiyun 	}
826*4882a593Smuzhiyun 	if (tcp_flag==3) {
827*4882a593Smuzhiyun 		char buf[256];
828*4882a593Smuzhiyun 		char *p;
829*4882a593Smuzhiyun 		p=strchr(tcp_server_address,':');
830*4882a593Smuzhiyun 		if (!p)
831*4882a593Smuzhiyun 			error(1,0, _("illegal server address\n"));
832*4882a593Smuzhiyun 		*p++=0;
833*4882a593Smuzhiyun 		sprintf(buf,"[%s] <%s>\n",tcp_server_address,p);
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun 		fprintf(stdout,"connecting to %s\n",buf);
836*4882a593Smuzhiyun 		fflush(stdout);
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 		/* we need to switch to tcp mode */
839*4882a593Smuzhiyun 		tcp_socket=tcp_connect(buf);
840*4882a593Smuzhiyun 		dup2(tcp_socket,0);
841*4882a593Smuzhiyun 		dup2(tcp_socket,1);
842*4882a593Smuzhiyun 	}
843*4882a593Smuzhiyun #endif
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	io_mode(0,1);
846*4882a593Smuzhiyun 	readline_setup(0, HOWMANY, MAX_BLOCK*2);
847*4882a593Smuzhiyun 	//if (signal(SIGINT, bibi) == SIG_IGN)
848*4882a593Smuzhiyun 	//	signal(SIGINT, SIG_IGN);
849*4882a593Smuzhiyun 	//else
850*4882a593Smuzhiyun 	//	signal(SIGINT, bibi);
851*4882a593Smuzhiyun 	//signal(SIGTERM, bibi);
852*4882a593Smuzhiyun 	//signal(SIGPIPE, bibi);
853*4882a593Smuzhiyun 	xil_printf("Starto wait rx data\n\r");
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	if (wcreceive(0, NULL)==ERROR) {
856*4882a593Smuzhiyun 		exitcode=0200;
857*4882a593Smuzhiyun 		canit(0);
858*4882a593Smuzhiyun 	}
859*4882a593Smuzhiyun 	xil_printf("Receive done\n\r");
860*4882a593Smuzhiyun 	io_mode(0,0);
861*4882a593Smuzhiyun 	if (exitcode && !zmodem_requested)	/* bellow again with all thy might. */
862*4882a593Smuzhiyun 		canit(0);
863*4882a593Smuzhiyun 	if (Verbose)
864*4882a593Smuzhiyun 	{
865*4882a593Smuzhiyun 		fputs(stderr, "\r\n");
866*4882a593Smuzhiyun 		if (exitcode)
867*4882a593Smuzhiyun 			fputs(stderr, "Transfer incomplete\n");
868*4882a593Smuzhiyun 		else
869*4882a593Smuzhiyun 			fputs(stderr, "Transfer complete\n");
870*4882a593Smuzhiyun 	}
871*4882a593Smuzhiyun 	*rxsize = zmodem_offset;
872*4882a593Smuzhiyun 	return exitcode;
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun void
usage1(int exitcode)876*4882a593Smuzhiyun usage1(int exitcode)
877*4882a593Smuzhiyun {
878*4882a593Smuzhiyun 	usage(exitcode,NULL);
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun static void
usage(int exitcode,const char * what)882*4882a593Smuzhiyun usage(int exitcode, const char *what)
883*4882a593Smuzhiyun {
884*4882a593Smuzhiyun 	printf("TBD\n");
885*4882a593Smuzhiyun 	return;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun /*
889*4882a593Smuzhiyun  * Let's receive something already.
890*4882a593Smuzhiyun  */
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun static int
wcreceive(int argc,char ** argp)893*4882a593Smuzhiyun wcreceive(int argc, char **argp)
894*4882a593Smuzhiyun {
895*4882a593Smuzhiyun 	int c;
896*4882a593Smuzhiyun 	struct zm_fileinfo zi;
897*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
898*4882a593Smuzhiyun 	const char *shortname=NULL;;
899*4882a593Smuzhiyun #endif
900*4882a593Smuzhiyun 	zi.fname=NULL;
901*4882a593Smuzhiyun 	zi.modtime=0;
902*4882a593Smuzhiyun 	zi.mode=0;
903*4882a593Smuzhiyun 	zi.bytes_total=0;
904*4882a593Smuzhiyun 	zi.bytes_sent=0;
905*4882a593Smuzhiyun 	zi.bytes_received=0;
906*4882a593Smuzhiyun 	zi.bytes_skipped=0;
907*4882a593Smuzhiyun 	zi.eof_seen=0;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 	if (protocol!=ZM_XMODEM || argc==0) {
910*4882a593Smuzhiyun 		Crcflg=1;
911*4882a593Smuzhiyun 		if ( !Quiet)
912*4882a593Smuzhiyun 			vstringf(_("%s waiting to receive."), program_name);
913*4882a593Smuzhiyun 		if ((c=tryz())!=0) {
914*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
915*4882a593Smuzhiyun 			if (c == ZCOMPL) {
916*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
917*4882a593Smuzhiyun 				return OK;
918*4882a593Smuzhiyun 			}
919*4882a593Smuzhiyun 			if (c == ERROR) {
920*4882a593Smuzhiyun 				xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
921*4882a593Smuzhiyun 				goto fubar;
922*4882a593Smuzhiyun 			}
923*4882a593Smuzhiyun 			c = rzfiles(&zi);
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
926*4882a593Smuzhiyun 			shortname=NULL;
927*4882a593Smuzhiyun #endif
928*4882a593Smuzhiyun 			if (c) {
929*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
930*4882a593Smuzhiyun 				goto fubar;
931*4882a593Smuzhiyun 			}
932*4882a593Smuzhiyun 		} else {
933*4882a593Smuzhiyun 			for (;;) {
934*4882a593Smuzhiyun 				if (Verbose > 1
935*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
936*4882a593Smuzhiyun 					|| enable_syslog
937*4882a593Smuzhiyun #endif
938*4882a593Smuzhiyun 				)
939*4882a593Smuzhiyun 					timing(1,NULL);
940*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
941*4882a593Smuzhiyun 				shortname=NULL;
942*4882a593Smuzhiyun #endif
943*4882a593Smuzhiyun 				if (wcrxpn(&zi,secbuf)== ERROR) {
944*4882a593Smuzhiyun 					xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
945*4882a593Smuzhiyun 					goto fubar;
946*4882a593Smuzhiyun 				}
947*4882a593Smuzhiyun 				if (secbuf[0]==0) {
948*4882a593Smuzhiyun 					//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
949*4882a593Smuzhiyun 					return OK;
950*4882a593Smuzhiyun 				}
951*4882a593Smuzhiyun 				if (procheader(secbuf, &zi) == ERROR) {
952*4882a593Smuzhiyun 					xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
953*4882a593Smuzhiyun 					goto fubar;
954*4882a593Smuzhiyun 				}
955*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
956*4882a593Smuzhiyun 				shortname=strrchr(zi.fname,'/');
957*4882a593Smuzhiyun 				if (shortname)
958*4882a593Smuzhiyun 					shortname++;
959*4882a593Smuzhiyun 				else
960*4882a593Smuzhiyun 					shortname=zi.fname;
961*4882a593Smuzhiyun #endif
962*4882a593Smuzhiyun 				if (wcrx(&zi)==ERROR) {
963*4882a593Smuzhiyun 					xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
964*4882a593Smuzhiyun 					goto fubar;
965*4882a593Smuzhiyun 				}
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 				if (Verbose > 1
968*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
969*4882a593Smuzhiyun 					|| enable_syslog
970*4882a593Smuzhiyun #endif
971*4882a593Smuzhiyun 				) {
972*4882a593Smuzhiyun 					ulong d;
973*4882a593Smuzhiyun 					long bps;
974*4882a593Smuzhiyun 					d=timing(0,NULL);
975*4882a593Smuzhiyun 					if (d==0)
976*4882a593Smuzhiyun 						d=0.5; /* can happen if timing uses time() */
977*4882a593Smuzhiyun 					bps=(zi.bytes_received-zi.bytes_skipped)/d;
978*4882a593Smuzhiyun 
979*4882a593Smuzhiyun 					if (Verbose>1) {
980*4882a593Smuzhiyun 						vstringf(
981*4882a593Smuzhiyun 							_("\rBytes received: %7ld/%7ld   BPS:%-6ld                \r\n"),
982*4882a593Smuzhiyun 							(long) zi.bytes_received, (long) zi.bytes_total, bps);
983*4882a593Smuzhiyun 					}
984*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
985*4882a593Smuzhiyun 					if (enable_syslog)
986*4882a593Smuzhiyun 						lsyslog(LOG_INFO,"%s/%s: %ld Bytes, %ld BPS",
987*4882a593Smuzhiyun 							shortname,protname(),zi.bytes_received, bps);
988*4882a593Smuzhiyun #endif
989*4882a593Smuzhiyun 				}
990*4882a593Smuzhiyun 			}
991*4882a593Smuzhiyun 		}
992*4882a593Smuzhiyun 	} else {
993*4882a593Smuzhiyun 		printf("Only support ZModem\n");
994*4882a593Smuzhiyun #if 0
995*4882a593Smuzhiyun 		char dummy[128];
996*4882a593Smuzhiyun 		dummy[0]='\0'; /* pre-ANSI HPUX cc demands this */
997*4882a593Smuzhiyun 		dummy[1]='\0'; /* procheader uses name + 1 + strlen(name) */
998*4882a593Smuzhiyun 		zi.bytes_total = DEFBYTL;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 		if (Verbose > 1
1001*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1002*4882a593Smuzhiyun 			|| enable_syslog
1003*4882a593Smuzhiyun #endif
1004*4882a593Smuzhiyun 			)
1005*4882a593Smuzhiyun 			timing(1,NULL);
1006*4882a593Smuzhiyun 		procheader(dummy, &zi);
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun 		if (Pathname)
1009*4882a593Smuzhiyun 			free(Pathname);
1010*4882a593Smuzhiyun 		errno=0;
1011*4882a593Smuzhiyun 		Pathname=malloc(PATH_MAX+1);
1012*4882a593Smuzhiyun 		//if (!Pathname)
1013*4882a593Smuzhiyun 		//	error(1,0,_("out of memory"));
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 		strcpy(Pathname, *argp);
1016*4882a593Smuzhiyun 		checkpath(Pathname);
1017*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1018*4882a593Smuzhiyun 		shortname=strrchr(*argp,'/');
1019*4882a593Smuzhiyun 		if (shortname)
1020*4882a593Smuzhiyun 			shortname++;
1021*4882a593Smuzhiyun 		else
1022*4882a593Smuzhiyun 			shortname=*argp;
1023*4882a593Smuzhiyun #endif
1024*4882a593Smuzhiyun 		vchar('\n');
1025*4882a593Smuzhiyun 		vstringf(_("%s: ready to receive %s"), program_name, Pathname);
1026*4882a593Smuzhiyun 		vstring("\r\n");
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun 		//if ((fout=fopen(Pathname, "w")) == NULL) {
1029*4882a593Smuzhiyun 		if (0) {
1030*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1031*4882a593Smuzhiyun 			if (enable_syslog)
1032*4882a593Smuzhiyun 				lsyslog(LOG_ERR,"%s/%s: cannot open: %m",
1033*4882a593Smuzhiyun 					shortname,protname());
1034*4882a593Smuzhiyun #endif
1035*4882a593Smuzhiyun 			return ERROR;
1036*4882a593Smuzhiyun 		}
1037*4882a593Smuzhiyun 		if (wcrx(&zi)==ERROR) {
1038*4882a593Smuzhiyun 			goto fubar;
1039*4882a593Smuzhiyun 		}
1040*4882a593Smuzhiyun 		if (Verbose > 1
1041*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1042*4882a593Smuzhiyun 			|| enable_syslog
1043*4882a593Smuzhiyun #endif
1044*4882a593Smuzhiyun 	 		) {
1045*4882a593Smuzhiyun 			ulong d;
1046*4882a593Smuzhiyun 			long bps;
1047*4882a593Smuzhiyun 			d=timing(0,NULL);
1048*4882a593Smuzhiyun 			if (d==0)
1049*4882a593Smuzhiyun 				d=0.5; /* can happen if timing uses time() */
1050*4882a593Smuzhiyun 			bps=(zi.bytes_received-zi.bytes_skipped)/d;
1051*4882a593Smuzhiyun 			if (Verbose) {
1052*4882a593Smuzhiyun 				vstringf(
1053*4882a593Smuzhiyun 					_("\rBytes received: %7ld   BPS:%-6ld                \r\n"),
1054*4882a593Smuzhiyun 					(long) zi.bytes_received, bps);
1055*4882a593Smuzhiyun 			}
1056*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1057*4882a593Smuzhiyun 			if (enable_syslog)
1058*4882a593Smuzhiyun 				lsyslog(LOG_INFO,"%s/%s: %ld Bytes, %ld BPS",
1059*4882a593Smuzhiyun 					shortname,protname(),zi.bytes_received, bps);
1060*4882a593Smuzhiyun #endif
1061*4882a593Smuzhiyun 		}
1062*4882a593Smuzhiyun #endif
1063*4882a593Smuzhiyun 	}
1064*4882a593Smuzhiyun 	return OK;
1065*4882a593Smuzhiyun fubar:
1066*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1067*4882a593Smuzhiyun 	if (enable_syslog)
1068*4882a593Smuzhiyun 		lsyslog(LOG_ERR,"%s/%s: got error",
1069*4882a593Smuzhiyun 			shortname ? shortname : "no.name", protname());
1070*4882a593Smuzhiyun #endif
1071*4882a593Smuzhiyun 	canit(0);
1072*4882a593Smuzhiyun #if 0
1073*4882a593Smuzhiyun 	if (Topipe && fout) {
1074*4882a593Smuzhiyun 		pclose(fout);  return ERROR;
1075*4882a593Smuzhiyun 	}
1076*4882a593Smuzhiyun 	if (fout)
1077*4882a593Smuzhiyun 		fclose(fout);
1078*4882a593Smuzhiyun #endif
1079*4882a593Smuzhiyun 
1080*4882a593Smuzhiyun 	if (Restricted && Pathname) {
1081*4882a593Smuzhiyun 		//unlink(Pathname);
1082*4882a593Smuzhiyun 		vstringf(_("\r\n%s: %s removed.\r\n"), program_name, Pathname);
1083*4882a593Smuzhiyun 	}
1084*4882a593Smuzhiyun 	return ERROR;
1085*4882a593Smuzhiyun }
1086*4882a593Smuzhiyun 
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun /*
1089*4882a593Smuzhiyun  * Fetch a pathname from the other end as a C ctyle ASCIZ string.
1090*4882a593Smuzhiyun  * Length is indeterminate as long as less than Blklen
1091*4882a593Smuzhiyun  * A null string represents no more files (YMODEM)
1092*4882a593Smuzhiyun  */
1093*4882a593Smuzhiyun static int
wcrxpn(struct zm_fileinfo * zi,char * rpn)1094*4882a593Smuzhiyun wcrxpn(struct zm_fileinfo *zi, char *rpn)
1095*4882a593Smuzhiyun {
1096*4882a593Smuzhiyun 	register int c;
1097*4882a593Smuzhiyun 	size_t Blklen=0;		/* record length of received packets */
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun #ifdef NFGVMIN
1100*4882a593Smuzhiyun 	READLINE_PF(1);
1101*4882a593Smuzhiyun #else
1102*4882a593Smuzhiyun 	purgeline(0);
1103*4882a593Smuzhiyun #endif
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun et_tu:
1106*4882a593Smuzhiyun 	Firstsec=TRUE;
1107*4882a593Smuzhiyun 	zi->eof_seen=FALSE;
1108*4882a593Smuzhiyun 	sendline(Crcflg?WANTCRC:NAK);
1109*4882a593Smuzhiyun 	flushmo();
1110*4882a593Smuzhiyun 	purgeline(0); /* Do read next time ... */
1111*4882a593Smuzhiyun 	while ((c = wcgetsec(&Blklen, rpn, 100)) != 0) {
1112*4882a593Smuzhiyun 		if (c == WCEOT) {
1113*4882a593Smuzhiyun 			xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
1114*4882a593Smuzhiyun 			zperr( _("Pathname fetch returned EOT"));
1115*4882a593Smuzhiyun 			sendline(ACK);
1116*4882a593Smuzhiyun 			flushmo();
1117*4882a593Smuzhiyun 			purgeline(0);	/* Do read next time ... */
1118*4882a593Smuzhiyun 			READLINE_PF(1);
1119*4882a593Smuzhiyun 			goto et_tu;
1120*4882a593Smuzhiyun 		}
1121*4882a593Smuzhiyun 		return ERROR;
1122*4882a593Smuzhiyun 	}
1123*4882a593Smuzhiyun 	sendline(ACK);
1124*4882a593Smuzhiyun 	flushmo();
1125*4882a593Smuzhiyun 	return OK;
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun /*
1129*4882a593Smuzhiyun  * Adapted from CMODEM13.C, written by
1130*4882a593Smuzhiyun  * Jack M. Wierda and Roderick W. Hart
1131*4882a593Smuzhiyun  */
1132*4882a593Smuzhiyun static int
wcrx(struct zm_fileinfo * zi)1133*4882a593Smuzhiyun wcrx(struct zm_fileinfo *zi)
1134*4882a593Smuzhiyun {
1135*4882a593Smuzhiyun 	register int sectnum, sectcurr;
1136*4882a593Smuzhiyun 	register char sendchar;
1137*4882a593Smuzhiyun 	size_t Blklen;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	Firstsec=TRUE;sectnum=0;
1140*4882a593Smuzhiyun 	zi->eof_seen=FALSE;
1141*4882a593Smuzhiyun 	sendchar=Crcflg?WANTCRC:NAK;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	for (;;) {
1144*4882a593Smuzhiyun 		sendline(sendchar);	/* send it now, we're ready! */
1145*4882a593Smuzhiyun 		flushmo();
1146*4882a593Smuzhiyun 		purgeline(0);	/* Do read next time ... */
1147*4882a593Smuzhiyun 		sectcurr=wcgetsec(&Blklen, secbuf,
1148*4882a593Smuzhiyun 			(unsigned int) ((sectnum&0177) ? 50 : 130));
1149*4882a593Smuzhiyun 		report(sectcurr);
1150*4882a593Smuzhiyun 		if (sectcurr==((sectnum+1) &0377)) {
1151*4882a593Smuzhiyun 			sectnum++;
1152*4882a593Smuzhiyun 			/* if using xmodem we don't know how long a file is */
1153*4882a593Smuzhiyun 			if (zi->bytes_total && R_BYTESLEFT(zi) < Blklen)
1154*4882a593Smuzhiyun 				Blklen=R_BYTESLEFT(zi);
1155*4882a593Smuzhiyun 			zi->bytes_received+=Blklen;
1156*4882a593Smuzhiyun 			if (putsec(zi, secbuf, Blklen)==ERROR) {
1157*4882a593Smuzhiyun 				return ERROR;
1158*4882a593Smuzhiyun 			}
1159*4882a593Smuzhiyun 			sendchar=ACK;
1160*4882a593Smuzhiyun 		}
1161*4882a593Smuzhiyun 		else if (sectcurr==(sectnum&0377)) {
1162*4882a593Smuzhiyun 			zperr( _("Received dup Sector"));
1163*4882a593Smuzhiyun 			sendchar=ACK;
1164*4882a593Smuzhiyun 		}
1165*4882a593Smuzhiyun 		else if (sectcurr==WCEOT) {
1166*4882a593Smuzhiyun 			if (closeit(zi)) {
1167*4882a593Smuzhiyun 				return ERROR;
1168*4882a593Smuzhiyun 			}
1169*4882a593Smuzhiyun 			sendline(ACK);
1170*4882a593Smuzhiyun 			flushmo();
1171*4882a593Smuzhiyun 			purgeline(0);	/* Do read next time ... */
1172*4882a593Smuzhiyun 			return OK;
1173*4882a593Smuzhiyun 		}
1174*4882a593Smuzhiyun 		else if (sectcurr==ERROR) {
1175*4882a593Smuzhiyun 			return ERROR;
1176*4882a593Smuzhiyun 		}
1177*4882a593Smuzhiyun 		else {
1178*4882a593Smuzhiyun 			zperr( _("Sync Error"));
1179*4882a593Smuzhiyun 			return ERROR;
1180*4882a593Smuzhiyun 		}
1181*4882a593Smuzhiyun 	}
1182*4882a593Smuzhiyun }
1183*4882a593Smuzhiyun 
1184*4882a593Smuzhiyun /*
1185*4882a593Smuzhiyun  * Wcgetsec fetches a Ward Christensen type sector.
1186*4882a593Smuzhiyun  * Returns sector number encountered or ERROR if valid sector not received,
1187*4882a593Smuzhiyun  * or CAN CAN received
1188*4882a593Smuzhiyun  * or WCEOT if eot sector
1189*4882a593Smuzhiyun  * time is timeout for first char, set to 4 seconds thereafter
1190*4882a593Smuzhiyun  ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
1191*4882a593Smuzhiyun  *    (Caller must do that when he is good and ready to get next sector)
1192*4882a593Smuzhiyun  */
1193*4882a593Smuzhiyun static int
wcgetsec(size_t * Blklen,char * rxbuf,unsigned int maxtime)1194*4882a593Smuzhiyun wcgetsec(size_t *Blklen, char *rxbuf, unsigned int maxtime)
1195*4882a593Smuzhiyun {
1196*4882a593Smuzhiyun 	register int checksum, wcj, firstch;
1197*4882a593Smuzhiyun 	register unsigned short oldcrc;
1198*4882a593Smuzhiyun 	register char *p;
1199*4882a593Smuzhiyun 	int sectcurr;
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 	for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
1202*4882a593Smuzhiyun 
1203*4882a593Smuzhiyun 		if ((firstch=READLINE_PF(maxtime))==STX) {
1204*4882a593Smuzhiyun 			*Blklen=1024; goto get2;
1205*4882a593Smuzhiyun 		}
1206*4882a593Smuzhiyun 		if (firstch==SOH) {
1207*4882a593Smuzhiyun 			*Blklen=128;
1208*4882a593Smuzhiyun get2:
1209*4882a593Smuzhiyun 			sectcurr=READLINE_PF(1);
1210*4882a593Smuzhiyun 			if ((sectcurr+(oldcrc=READLINE_PF(1)))==0377) {
1211*4882a593Smuzhiyun 				oldcrc=checksum=0;
1212*4882a593Smuzhiyun 				for (p=rxbuf,wcj=*Blklen; --wcj>=0; ) {
1213*4882a593Smuzhiyun 					if ((firstch=READLINE_PF(1)) < 0)
1214*4882a593Smuzhiyun 						goto bilge;
1215*4882a593Smuzhiyun 					oldcrc=updcrc(firstch, oldcrc);
1216*4882a593Smuzhiyun 					checksum += (*p++ = firstch);
1217*4882a593Smuzhiyun 				}
1218*4882a593Smuzhiyun 				if ((firstch=READLINE_PF(1)) < 0)
1219*4882a593Smuzhiyun 					goto bilge;
1220*4882a593Smuzhiyun 				if (Crcflg) {
1221*4882a593Smuzhiyun 					oldcrc=updcrc(firstch, oldcrc);
1222*4882a593Smuzhiyun 					if ((firstch=READLINE_PF(1)) < 0)
1223*4882a593Smuzhiyun 						goto bilge;
1224*4882a593Smuzhiyun 					oldcrc=updcrc(firstch, oldcrc);
1225*4882a593Smuzhiyun 					if (oldcrc & 0xFFFF)
1226*4882a593Smuzhiyun 						zperr( _("CRC"));
1227*4882a593Smuzhiyun 					else {
1228*4882a593Smuzhiyun 						Firstsec=FALSE;
1229*4882a593Smuzhiyun 						return sectcurr;
1230*4882a593Smuzhiyun 					}
1231*4882a593Smuzhiyun 				}
1232*4882a593Smuzhiyun 				else if (((checksum-firstch)&0377)==0) {
1233*4882a593Smuzhiyun 					Firstsec=FALSE;
1234*4882a593Smuzhiyun 					return sectcurr;
1235*4882a593Smuzhiyun 				}
1236*4882a593Smuzhiyun 				else
1237*4882a593Smuzhiyun 					zperr( _("Checksum"));
1238*4882a593Smuzhiyun 			}
1239*4882a593Smuzhiyun 			else
1240*4882a593Smuzhiyun 				zperr(_("Sector number garbled"));
1241*4882a593Smuzhiyun 		}
1242*4882a593Smuzhiyun 		/* make sure eot really is eot and not just mixmash */
1243*4882a593Smuzhiyun #if 1
1244*4882a593Smuzhiyun 		else if (firstch==EOT && READLINE_PF(1)==TIMEOUT)
1245*4882a593Smuzhiyun 			return WCEOT;
1246*4882a593Smuzhiyun #else
1247*4882a593Smuzhiyun 		else if (firstch==EOT && READLINE_PF>0)
1248*4882a593Smuzhiyun 			return WCEOT;
1249*4882a593Smuzhiyun #endif
1250*4882a593Smuzhiyun 		else if (firstch==CAN) {
1251*4882a593Smuzhiyun 			if (Lastrx==CAN) {
1252*4882a593Smuzhiyun 				zperr( _("Sender Cancelled"));
1253*4882a593Smuzhiyun 				return ERROR;
1254*4882a593Smuzhiyun 			} else {
1255*4882a593Smuzhiyun 				Lastrx=CAN;
1256*4882a593Smuzhiyun 				continue;
1257*4882a593Smuzhiyun 			}
1258*4882a593Smuzhiyun 		}
1259*4882a593Smuzhiyun 		else if (firstch==TIMEOUT) {
1260*4882a593Smuzhiyun 			if (Firstsec)
1261*4882a593Smuzhiyun 				goto humbug;
1262*4882a593Smuzhiyun bilge:
1263*4882a593Smuzhiyun 			zperr( _("TIMEOUT"));
1264*4882a593Smuzhiyun 		}
1265*4882a593Smuzhiyun 		else
1266*4882a593Smuzhiyun 			zperr( _("Got 0%o sector header"), firstch);
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun humbug:
1269*4882a593Smuzhiyun 		Lastrx=0;
1270*4882a593Smuzhiyun 		{
1271*4882a593Smuzhiyun 			int cnt=1000;
1272*4882a593Smuzhiyun 			while(cnt-- && READLINE_PF(1)!=TIMEOUT)
1273*4882a593Smuzhiyun 				;
1274*4882a593Smuzhiyun 		}
1275*4882a593Smuzhiyun 		if (Firstsec) {
1276*4882a593Smuzhiyun 			sendline(Crcflg?WANTCRC:NAK);
1277*4882a593Smuzhiyun 			flushmo();
1278*4882a593Smuzhiyun 			purgeline(0);	/* Do read next time ... */
1279*4882a593Smuzhiyun 		} else {
1280*4882a593Smuzhiyun 			maxtime=40;
1281*4882a593Smuzhiyun 			sendline(NAK);
1282*4882a593Smuzhiyun 			flushmo();
1283*4882a593Smuzhiyun 			purgeline(0);	/* Do read next time ... */
1284*4882a593Smuzhiyun 		}
1285*4882a593Smuzhiyun 	}
1286*4882a593Smuzhiyun 	/* try to stop the bubble machine. */
1287*4882a593Smuzhiyun 	canit(0);
1288*4882a593Smuzhiyun 	return ERROR;
1289*4882a593Smuzhiyun }
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun #define ZCRC_DIFFERS (ERROR+1)
1292*4882a593Smuzhiyun #define ZCRC_EQUAL (ERROR+2)
1293*4882a593Smuzhiyun /*
1294*4882a593Smuzhiyun  * do ZCRC-Check for open file f.
1295*4882a593Smuzhiyun  * check at most check_bytes bytes (crash recovery). if 0 -> whole file.
1296*4882a593Smuzhiyun  * remote file size is remote_bytes.
1297*4882a593Smuzhiyun  */
zmodem_buf_getc(int c)1298*4882a593Smuzhiyun int zmodem_buf_getc(int c)
1299*4882a593Smuzhiyun {
1300*4882a593Smuzhiyun 	return *(unsigned char *)(zmodem_addr+c);
1301*4882a593Smuzhiyun }
1302*4882a593Smuzhiyun static int
do_crc_check(void * f,size_t remote_bytes,size_t check_bytes)1303*4882a593Smuzhiyun do_crc_check(void *f, size_t remote_bytes, size_t check_bytes)
1304*4882a593Smuzhiyun {
1305*4882a593Smuzhiyun 	//struct stat st;
1306*4882a593Smuzhiyun 	unsigned long crc;
1307*4882a593Smuzhiyun 	unsigned long rcrc;
1308*4882a593Smuzhiyun 	size_t n;
1309*4882a593Smuzhiyun 	int c;
1310*4882a593Smuzhiyun 	int t1=0,t2=0;
1311*4882a593Smuzhiyun 	int i;
1312*4882a593Smuzhiyun #if 0
1313*4882a593Smuzhiyun 	if (-1==fstat(fileno(f),&st)) {
1314*4882a593Smuzhiyun 		DO_SYSLOG((LOG_ERR,"cannot fstat open file: %s",strerror(errno)));
1315*4882a593Smuzhiyun 		return ERROR;
1316*4882a593Smuzhiyun 	}
1317*4882a593Smuzhiyun #endif
1318*4882a593Smuzhiyun 	//if (check_bytes==0 && ((size_t) st.st_size)!=remote_bytes)
1319*4882a593Smuzhiyun 	//	return ZCRC_DIFFERS; /* shortcut */
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun 	crc=0xFFFFFFFFL;
1322*4882a593Smuzhiyun 	n=check_bytes;
1323*4882a593Smuzhiyun 	if (n==0)
1324*4882a593Smuzhiyun 		n=zmodem_offset;
1325*4882a593Smuzhiyun 	//while (n-- && ((c = getc(f)) != EOF))
1326*4882a593Smuzhiyun 	for(i=0;i<zmodem_offset;i++) {
1327*4882a593Smuzhiyun 		c = zmodem_buf_getc(i);
1328*4882a593Smuzhiyun 		crc = UPDC32(c, crc);
1329*4882a593Smuzhiyun 	}
1330*4882a593Smuzhiyun 	crc = ~crc;
1331*4882a593Smuzhiyun 	//clearerr(f);  /* Clear EOF */
1332*4882a593Smuzhiyun 	//fseek(f, 0L, 0);
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun 	while (t1<3) {
1335*4882a593Smuzhiyun 		stohdr(check_bytes);
1336*4882a593Smuzhiyun 		zshhdr(ZCRC, Txhdr);
1337*4882a593Smuzhiyun 		while(t2<3) {
1338*4882a593Smuzhiyun 			size_t tmp;
1339*4882a593Smuzhiyun 			c = zgethdr(Rxhdr, 0, &tmp);
1340*4882a593Smuzhiyun 			rcrc=(unsigned long) tmp;
1341*4882a593Smuzhiyun 			switch (c) {
1342*4882a593Smuzhiyun 			default: /* ignore */
1343*4882a593Smuzhiyun 				break;
1344*4882a593Smuzhiyun 			case ZFIN:
1345*4882a593Smuzhiyun 				return ERROR;
1346*4882a593Smuzhiyun 			case ZRINIT:
1347*4882a593Smuzhiyun 				return ERROR;
1348*4882a593Smuzhiyun 			case ZCAN:
1349*4882a593Smuzhiyun 				if (Verbose)
1350*4882a593Smuzhiyun 					vstringf(_("got ZCAN"));
1351*4882a593Smuzhiyun 				return ERROR;
1352*4882a593Smuzhiyun 				break;
1353*4882a593Smuzhiyun 			case ZCRC:
1354*4882a593Smuzhiyun 				if (crc!=rcrc)
1355*4882a593Smuzhiyun 					return ZCRC_DIFFERS;
1356*4882a593Smuzhiyun 				return ZCRC_EQUAL;
1357*4882a593Smuzhiyun 				break;
1358*4882a593Smuzhiyun 			}
1359*4882a593Smuzhiyun 		}
1360*4882a593Smuzhiyun 	}
1361*4882a593Smuzhiyun 	return ERROR;
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun /*
1365*4882a593Smuzhiyun  * Process incoming file information header
1366*4882a593Smuzhiyun  */
1367*4882a593Smuzhiyun static int
procheader(char * name,struct zm_fileinfo * zi)1368*4882a593Smuzhiyun procheader(char *name, struct zm_fileinfo *zi)
1369*4882a593Smuzhiyun {
1370*4882a593Smuzhiyun 	__maybe_unused const char *openmode;
1371*4882a593Smuzhiyun 	char *p;
1372*4882a593Smuzhiyun 	static char *name_static=NULL;
1373*4882a593Smuzhiyun 	char *nameend;
1374*4882a593Smuzhiyun 
1375*4882a593Smuzhiyun 	if (name_static)
1376*4882a593Smuzhiyun 		free(name_static);
1377*4882a593Smuzhiyun 	if (junk_path) {
1378*4882a593Smuzhiyun 		p=strrchr(name,'/');
1379*4882a593Smuzhiyun 		if (p) {
1380*4882a593Smuzhiyun 			p++;
1381*4882a593Smuzhiyun 			if (!*p) {
1382*4882a593Smuzhiyun 				/* alert - file name ended in with a / */
1383*4882a593Smuzhiyun 				if (Verbose)
1384*4882a593Smuzhiyun 					vstringf(_("file name ends with a /, skipped: %s\n"),name);
1385*4882a593Smuzhiyun 				DO_SYSLOG((LOG_ERR,"file name ends with a /, skipped: %s", name));
1386*4882a593Smuzhiyun 				return ERROR;
1387*4882a593Smuzhiyun 			}
1388*4882a593Smuzhiyun 			name=p;
1389*4882a593Smuzhiyun 		}
1390*4882a593Smuzhiyun 	}
1391*4882a593Smuzhiyun 	name_static=malloc(strlen(name)+1);
1392*4882a593Smuzhiyun 	//if (!name_static)
1393*4882a593Smuzhiyun 	//	error(1,0,_("out of memory"));
1394*4882a593Smuzhiyun 	strcpy(name_static,name);
1395*4882a593Smuzhiyun 	zi->fname=name_static;
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun 	if (Verbose>2) {
1398*4882a593Smuzhiyun 		vstringf(_("zmanag=%d, Lzmanag=%d\n"),zmanag,Lzmanag);
1399*4882a593Smuzhiyun 		vstringf(_("zconv=%d\n"),zconv);
1400*4882a593Smuzhiyun 	}
1401*4882a593Smuzhiyun 
1402*4882a593Smuzhiyun 	/* set default parameters and overrides */
1403*4882a593Smuzhiyun 	openmode = "w";
1404*4882a593Smuzhiyun 	Thisbinary = (!Rxascii) || Rxbinary;
1405*4882a593Smuzhiyun 	if (Lzmanag)
1406*4882a593Smuzhiyun 		zmanag = Lzmanag;
1407*4882a593Smuzhiyun 
1408*4882a593Smuzhiyun 	/*
1409*4882a593Smuzhiyun 	 *  Process ZMODEM remote file management requests
1410*4882a593Smuzhiyun 	 */
1411*4882a593Smuzhiyun 	if (!Rxbinary && zconv == ZCNL)	/* Remote ASCII override */
1412*4882a593Smuzhiyun 		Thisbinary = 0;
1413*4882a593Smuzhiyun 	if (zconv == ZCBIN)	/* Remote Binary override */
1414*4882a593Smuzhiyun 		Thisbinary = TRUE;
1415*4882a593Smuzhiyun 	if (Thisbinary && zconv == ZCBIN && try_resume)
1416*4882a593Smuzhiyun 		zconv=ZCRESUM;
1417*4882a593Smuzhiyun 	if (zmanag == ZF1_ZMAPND && zconv!=ZCRESUM)
1418*4882a593Smuzhiyun 		openmode = "a";
1419*4882a593Smuzhiyun 	if (skip_if_not_found)
1420*4882a593Smuzhiyun 		openmode="r+";
1421*4882a593Smuzhiyun 
1422*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
1423*4882a593Smuzhiyun 	in_timesync=0;
1424*4882a593Smuzhiyun 	if (timesync_flag && 0==strcmp(name,"$time$.t"))
1425*4882a593Smuzhiyun 		in_timesync=1;
1426*4882a593Smuzhiyun #endif
1427*4882a593Smuzhiyun 	in_tcpsync=0;
1428*4882a593Smuzhiyun 	if (tcpsync_flag && 0==strcmp(name,"$tcp$.t"))
1429*4882a593Smuzhiyun 		in_tcpsync=1;
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun 	zi->bytes_total = DEFBYTL;
1432*4882a593Smuzhiyun 	zi->mode = 0;
1433*4882a593Smuzhiyun 	zi->eof_seen = 0;
1434*4882a593Smuzhiyun 	zi->modtime = 0;
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun 	nameend = name + 1 + strlen(name);
1437*4882a593Smuzhiyun #if 0
1438*4882a593Smuzhiyun 	if (*nameend) {	/* file coming from Unix or DOS system */
1439*4882a593Smuzhiyun 		long modtime;
1440*4882a593Smuzhiyun 		long bytes_total;
1441*4882a593Smuzhiyun 		int mode;
1442*4882a593Smuzhiyun 		sscanf(nameend, "%ld%lo%o", &bytes_total, &modtime, &mode);
1443*4882a593Smuzhiyun 		zi->modtime=modtime;
1444*4882a593Smuzhiyun 		zi->bytes_total=bytes_total;
1445*4882a593Smuzhiyun 		zi->mode=mode;
1446*4882a593Smuzhiyun 		if (zi->mode & UNIXFILE)
1447*4882a593Smuzhiyun 			++Thisbinary;
1448*4882a593Smuzhiyun 	}
1449*4882a593Smuzhiyun #endif
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	/* Check for existing file */
1452*4882a593Smuzhiyun 	if (zconv != ZCRESUM && !Rxclob && (zmanag&ZF1_ZMMASK) != ZF1_ZMCLOB
1453*4882a593Smuzhiyun 		&& (zmanag&ZF1_ZMMASK) != ZF1_ZMAPND
1454*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
1455*4882a593Smuzhiyun 	    && !in_timesync
1456*4882a593Smuzhiyun 	    && !in_tcpsync
1457*4882a593Smuzhiyun #endif
1458*4882a593Smuzhiyun 		//&& (fout=fopen(name, "r"))) {
1459*4882a593Smuzhiyun 		){
1460*4882a593Smuzhiyun 		//struct stat sta;
1461*4882a593Smuzhiyun 		char *tmpname;
1462*4882a593Smuzhiyun 		char *ptr;
1463*4882a593Smuzhiyun 		int i  __maybe_unused;
1464*4882a593Smuzhiyun 		if (zmanag == ZF1_ZMNEW || zmanag==ZF1_ZMNEWL) {
1465*4882a593Smuzhiyun #if 0
1466*4882a593Smuzhiyun 			if (-1==fstat(fileno(fout),&sta)) {
1467*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1468*4882a593Smuzhiyun 				int e=errno;
1469*4882a593Smuzhiyun #endif
1470*4882a593Smuzhiyun 				if (Verbose)
1471*4882a593Smuzhiyun 					vstringf(_("file exists, skipped: %s\n"),name);
1472*4882a593Smuzhiyun 				DO_SYSLOG((LOG_ERR,"cannot fstat open file %s: %s",
1473*4882a593Smuzhiyun 					name,strerror(e)));
1474*4882a593Smuzhiyun 				return ERROR;
1475*4882a593Smuzhiyun 			}
1476*4882a593Smuzhiyun #endif
1477*4882a593Smuzhiyun 			if (zmanag == ZF1_ZMNEW) {
1478*4882a593Smuzhiyun #if 0
1479*4882a593Smuzhiyun 				if (sta.st_mtime > zi->modtime) {
1480*4882a593Smuzhiyun 					DO_SYSLOG((LOG_INFO,"skipping %s: newer file exists", name));
1481*4882a593Smuzhiyun 					return ERROR; /* skips file */
1482*4882a593Smuzhiyun 				}
1483*4882a593Smuzhiyun #endif
1484*4882a593Smuzhiyun 			} else {
1485*4882a593Smuzhiyun 				/* newer-or-longer */
1486*4882a593Smuzhiyun #if 0
1487*4882a593Smuzhiyun 				if (((size_t) sta.st_size) >= zi->bytes_total
1488*4882a593Smuzhiyun 					&& sta.st_mtime > zi->modtime) {
1489*4882a593Smuzhiyun 					DO_SYSLOG((LOG_INFO,"skipping %s: longer+newer file exists", name));
1490*4882a593Smuzhiyun 					return ERROR; /* skips file */
1491*4882a593Smuzhiyun 				}
1492*4882a593Smuzhiyun #endif
1493*4882a593Smuzhiyun 			}
1494*4882a593Smuzhiyun 			//fclose(fout);
1495*4882a593Smuzhiyun 		} else if (zmanag==ZF1_ZMCRC) {
1496*4882a593Smuzhiyun 			int r=do_crc_check(NULL,zi->bytes_total,0);
1497*4882a593Smuzhiyun 			if (r==ERROR) {
1498*4882a593Smuzhiyun 				//fclose(fout);
1499*4882a593Smuzhiyun 				return ERROR;
1500*4882a593Smuzhiyun 			}
1501*4882a593Smuzhiyun 			if (r!=ZCRC_DIFFERS) {
1502*4882a593Smuzhiyun 				return ERROR; /* skips */
1503*4882a593Smuzhiyun 			}
1504*4882a593Smuzhiyun 			//fclose(fout);
1505*4882a593Smuzhiyun 		} else {
1506*4882a593Smuzhiyun 			size_t namelen;
1507*4882a593Smuzhiyun 			//fclose(fout);
1508*4882a593Smuzhiyun 			if ((zmanag & ZF1_ZMMASK)!=ZF1_ZMCHNG) {
1509*4882a593Smuzhiyun 				if (Verbose)
1510*4882a593Smuzhiyun 					vstringf(_("file exists, skipped: %s\n"),name);
1511*4882a593Smuzhiyun 				return ERROR;
1512*4882a593Smuzhiyun 			}
1513*4882a593Smuzhiyun 			/* try to rename */
1514*4882a593Smuzhiyun 			namelen=strlen(name);
1515*4882a593Smuzhiyun 			tmpname=alloca(namelen+5);
1516*4882a593Smuzhiyun 			memcpy(tmpname,name,namelen);
1517*4882a593Smuzhiyun 			ptr=tmpname+namelen;
1518*4882a593Smuzhiyun 			*ptr++='.';
1519*4882a593Smuzhiyun 			i=0;
1520*4882a593Smuzhiyun 			printf("Not going to happend\n");
1521*4882a593Smuzhiyun #if 0
1522*4882a593Smuzhiyun 			do {
1523*4882a593Smuzhiyun 				sprintf(ptr,"%d",i++);
1524*4882a593Smuzhiyun 			} while (i<1000 && stat(tmpname,&sta)==0);
1525*4882a593Smuzhiyun 			if (i==1000)
1526*4882a593Smuzhiyun 				return ERROR;
1527*4882a593Smuzhiyun 			free(name_static);
1528*4882a593Smuzhiyun 			name_static=malloc(strlen(tmpname)+1);
1529*4882a593Smuzhiyun 			//if (!name_static)
1530*4882a593Smuzhiyun 			//	error(1,0,_("out of memory"));
1531*4882a593Smuzhiyun 			strcpy(name_static,tmpname);
1532*4882a593Smuzhiyun 			zi->fname=name_static;
1533*4882a593Smuzhiyun #endif
1534*4882a593Smuzhiyun 		}
1535*4882a593Smuzhiyun 	}
1536*4882a593Smuzhiyun 
1537*4882a593Smuzhiyun 	if (!*nameend) {		/* File coming from CP/M system */
1538*4882a593Smuzhiyun 		for (p=name_static; *p; ++p)		/* change / to _ */
1539*4882a593Smuzhiyun 			if ( *p == '/')
1540*4882a593Smuzhiyun 				*p = '_';
1541*4882a593Smuzhiyun 
1542*4882a593Smuzhiyun 		if ( *--p == '.')		/* zap trailing period */
1543*4882a593Smuzhiyun 			*p = 0;
1544*4882a593Smuzhiyun 	}
1545*4882a593Smuzhiyun 
1546*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
1547*4882a593Smuzhiyun 	if (in_timesync)
1548*4882a593Smuzhiyun 	{
1549*4882a593Smuzhiyun 		long t=time(0);
1550*4882a593Smuzhiyun 		long d=t-zi->modtime;
1551*4882a593Smuzhiyun 		if (d<0)
1552*4882a593Smuzhiyun 			d=0;
1553*4882a593Smuzhiyun 		if ((Verbose && d>60) || Verbose > 1)
1554*4882a593Smuzhiyun 			vstringf(_("TIMESYNC: here %ld, remote %ld, diff %ld seconds\n"),
1555*4882a593Smuzhiyun 			(long) t, (long) zi->modtime, d);
1556*4882a593Smuzhiyun #ifdef HAVE_SETTIMEOFDAY
1557*4882a593Smuzhiyun 		if (timesync_flag > 1 && d > 10)
1558*4882a593Smuzhiyun 		{
1559*4882a593Smuzhiyun 			struct timeval tv;
1560*4882a593Smuzhiyun 			tv.tv_sec=zi->modtime;
1561*4882a593Smuzhiyun 			tv.tv_usec=0;
1562*4882a593Smuzhiyun 			//if (settimeofday(&tv,NULL))
1563*4882a593Smuzhiyun 			//	vstringf(_("TIMESYNC: cannot set time: %s\n"),
1564*4882a593Smuzhiyun 			//		strerror(errno));
1565*4882a593Smuzhiyun 		}
1566*4882a593Smuzhiyun #endif
1567*4882a593Smuzhiyun 		return ERROR; /* skips file */
1568*4882a593Smuzhiyun 	}
1569*4882a593Smuzhiyun #endif /* ENABLE_TIMESYNC */
1570*4882a593Smuzhiyun #if 0
1571*4882a593Smuzhiyun 	if (in_tcpsync) {
1572*4882a593Smuzhiyun 		fout=tmpfile();
1573*4882a593Smuzhiyun 		if (!fout) {
1574*4882a593Smuzhiyun 			error(1,errno,_("cannot tmpfile() for tcp protocol synchronization"));
1575*4882a593Smuzhiyun 		}
1576*4882a593Smuzhiyun 		zi->bytes_received=0;
1577*4882a593Smuzhiyun 		return OK;
1578*4882a593Smuzhiyun 	}
1579*4882a593Smuzhiyun #endif
1580*4882a593Smuzhiyun 
1581*4882a593Smuzhiyun 
1582*4882a593Smuzhiyun 	if (!zmodem_requested && MakeLCPathname && !IsAnyLower(name_static)
1583*4882a593Smuzhiyun 	  && !(zi->mode&UNIXFILE))
1584*4882a593Smuzhiyun 		uncaps(name_static);
1585*4882a593Smuzhiyun 	if (Topipe > 0) {
1586*4882a593Smuzhiyun #if 0
1587*4882a593Smuzhiyun 		if (Pathname)
1588*4882a593Smuzhiyun 			free(Pathname);
1589*4882a593Smuzhiyun 		Pathname=malloc((PATH_MAX)*2);
1590*4882a593Smuzhiyun 		if (!Pathname)
1591*4882a593Smuzhiyun 			error(1,0,_("out of memory"));
1592*4882a593Smuzhiyun 		sprintf(Pathname, "%s %s", program_name+2, name_static);
1593*4882a593Smuzhiyun 		if (Verbose) {
1594*4882a593Smuzhiyun 			vstringf("%s: %s %s\n",
1595*4882a593Smuzhiyun 				_("Topipe"),
1596*4882a593Smuzhiyun 				Pathname, Thisbinary?"BIN":"ASCII");
1597*4882a593Smuzhiyun 		}
1598*4882a593Smuzhiyun 
1599*4882a593Smuzhiyun 		if ((fout=popen(Pathname, "w")) == NULL)
1600*4882a593Smuzhiyun 			return ERROR;
1601*4882a593Smuzhiyun #endif
1602*4882a593Smuzhiyun 	} else {
1603*4882a593Smuzhiyun 		if (protocol==ZM_XMODEM)
1604*4882a593Smuzhiyun 			/* we don't have the filename yet */
1605*4882a593Smuzhiyun 			return OK; /* dummy */
1606*4882a593Smuzhiyun 		if (Pathname)
1607*4882a593Smuzhiyun 			free(Pathname);
1608*4882a593Smuzhiyun 		Pathname=malloc((PATH_MAX)*2);
1609*4882a593Smuzhiyun 		//if (!Pathname)
1610*4882a593Smuzhiyun 		//	error(1,0,_("out of memory"));
1611*4882a593Smuzhiyun 		strcpy(Pathname, name_static);
1612*4882a593Smuzhiyun 		if (Verbose) {
1613*4882a593Smuzhiyun 			/* overwrite the "waiting to receive" line */
1614*4882a593Smuzhiyun 			vstring("\r                                                                     \r");
1615*4882a593Smuzhiyun 			vstringf(_("Receiving: %s\n"), name_static);
1616*4882a593Smuzhiyun 		}
1617*4882a593Smuzhiyun 		checkpath(name_static);
1618*4882a593Smuzhiyun 		if (Nflag)
1619*4882a593Smuzhiyun 		{
1620*4882a593Smuzhiyun 			/* cast because we might not have a prototyp for strdup :-/ */
1621*4882a593Smuzhiyun 			free(name_static);
1622*4882a593Smuzhiyun 			name_static=(char *) strdup("/dev/null");
1623*4882a593Smuzhiyun 			if (!name_static)
1624*4882a593Smuzhiyun 			{
1625*4882a593Smuzhiyun 				fprintf(stderr,"%s: %s\n", program_name, _("out of memory"));
1626*4882a593Smuzhiyun 				return -1;
1627*4882a593Smuzhiyun 			}
1628*4882a593Smuzhiyun 		}
1629*4882a593Smuzhiyun #ifdef OMEN
1630*4882a593Smuzhiyun #if 0
1631*4882a593Smuzhiyun asdfadsf
1632*4882a593Smuzhiyun 		/* looks like a security hole -- uwe */
1633*4882a593Smuzhiyun 		if (name_static[0] == '!' || name_static[0] == '|') {
1634*4882a593Smuzhiyun 			if ( !(fout = popen(name_static+1, "w"))) {
1635*4882a593Smuzhiyun 				return ERROR;
1636*4882a593Smuzhiyun 			}
1637*4882a593Smuzhiyun 			Topipe = -1;  return(OK);
1638*4882a593Smuzhiyun 		}
1639*4882a593Smuzhiyun #endif
1640*4882a593Smuzhiyun #endif
1641*4882a593Smuzhiyun 		if (Thisbinary && zconv==ZCRESUM) {
1642*4882a593Smuzhiyun 			//struct stat st;
1643*4882a593Smuzhiyun 			//fout = fopen(name_static, "r+");
1644*4882a593Smuzhiyun 			//if (fout && 0==fstat(fileno(fout),&st))
1645*4882a593Smuzhiyun 			if(1)
1646*4882a593Smuzhiyun 			{
1647*4882a593Smuzhiyun 				printf("This should not happened\n");
1648*4882a593Smuzhiyun 				int can_resume=FALSE;
1649*4882a593Smuzhiyun 				if (zmanag==ZF1_ZMCRC) {
1650*4882a593Smuzhiyun 					int r=do_crc_check(NULL,zi->bytes_total,0);
1651*4882a593Smuzhiyun 					if (r==ERROR) {
1652*4882a593Smuzhiyun 						//fclose(fout);
1653*4882a593Smuzhiyun 						return ZFERR;
1654*4882a593Smuzhiyun 					}
1655*4882a593Smuzhiyun 					if (r==ZCRC_DIFFERS) {
1656*4882a593Smuzhiyun 						can_resume=FALSE;
1657*4882a593Smuzhiyun 					}
1658*4882a593Smuzhiyun 				}
1659*4882a593Smuzhiyun 				//if ((unsigned long)st.st_size > zi->bytes_total) {
1660*4882a593Smuzhiyun 				{
1661*4882a593Smuzhiyun 					can_resume=FALSE;
1662*4882a593Smuzhiyun 				}
1663*4882a593Smuzhiyun 				/* retransfer whole blocks */
1664*4882a593Smuzhiyun 				zi->bytes_skipped = 0 & ~(1023);
1665*4882a593Smuzhiyun 				if (can_resume) {
1666*4882a593Smuzhiyun #if 0
1667*4882a593Smuzhiyun 					if (fseek(fout, (long) zi->bytes_skipped, SEEK_SET)) {
1668*4882a593Smuzhiyun 						fclose(fout);
1669*4882a593Smuzhiyun 						return ZFERR;
1670*4882a593Smuzhiyun 					}
1671*4882a593Smuzhiyun #endif
1672*4882a593Smuzhiyun 				}
1673*4882a593Smuzhiyun 				else
1674*4882a593Smuzhiyun 					zi->bytes_skipped=0; /* resume impossible, file has changed */
1675*4882a593Smuzhiyun 				goto buffer_it;
1676*4882a593Smuzhiyun 			}
1677*4882a593Smuzhiyun 			zi->bytes_skipped=0;
1678*4882a593Smuzhiyun #if  0
1679*4882a593Smuzhiyun 			if (fout)
1680*4882a593Smuzhiyun 				fclose(fout);
1681*4882a593Smuzhiyun #endif
1682*4882a593Smuzhiyun 		}
1683*4882a593Smuzhiyun #if 0
1684*4882a593Smuzhiyun 		fout = fopen(name_static, openmode);
1685*4882a593Smuzhiyun #ifdef ENABLE_MKDIR
1686*4882a593Smuzhiyun 		if ( !fout && Restricted < 2) {
1687*4882a593Smuzhiyun 			if (make_dirs(name_static))
1688*4882a593Smuzhiyun 				fout = fopen(name_static, openmode);
1689*4882a593Smuzhiyun 		}
1690*4882a593Smuzhiyun #endif
1691*4882a593Smuzhiyun 		if ( !fout)
1692*4882a593Smuzhiyun 		{
1693*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
1694*4882a593Smuzhiyun 			int e=errno;
1695*4882a593Smuzhiyun #endif
1696*4882a593Smuzhiyun 			zpfatal(_("cannot open %s"), name_static);
1697*4882a593Smuzhiyun 			DO_SYSLOG((LOG_ERR,"%s: cannot open: %s",
1698*4882a593Smuzhiyun 				protname(),strerror(e)));
1699*4882a593Smuzhiyun 			return ERROR;
1700*4882a593Smuzhiyun 		}
1701*4882a593Smuzhiyun #endif
1702*4882a593Smuzhiyun 	}
1703*4882a593Smuzhiyun buffer_it:
1704*4882a593Smuzhiyun 	if (Topipe == 0) {
1705*4882a593Smuzhiyun 		static char *s=NULL;
1706*4882a593Smuzhiyun 		static size_t last_length=0;
1707*4882a593Smuzhiyun #if defined(F_GETFD) && defined(F_SETFD) && defined(O_SYNC)
1708*4882a593Smuzhiyun #if 0
1709*4882a593Smuzhiyun 		if (o_sync) {
1710*4882a593Smuzhiyun 			int oldflags;
1711*4882a593Smuzhiyun 			oldflags = fcntl (fileno(fout), F_GETFD, 0);
1712*4882a593Smuzhiyun 			if (oldflags>=0 && !(oldflags & O_SYNC)) {
1713*4882a593Smuzhiyun 				oldflags|=O_SYNC;
1714*4882a593Smuzhiyun 				fcntl (fileno(fout), F_SETFD, oldflags); /* errors don't matter */
1715*4882a593Smuzhiyun 			}
1716*4882a593Smuzhiyun 		}
1717*4882a593Smuzhiyun #endif
1718*4882a593Smuzhiyun #endif
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun 		if (buffersize==-1 && s) {
1721*4882a593Smuzhiyun 			if (zi->bytes_total>last_length) {
1722*4882a593Smuzhiyun 				free(s);
1723*4882a593Smuzhiyun 				s=NULL;
1724*4882a593Smuzhiyun 				last_length=0;
1725*4882a593Smuzhiyun 			}
1726*4882a593Smuzhiyun 		}
1727*4882a593Smuzhiyun 		if (!s && buffersize) {
1728*4882a593Smuzhiyun 			last_length=32768;
1729*4882a593Smuzhiyun 			if (buffersize==-1) {
1730*4882a593Smuzhiyun 				if (zi->bytes_total>0)
1731*4882a593Smuzhiyun 					last_length=zi->bytes_total;
1732*4882a593Smuzhiyun 			} else
1733*4882a593Smuzhiyun 				last_length=buffersize;
1734*4882a593Smuzhiyun 			/* buffer `4096' bytes pages */
1735*4882a593Smuzhiyun 			last_length=(last_length+4095)&0xfffff000;
1736*4882a593Smuzhiyun 			s=malloc(last_length);
1737*4882a593Smuzhiyun 			if (!s) {
1738*4882a593Smuzhiyun 				zpfatal(_("out of memory"));
1739*4882a593Smuzhiyun 				return 1;
1740*4882a593Smuzhiyun 			}
1741*4882a593Smuzhiyun 		}
1742*4882a593Smuzhiyun 		if (s) {
1743*4882a593Smuzhiyun #if 0
1744*4882a593Smuzhiyun #ifdef SETVBUF_REVERSED
1745*4882a593Smuzhiyun 			setvbuf(fout,_IOFBF,s,last_length);
1746*4882a593Smuzhiyun #else
1747*4882a593Smuzhiyun 			setvbuf(fout,s,_IOFBF,last_length);
1748*4882a593Smuzhiyun #endif
1749*4882a593Smuzhiyun #endif
1750*4882a593Smuzhiyun 		}
1751*4882a593Smuzhiyun 	}
1752*4882a593Smuzhiyun 	zi->bytes_received=zi->bytes_skipped;
1753*4882a593Smuzhiyun 
1754*4882a593Smuzhiyun 	return OK;
1755*4882a593Smuzhiyun }
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun #ifdef ENABLE_MKDIR
1758*4882a593Smuzhiyun /*
1759*4882a593Smuzhiyun  *  Directory-creating routines from Public Domain TAR by John Gilmore
1760*4882a593Smuzhiyun  */
1761*4882a593Smuzhiyun 
1762*4882a593Smuzhiyun /*
1763*4882a593Smuzhiyun  * After a file/link/symlink/dir creation has failed, see if
1764*4882a593Smuzhiyun  * it's because some required directory was not present, and if
1765*4882a593Smuzhiyun  * so, create all required dirs.
1766*4882a593Smuzhiyun  */
1767*4882a593Smuzhiyun int
make_dirs(char * pathname)1768*4882a593Smuzhiyun make_dirs(char *pathname)
1769*4882a593Smuzhiyun {
1770*4882a593Smuzhiyun 	register char *p;		/* Points into path */
1771*4882a593Smuzhiyun 	int madeone = 0;		/* Did we do anything yet? */
1772*4882a593Smuzhiyun 	int save_errno = errno;		/* Remember caller's errno */
1773*4882a593Smuzhiyun 
1774*4882a593Smuzhiyun 	if (errno != ENOENT)
1775*4882a593Smuzhiyun 		return 0;		/* Not our problem */
1776*4882a593Smuzhiyun 
1777*4882a593Smuzhiyun 	for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {
1778*4882a593Smuzhiyun 		/* Avoid mkdir of empty string, if leading or ulong '/' */
1779*4882a593Smuzhiyun 		if (p == pathname || p[-1] == '/')
1780*4882a593Smuzhiyun 			continue;
1781*4882a593Smuzhiyun 		/* Avoid mkdir where last part of path is '.' */
1782*4882a593Smuzhiyun 		if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
1783*4882a593Smuzhiyun 			continue;
1784*4882a593Smuzhiyun 		*p = 0;				/* Truncate the path there */
1785*4882a593Smuzhiyun 		if ( !mkdir(pathname, 0777)) {	/* Try to create it as a dir */
1786*4882a593Smuzhiyun 			vfile("Made directory %s\n", pathname);
1787*4882a593Smuzhiyun 			madeone++;		/* Remember if we made one */
1788*4882a593Smuzhiyun 			*p = '/';
1789*4882a593Smuzhiyun 			continue;
1790*4882a593Smuzhiyun 		}
1791*4882a593Smuzhiyun 		*p = '/';
1792*4882a593Smuzhiyun 		if (errno == EEXIST)		/* Directory already exists */
1793*4882a593Smuzhiyun 			continue;
1794*4882a593Smuzhiyun 		/*
1795*4882a593Smuzhiyun 		 * Some other error in the mkdir.  We return to the caller.
1796*4882a593Smuzhiyun 		 */
1797*4882a593Smuzhiyun 		break;
1798*4882a593Smuzhiyun 	}
1799*4882a593Smuzhiyun 	errno = save_errno;		/* Restore caller's errno */
1800*4882a593Smuzhiyun 	return madeone;			/* Tell them to retry if we made one */
1801*4882a593Smuzhiyun }
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun #endif /* ENABLE_MKDIR */
1804*4882a593Smuzhiyun 
1805*4882a593Smuzhiyun /*
1806*4882a593Smuzhiyun  * Putsec writes the n characters of buf to receive file fout.
1807*4882a593Smuzhiyun  *  If not in binary mode, carriage returns, and all characters
1808*4882a593Smuzhiyun  *  starting with CPMEOF are discarded.
1809*4882a593Smuzhiyun  */
putsec(struct zm_fileinfo * zi,char * buf,size_t n)1810*4882a593Smuzhiyun static int putsec(struct zm_fileinfo *zi, char *buf, size_t n)
1811*4882a593Smuzhiyun {
1812*4882a593Smuzhiyun 	memcpy(zmodem_addr + zmodem_offset, buf, n);
1813*4882a593Smuzhiyun 	zmodem_offset += n;
1814*4882a593Smuzhiyun 	return 0;
1815*4882a593Smuzhiyun }
1816*4882a593Smuzhiyun #if 0
1817*4882a593Smuzhiyun static int
1818*4882a593Smuzhiyun putsec(struct zm_fileinfo *zi, char *buf, size_t n)
1819*4882a593Smuzhiyun {
1820*4882a593Smuzhiyun 	register char *p;
1821*4882a593Smuzhiyun 
1822*4882a593Smuzhiyun 	if (n == 0)
1823*4882a593Smuzhiyun 		return OK;
1824*4882a593Smuzhiyun 	if (Thisbinary) {
1825*4882a593Smuzhiyun 		if (fwrite(buf,n,1,fout)!=1)
1826*4882a593Smuzhiyun 			return ERROR;
1827*4882a593Smuzhiyun 	}
1828*4882a593Smuzhiyun 	else {
1829*4882a593Smuzhiyun 		if (zi->eof_seen)
1830*4882a593Smuzhiyun 			return OK;
1831*4882a593Smuzhiyun 		for (p=buf; n>0; ++p,n-- ) {
1832*4882a593Smuzhiyun 			if ( *p == '\r')
1833*4882a593Smuzhiyun 				continue;
1834*4882a593Smuzhiyun 			if (*p == CPMEOF) {
1835*4882a593Smuzhiyun 				zi->eof_seen=TRUE;
1836*4882a593Smuzhiyun 				return OK;
1837*4882a593Smuzhiyun 			}
1838*4882a593Smuzhiyun 			putc(*p ,fout);
1839*4882a593Smuzhiyun 		}
1840*4882a593Smuzhiyun 	}
1841*4882a593Smuzhiyun 	return OK;
1842*4882a593Smuzhiyun }
1843*4882a593Smuzhiyun #endif
1844*4882a593Smuzhiyun 
islower(int c)1845*4882a593Smuzhiyun int islower(int c)
1846*4882a593Smuzhiyun {
1847*4882a593Smuzhiyun 	if((c >='a') && (c<='z'))
1848*4882a593Smuzhiyun 		return 1;
1849*4882a593Smuzhiyun 	return 0;
1850*4882a593Smuzhiyun }
isupper(int c)1851*4882a593Smuzhiyun int isupper(int c)
1852*4882a593Smuzhiyun {
1853*4882a593Smuzhiyun 	if((c >='A') && (c<='Z'))
1854*4882a593Smuzhiyun 		return 1;
1855*4882a593Smuzhiyun 	return 0;
1856*4882a593Smuzhiyun }
tolower(int c)1857*4882a593Smuzhiyun int tolower(int c)
1858*4882a593Smuzhiyun {
1859*4882a593Smuzhiyun 	if((c >='A') && (c<='Z'))
1860*4882a593Smuzhiyun 		return c+32;
1861*4882a593Smuzhiyun 	return c;
1862*4882a593Smuzhiyun }
1863*4882a593Smuzhiyun /* make string s lower case */
1864*4882a593Smuzhiyun static void
uncaps(char * s)1865*4882a593Smuzhiyun uncaps(char *s)
1866*4882a593Smuzhiyun {
1867*4882a593Smuzhiyun 	for ( ; *s; ++s)
1868*4882a593Smuzhiyun 		if (isupper((unsigned char)(*s)))
1869*4882a593Smuzhiyun 			*s = tolower(*s);
1870*4882a593Smuzhiyun }
1871*4882a593Smuzhiyun /*
1872*4882a593Smuzhiyun  * IsAnyLower returns TRUE if string s has lower case letters.
1873*4882a593Smuzhiyun  */
1874*4882a593Smuzhiyun static int
IsAnyLower(const char * s)1875*4882a593Smuzhiyun IsAnyLower(const char *s)
1876*4882a593Smuzhiyun {
1877*4882a593Smuzhiyun 	for ( ; *s; ++s)
1878*4882a593Smuzhiyun 		if (islower((unsigned char)(*s)))
1879*4882a593Smuzhiyun 			return TRUE;
1880*4882a593Smuzhiyun 	return FALSE;
1881*4882a593Smuzhiyun }
1882*4882a593Smuzhiyun 
1883*4882a593Smuzhiyun static void
report(int sct)1884*4882a593Smuzhiyun report(int sct)
1885*4882a593Smuzhiyun {
1886*4882a593Smuzhiyun 	if (Verbose>1)
1887*4882a593Smuzhiyun 	{
1888*4882a593Smuzhiyun 		vstringf(_("Blocks received: %d"),sct);
1889*4882a593Smuzhiyun 		//vchar('\r');
1890*4882a593Smuzhiyun 	}
1891*4882a593Smuzhiyun }
1892*4882a593Smuzhiyun 
1893*4882a593Smuzhiyun /*
1894*4882a593Smuzhiyun  * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
1895*4882a593Smuzhiyun  * If called as [-][dir/../]rzCOMMAND set the pipe flag
1896*4882a593Smuzhiyun  * If called as rb use YMODEM protocol
1897*4882a593Smuzhiyun  */
1898*4882a593Smuzhiyun void
chkinvok(const char * s)1899*4882a593Smuzhiyun chkinvok(const char *s)
1900*4882a593Smuzhiyun {
1901*4882a593Smuzhiyun 	const char *p;
1902*4882a593Smuzhiyun 
1903*4882a593Smuzhiyun 	p = s;
1904*4882a593Smuzhiyun 	while (*p == '-')
1905*4882a593Smuzhiyun 		s = ++p;
1906*4882a593Smuzhiyun 	while (*p)
1907*4882a593Smuzhiyun 		if (*p++ == '/')
1908*4882a593Smuzhiyun 			s = p;
1909*4882a593Smuzhiyun 	if (*s == 'v') {
1910*4882a593Smuzhiyun 		Verbose=1; ++s;
1911*4882a593Smuzhiyun 	}
1912*4882a593Smuzhiyun 	program_name = s;
1913*4882a593Smuzhiyun 	if (*s == 'l')
1914*4882a593Smuzhiyun 		s++; /* lrz -> rz */
1915*4882a593Smuzhiyun 	protocol=ZM_ZMODEM;
1916*4882a593Smuzhiyun 	if (s[0]=='r' && s[1]=='x')
1917*4882a593Smuzhiyun 		protocol=ZM_XMODEM;
1918*4882a593Smuzhiyun 	if (s[0]=='r' && (s[1]=='b' || s[1]=='y'))
1919*4882a593Smuzhiyun 		protocol=ZM_YMODEM;
1920*4882a593Smuzhiyun 	//if (s[2] && protocol!=ZM_XMODEM)
1921*4882a593Smuzhiyun 	//	Topipe = 1;
1922*4882a593Smuzhiyun }
1923*4882a593Smuzhiyun 
1924*4882a593Smuzhiyun /*
1925*4882a593Smuzhiyun  * Totalitarian Communist pathname processing
1926*4882a593Smuzhiyun  */
1927*4882a593Smuzhiyun static void
checkpath(const char * name)1928*4882a593Smuzhiyun checkpath(const char *name)
1929*4882a593Smuzhiyun {
1930*4882a593Smuzhiyun 	if (Restricted) {
1931*4882a593Smuzhiyun 		const char *p;
1932*4882a593Smuzhiyun 		p=strrchr(name,'/');
1933*4882a593Smuzhiyun 		if (p)
1934*4882a593Smuzhiyun 			p++;
1935*4882a593Smuzhiyun 		else
1936*4882a593Smuzhiyun 			p=name;
1937*4882a593Smuzhiyun 		/* don't overwrite any file in very restricted mode.
1938*4882a593Smuzhiyun 		 * don't overwrite hidden files in restricted mode */
1939*4882a593Smuzhiyun #if 0
1940*4882a593Smuzhiyun 		if ((Restricted==2 || *name=='.') && fopen(name, "r") != NULL) {
1941*4882a593Smuzhiyun 			canit(0);
1942*4882a593Smuzhiyun 			vstring("\r\n");
1943*4882a593Smuzhiyun 			vstringf(_("%s: %s exists\n"),
1944*4882a593Smuzhiyun 				program_name, name);
1945*4882a593Smuzhiyun 			bibi(-1);
1946*4882a593Smuzhiyun 		}
1947*4882a593Smuzhiyun #endif
1948*4882a593Smuzhiyun 		/* restrict pathnames to current tree or uucppublic */
1949*4882a593Smuzhiyun 		if ( strstr(name, "../")
1950*4882a593Smuzhiyun #ifdef PUBDIR
1951*4882a593Smuzhiyun 		 || (name[0]== '/' && strncmp(name, PUBDIR,
1952*4882a593Smuzhiyun 		 	strlen(PUBDIR)))
1953*4882a593Smuzhiyun #endif
1954*4882a593Smuzhiyun 		) {
1955*4882a593Smuzhiyun 			canit(0);
1956*4882a593Smuzhiyun 			vstring("\r\n");
1957*4882a593Smuzhiyun 			vstringf(_("%s:\tSecurity Violation"),program_name);
1958*4882a593Smuzhiyun 			vstring("\r\n");
1959*4882a593Smuzhiyun 			bibi(-1);
1960*4882a593Smuzhiyun 		}
1961*4882a593Smuzhiyun 		if (Restricted > 1) {
1962*4882a593Smuzhiyun 			if (name[0]=='.' || strstr(name,"/.")) {
1963*4882a593Smuzhiyun 				canit(0);
1964*4882a593Smuzhiyun 				vstring("\r\n");
1965*4882a593Smuzhiyun 				vstringf(_("%s:\tSecurity Violation"),program_name);
1966*4882a593Smuzhiyun 				vstring("\r\n");
1967*4882a593Smuzhiyun 				bibi(-1);
1968*4882a593Smuzhiyun 			}
1969*4882a593Smuzhiyun 		}
1970*4882a593Smuzhiyun 	}
1971*4882a593Smuzhiyun }
1972*4882a593Smuzhiyun 
1973*4882a593Smuzhiyun /*
1974*4882a593Smuzhiyun  * Initialize for Zmodem receive attempt, try to activate Zmodem sender
1975*4882a593Smuzhiyun  *  Handles ZSINIT frame
1976*4882a593Smuzhiyun  *  Return ZFILE if Zmodem filename received, -1 on error,
1977*4882a593Smuzhiyun  *   ZCOMPL if transaction finished,  else 0
1978*4882a593Smuzhiyun  */
1979*4882a593Smuzhiyun static int
tryz(void)1980*4882a593Smuzhiyun tryz(void)
1981*4882a593Smuzhiyun {
1982*4882a593Smuzhiyun 	register int c, n;
1983*4882a593Smuzhiyun 	register int cmdzack1flg;
1984*4882a593Smuzhiyun 	int zrqinits_received=0;
1985*4882a593Smuzhiyun 	size_t bytes_in_block=0;
1986*4882a593Smuzhiyun 
1987*4882a593Smuzhiyun 	if (protocol!=ZM_ZMODEM)		/* Check for "rb" program name */
1988*4882a593Smuzhiyun 		return 0;
1989*4882a593Smuzhiyun 
1990*4882a593Smuzhiyun 	for (n=zmodem_requested?15:5;
1991*4882a593Smuzhiyun 		 (--n + zrqinits_received) >=0 && zrqinits_received<10; ) {
1992*4882a593Smuzhiyun 		/* Set buffer length (0) and capability flags */
1993*4882a593Smuzhiyun #ifdef SEGMENTS
1994*4882a593Smuzhiyun 		stohdr(SEGMENTS*MAX_BLOCK);
1995*4882a593Smuzhiyun #else
1996*4882a593Smuzhiyun 		stohdr(0L);
1997*4882a593Smuzhiyun #endif
1998*4882a593Smuzhiyun #ifdef CANBREAK
1999*4882a593Smuzhiyun 		Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
2000*4882a593Smuzhiyun #else
2001*4882a593Smuzhiyun 		Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
2002*4882a593Smuzhiyun #endif
2003*4882a593Smuzhiyun #ifdef ENABLE_TIMESYNC
2004*4882a593Smuzhiyun 		if (timesync_flag)
2005*4882a593Smuzhiyun 			Txhdr[ZF1] |= ZF1_TIMESYNC;
2006*4882a593Smuzhiyun #endif
2007*4882a593Smuzhiyun 		if (Zctlesc)
2008*4882a593Smuzhiyun 			Txhdr[ZF0] |= TESCCTL; /* TESCCTL == ESCCTL */
2009*4882a593Smuzhiyun 		zshhdr(tryzhdrtype, Txhdr);
2010*4882a593Smuzhiyun 
2011*4882a593Smuzhiyun #if 0
2012*4882a593Smuzhiyun 		if (tcp_socket==-1 && *tcp_buf) {
2013*4882a593Smuzhiyun 			/* we need to switch to tcp mode */
2014*4882a593Smuzhiyun 			tcp_socket=tcp_connect(tcp_buf);
2015*4882a593Smuzhiyun 			tcp_buf[0]=0;
2016*4882a593Smuzhiyun 			dup2(tcp_socket,0);
2017*4882a593Smuzhiyun 			dup2(tcp_socket,1);
2018*4882a593Smuzhiyun 		}
2019*4882a593Smuzhiyun #endif
2020*4882a593Smuzhiyun 		if (tryzhdrtype == ZSKIP)	/* Don't skip too far */
2021*4882a593Smuzhiyun 			tryzhdrtype = ZRINIT;	/* CAF 8-21-87 */
2022*4882a593Smuzhiyun again:
2023*4882a593Smuzhiyun 		switch (zgethdr(Rxhdr, 0, NULL)) {
2024*4882a593Smuzhiyun 		case ZRQINIT:
2025*4882a593Smuzhiyun 			/* getting one ZRQINIT is totally ok. Normally a ZFILE follows
2026*4882a593Smuzhiyun 			 * (and might be in our buffer, so don't purge it). But if we
2027*4882a593Smuzhiyun 			 * get more ZRQINITs than the sender has started up before us
2028*4882a593Smuzhiyun 			 * and sent ZRQINITs while waiting.
2029*4882a593Smuzhiyun 			 */
2030*4882a593Smuzhiyun 			zrqinits_received++;
2031*4882a593Smuzhiyun 			continue;
2032*4882a593Smuzhiyun 
2033*4882a593Smuzhiyun 		case ZEOF:
2034*4882a593Smuzhiyun 			continue;
2035*4882a593Smuzhiyun 		case TIMEOUT:
2036*4882a593Smuzhiyun 			continue;
2037*4882a593Smuzhiyun 		case ZFILE:
2038*4882a593Smuzhiyun 			zconv = Rxhdr[ZF0];
2039*4882a593Smuzhiyun 			if (!zconv)
2040*4882a593Smuzhiyun 				/* resume with sz -r is impossible (at least with unix sz)
2041*4882a593Smuzhiyun 				 * if this is not set */
2042*4882a593Smuzhiyun 				zconv=ZCBIN;
2043*4882a593Smuzhiyun 			if (Rxhdr[ZF1] & ZF1_ZMSKNOLOC) {
2044*4882a593Smuzhiyun 				Rxhdr[ZF1] &= ~(ZF1_ZMSKNOLOC);
2045*4882a593Smuzhiyun 				skip_if_not_found=TRUE;
2046*4882a593Smuzhiyun 			}
2047*4882a593Smuzhiyun 			zmanag = Rxhdr[ZF1];
2048*4882a593Smuzhiyun 			ztrans = Rxhdr[ZF2];
2049*4882a593Smuzhiyun 			tryzhdrtype = ZRINIT;
2050*4882a593Smuzhiyun 			c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block);
2051*4882a593Smuzhiyun 			io_mode(0,3);
2052*4882a593Smuzhiyun 			if (c == GOTCRCW)
2053*4882a593Smuzhiyun 				return ZFILE;
2054*4882a593Smuzhiyun 			zshhdr(ZNAK, Txhdr);
2055*4882a593Smuzhiyun 			goto again;
2056*4882a593Smuzhiyun 		case ZSINIT:
2057*4882a593Smuzhiyun 			/* this once was:
2058*4882a593Smuzhiyun 			 * Zctlesc = TESCCTL & Rxhdr[ZF0];
2059*4882a593Smuzhiyun 			 * trouble: if rz get --escape flag:
2060*4882a593Smuzhiyun 			 * - it sends TESCCTL to sz,
2061*4882a593Smuzhiyun 			 *   get a ZSINIT _without_ TESCCTL (yeah - sender didn't know),
2062*4882a593Smuzhiyun 			 *   overwrites Zctlesc flag ...
2063*4882a593Smuzhiyun 			 * - sender receives TESCCTL and uses "|=..."
2064*4882a593Smuzhiyun 			 * so: sz escapes, but rz doesn't unescape ... not good.
2065*4882a593Smuzhiyun 			 */
2066*4882a593Smuzhiyun 			Zctlesc |= TESCCTL & Rxhdr[ZF0];
2067*4882a593Smuzhiyun 			if (zrdata(Attn, ZATTNLEN,&bytes_in_block) == GOTCRCW) {
2068*4882a593Smuzhiyun 				stohdr(1L);
2069*4882a593Smuzhiyun 				zshhdr(ZACK, Txhdr);
2070*4882a593Smuzhiyun 				goto again;
2071*4882a593Smuzhiyun 			}
2072*4882a593Smuzhiyun 			zshhdr(ZNAK, Txhdr);
2073*4882a593Smuzhiyun 			goto again;
2074*4882a593Smuzhiyun 		case ZFREECNT:
2075*4882a593Smuzhiyun 			stohdr(getfree());
2076*4882a593Smuzhiyun 			zshhdr(ZACK, Txhdr);
2077*4882a593Smuzhiyun 			goto again;
2078*4882a593Smuzhiyun 		case ZCOMMAND:
2079*4882a593Smuzhiyun 			cmdzack1flg = Rxhdr[ZF0];
2080*4882a593Smuzhiyun 			if (zrdata(secbuf, MAX_BLOCK,&bytes_in_block) == GOTCRCW) {
2081*4882a593Smuzhiyun 				if (Verbose)
2082*4882a593Smuzhiyun 				{
2083*4882a593Smuzhiyun 					vstringf("%s: %s\n", program_name,
2084*4882a593Smuzhiyun 						_("remote command execution requested"));
2085*4882a593Smuzhiyun 					vstringf("%s: %s\n", program_name, secbuf);
2086*4882a593Smuzhiyun 				}
2087*4882a593Smuzhiyun 				if (!allow_remote_commands)
2088*4882a593Smuzhiyun 				{
2089*4882a593Smuzhiyun 					if (Verbose)
2090*4882a593Smuzhiyun 						vstringf("%s: %s\n", program_name,
2091*4882a593Smuzhiyun 							_("not executed"));
2092*4882a593Smuzhiyun 					zshhdr(ZCOMPL, Txhdr);
2093*4882a593Smuzhiyun 					DO_SYSLOG((LOG_INFO,"rexec denied: %s",secbuf));
2094*4882a593Smuzhiyun 					return ZCOMPL;
2095*4882a593Smuzhiyun 				}
2096*4882a593Smuzhiyun 				DO_SYSLOG((LOG_INFO,"rexec allowed: %s",secbuf));
2097*4882a593Smuzhiyun 				if (cmdzack1flg & ZCACK1)
2098*4882a593Smuzhiyun 					stohdr(0L);
2099*4882a593Smuzhiyun 				else
2100*4882a593Smuzhiyun 					stohdr((size_t)sys2(secbuf));
2101*4882a593Smuzhiyun 				purgeline(0);	/* dump impatient questions */
2102*4882a593Smuzhiyun 				do {
2103*4882a593Smuzhiyun 					zshhdr(ZCOMPL, Txhdr);
2104*4882a593Smuzhiyun 				}
2105*4882a593Smuzhiyun 				while (++errors<20 && zgethdr(Rxhdr,1, NULL) != ZFIN);
2106*4882a593Smuzhiyun 				ackbibi();
2107*4882a593Smuzhiyun 				if (cmdzack1flg & ZCACK1)
2108*4882a593Smuzhiyun 					exec2(secbuf);
2109*4882a593Smuzhiyun 				return ZCOMPL;
2110*4882a593Smuzhiyun 			}
2111*4882a593Smuzhiyun 			zshhdr(ZNAK, Txhdr);
2112*4882a593Smuzhiyun 			goto again;
2113*4882a593Smuzhiyun 		case ZCOMPL:
2114*4882a593Smuzhiyun 			goto again;
2115*4882a593Smuzhiyun 		default:
2116*4882a593Smuzhiyun 			continue;
2117*4882a593Smuzhiyun 		case ZFIN:
2118*4882a593Smuzhiyun 			ackbibi();
2119*4882a593Smuzhiyun 			return ZCOMPL;
2120*4882a593Smuzhiyun 		case ZRINIT:
2121*4882a593Smuzhiyun 			if (Verbose)
2122*4882a593Smuzhiyun 				vstringf(_("got ZRINIT"));
2123*4882a593Smuzhiyun 			return ERROR;
2124*4882a593Smuzhiyun 		case ZCAN:
2125*4882a593Smuzhiyun 			if (Verbose)
2126*4882a593Smuzhiyun 				vstringf(_("got ZCAN"));
2127*4882a593Smuzhiyun 			return ERROR;
2128*4882a593Smuzhiyun 		}
2129*4882a593Smuzhiyun 	}
2130*4882a593Smuzhiyun 	return 0;
2131*4882a593Smuzhiyun }
2132*4882a593Smuzhiyun 
2133*4882a593Smuzhiyun 
2134*4882a593Smuzhiyun /*
2135*4882a593Smuzhiyun  * Receive 1 or more files with ZMODEM protocol
2136*4882a593Smuzhiyun  */
2137*4882a593Smuzhiyun static int
rzfiles(struct zm_fileinfo * zi)2138*4882a593Smuzhiyun rzfiles(struct zm_fileinfo *zi)
2139*4882a593Smuzhiyun {
2140*4882a593Smuzhiyun 	register int c;
2141*4882a593Smuzhiyun 
2142*4882a593Smuzhiyun 	//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2143*4882a593Smuzhiyun 	for (;;) {
2144*4882a593Smuzhiyun 		timing(1,NULL);
2145*4882a593Smuzhiyun 		c = rzfile(zi);
2146*4882a593Smuzhiyun 		//xil_printf("%s(): L%d debug, c=%d\n\r", __func__, __LINE__, c);
2147*4882a593Smuzhiyun 		switch (c) {
2148*4882a593Smuzhiyun 		case ZEOF:
2149*4882a593Smuzhiyun 			xil_printf("%s(): receive %s (%d bytes)complete\n\r", __func__, zi->fname, (u32)zi->bytes_total);
2150*4882a593Smuzhiyun 			if (Verbose > 1
2151*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
2152*4882a593Smuzhiyun 				|| enable_syslog
2153*4882a593Smuzhiyun #endif
2154*4882a593Smuzhiyun 	 		) {
2155*4882a593Smuzhiyun 				ulong d;
2156*4882a593Smuzhiyun 				long bps;
2157*4882a593Smuzhiyun 				d=timing(0,NULL);
2158*4882a593Smuzhiyun 				if (d==0)
2159*4882a593Smuzhiyun 					d=0.5; /* can happen if timing uses time() */
2160*4882a593Smuzhiyun 				bps=(zi->bytes_received-zi->bytes_skipped)/d;
2161*4882a593Smuzhiyun 				if (Verbose > 1) {
2162*4882a593Smuzhiyun 					vstringf(
2163*4882a593Smuzhiyun 						_("\rBytes received: %7ld/%7ld   BPS:%-6ld                \r\n"),
2164*4882a593Smuzhiyun 						(long) zi->bytes_received, (long) zi->bytes_total, bps);
2165*4882a593Smuzhiyun 				}
2166*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: %ld Bytes, %ld BPS",shortname,
2167*4882a593Smuzhiyun 						   protname(), (long) zi->bytes_total,bps));
2168*4882a593Smuzhiyun 			}
2169*4882a593Smuzhiyun 			/* FALL THROUGH */
2170*4882a593Smuzhiyun 		case ZSKIP:
2171*4882a593Smuzhiyun 			if (c==ZSKIP)
2172*4882a593Smuzhiyun 			{
2173*4882a593Smuzhiyun 				if (Verbose)
2174*4882a593Smuzhiyun 					vstringf(_("Skipped"));
2175*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: skipped",shortname,protname()));
2176*4882a593Smuzhiyun 			}
2177*4882a593Smuzhiyun 			switch (tryz()) {
2178*4882a593Smuzhiyun 			case ZCOMPL:
2179*4882a593Smuzhiyun 				return OK;
2180*4882a593Smuzhiyun 			default:
2181*4882a593Smuzhiyun 				return ERROR;
2182*4882a593Smuzhiyun 			case ZFILE:
2183*4882a593Smuzhiyun 				break;
2184*4882a593Smuzhiyun 			}
2185*4882a593Smuzhiyun 			continue;
2186*4882a593Smuzhiyun 		default:
2187*4882a593Smuzhiyun 			return c;
2188*4882a593Smuzhiyun 		case ERROR:
2189*4882a593Smuzhiyun 			DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error",shortname,protname()));
2190*4882a593Smuzhiyun 			return ERROR;
2191*4882a593Smuzhiyun 		}
2192*4882a593Smuzhiyun 	}
2193*4882a593Smuzhiyun }
2194*4882a593Smuzhiyun 
2195*4882a593Smuzhiyun /* "OOSB" means Out Of Sync Block. I once thought that if sz sents
2196*4882a593Smuzhiyun  * blocks a,b,c,d, of which a is ok, b fails, we might want to save
2197*4882a593Smuzhiyun  * c and d. But, alas, i never saw c and d.
2198*4882a593Smuzhiyun  */
2199*4882a593Smuzhiyun #define SAVE_OOSB
2200*4882a593Smuzhiyun #ifdef SAVE_OOSB
2201*4882a593Smuzhiyun typedef struct oosb_t {
2202*4882a593Smuzhiyun 	size_t pos;
2203*4882a593Smuzhiyun 	size_t len;
2204*4882a593Smuzhiyun 	char *data;
2205*4882a593Smuzhiyun 	struct oosb_t *next;
2206*4882a593Smuzhiyun } oosb_t;
2207*4882a593Smuzhiyun struct oosb_t *anker=NULL;
2208*4882a593Smuzhiyun #endif
2209*4882a593Smuzhiyun 
2210*4882a593Smuzhiyun /*
2211*4882a593Smuzhiyun  * Receive a file with ZMODEM protocol
2212*4882a593Smuzhiyun  *  Assumes file name frame is in secbuf
2213*4882a593Smuzhiyun  */
2214*4882a593Smuzhiyun static int
rzfile(struct zm_fileinfo * zi)2215*4882a593Smuzhiyun rzfile(struct zm_fileinfo *zi)
2216*4882a593Smuzhiyun {
2217*4882a593Smuzhiyun 	register int c, n;
2218*4882a593Smuzhiyun 	long last_rxbytes=0;
2219*4882a593Smuzhiyun 	unsigned long last_bps=0;
2220*4882a593Smuzhiyun 	long not_printed=0;
2221*4882a593Smuzhiyun 	time_t low_bps=0;
2222*4882a593Smuzhiyun 	size_t bytes_in_block=0;
2223*4882a593Smuzhiyun 
2224*4882a593Smuzhiyun 	zi->eof_seen=FALSE;
2225*4882a593Smuzhiyun 
2226*4882a593Smuzhiyun 	n = 20;
2227*4882a593Smuzhiyun 
2228*4882a593Smuzhiyun 	if (procheader(secbuf,zi) == ERROR) {
2229*4882a593Smuzhiyun 		xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2230*4882a593Smuzhiyun 		DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: procheader error",
2231*4882a593Smuzhiyun 				   shortname,protname()));
2232*4882a593Smuzhiyun 		return (tryzhdrtype = ZSKIP);
2233*4882a593Smuzhiyun 	}
2234*4882a593Smuzhiyun 
2235*4882a593Smuzhiyun 	for (;;) {
2236*4882a593Smuzhiyun #ifdef SEGMENTS
2237*4882a593Smuzhiyun 		chinseg = 0;
2238*4882a593Smuzhiyun #endif
2239*4882a593Smuzhiyun 		stohdr(zi->bytes_received);
2240*4882a593Smuzhiyun 		zshhdr(ZRPOS, Txhdr);
2241*4882a593Smuzhiyun 		goto skip_oosb;
2242*4882a593Smuzhiyun nxthdr:
2243*4882a593Smuzhiyun #ifdef SAVE_OOSB
2244*4882a593Smuzhiyun 		if (anker) {
2245*4882a593Smuzhiyun 			oosb_t *akt,*last,*next;
2246*4882a593Smuzhiyun 			for (akt=anker,last=NULL;akt;last= akt ? akt : last ,akt=next) {
2247*4882a593Smuzhiyun 				if (akt->pos==zi->bytes_received) {
2248*4882a593Smuzhiyun 					putsec(zi, akt->data, akt->len);
2249*4882a593Smuzhiyun 					zi->bytes_received += akt->len;
2250*4882a593Smuzhiyun 					vfile("using saved out-of-sync-paket %lx, len %ld",
2251*4882a593Smuzhiyun 						  akt->pos,akt->len);
2252*4882a593Smuzhiyun 					//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2253*4882a593Smuzhiyun 					goto nxthdr;
2254*4882a593Smuzhiyun 				}
2255*4882a593Smuzhiyun 				next=akt->next;
2256*4882a593Smuzhiyun 				if (akt->pos<zi->bytes_received) {
2257*4882a593Smuzhiyun 					vfile("removing unneeded saved out-of-sync-paket %lx, len %ld",
2258*4882a593Smuzhiyun 						  akt->pos,akt->len);
2259*4882a593Smuzhiyun 					if (last)
2260*4882a593Smuzhiyun 						last->next=akt->next;
2261*4882a593Smuzhiyun 					else
2262*4882a593Smuzhiyun 						anker=akt->next;
2263*4882a593Smuzhiyun 					free(akt->data);
2264*4882a593Smuzhiyun 					free(akt);
2265*4882a593Smuzhiyun 					akt=NULL;
2266*4882a593Smuzhiyun 				}
2267*4882a593Smuzhiyun 			}
2268*4882a593Smuzhiyun 		}
2269*4882a593Smuzhiyun #endif
2270*4882a593Smuzhiyun 	skip_oosb:
2271*4882a593Smuzhiyun 		c = zgethdr(Rxhdr, 0, NULL);
2272*4882a593Smuzhiyun 		switch (c) {
2273*4882a593Smuzhiyun 		default:
2274*4882a593Smuzhiyun 			xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2275*4882a593Smuzhiyun 			DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %d",shortname,
2276*4882a593Smuzhiyun 					   protname(),c));
2277*4882a593Smuzhiyun 			vfile("rzfile: zgethdr returned %d", c);
2278*4882a593Smuzhiyun 			return ERROR;
2279*4882a593Smuzhiyun 		case ZNAK:
2280*4882a593Smuzhiyun 		case TIMEOUT:
2281*4882a593Smuzhiyun 			xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2282*4882a593Smuzhiyun #ifdef SEGMENTS
2283*4882a593Smuzhiyun 			putsec(secbuf, chinseg);
2284*4882a593Smuzhiyun 			chinseg = 0;
2285*4882a593Smuzhiyun #endif
2286*4882a593Smuzhiyun 			if ( --n < 0) {
2287*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %s",shortname,
2288*4882a593Smuzhiyun 					   protname(),c == ZNAK ? "ZNAK" : "TIMEOUT"));
2289*4882a593Smuzhiyun 				vfile("rzfile: zgethdr returned %d", c);
2290*4882a593Smuzhiyun 				return ERROR;
2291*4882a593Smuzhiyun 			}
2292*4882a593Smuzhiyun 		case ZFILE:
2293*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2294*4882a593Smuzhiyun 			zrdata(secbuf, MAX_BLOCK,&bytes_in_block);
2295*4882a593Smuzhiyun 			continue;
2296*4882a593Smuzhiyun 		case ZEOF:
2297*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2298*4882a593Smuzhiyun #ifdef SEGMENTS
2299*4882a593Smuzhiyun 			putsec(secbuf, chinseg);
2300*4882a593Smuzhiyun 			chinseg = 0;
2301*4882a593Smuzhiyun #endif
2302*4882a593Smuzhiyun 			if (rclhdr(Rxhdr) != (long) zi->bytes_received) {
2303*4882a593Smuzhiyun 				/*
2304*4882a593Smuzhiyun 				 * Ignore eof if it's at wrong place - force
2305*4882a593Smuzhiyun 				 *  a timeout because the eof might have gone
2306*4882a593Smuzhiyun 				 *  out before we sent our zrpos.
2307*4882a593Smuzhiyun 				 */
2308*4882a593Smuzhiyun 				errors = 0;  goto nxthdr;
2309*4882a593Smuzhiyun 			}
2310*4882a593Smuzhiyun 			if (closeit(zi)) {
2311*4882a593Smuzhiyun 				tryzhdrtype = ZFERR;
2312*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: closeit return <>0",
2313*4882a593Smuzhiyun 						   shortname, protname()));
2314*4882a593Smuzhiyun 				vfile("rzfile: closeit returned <> 0");
2315*4882a593Smuzhiyun 				return ERROR;
2316*4882a593Smuzhiyun 			}
2317*4882a593Smuzhiyun 			vfile("rzfile: normal EOF");
2318*4882a593Smuzhiyun 			return c;
2319*4882a593Smuzhiyun 		case ERROR:	/* Too much garbage in header search error */
2320*4882a593Smuzhiyun 			xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2321*4882a593Smuzhiyun #ifdef SEGMENTS
2322*4882a593Smuzhiyun 			putsec(secbuf, chinseg);
2323*4882a593Smuzhiyun 			chinseg = 0;
2324*4882a593Smuzhiyun #endif
2325*4882a593Smuzhiyun 			if ( --n < 0) {
2326*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: zgethdr returned %d",
2327*4882a593Smuzhiyun 						   shortname, protname(),c));
2328*4882a593Smuzhiyun 				vfile("rzfile: zgethdr returned %d", c);
2329*4882a593Smuzhiyun 				return ERROR;
2330*4882a593Smuzhiyun 			}
2331*4882a593Smuzhiyun 			zmputs(Attn);
2332*4882a593Smuzhiyun 			continue;
2333*4882a593Smuzhiyun 		case ZSKIP:
2334*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2335*4882a593Smuzhiyun #ifdef SEGMENTS
2336*4882a593Smuzhiyun 			putsec(secbuf, chinseg);
2337*4882a593Smuzhiyun 			chinseg = 0;
2338*4882a593Smuzhiyun #endif
2339*4882a593Smuzhiyun 			closeit(zi);
2340*4882a593Smuzhiyun 			DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: sender skipped",
2341*4882a593Smuzhiyun 					   shortname, protname()));
2342*4882a593Smuzhiyun 			vfile("rzfile: Sender SKIPPED file");
2343*4882a593Smuzhiyun 			return c;
2344*4882a593Smuzhiyun 		case ZDATA:
2345*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2346*4882a593Smuzhiyun 			if (rclhdr(Rxhdr) != (long) zi->bytes_received) {
2347*4882a593Smuzhiyun #if defined(SAVE_OOSB)
2348*4882a593Smuzhiyun 				oosb_t *neu;
2349*4882a593Smuzhiyun 				size_t pos=rclhdr(Rxhdr);
2350*4882a593Smuzhiyun #endif
2351*4882a593Smuzhiyun 				if ( --n < 0) {
2352*4882a593Smuzhiyun 					vfile("rzfile: out of sync");
2353*4882a593Smuzhiyun 					DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: error: out of sync",
2354*4882a593Smuzhiyun 					   shortname, protname()));
2355*4882a593Smuzhiyun 					return ERROR;
2356*4882a593Smuzhiyun 				}
2357*4882a593Smuzhiyun #if defined(SAVE_OOSB)
2358*4882a593Smuzhiyun 				switch (c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block))
2359*4882a593Smuzhiyun 				{
2360*4882a593Smuzhiyun 				case GOTCRCW:
2361*4882a593Smuzhiyun 				case GOTCRCG:
2362*4882a593Smuzhiyun 				case GOTCRCE:
2363*4882a593Smuzhiyun 				case GOTCRCQ:
2364*4882a593Smuzhiyun 					if (pos>zi->bytes_received) {
2365*4882a593Smuzhiyun 						neu=malloc(sizeof(oosb_t));
2366*4882a593Smuzhiyun 						if (neu)
2367*4882a593Smuzhiyun 							neu->data=malloc(bytes_in_block);
2368*4882a593Smuzhiyun 						if (neu && neu->data) {
2369*4882a593Smuzhiyun #ifdef ENABLE_SYSLOG
2370*4882a593Smuzhiyun /* call syslog to tell me if this happens */
2371*4882a593Smuzhiyun 							lsyslog(LOG_ERR,
2372*4882a593Smuzhiyun 								   "saving out-of-sync-block %lx, len %lu",
2373*4882a593Smuzhiyun 								   pos, (unsigned long) bytes_in_block);
2374*4882a593Smuzhiyun #endif
2375*4882a593Smuzhiyun 							vfile("saving out-of-sync-block %lx, len %lu",pos,
2376*4882a593Smuzhiyun 								  (unsigned long) bytes_in_block);
2377*4882a593Smuzhiyun 							memcpy(neu->data,secbuf,bytes_in_block);
2378*4882a593Smuzhiyun 							neu->pos=pos;
2379*4882a593Smuzhiyun 							neu->len=bytes_in_block;
2380*4882a593Smuzhiyun 							neu->next=anker;
2381*4882a593Smuzhiyun 							anker=neu;
2382*4882a593Smuzhiyun 						}
2383*4882a593Smuzhiyun 						else if (neu)
2384*4882a593Smuzhiyun 							free(neu);
2385*4882a593Smuzhiyun 					}
2386*4882a593Smuzhiyun 				}
2387*4882a593Smuzhiyun #endif
2388*4882a593Smuzhiyun #ifdef SEGMENTS
2389*4882a593Smuzhiyun 				putsec(secbuf, chinseg);
2390*4882a593Smuzhiyun 				chinseg = 0;
2391*4882a593Smuzhiyun #endif
2392*4882a593Smuzhiyun 				zmputs(Attn);  continue;
2393*4882a593Smuzhiyun 			}
2394*4882a593Smuzhiyun moredata:
2395*4882a593Smuzhiyun 			//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2396*4882a593Smuzhiyun 			if ((Verbose>1 || min_bps || stop_time)
2397*4882a593Smuzhiyun 				&& (not_printed > (min_bps ? 3 : 7)
2398*4882a593Smuzhiyun 					|| zi->bytes_received > last_bps / 2 + last_rxbytes)) {
2399*4882a593Smuzhiyun 				int minleft =  0;
2400*4882a593Smuzhiyun 				int secleft =  0;
2401*4882a593Smuzhiyun 				time_t now;
2402*4882a593Smuzhiyun 				ulong d;
2403*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2404*4882a593Smuzhiyun 				d=timing(0,&now);
2405*4882a593Smuzhiyun 				if (d==0)
2406*4882a593Smuzhiyun 					d=0.5; /* timing() might use time() */
2407*4882a593Smuzhiyun 				last_bps=zi->bytes_received/d;
2408*4882a593Smuzhiyun 				if (last_bps > 0) {
2409*4882a593Smuzhiyun 					minleft =  (R_BYTESLEFT(zi))/last_bps/60;
2410*4882a593Smuzhiyun 					secleft =  ((R_BYTESLEFT(zi))/last_bps)%60;
2411*4882a593Smuzhiyun 				}
2412*4882a593Smuzhiyun 				if (min_bps) {
2413*4882a593Smuzhiyun 					if (low_bps) {
2414*4882a593Smuzhiyun 						if (last_bps<min_bps) {
2415*4882a593Smuzhiyun 							if (now-low_bps>=min_bps_time) {
2416*4882a593Smuzhiyun 								/* too bad */
2417*4882a593Smuzhiyun 								vfile(_("rzfile: bps rate %ld below min %ld"),
2418*4882a593Smuzhiyun 									  last_bps, min_bps);
2419*4882a593Smuzhiyun 								DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: bps rate low: %ld < %ld",
2420*4882a593Smuzhiyun 										   shortname, protname(), last_bps, min_bps));
2421*4882a593Smuzhiyun 								xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2422*4882a593Smuzhiyun 								return ERROR;
2423*4882a593Smuzhiyun 							}
2424*4882a593Smuzhiyun 						}
2425*4882a593Smuzhiyun 						else
2426*4882a593Smuzhiyun 							low_bps=0;
2427*4882a593Smuzhiyun 					} else if (last_bps<min_bps) {
2428*4882a593Smuzhiyun 						low_bps=now;
2429*4882a593Smuzhiyun 					}
2430*4882a593Smuzhiyun 				}
2431*4882a593Smuzhiyun 				if (stop_time && now>=stop_time) {
2432*4882a593Smuzhiyun 					/* too bad */
2433*4882a593Smuzhiyun 					vfile(_("rzfile: reached stop time"));
2434*4882a593Smuzhiyun 					DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: reached stop time",
2435*4882a593Smuzhiyun 							   shortname, protname()));
2436*4882a593Smuzhiyun 					xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2437*4882a593Smuzhiyun 					return ERROR;
2438*4882a593Smuzhiyun 				}
2439*4882a593Smuzhiyun 
2440*4882a593Smuzhiyun 				if (Verbose > 1) {
2441*4882a593Smuzhiyun 					vstringf(_("\rBytes received: %7ld/%7ld   BPS:%-6ld ETA %02d:%02d  "),
2442*4882a593Smuzhiyun 						(long) zi->bytes_received, (long) zi->bytes_total,
2443*4882a593Smuzhiyun 						last_bps, minleft, secleft);
2444*4882a593Smuzhiyun 					last_rxbytes=zi->bytes_received;
2445*4882a593Smuzhiyun 					not_printed=0;
2446*4882a593Smuzhiyun 				}
2447*4882a593Smuzhiyun 			} else if (Verbose)
2448*4882a593Smuzhiyun 				not_printed++;
2449*4882a593Smuzhiyun #ifdef SEGMENTS
2450*4882a593Smuzhiyun 			if (chinseg >= (MAX_BLOCK * SEGMENTS)) {
2451*4882a593Smuzhiyun 				putsec(secbuf, chinseg);
2452*4882a593Smuzhiyun 				chinseg = 0;
2453*4882a593Smuzhiyun 			}
2454*4882a593Smuzhiyun 			switch (c = zrdata(secbuf+chinseg, MAX_BLOCK,&bytes_in_block))
2455*4882a593Smuzhiyun #else
2456*4882a593Smuzhiyun 			switch (c = zrdata(secbuf, MAX_BLOCK,&bytes_in_block))
2457*4882a593Smuzhiyun #endif
2458*4882a593Smuzhiyun 			{
2459*4882a593Smuzhiyun 			case ZCAN:
2460*4882a593Smuzhiyun 				xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2461*4882a593Smuzhiyun #ifdef SEGMENTS
2462*4882a593Smuzhiyun 				putsec(secbuf, chinseg);
2463*4882a593Smuzhiyun 				chinseg = 0;
2464*4882a593Smuzhiyun #endif
2465*4882a593Smuzhiyun 				vfile("rzfile: zrdata returned %d", c);
2466*4882a593Smuzhiyun 				DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned ZCAN",
2467*4882a593Smuzhiyun 						   shortname, protname()));
2468*4882a593Smuzhiyun 				return ERROR;
2469*4882a593Smuzhiyun 			case ERROR:	/* CRC error */
2470*4882a593Smuzhiyun 				xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2471*4882a593Smuzhiyun #ifdef SEGMENTS
2472*4882a593Smuzhiyun 				putsec(secbuf, chinseg);
2473*4882a593Smuzhiyun 				chinseg = 0;
2474*4882a593Smuzhiyun #endif
2475*4882a593Smuzhiyun 				if ( --n < 0) {
2476*4882a593Smuzhiyun 					vfile("rzfile: zgethdr returned %d", c);
2477*4882a593Smuzhiyun 					DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned ERROR",
2478*4882a593Smuzhiyun 							   shortname, protname()));
2479*4882a593Smuzhiyun 					return ERROR;
2480*4882a593Smuzhiyun 				}
2481*4882a593Smuzhiyun 				zmputs(Attn);
2482*4882a593Smuzhiyun 				continue;
2483*4882a593Smuzhiyun 			case TIMEOUT:
2484*4882a593Smuzhiyun 				xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2485*4882a593Smuzhiyun #ifdef SEGMENTS
2486*4882a593Smuzhiyun 				putsec(secbuf, chinseg);
2487*4882a593Smuzhiyun 				chinseg = 0;
2488*4882a593Smuzhiyun #endif
2489*4882a593Smuzhiyun 				if ( --n < 0) {
2490*4882a593Smuzhiyun 					DO_SYSLOG_FNAME((LOG_INFO, "%s/%s: zrdata returned TIMEOUT",
2491*4882a593Smuzhiyun 							   shortname, protname()));
2492*4882a593Smuzhiyun 					vfile("rzfile: zgethdr returned %d", c);
2493*4882a593Smuzhiyun 					return ERROR;
2494*4882a593Smuzhiyun 				}
2495*4882a593Smuzhiyun 				continue;
2496*4882a593Smuzhiyun 			case GOTCRCW:
2497*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2498*4882a593Smuzhiyun 				n = 20;
2499*4882a593Smuzhiyun #ifdef SEGMENTS
2500*4882a593Smuzhiyun 				chinseg += bytes_in_block;
2501*4882a593Smuzhiyun 				putsec(zi, secbuf, chinseg);
2502*4882a593Smuzhiyun 				chinseg = 0;
2503*4882a593Smuzhiyun #else
2504*4882a593Smuzhiyun 				putsec(zi, secbuf, bytes_in_block);
2505*4882a593Smuzhiyun #endif
2506*4882a593Smuzhiyun 				zi->bytes_received += bytes_in_block;
2507*4882a593Smuzhiyun 				stohdr(zi->bytes_received);
2508*4882a593Smuzhiyun 				zshhdr(ZACK | 0x80, Txhdr);
2509*4882a593Smuzhiyun 				goto nxthdr;
2510*4882a593Smuzhiyun 			case GOTCRCQ:
2511*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2512*4882a593Smuzhiyun 				n = 20;
2513*4882a593Smuzhiyun #ifdef SEGMENTS
2514*4882a593Smuzhiyun 				chinseg += bytes_in_block;
2515*4882a593Smuzhiyun #else
2516*4882a593Smuzhiyun 				putsec(zi, secbuf, bytes_in_block);
2517*4882a593Smuzhiyun #endif
2518*4882a593Smuzhiyun 				zi->bytes_received += bytes_in_block;
2519*4882a593Smuzhiyun 				stohdr(zi->bytes_received);
2520*4882a593Smuzhiyun 				zshhdr(ZACK, Txhdr);
2521*4882a593Smuzhiyun 				goto moredata;
2522*4882a593Smuzhiyun 			case GOTCRCG:
2523*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2524*4882a593Smuzhiyun 				n = 20;
2525*4882a593Smuzhiyun #ifdef SEGMENTS
2526*4882a593Smuzhiyun 				chinseg += bytes_in_block;
2527*4882a593Smuzhiyun #else
2528*4882a593Smuzhiyun 				putsec(zi, secbuf, bytes_in_block);
2529*4882a593Smuzhiyun #endif
2530*4882a593Smuzhiyun 				zi->bytes_received += bytes_in_block;
2531*4882a593Smuzhiyun 				goto moredata;
2532*4882a593Smuzhiyun 			case GOTCRCE:
2533*4882a593Smuzhiyun 				//xil_printf("%s(): L%d debug\n\r", __func__, __LINE__);
2534*4882a593Smuzhiyun 				n = 20;
2535*4882a593Smuzhiyun #ifdef SEGMENTS
2536*4882a593Smuzhiyun 				chinseg += bytes_in_block;
2537*4882a593Smuzhiyun #else
2538*4882a593Smuzhiyun 				putsec(zi, secbuf, bytes_in_block);
2539*4882a593Smuzhiyun #endif
2540*4882a593Smuzhiyun 				zi->bytes_received += bytes_in_block;
2541*4882a593Smuzhiyun 				goto nxthdr;
2542*4882a593Smuzhiyun 			}
2543*4882a593Smuzhiyun 		}
2544*4882a593Smuzhiyun 	}
2545*4882a593Smuzhiyun }
2546*4882a593Smuzhiyun 
2547*4882a593Smuzhiyun /*
2548*4882a593Smuzhiyun  * Send a string to the modem, processing for \336 (sleep 1 sec)
2549*4882a593Smuzhiyun  *   and \335 (break signal)
2550*4882a593Smuzhiyun  */
2551*4882a593Smuzhiyun static void
zmputs(const char * s)2552*4882a593Smuzhiyun zmputs(const char *s)
2553*4882a593Smuzhiyun {
2554*4882a593Smuzhiyun 	__maybe_unused const char *p;
2555*4882a593Smuzhiyun 
2556*4882a593Smuzhiyun 	xil_printf("%s(): L%d zmputs not implmenment yet\n\r", __func__, __LINE__);
2557*4882a593Smuzhiyun #if 0
2558*4882a593Smuzhiyun 	while (s && *s)
2559*4882a593Smuzhiyun 	{
2560*4882a593Smuzhiyun 		p=strpbrk(s,"\335\336");
2561*4882a593Smuzhiyun 		if (!p)
2562*4882a593Smuzhiyun 		{
2563*4882a593Smuzhiyun 			write(1,s,strlen(s));
2564*4882a593Smuzhiyun 			return;
2565*4882a593Smuzhiyun 		}
2566*4882a593Smuzhiyun 		if (p!=s)
2567*4882a593Smuzhiyun 		{
2568*4882a593Smuzhiyun 			write(1,s,(size_t) (p-s));
2569*4882a593Smuzhiyun 			s=p;
2570*4882a593Smuzhiyun 		}
2571*4882a593Smuzhiyun 		if (*p=='\336')
2572*4882a593Smuzhiyun 			sleep(1);
2573*4882a593Smuzhiyun 		else
2574*4882a593Smuzhiyun 			sendbrk(0);
2575*4882a593Smuzhiyun 		p++;
2576*4882a593Smuzhiyun 	}
2577*4882a593Smuzhiyun #endif
2578*4882a593Smuzhiyun }
2579*4882a593Smuzhiyun 
2580*4882a593Smuzhiyun /*
2581*4882a593Smuzhiyun  * Close the receive dataset, return OK or ERROR
2582*4882a593Smuzhiyun  */
2583*4882a593Smuzhiyun #if 0
2584*4882a593Smuzhiyun int print_filename(FILE *f)
2585*4882a593Smuzhiyun {
2586*4882a593Smuzhiyun static	char buf[1024];
2587*4882a593Smuzhiyun 	char fnmbuf[1024];
2588*4882a593Smuzhiyun 	sprintf(fnmbuf, "/proc/self/fd/%d", fileno(f));
2589*4882a593Smuzhiyun 	ssize_t nr;
2590*4882a593Smuzhiyun 	if(0>(nr=readlink(fnmbuf, buf, sizeof(buf)))) return -1;
2591*4882a593Smuzhiyun 	else buf[nr] = 0;
2592*4882a593Smuzhiyun 	return buf;
2593*4882a593Smuzhiyun }
2594*4882a593Smuzhiyun #endif
2595*4882a593Smuzhiyun static int
closeit(struct zm_fileinfo * zi)2596*4882a593Smuzhiyun closeit(struct zm_fileinfo *zi)
2597*4882a593Smuzhiyun {
2598*4882a593Smuzhiyun 	int ret;
2599*4882a593Smuzhiyun 	if (Topipe) {
2600*4882a593Smuzhiyun #if 0
2601*4882a593Smuzhiyun 		if (pclose(fout)) {
2602*4882a593Smuzhiyun 			return ERROR;
2603*4882a593Smuzhiyun 		}
2604*4882a593Smuzhiyun #endif
2605*4882a593Smuzhiyun 		return OK;
2606*4882a593Smuzhiyun 	}
2607*4882a593Smuzhiyun #if 0
2608*4882a593Smuzhiyun 	if (in_tcpsync) {
2609*4882a593Smuzhiyun 		rewind(fout);
2610*4882a593Smuzhiyun 		if (!fgets(tcp_buf,sizeof(tcp_buf),fout)) {
2611*4882a593Smuzhiyun 			error(1,errno,_("fgets for tcp protocol synchronization failed: "));
2612*4882a593Smuzhiyun 		}
2613*4882a593Smuzhiyun 		fclose(fout);
2614*4882a593Smuzhiyun 		return OK;
2615*4882a593Smuzhiyun 	}
2616*4882a593Smuzhiyun #endif
2617*4882a593Smuzhiyun 	//ret=fclose(fout);
2618*4882a593Smuzhiyun 	ret = 0;
2619*4882a593Smuzhiyun 	if (ret) {
2620*4882a593Smuzhiyun 		zpfatal(_("file close error"));
2621*4882a593Smuzhiyun 		/* this may be any sort of error, including random data corruption */
2622*4882a593Smuzhiyun 
2623*4882a593Smuzhiyun 		//unlink(Pathname);
2624*4882a593Smuzhiyun 		return ERROR;
2625*4882a593Smuzhiyun 	}
2626*4882a593Smuzhiyun 	if (zi->modtime) {
2627*4882a593Smuzhiyun #ifdef HAVE_STRUCT_UTIMBUF
2628*4882a593Smuzhiyun 		struct utimbuf timep;
2629*4882a593Smuzhiyun 		timep.actime = time(NULL);
2630*4882a593Smuzhiyun 		timep.modtime = zi->modtime;
2631*4882a593Smuzhiyun 		//utime(Pathname, &timep);
2632*4882a593Smuzhiyun #else
2633*4882a593Smuzhiyun 		__maybe_unused time_t timep[2];
2634*4882a593Smuzhiyun 		//timep[0] = time(NULL);
2635*4882a593Smuzhiyun 		//timep[1] = zi->modtime;
2636*4882a593Smuzhiyun 		//utime(Pathname, timep);
2637*4882a593Smuzhiyun #endif
2638*4882a593Smuzhiyun 	}
2639*4882a593Smuzhiyun #ifdef S_ISREG
2640*4882a593Smuzhiyun 	if (S_ISREG(zi->mode)) {
2641*4882a593Smuzhiyun #else
2642*4882a593Smuzhiyun 	//if ((zi->mode&S_IFMT) == S_IFREG) {
2643*4882a593Smuzhiyun 	if(1) {
2644*4882a593Smuzhiyun #endif
2645*4882a593Smuzhiyun 		/* we must not make this program executable if running
2646*4882a593Smuzhiyun 		 * under rsh, because the user might have uploaded an
2647*4882a593Smuzhiyun 		 * unrestricted shell.
2648*4882a593Smuzhiyun 		 */
2649*4882a593Smuzhiyun #if 0
2650*4882a593Smuzhiyun 		if (under_rsh)
2651*4882a593Smuzhiyun 			chmod(Pathname, (00666 & zi->mode));
2652*4882a593Smuzhiyun 		else
2653*4882a593Smuzhiyun 			chmod(Pathname, (07777 & zi->mode));
2654*4882a593Smuzhiyun #endif
2655*4882a593Smuzhiyun 	}
2656*4882a593Smuzhiyun 	//chmod(Pathname, 00777);
2657*4882a593Smuzhiyun 	return OK;
2658*4882a593Smuzhiyun }
2659*4882a593Smuzhiyun 
2660*4882a593Smuzhiyun /*
2661*4882a593Smuzhiyun  * Ack a ZFIN packet, let byegones be byegones
2662*4882a593Smuzhiyun  */
2663*4882a593Smuzhiyun static void
2664*4882a593Smuzhiyun ackbibi(void)
2665*4882a593Smuzhiyun {
2666*4882a593Smuzhiyun 	int n;
2667*4882a593Smuzhiyun 
2668*4882a593Smuzhiyun 	vfile("ackbibi:");
2669*4882a593Smuzhiyun 	Readnum = 1;
2670*4882a593Smuzhiyun 	stohdr(0L);
2671*4882a593Smuzhiyun 	for (n=3; --n>=0; ) {
2672*4882a593Smuzhiyun 		purgeline(0);
2673*4882a593Smuzhiyun 		zshhdr(ZFIN, Txhdr);
2674*4882a593Smuzhiyun 		switch (READLINE_PF(100)) {
2675*4882a593Smuzhiyun 		case 'O':
2676*4882a593Smuzhiyun 			READLINE_PF(1);	/* Discard 2nd 'O' */
2677*4882a593Smuzhiyun 			vfile("ackbibi complete");
2678*4882a593Smuzhiyun 			return;
2679*4882a593Smuzhiyun 		case RCDO:
2680*4882a593Smuzhiyun 			return;
2681*4882a593Smuzhiyun 		case TIMEOUT:
2682*4882a593Smuzhiyun 		default:
2683*4882a593Smuzhiyun 			break;
2684*4882a593Smuzhiyun 		}
2685*4882a593Smuzhiyun 	}
2686*4882a593Smuzhiyun }
2687*4882a593Smuzhiyun 
2688*4882a593Smuzhiyun /*
2689*4882a593Smuzhiyun  * Strip leading ! if present, do shell escape.
2690*4882a593Smuzhiyun  */
2691*4882a593Smuzhiyun static int
2692*4882a593Smuzhiyun sys2(const char *s)
2693*4882a593Smuzhiyun {
2694*4882a593Smuzhiyun 	if (*s == '!')
2695*4882a593Smuzhiyun 		++s;
2696*4882a593Smuzhiyun 	return 0;
2697*4882a593Smuzhiyun 	//return system(s);
2698*4882a593Smuzhiyun }
2699*4882a593Smuzhiyun 
2700*4882a593Smuzhiyun /*
2701*4882a593Smuzhiyun  * Strip leading ! if present, do exec.
2702*4882a593Smuzhiyun  */
2703*4882a593Smuzhiyun static void
2704*4882a593Smuzhiyun exec2(const char *s)
2705*4882a593Smuzhiyun {
2706*4882a593Smuzhiyun #if 0
2707*4882a593Smuzhiyun 	if (*s == '!')
2708*4882a593Smuzhiyun 		++s;
2709*4882a593Smuzhiyun 	io_mode(0,0);
2710*4882a593Smuzhiyun 	execl("/bin/sh", "sh", "-c", s);
2711*4882a593Smuzhiyun 	zpfatal("execl");
2712*4882a593Smuzhiyun 	exit(1);
2713*4882a593Smuzhiyun #endif
2714*4882a593Smuzhiyun }
2715*4882a593Smuzhiyun 
2716*4882a593Smuzhiyun /*
2717*4882a593Smuzhiyun  * Routine to calculate the free bytes on the current file system
2718*4882a593Smuzhiyun  *  ~0 means many free bytes (unknown)
2719*4882a593Smuzhiyun  */
2720*4882a593Smuzhiyun static size_t
2721*4882a593Smuzhiyun getfree(void)
2722*4882a593Smuzhiyun {
2723*4882a593Smuzhiyun 	return((size_t) (~0L));	/* many free bytes ... */
2724*4882a593Smuzhiyun }
2725