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 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 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 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 250 void flushmo(void) 251 { 252 //flush tx 253 } 254 //return seconds elapsed between reset=1 & reset=0. float allowed 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 /***************************************************/ 270 void xsendline(int c) 271 { 272 sendline(c); 273 } 274 int printable(int c) 275 { 276 if((c>=' ') && (c <= '~')) 277 return c; 278 return '?'; 279 } 280 281 void 282 #ifdef WAYTOGO 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 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 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 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 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 * 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 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 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[]) 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 876 usage1(int exitcode) 877 { 878 usage(exitcode,NULL); 879 } 880 881 static void 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 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 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 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 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 */ 1298 int zmodem_buf_getc(int c) 1299 { 1300 return *(unsigned char *)(zmodem_addr+c); 1301 } 1302 static int 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 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 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 */ 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 1845 int islower(int c) 1846 { 1847 if((c >='a') && (c<='z')) 1848 return 1; 1849 return 0; 1850 } 1851 int isupper(int c) 1852 { 1853 if((c >='A') && (c<='Z')) 1854 return 1; 1855 return 0; 1856 } 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 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 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 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 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 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 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 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 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 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 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