receive.c

来自「Gcomm is a serial communications program」· C语言 代码 · 共 601 行 · 第 1/2 页

C
601
字号
	  0x78, 0x37, 0x35, 0x2c, 0x20, 0x30, 0x78, 0x36, 	  0x34, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x35, 0x2c, 	  0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 	  0x78, 0x32, 0x32, 0x2c, 0x20, 0x0a, 0x09, 0x20, 	  0x20, 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30, 	  0x78, 0x36, 0x64, 0x2c, 0x20, 0x30, 0x78, 0x36, 	  0x66, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x34, 0x2c, 	  0x20, 0x30, 0x78, 0x36, 0x35, 0x2c, 0x20, 0x30, 	  0x78, 0x36, 0x64, 0x2c, 0x20, 0x30, 0x78, 0x32, 	  0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x38, 0x2c, 	  0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x32, 	  0x32, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x61, 0x2c, 	  0x20, 0x30, 0x78, 0x30, 0x61, 0x2c, 0x20, 0x30, 	  0x78, 0x30, 0x61, 0x2c, 0x20, 0x30, 0x78, 0x36, 	  0x39, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x65, 0x2c, 	  0x20, 0x30, 0x78, 0x37, 0x34, 0x2c, 0x20, 0x30, 	  0x78, 0x30, 0x61, 0x2c, 0x20, 0x0a, 0x09, 0x20, 	  0x20, 0x30, 0x78, 0x37, 0x33, 0x2c, 0x20, 0x30, 	  0x78, 0x36, 0x35, 0x2c, 0x20, 0x30, 0x78, 0x36, 	  0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x34, 0x2c, 	  0x20, 0x30, 0x78, 0x34, 0x33, 0x2c, 0x20, 0x30, 	  0x78, 0x36, 0x18, 0x6a, 0x4a, 0xe5, 0x72, 0x71, 	} ;#define	E(b)	{b, sizeof(b)}static	struct {u_char *am; int len} Amsgs[] = {	  E(Amsg0),	  E(Amsg1),	  E(Amsg2),	  E(Amsg3),	  E(Amsg4),} ;#endif	/* TEST */	/* try to trap uninit. variables */	memset(&info,0xa5,sizeof(info)) ;	info.zrinitflags = CANFDX|CANOVIO|CANBRK|CANFC32 ;	info.packetsize = 128 ;	info.bufsize = 0 ;#ifdef	TEST	done = ZmodemRInit(&info) ;	for(i=0; !done; ++i )	  done = ZmodemRcv(Amsgs[i].am, Amsgs[i].len, &info) ;#else	if( argc < 2 )	  exit(2) ;	info.ifd = open(argv[1], O_RDWR) ;	if( info.ifd == -1 )	  exit(1) ;	tcgetattr(info.ifd,&old_settings) ;	new_settings = old_settings ;	new_settings.c_iflag &=	  ~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;	new_settings.c_oflag = 0 ;	new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;	new_settings.c_lflag = 0 ;	new_settings.c_cc[VMIN] = 32 ;	new_settings.c_cc[VTIME] = 1 ;	tcsetattr(info.ifd,TCSADRAIN, &new_settings) ;	done = ZmodemRInit(&info) ;	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( i<0 )	    perror("select") ;	  else if( i==0 )	    done = ZmodemTimeout(&info) ;	  else {	    len = read(info.ifd, buffer, sizeof(buffer)) ;	    done = ZmodemRcv(buffer, len, &info) ;	  }	}	tcsetattr(info.ifd,TCSADRAIN, &old_settings) ;#endif	/* TEST */	exit(0) ;}intZXmitStr(buffer, len, info)	u_char	*buffer ;	int	len ;	ZModem	*info ;{	int	i,j ;	u_char	c ;extern	double	drand48() ;#ifdef	TEST	for(i=0; i<len; i += 16)	{	  printf("   ") ;	  for(j=0; j<16 && i+j<len; ++j)	    printf("%2.2x ", buffer[i+j]) ;	  for(; j<16; ++j)	    printf("   ") ;	  printf("  |") ;	  for(j=0; j<16 && i+j<len; ++j)	    putchar(((c=buffer[i+j]) < 040 || c >= 0177) ? '.' : c ) ;	  printf("|\n") ;	}#else#ifdef	COMMENT/* TEST: randomly corrupt one out of every 300 bytes */for(i=0; i<len; ++i)  if( drand48() < 1./300. ) {    fprintf(stderr, "byte %d was %2.2x, is", i, buffer[i]) ;    buffer[i] ^= 1<<(lrand48()&7) ;    fprintf(stderr, " %2.2x\n", buffer[i]) ;  }#endif	/* COMMENT */	if( write(info->ifd, buffer, len) != len )	  return ZmErrSys ;#endif	/* TEST */	return 0 ;}voidZIFlush(info)	ZModem	*info ;{}voidZOFlush(info)	ZModem	*info ;{}voidZStatus(i,j,str){	fprintf(stderr,"status %d=%d\n",i,j) ;}intZAttn(info)	ZModem	*info ;{	char	*ptr ;	int	i = 0 ;	for(ptr = info->attn; *ptr != '\0'; ++ptr) {	  if( *ptr == ATTNBRK )	    ioctl(info->ifd, TCSBRK, 0) ;	  else if( *ptr == ATTNPSE )	    sleep(1) ;	  else	    write(info->ifd, ptr, 1) ;	}	return 0 ;}FILE *ZOpenFile(name, crc, info)	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,f2,f3 ;	/* 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 == 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) )	      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 )	      return NULL ;	    break ;	  case ZMCRC:		/* take if different CRC or length */	    if( exists  &&  info->len == buf.st_size && crc == FileCrc(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 )	      return NULL ;	    break ;	  case ZMDIFF:	/* take if different date or length */	    if( exists  &&  info->date == buf.st_mtime  &&		info->len == buf.st_size )	      return NULL ;	    break ;	  case ZMPROT:	/* only if dest does not exist */	    if( exists )	      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 */	if( exists && !apnd && unlink(name) != 0 )	  return NULL ;	/* TODO: build directory path if needed */	return fopen(name, apnd ? "a" : "w") ;}intZWriteFile(buffer, len, file, info)	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(info)	ZModem *info ;{	fclose(info->file) ;	chmod(info->filename, info->mode&0777) ;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?