⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xcb+.c

📁 支持X/YModem和cis_b+协议的串口通讯程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	PendinG_Count++;	Next_Seq=Seq_Num=(Seq_Num+1)%10;	Pending[Next].Seq=Next_Seq;	Pending[Next].packet=xc_strdup(S_Buffer);	Pending[Next].PackeT_Size=Size;	Packets_Btwn_ACKs=0;	Xmit_Packet(Size,Next_Seq,S_Buffer);	return SUCCESS;}static unsigned longcnvAtoL(ptr)char *ptr;{	unsigned short sign=FALSE;	char ch;	unsigned long result=0;	ch= *ptr++;	if (ch=='-')		sign=TRUE,		ch= *ptr++;	while (ch>='0'&&ch<='9')		result=result*10+(ch-'0'),		ch= *ptr++;	return(sign?-result:result);}staticchar *cnvLtoA(ptr, n)char *ptr;unsigned long n;{	char tmp1[11], *tmp2=tmp1;	if (!n){		*ptr++ ='0';		return ptr;	}	*tmp2++ =0;	do 		*tmp2++ =((char)(n%10))+'0',		n/=10;	while (n>0);	tmp2--;	while (*tmp2)		*ptr++ = *tmp2--;	return ptr;}static voidSend_Unexpected_Packet(){	sprintf(Msg,"Unexpected packet type");	S0(Msg);	Send_Failure('N',Msg);}FILE *QueryCreate(Offer_Resume)short Offer_Resume;{	int key;	short Condition;	FILE *fileptr;	Condition = isregfile(Name) ? Offer_Resume : Resume_Denied;	if (access(Name,0)&&(fileptr=fopen(Name,"w"))){		Result=Overwrite;		return fileptr;	} else if (access(Name,2))		Condition = Resume_Denied;	switch(Condition){	case Resume_Allowed:		sprintf(Msg,"'%s' exists; Overwrite, Resume, reName, or Abort?",Name);		break;	case Resume_Not_Allowed:		sprintf(Msg,"'%s' exists; Overwrite, reName, or Abort?",Name);		break;	case Resume_Failed:		sprintf(Msg,"'%s' CRC error; Overwrite, reName or Abort?",Name);		break;	case Resume_Denied:		sprintf(Msg,"Permission denied for '%s'; reName, or Abort?",Name);		break;	}	if (cismode)		S0(Msg);	else		S2(Msg);	for (;;){		beep();		key=toupper(fgetc(stdin));		if (isupper(key)){			fputc(key,tfp);			switch(key){			case 'O':				if (Condition!=Resume_Denied){					Result=Overwrite;					return fopen(Name,"w");				}				break;			case 'N':				fputc('\r',tfp);				cl_line();				show(-1,"Enter New Name:");				getline();				getword();				strcpy(Name,word);				return QueryCreate(Offer_Resume);			case 'A':				return NIL(FILE);			case 'R':				if (Condition==Resume_Allowed){					Result=Resume;					return fopen(Name,"r+");				}				break;			}			fputc('\b',tfp);		}	}}static intRead(fp, buf, want)FILE *fp;char *buf;register int want;{	register c;	int read_ct=0;	while (want--)		switch(c=getc(fp)){		case EOF:			return read_ct;		case '\n':			if (cr_add&&textmode&&Last_Chr!='\r')				ungetc(c,fp),				carriage_return++,				c='\r';		default:			Last_Chr= *buf++ =c;			read_ct++;		}	return read_ct;}static intWrite(fp, buf, want)FILE *fp;char *buf;register int want;{	int written=0;	for (;want-->0;buf++){		if (textmode){			if (*buf=='\r'){				Last_Chr= *buf;				continue;			}			if (Last_Chr=='\r')				if (*buf=='\n')					carriage_return--;				else					if (fputc('\r',fp)== -1)						return -1;					else						written++;			Last_Chr= *buf;		}	if (fputc(*buf,fp)== -1)		return -1;	else		written++;	}	return written;}static intReceive_File(){	char *ptr;	int N, i;	short Request_Resume;	Result=Overwrite;	if (Valid_To_Resume_Download==2)		Request_Resume=Resume_Allowed;	else		Request_Resume=Resume_Not_Allowed;	if (!(Data_File=QueryCreate(Request_Resume))){		Send_Abort();		return FAILURE;	}	chown(Name,getuid(),getgid());	if (Result==Resume){		strcpy(tdir,"Attempting receive resume of");		init_check();		do {			S_Buffer[0]='N';			N=Read(Data_File,&S_Buffer[0],PackeT_Size);			if (N>0){				for (i=0;i<N;i++)					do_checksum(S_Buffer[i]);				if (Abort_Flag){					Send_Abort();					return FAILURE;				}				already_have+=N;			}		} while (N>0);		ptr= &S_Buffer[0];		*ptr++ ='T';		*ptr++ ='r';		ptr=cnvLtoA(ptr,already_have);		*ptr++ =' ';		ptr=cnvLtoA(ptr,Checksum);		if (!Send_Packet(ptr- &S_Buffer[0])||!Flush_Pending()){			fclose(Data_File);			S0("Can't resume transfer");			return FAILURE;		}		fseek(Data_File,0L,2);		strcpy(tdir,"Resuming receive of");		data=already_have-carriage_return;		carriage_return= -carriage_return;		showmode();	} else		Send_ACK(),		strcpy(tdir,"Receiving"),		already_have=0;	for (;;){		if (Abort_Flag){			Send_Abort();			return FAILURE;		}		Wait_For_ACK(FALSE,TRUE,TRUE);		if (Packet_Received)			switch(R_Buffer[0]){			case 'N':				if ((N=Write(Data_File,&R_Buffer[1],R_BUffer_Len-1))== -1){					sprintf(Msg,"Disk write error");					S0(Msg);					Send_Failure('I',Msg);					fclose(Data_File);					return FAILURE;				}				stats(N);				break;			case 'T':				switch(R_Buffer[1]){				case 'I':					fsize=cnvAtoL(&R_Buffer[4]);					showmode();					break;				case 'C':					fclose(Data_File);					return SUCCESS;				case 'f':					fclose(Data_File);					if (!(Data_File=QueryCreate(Resume_Failed))){						Send_Abort();						return FAILURE;					}					chown(Name,getuid(),getgid());					strcpy(tdir,"Receiving");					data=already_have=carriage_return=0;					showmode();					break;				default:					Send_Unexpected_Packet();					fclose(Data_File);					return FAILURE;				}				break;			case 'F':				fclose(Data_File);				R_Buffer[R_BUffer_Len]=0;				if (Result==Resume)					sprintf(Msg,"Can't resume transfer: %s",&R_Buffer[3]);				else					sprintf(Msg,"B protocol Failure: %s",&R_Buffer[3]);				S0(Msg);				return FAILURE;			default:				Send_Unexpected_Packet();				fclose(Data_File);				return FAILURE;			}		else {			fclose(Data_File);			return FAILURE;		}	}}static char *Handle_Send_Failure(){	if (!R_BUffer_Len)		return("Remote is not responding");	else {		if (R_Buffer[0]=='F'){			if (R_BUffer_Len>=2){					R_Buffer[min(81,R_BUffer_Len)]='\0';					return(&R_Buffer[1]);				} else					return("No reason given by remote");		} else {			Send_Failure('E',"Unexpected packet type");			return("Unexpected packet type");		}	}}static intSend_File(){	int N;	struct stat statbuf;	if (!(Data_File=fopen(Name,"r"))){		sprintf(Msg,"Can't access '%s'",Name);		S0(Msg);		Send_Failure('M',Msg);		return FAILURE;	}	fstat(fileno(Data_File),&statbuf);	fsize=statbuf.st_size;	strcpy(tdir,"Transmitting");	showmode();	do {		S_Buffer[0]='N';		N=Read(Data_File,&S_Buffer[1],PackeT_Size);		if (N>0){			if (!Send_Packet(N+1)){				fclose(Data_File);				S0(Handle_Send_Failure());				return FAILURE;			}			if (Abort_Flag){				Send_Abort();				return FAILURE;			}			stats(N);		}	} while (N>0);	if (!N){		fclose(Data_File);		S_Buffer[0]='T';		S_Buffer[1]='C';		if (!Send_Packet(2)){			S0(Handle_Send_Failure());			return FAILURE;		}		return Flush_Pending();	} else {		sprintf(Msg,"Disk read error");		S0(Msg);		Send_Failure('I',Msg);		return FAILURE;	}}#define Plus_PackeT_Size	18#define LowRange		7#define HiRange			11#define My_Send_Window_Size	1#define My_Recv_Window_Size	1#define My_Buffer_Size		8#define My_Check_Method		Check_CRC#define My_Download_Resume	2#define My_Upload_Resume	0#define My_File_Information	1static unsigned char Quote_Level_Select_Low[]={	1, 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	0, 0, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};static unsigned char QuotE_Level_select_Hi[]={	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};static char QUote_Level_Mapping[]={	Quote_Not_NULL,	Quote_Default,	Quote_Extended,	Quote_Full};static intPlus_Respond(){	int Status, temp_window_size, temp_method, temp_size, MaskByte, Bit, i;	unsigned char Estimated_Quote_Level=0;	S_Buffer[0]='+';	S_Buffer[1]=My_Send_Window_Size;	S_Buffer[2]=My_Recv_Window_Size;	S_Buffer[3]=PackeT_Size/128;	S_Buffer[4]=My_Check_Method;	S_Buffer[5]=Quote_Default;	S_Buffer[6]=FALSE;	S_Buffer[15]=My_Download_Resume;	S_Buffer[16]=My_Upload_Resume;	S_Buffer[17]=My_File_Information;	for (i=0;i<8;i++)		S_Buffer[i+LowRange]=0;	for (MaskByte=0;MaskByte<4;MaskByte++)		for (Bit=0;Bit<8;Bit++){			if (Mask[MaskByte*8+Bit]&MaskLowRange)				S_Buffer[MaskByte+LowRange]|=0x80>>Bit;			if (Mask[MaskByte*8+Bit]&MaskHiRange)				S_Buffer[MaskByte+HiRange]|=0x80>>Bit;		}	for (i=R_BUffer_Len;i<Plus_PackeT_Size;i++)		R_Buffer[i]=0;	if (R_Buffer[3]<S_Buffer[3])		temp_size=(R_Buffer[3]*128);	else		temp_size=(S_Buffer[3]*128);	temp_window_size=min(R_Buffer[2],My_Send_Window_Size);	temp_method=min(R_Buffer[4],My_Check_Method);	Valid_To_Resume_Download=min(R_Buffer[15],My_Download_Resume);	ValiD_To_Resume_Upload=min(R_Buffer[16],My_Upload_Resume);	Send_FIle_Information=min(R_Buffer[17],My_File_Information);	if (R_BUffer_Len>=Plus_PackeT_Size)		for (MaskByte=0;MaskByte<4;MaskByte++)			for (Bit=0;Bit<8;Bit++){				if (R_Buffer[LowRange+MaskByte]&(0x80>>Bit))					Mask[MaskByte*8+Bit]|=MaskLowRange;				if (R_Buffer[HiRange+MaskByte]&(0x80>>Bit))					Mask[MaskByte*8+Bit]|=MaskHiRange;			}	else {		for (i=0;i<32&&Estimated_Quote_Level<3;i++){			if (Mask[i]&MaskLowRange)				Estimated_Quote_Level=					max(Quote_Level_Select_Low[i],Estimated_Quote_Level);			if (Mask[i]&MaskHiRange)				Estimated_Quote_Level=					max(QuotE_Level_select_Hi[i],Estimated_Quote_Level);		}	}	Quoting=Quote_Full;	S_Buffer[5]=QUote_Level_Mapping[Estimated_Quote_Level];	if ((Status=Send_Packet(Plus_PackeT_Size)))		if ((Status=Flush_Pending())){			Actual_Check=temp_method;			PackeT_Size=temp_size;			Window_Size=temp_window_size;		}	Quoting=Quote_Mask;	return Status;}static intDo_Transfer(){	int I, N;	short Have_DLE_B=TRUE;	for (;;){		Wait_For_ACK(Have_DLE_B,FALSE,TRUE);		if (Packet_Received){			if (R_Buffer[0]=='T'){				if (R_Buffer[1]!='D'&&R_Buffer[1]!='U'){					S0("Invalid transfer direction");					Send_Failure('N',"Not implemented");					return FAILURE;				}				if (R_Buffer[2]!='A'&&R_Buffer[2]!='B'){					S0("Invalid transfer type");					Send_Failure('N',"Not implemented");					return FAILURE;				}				N=min(R_BUffer_Len-3,SM_BUFF-1);				for (I=0;I<N;I++)					Name[I]=R_Buffer[I+3];				Name[I]='\0';				textmode=(R_Buffer[2]=='A');				if (R_Buffer[1]=='U'){					Send_ACK();					return Send_File();				} else					return Receive_File();			} else if (R_Buffer[0]=='+'){				if (Plus_Respond())					Have_DLE_B=FALSE;				else {					S0("Could not negotiate B-Plus parameters");					return FAILURE;				}			} else {				Send_Unexpected_Packet();				return FAILURE;			}		} else {			S0("Remote is not responding");			return FAILURE;		}	}}staticRETSIGTYPE cisbsigint(junk)int junk;{	signal(SIGINT,cisbsigint);	Abort_Flag=TRUE;}voidB_Transfer(){	short Status=FALSE;	RETSIGTYPE (*oldvec)();	oldvec = signal(SIGINT,cisbsigint);	cur_off();	Init();	purge();	Send_Byte(DLE);	Send_Byte('+');	Send_Byte('+');	Send_ACK();	Read_Byte();	switch(Ch){	case DLE:		Read_Byte();		if (Ch=='B')			Status=Do_Transfer();		break;	default:		fputc(Ch,tfp);		break;	}	sprintf(Msg,"File Transfer %s",Status?"Succeeded":"Failed");	S0(Msg);	beep();	if (Abort_Flag){		while (Read_Byte() && Ch==ENQ){			Seq_Num=0;			Send_Byte(DLE);			Send_Byte('+');			Send_Byte('+');			Send_ACK();		}	}	cur_on();	signal(SIGINT,oldvec);}

⌨️ 快捷键说明

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