📄 main.c
字号:
corrupt(u_char *buffer, int len){ extern double drand48() ; while( --len >= 0 ) { if( drand48() < 1./1000. ) *buffer ^= 0x81 ; ++buffer ; }}static intdoIO(ZModem *info){ fd_set readfds ; struct timeval timeout ; int i ; int len ; u_char buffer[1024] ; int done = 0 ; while(!done) { FD_ZERO(&readfds) ; FD_SET(info->ifd, &readfds) ; timeout.tv_sec = info->timeout ; timeout.tv_usec = 0 ; i = select(info->ifd+1, &readfds,NULL,NULL, &timeout) ; if( doCancel ) { ZmodemAbort(info) ; fprintf(stderr, "cancelled by user\n") ; resetCom() ; exit(3) ; } if( i<0 ) perror("select") ; else if( i==0 ) done = ZmodemTimeout(info) ; else { len = read(info->ifd, buffer, sizeof(buffer)) ; if( Corrupt ) corrupt(buffer, len) ; if( SerialLogFile != NULL ) SerialLog(buffer, len, 1) ; done = ZmodemRcv(buffer, len, info) ; } } if( SerialLogFile != NULL ) SerialLogFlush() ; return done ;}static intInitXmit(ZModem *info){ int done ; if( xmodem ) done = XmodemTInit(info) ; else if( ymodem ) done = YmodemTInit(info) ; else done = ZmodemTInit(info) ; if( !done ) done = doIO(info) ; return done != ZmDone ;}static intXmitFile(char *filename, int f0, int f1, ZModem *info){ int done ; done = ZmodemTFile(filename,filename, f0,f1,0,0, 0,0, info) ; switch( done ) { case 0: if( verbose ) fprintf(stderr, "Sending: \"%s\"\n", filename) ; break ; case ZmErrCantOpen: fprintf(stderr, "cannot open file \"%s\": %s\n", filename, strerror(errno)) ; return 0 ; case ZmFileTooLong: fprintf(stderr, "filename \"%s\" too long, skipping...\n", filename) ; return 0 ; case ZmDone: return 0 ; default: return 1 ; } if( !done ) done = doIO(info) ; return done != ZmDone ;}static intFinishXmit(ZModem *info){ int done ; done = ZmodemTFinish(info) ; if( !done ) done = doIO(info) ; return done != ZmDone ;}static intDoReceive(ZModem *info){ int done ; if( ymodem ) done = YmodemRInit(info) ; else done = ZmodemRInit(info) ; if( !done ) done = doIO(info) ; return done != ZmDone ;}intZXmitStr(u_char *buffer, int len, ZModem *info){ u_char b2[1024] ; /* TEST: randomly corrupt every 1000th byte */ if( Corrupt ) { bcopy(buffer, b2, len) ; corrupt(b2, len) ; buffer = b2 ; } if( SerialLogFile != NULL ) SerialLog(buffer, len, 0) ; if( write(info->ofd, buffer, len) != len ) return ZmErrSys ; return 0 ;}voidZIFlush(ZModem *info){ if( SerialLogFile != NULL ) SerialLogFlush() ; if( tcflush(info->ifd, TCIFLUSH) != 0 ) perror("TCIFLUSH") ;}voidZOFlush(ZModem *info){ if( SerialLogFile != NULL ) SerialLogFlush() ; if( tcflush(info->ifd, TCOFLUSH) != 0 ) perror("TCOFLUSH") ;}voidZStatus(int type, int j, char *str){ switch( type ) { case RcvByteCount: if( verbose >= 2 ) fprintf(stderr, "received: %6d bytes\n", j) ; break ; case SndByteCount: fileSent = j ; if( verbose >= 2 ) fprintf(stderr, "sent: %6d bytes\n", j) ; break ; case RcvTimeout: if( verbose ) fprintf(stderr, "receiver timeouts: %2d\n", j) ; break ; case SndTimeout: if( verbose ) fprintf(stderr, "sender timeouts: %2d\n", j) ; break ; case RmtCancel: fprintf(stderr, "transfer cancelled by remote\n") ; break ; case ProtocolErr: if( verbose >= 3 ) fprintf(stderr, "protocol error: %2.2d\n", j) ; break ; case RemoteMessage: fprintf(stderr, "remote message: %s\n",str) ; break ; case DataErr: if( verbose >= 3 ) fprintf(stderr, "data errors: %2d\n", j) ;#ifdef COMMENT if( ++fileErrs > 20 ) { /* something's wrong */ ZmodemAbort(&info) ; }#endif /* COMMENT */ break ; case FileErr: fprintf(stderr, "cannot write file: %s\n", strerror(errno)) ; break ; }}intZAttn(ZModem *info){ char *ptr ; if( info->attn == NULL ) return 0 ; for(ptr = info->attn; *ptr != '\0'; ++ptr) { if( *ptr == ATTNBRK ) tcsendbreak(info->ifd, 0) ; else if( *ptr == ATTNPSE ) sleep(1) ; else write(info->ifd, ptr, 1) ; } return 0 ;}FILE *ZOpenFile(char *name, u_long crc, ZModem *info){ struct stat buf ; int exists ; /* file already exists */static int changeCount = 0 ; char name2[MAXPATHLEN] ; int apnd = 0 ; int f0,f1 ; FILE *rval ; /* TODO: if absolute path, do we want to allow it? * if relative path, do we want to prepend something? */ if( *name == '/' ) /* for now, disallow absolute paths */ return NULL ; if( stat(name, &buf) == 0 ) exists = 1 ; else if( errno == ENOENT ) exists = 0 ; else return NULL ; /* if remote end has not specified transfer flags, we can * accept the local definitions */ if( (f0=info->f0) == 0 ) { if( ascii ) f0 = ZCNL ; else if( binary ) f0 = ZCBIN ; else if( resume ) f0 = ZCRESUM ; else f0 = 0 ; } if( (f1=info->f1) == 0 ) f1 = xferType | noloc ; if( f0 == ZCRESUM ) { /* if exists, and we already have it, return */ if( exists && buf.st_size == info->len ) return NULL ; apnd = 1 ; } /* reject if file not found and it most be there (ZMSKNOLOC) */ if( !exists && (f1 & ZMSKNOLOC) ) return NULL ; switch( f1 & ZMMASK ) { case 0: /* Implementation-dependent. In this case, we * reject if file exists (and ZMSKNOLOC not set) */ if( exists && !(f1 & ZMSKNOLOC) ) { fprintf(stderr, "%s already exists\n", name) ; return NULL ; } break ; case ZMNEWL: /* take if newer or longer than file on disk */ if( exists && info->date <= buf.st_mtime && info->len <= buf.st_size ) { fprintf(stderr, "%s already exists\n", name) ; return NULL ; } break ; case ZMCRC: /* take if different CRC or length */ if( exists && info->len == buf.st_size && crc == FileCrc(name) ) { fprintf(stderr, "%s already exists\n", name) ; return NULL ; } break ; case ZMAPND: /* append */ apnd = 1 ; case ZMCLOB: /* unconditional replace */ break ; case ZMNEW: /* take if newer than file on disk */ if( exists && info->date <= buf.st_mtime ) { fprintf(stderr, "%s already exists and is newer\n", name) ; return NULL ; } break ; case ZMDIFF: /* take if different date or length */ if( exists && info->date == buf.st_mtime && info->len == buf.st_size ) { fprintf(stderr, "%s already exists\n", name) ; return NULL ; } break ; case ZMPROT: /* only if dest does not exist */ if( exists ) { fprintf(stderr, "%s already exists\n", name) ; return NULL ; } break ; case ZMCHNG: /* invent new filename if exists */ if( exists ) { while( exists ) { sprintf(name2, "%s_%d", name, changeCount++) ; exists = stat(name2, &buf) == 0 || errno != ENOENT ; } name = name2 ; } break ; } /* here if we've decided to accept */#ifdef COMMENT if( exists && !apnd && unlink(name) != 0 ) return NULL ;#endif /* COMMENT */ /* TODO: build directory path if needed */ if( verbose ) fprintf(stderr, "Receiving: \"%s\"\n", name) ; rval = fopen(name, apnd ? "a" : "w") ; if( rval == NULL ) perror(name) ; return rval ;}intZWriteFile(u_char *buffer, int len, FILE *file, ZModem *info){ /* TODO: if ZCNL set in info->f0, convert * newlines to local convention */ return fwrite(buffer, 1, len, file) == len ? 0 : ZmErrSys ;}intZCloseFile(ZModem *info){ struct timeval tvp[2] ; fclose(info->file) ; if( ymodem ) truncate(info->filename, info->len) ; if( info->date != 0 ) { tvp[0].tv_sec = tvp[1].tv_sec = info->date ; tvp[0].tv_usec = tvp[1].tv_usec = 0 ; utimes(info->filename, tvp) ; } if( info->mode & 01000000 ) chmod(info->filename, info->mode&0777) ; return 0 ;}voidZIdleStr(u_char *buffer, int len, ZModem *info){#ifdef COMMENT fwrite(buffer, 1,len, stdout) ;#endif /* COMMENT */}voidZFlowControl(int onoff, ZModem *info){ if( onoff ) { new_settings.c_iflag |= IXON|IXANY|IXOFF ;#ifdef COMMENT new_settings.c_cflag |= CRTSCTS ;#endif /* COMMENT */ } else { new_settings.c_iflag &= ~(IXON|IXANY|IXOFF) ; new_settings.c_cflag &= ~CRTSCTS ; } tcsetattr(info->ifd,TCSADRAIN, &new_settings) ;}static char *basename(char *name){ char *ptr ; if( (ptr = strrchr(name, '/')) == NULL ) return name ; else return ++ptr ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -