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

📄 ftpserv.c

📁 在51单片机上实现TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
			logmsg(fileno(ftp.control),"DELE %s",file);
			fprintf(ftp.control,deleok);
		} else {
			fprintf(ftp.control,delefail,sys_errlist[errno]);
		}
		FREE(file);
		break;
	case PASS_CMD:
		if(ftp.username == NULL)
			fprintf(ftp.control,userfirst);
		else
			ftplogin(&ftp,arg);			
		break;
#ifndef	CPM
	case XMKD_CMD:
	case MKD_CMD:
		file = pathname(ftp.cd,arg);
		if(!permcheck(ftp.path,ftp.perms,MKD_CMD,file)){
			fprintf(ftp.control,noperm);
#ifdef	__TURBOC__
		} else if(mkdir(file) == 0){
#else
		} else if(mkdir(file,0777) == 0){
#endif
			logmsg(fileno(ftp.control),"MKD %s",file);
			fprintf(ftp.control,mkdok);
		} else {
			fprintf(ftp.control,cantmake,file,sys_errlist[errno]);
		}
		FREE(file);
		break;
	case XRMD_CMD:
	case RMD_CMD:
		file = pathname(ftp.cd,arg);
		if(!permcheck(ftp.path,ftp.perms,RMD_CMD,file)){
		 	fprintf(ftp.control,noperm);
		} else if(rmdir(file) == 0){
			logmsg(fileno(ftp.control),"RMD %s",file);
			fprintf(ftp.control,deleok);
		} else {
			fprintf(ftp.control,delefail,sys_errlist[errno]);
		}
		FREE(file);
		break;
	case STRU_CMD:
		if(tolower(arg[0]) != 'f')
			fprintf(ftp.control,unsupp);
		else
			fprintf(ftp.control,okay);
		break;
	case MODE_CMD:
		if(tolower(arg[0]) != 's')
			fprintf(ftp.control,unsupp);
		else
			fprintf(ftp.control,okay);
		break;
	case SYST_CMD:
		fprintf(ftp.control,syst,System,NBBY,Version);
		break;
	case XMD5_CMD:
		file = pathname(ftp.cd,arg);
		switch(ftp.type){
		case IMAGE_TYPE:
		case LOGICAL_TYPE:
			mode = READ_BINARY;
			break;
		case ASCII_TYPE:
			mode = READ_TEXT;
			break;
		}
		if(!permcheck(ftp.path,ftp.perms,RETR_CMD,file)){
		 	fprintf(ftp.control,noperm);
		} else if((ftp.fp = fopen(file,mode)) == NULL){
			fprintf(ftp.control,cantopen,file,sys_errlist[errno]);
		} else {
			uint8 hash[16];

			logmsg(fileno(ftp.control),"XMD5 %s",file);
			if(ftp.type == ASCII_TYPE && isbinary(ftp.fp))
				fprintf(ftp.control,binwarn,file);

			md5hash(ftp.fp,hash,ftp.type == ASCII_TYPE);
			fclose(ftp.fp);
			ftp.fp = NULL;
			fprintf(ftp.control,"200 ");
			for(i=0;i<16;i++)
				fprintf(ftp.control,"%02x",hash[i]);
			fprintf(ftp.control," %s\n",file);
		}
		FREE(file);
		break;
	}
#endif
	goto loop;
finish:
	logmsg(fileno(ftp.control),"close FTP");
	/* Clean up */
	fclose(ftp.control);
	if(ftp.data != NULL)
		fclose(ftp.data);
	if(ftp.fp != NULL)
		fclose(ftp.fp);
	free(ftp.username);
	free(ftp.path);
	free(ftp.cd);
}

/* Shut down FTP server */
int
ftp0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_FTP;
	else
		port = atoi(argv[1]);

	return stop_tcp(port);
}
static
int
pport(sock,arg)
struct sockaddr_in *sock;
char *arg;
{
	int32 n;
	int i;

	n = 0;
	for(i=0;i<4;i++){
		n = atoi(arg) + (n << 8);
		if((arg = strchr(arg,',')) == NULL)
			return -1;
		arg++;
	}
	sock->sin_addr.s_addr = n;
	n = atoi(arg);
	if((arg = strchr(arg,',')) == NULL)
		return -1;
	arg++;
	n = atoi(arg) + (n << 8);
	sock->sin_port = n;
	return 0;
}

/* Attempt to log in the user whose name is in ftp->username and password
 * in pass
 */
static void
ftplogin(ftp,pass)
struct ftpserv *ftp;
char *pass;
{
	char *path;
	int anony = 0;

	path = mallocw(200);
	if((ftp->perms = userlogin(ftp->username,pass,&path,200,&anony))
	   == -1){
		fprintf(ftp->control,noperm);
		free(path);
		return;
	}
	/* Set up current directory and path prefix */
#if	defined(AMIGAGONE)
	ftp->cd = pathname("", path);
	ftp->path = strdup(ftp->cd);
	free(path);
#else
	ftp->cd = path;
	ftp->path = strdup(path);
#endif

	fprintf(ftp->control,logged);
	if(!anony)
		logmsg(fileno(ftp->control),"%s logged in",ftp->username);
	else
		logmsg(fileno(ftp->control),"%s logged in, ID %s",ftp->username,pass);
}

