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