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

📄 cmd.c

📁 福建博洋教育C/C++软件项目实战Linux网络编程阶段:FTP服务器开发
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	if (strcmp(State.uname, "ftp") == 0 && State.anodwload == 0)
	{
		Write(State.s, "553 Anonymous can not download\r\n", strlen("553 Anonymous can not download\r\n"));
		return -1;
	}

	if (Connect() == -1)
	{
		Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
		return -1;
	}

	int rt, total = 0;
	char type[MIN_BUF_SIZE];

	memset(type, 0, sizeof(type));
	sprintf(type, "150 Opening %s mode data connection for %s\r\n", State.type, fileName);
	Write(State.s, type, strlen(type));

	signal(SIGCHLD, SIG_IGN);
	signal(SIGUSR2, DownloadOK);

	RTrim(fileName);
	int fd = open(fileName, O_RDONLY);
	if (fd == -1)
	{
		Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
		return -1;
	}

	lseek(fd, State.offset, SEEK_SET);
	if ((rt = fork()) == 0)
	{
		char buf[FIL_BUF_SIZE];
		int readNum, semid, index = 0;

		int ibyte;
		if (State.MAX_DW != 0)
			ibyte = State.MAX_DW*1024;
		else
			ibyte = 0;

		semid = semget(shmkey, 1, 0666);
		for (;;)
		{
			memset(buf, 0, sizeof(buf));
			readNum = read(fd, buf, sizeof(buf));
			if (readNum <= 0)
				break;

			Write(State.Socket, buf, readNum);
			total += readNum;
			if (ibyte != 0)
			{
				index += readNum;
				if (index <= ibyte+FIL_BUF_SIZE && index >= ibyte-FIL_BUF_SIZE)
				{
					index = 0;
					sleep(1);
				}
			}
		}
		p(semid);
		if (State.offset == 0)
			ftpState->downFiles+=1;
		ftpState->downTraffic+=total;
		v(semid);

		close(fd);
		close(State.Socket);
		kill(getppid(), SIGUSR2);

		exit(0);
	}
	else if (rt == -1)
		return -1;

	State.offset = 0;
	close(fd);

	return 0;
}

/* 传输完毕 */
void TransOK(int i)
{
	close(State.Socket);
	State.Socket = -1;
}