#ifdef	MSDOS
/* Illegal characters in a DOS filename */
static char badchars[] = "\"[]:|<>+=;,";
#endif

/* Return 1 if the file operation is allowed, 0 otherwise */
int
permcheck(path,perms,op,file)
char *path;
int perms;
int op;
char *file;
{
#ifdef	MSDOS
	char *cp;
#endif

	if(file == NULL || path == NULL)
		return 0;	/* Probably hasn't logged in yet */
#ifdef	MSDOS
	/* Check for characters illegal in MS-DOS file names */
	for(cp = badchars;*cp != '\0';cp++){
		if(strchr(file,*cp) != NULL)
			return 0;	
	}
#endif
#ifndef MAC
	/* The target file must be under the user's allowed search path */
	if(strncmp(file,path,strlen(path)) != 0)
		return 0;
#endif

	switch(op){
	case RETR_CMD:
		/* User must have permission to read files */
		if(perms & FTP_READ)
			return 1;
		return 0;
	case DELE_CMD:
	case RMD_CMD:
		/* User must have permission to (over)write files */
		if(perms & FTP_WRITE)
			return 1;
		return 0;
	case STOR_CMD:
	case MKD_CMD:
		/* User must have permission to (over)write files, or permission
		 * to create them if the file doesn't already exist
		 */
		if(perms & FTP_WRITE)
			return 1;
		if(access(file,2) == -1 && (perms & FTP_CREATE))
			return 1;
		return 0;
	}
	return 0;	/* "can't happen" -- keep lint happy */
}
static int
sendit(ftp,command,file)
struct ftpserv *ftp;
char *command;
char *file;
{
	long total;
	struct sockaddr_in dport;
	int s;

	s = socket(AF_INET,SOCK_STREAM,0);
	dport.sin_family = AF_INET;
	dport.sin_addr.s_addr = INADDR_ANY;
	dport.sin_port = IPPORT_FTPD;
	bind(s,(struct sockaddr *)&dport,SOCKSIZE);
	fprintf(ftp->control,sending,command,file);
	fflush(ftp->control);
	if(connect(s,(struct sockaddr *)&ftp->port,SOCKSIZE) == -1){
		fclose(ftp->fp);
		ftp->fp = NULL;
		close_s(s);
		ftp->data = NULL;
		fprintf(ftp->control,noconn);
		return -1;
	}
	ftp->data = fdopen(s,"r+");
	/* Do the actual transfer */
	total = sendfile(ftp->fp,ftp->data,ftp->type,0);

	if(total == -1){
		/* An error occurred on the data connection */
		fprintf(ftp->control,noconn);
		shutdown(fileno(ftp->data),2);	/* Blow away data connection */
		fclose(ftp->data);
	} else {
		fprintf(ftp->control,txok);
	}
	fclose(ftp->fp);
	ftp->fp = NULL;
	fclose(ftp->data);
	ftp->data = NULL;
	if(total == -1)
		return -1;
	else
		return 0;
}
static int
recvit(ftp,command,file)
struct ftpserv *ftp;
char *command;
char *file;
{
	struct sockaddr_in dport;
	long total;
	int s;

	s = socket(AF_INET,SOCK_STREAM,0);
	dport.sin_family = AF_INET;
	dport.sin_addr.s_addr = INADDR_ANY;
	dport.sin_port = IPPORT_FTPD;
	bind(s,(struct sockaddr *)&dport,SOCKSIZE);
	fprintf(ftp->control,sending,command,file);
	fflush(ftp->control);
	if(connect(s,(struct sockaddr *)&ftp->port,SOCKSIZE) == -1){
		fclose(ftp->fp);
		ftp->fp = NULL;
		close_s(s);
		ftp->data = NULL;
		fprintf(ftp->control,noconn);
		return -1;
	}
	ftp->data = fdopen(s,"r+");
	/* Do the actual transfer */
	total = recvfile(ftp->fp,ftp->data,ftp->type,0);

#ifdef	CPM
	if(ftp->type == ASCII_TYPE)
		putc(CTLZ,ftp->fp);
#endif
	if(total == -1) {
		/* An error occurred while writing the file */
		fprintf(ftp->control,writerr,sys_errlist[errno]);
		shutdown(fileno(ftp->data),2);	/* Blow it away */
		fclose(ftp->data);
	} else {
		fprintf(ftp->control,rxok);
		fclose(ftp->data);
	}
	ftp->data = NULL;
	fclose(ftp->fp);
	ftp->fp = NULL;
	if(total == -1)
		return -1;
	else
		return 0;
}

⌨️ 快捷键说明

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