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