/* 上载 */
int do_stor(char *fileName)
{
	if (strcmp(State.uname, "ftp") == 0 && State.anoupload == 0)
	{
		Write(State.s, "553 Anonymous can not upload\r\n", strlen("553 Anonymous can not upload\r\n"));
		return -1;
	}

	if (Connect() == -1)
	{
		Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
		return -1;
	}

	char type[MIN_BUF_SIZE];
	memset(type, 0, sizeof(type));
	sprintf(type, "150 Receive %s\r\n", fileName);
	Write(State.s, type, strlen(type));

	int rt, fd, total = 0;
	signal(SIGCHLD, SIG_IGN);
	signal(SIGUSR1, TransOK);
	
	RTrim(fileName);
	if (State.offset == 0)
		fd = open(fileName, O_CREAT | O_TRUNC |O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	else
		fd = open(fileName, O_WRONLY);

	if (fd == -1)
	{
		Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
		return -1;
	}

	if (State.offset != 0)
		lseek(fd, State.offset, SEEK_SET);

	if ((rt = fork()) == 0)
	{
		char buf[FIL_BUF_SIZE];
		int readNum, semid, index = 0;

		int ibyte;
		if (State.MAX_UP != 0)
			ibyte = State.MAX_UP*1024;
		else
			ibyte = 0;

		semid = semget(semkey, 1, 0666);
		for (;;)
		{
			memset(buf, 0, sizeof(buf));
			readNum = read(State.Socket, buf, FIL_BUF_SIZE);
			if (readNum == -1)
				if (errno == -1)
					continue;
				else
					exit(-1);
			else if (readNum == 0)
				break;
			else
			{
				total += readNum;
				write(fd, buf, readNum);
				
				if (ibyte != 0)
				{
					index += readNum;
					if (index <= ibyte+FIL_BUF_SIZE && index >= ibyte-FIL_BUF_SIZE)
					{
						index = 0;
						sleep(1);
					}
				}
			}
		}
		p(semid);
		if (State.offset == 0)
			ftpState->upFiles+=1;
		ftpState->upTraffic+=total;
		v(semid);

		Write(State.s, "226 File receive OK\r\n", strlen("226 File receive OK\r\n"));

		close(fd);
		close(State.Socket);
		kill(getppid(), SIGUSR1);

		exit(0);
	}
	else if (rt == -1)
		return -1;

	State.offset = 0;
	close(fd);

	return 0;
}

/* 断点续传 */
int do_rest(char *offSet)
{
	State.offset = atol(offSet);
	Write(State.s, FTP_RESTOK, strlen(FTP_RESTOK));

	return 0;
}

/* 转到指定目录下 */
int do_cwd(char *path)
{
	int flag, len;
	char fpath[MAX_BUF_SIZE];

	RTrim(path);
	memset(fpath, 0, sizeof(fpath));
	getcwd(fpath, MAX_BUF_SIZE);

	if (*path != '/')
	{
		if (chdir(path) == -1)
			flag = -1;
		else
			flag = 1;
	}
	else if (*path == '.')
	{
		char ftpDir[MIN_BUF_SIZE];
		memset(ftpDir, 0, sizeof(ftpDir));

		GetHomeDir("ftp", ftpDir);
		if (strcmp(fpath, ftpDir) == 0 && strcmp(State.uname, "ftp") == 0 && strcmp(path, "..") == 0)
		{
		}
		else
		{
			strcat(fpath, "/");
			strcat(fpath, path);
			RTrim(fpath);
		}
		flag = 1;
	}
	else
	{
		if (chdir(path) == -1)
			flag = -1;
		else
			flag = 1;
	}
	
	if (flag == -1)
	{
		Write(State.s, FTP_NOPERM, strlen(FTP_NOPERM));
			return -1;
	}
	else
	{
		Write(State.s, FTP_CWDOK, strlen(FTP_CWDOK));
			return 0;
	}
}

/* 中断 */
int do_abor(char *param)
{
	if (State.Socket == -1)
	{
		Write(State.s, FTP_ABOR_NOCONN, strlen(FTP_ABOR_NOCONN));
		return -1;
	}
	Write(State.s, FTP_BADSENDNET, strlen(FTP_BADSENDNET));
	Write(State.s, FTP_ABOROK, strlen(FTP_ABOROK));

	return 0;
}

/* 删除目录 */
int do_rmd(char *dir)
{
	if (strcmp(State.uname, "ftp") == 0 && State.anoupload == 0)
	{
		Write(State.s, "553 Anonymous can not delete directory\r\n", strlen("553 Anonymous can not delete directory\r\n"));
		return -1;
	}

	RTrim(dir);
	if (rmdir(dir) == -1)
	{
		Write(State.s, FTP_RMDIRFAIL, strlen(FTP_RMDIRFAIL));
		return -1;
	}
	Write(State.s, FTP_RMDIROK, strlen(FTP_RMDIROK));
	return 0;
}

/* 创建目录 */
int do_mkd(char *dir)
{
	if (strcmp(State.uname, "ftp") == 0 && State.anoupload == 0)
	{
		Write(State.s, "553 Anonymous can not make directory\r\n", strlen("553 Anonymous can not make directory\r\n"));
		return -1;
	}

	RTrim(dir);
	if (mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
	{
		Write(State.s, FTP_MKDIRFAIL, strlen(FTP_MKDIRFAIL));
		return -1;
	}

	Write(State.s, FTP_MKDIROK, strlen(FTP_MKDIROK));
	return 0;
}

/* 指令帮助 */
int do_help(char *param)
{
	char helpbuf[MAX_BUF_SIZE];
	sprintf(helpbuf, "214-OHOH.\n   USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT\n   PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS\n   ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH\n   REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ\n   QUIT    MODE    SYST    ABOR    NLST    MKD     XPWD    MDTM    PROT\r\n");
	Write(State.s, helpbuf, strlen(helpbuf));
	Write(State.s, FTP_HELP, strlen(FTP_HELP));
	return 0;
}

/* 删除文件 */
int do_dele(char *fileName)
{
	RTrim(fileName);
	if (unlink(fileName) == -1)
	{
		Write(State.s, FTP_DELEFAIL, strlen(FTP_DELEFAIL));
		return -1;
	}

	Write(State.s, FTP_DELEOK, strlen(FTP_DELEOK));
	return 0;
}

/* 重新登入 */
int do_rein(char *param)
{
	State.isLogin = 0;
	memset(State.uname, 0, sizeof(State.uname));
	memset(State.upass, 0, sizeof(State.upass));

	Write(State.s, FTP_REINOK, strlen(FTP_REINOK));
	return 0;
}

/* 状态 */
int do_stat(char *param)
{
	char m211[MAX_BUF_SIZE];

	int semid = semget(semkey, 1, 0666);
	memset(m211, 0, sizeof(m211));
	p(semid);
	sprintf(m211, "211-Ftp Status:\n    Upload   %d files, %ld Bytes\n    Download %d files, %ld Bytes\r\n", 
		ftpState->upFiles, ftpState->upTraffic, ftpState->downFiles, ftpState->downTraffic);
	v(semid);
	Write(State.s, m211, strlen(m211));
	Write(State.s, FTP_STATOK, strlen(FTP_STATOK));

	return 0;
}

/* 追加续传 */
int do_appe(char *fileName)
{
	if (strcmp(State.uname, "ftp") == 0 && State.anoupload == 0)
	{
		Write(State.s, "553 Anonymous can not upload\r\n", strlen("553 Anonymous can not upload\r\n"));
		return -1;
	}

	if (Connect() == -1)
	{
		Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
		return -1;
	}

	char type[MIN_BUF_SIZE];
	memset(type, 0, sizeof(type));
	sprintf(type, "150 Opening %s mode data connection for %s\r\n", State.type, fileName);
	Write(State.s, type, strlen(type));

	int rt;
	signal(SIGCHLD, SIG_IGN);
	signal(SIGUSR1, TransOK);
	if ((rt = fork()) == 0)
	{
		RTrim(fileName);

		char buf[MIN_BUF_SIZE];
		int readNum, semid, total = 0, index = 0;

		semid = semget(semkey, 1, 0666);

		if (ftpState == NULL);
		int fd = open(fileName, O_WRONLY | O_APPEND);

		if (fd == -1)
		{
			Write(State.s, FTP_UPLOADFAIL, strlen(FTP_UPLOADFAIL));
			exit(-1);
		}

		int ibyte;
		if (State.MAX_UP != 0)
			ibyte = State.MAX_UP*1024;
		else
			ibyte = 0;

		for (;;)
		{
			memset(buf, 0, sizeof(buf));
			readNum = read(State.Socket, buf, FIL_BUF_SIZE);
			if (readNum == -1)
				if (errno == -1)
					continue;
				else
					exit(-1);
			else if (readNum == 0)
				break;
			else
			{
				total += readNum;
				write(fd, buf, readNum);
				
				if (ibyte != 0)
				{
					index += readNum;
					if (index <= ibyte+FIL_BUF_SIZE && index >= ibyte-FIL_BUF_SIZE)
					{
						index = 0;
						sleep(1);
					}
				}
			}
		}
		p(semid);
		if (State.offset == 0)
			ftpState->upTraffic+=total;
		ftpState->upFiles+=1;
		v(semid);

		Write(State.s, FTP_TRANSFEROK, strlen(FTP_TRANSFEROK));
		close(State.Socket);
		kill(getppid(), SIGUSR1);

		exit(0);
	}
	else if (rt == -1)
		return -1;

	return 0;
}

/* 保持在线 */
int do_noop(char *param)
{
	Write(State.s, FTP_NOOPOK, strlen(FTP_NOOPOK));
	return 0;
}

/* 发送要修改文件名的文件名 */
int do_rnfr(char *oldFile)
{
	RTrim(oldFile);
	strcpy(State.oFile, oldFile);
	Write(State.s, FTP_RNFROK, strlen(FTP_RNFROK));

	return 0;
}

/* 修改指定文件为目标文件名 */
int do_rnto(char *newFile)
{
	RTrim(newFile);
	if (!State.oFile)
	{
		Write(State.s, FTP_NEEDRNFR, strlen(FTP_NEEDRNFR));
		return -1;
	}
	if (rename(State.oFile, newFile) == -1)
	{
		Write(State.s, FTP_RENAMEFAIL, strlen(FTP_RENAMEFAIL));
		return -1;
	}

	memset(State.oFile, 0, sizeof(State.oFile));
	Write(State.s, FTP_RENAMEOK, strlen(FTP_RENAMEOK));

	return 0;
}

/* 退出 */
int do_quit(char *param)
{
	Write(State.s, FTP_GOODBYE, strlen(FTP_GOODBYE));
	exit(0);
}

⌨️ 快捷键说明

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