📄 204.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="185.htm">上一层</a>][<a href="205.htm">下一篇</a>]
<hr><p align="left"><small>Linux 环境下的程序设计 <br>
>> Linux 综合编程 主题阅读: 313 <br>
标题 Re: ftp协议实现求助,急 [re: wgkun] <br>
作者 guansan (stranger ) <br>
时间 05/21/01 05:00 PM <br>
我这里有`ftp的server和client的c程序,比较简单,但是实现原理很清楚,你可以拿去 <br>
参考一下. <br>
******************************************************** <br>
******************************************************** <br>
server 的头文件 <br>
Support command: <br>
214-The following commands are recognized (* =>'s unimplemented). <br>
USER PASS ACCT* CWD XCWD CDUP XCUP SMNT* <br>
QUIT REIN* PORT PASV TYPE STRU* MODE* RETR <br>
STOR STOU* APPE ALLO* REST RNFR RNTO ABOR <br>
DELE MDTM RMD XRMD MKD XMKD PWD XPWD <br>
SIZE LIST NLST SITE SYST STAT HELP NOOP <br>
214 Direct comments to nolove@263.net <br>
*/ <br>
#ifndef __FTPD_H__ <br>
#define __FTPD_H__ <br>
//#define _XOPEN_SOURCE <br>
#include <sys/types.h> <br>
#include <shadow.h> <br>
#include <unistd.h> <br>
#include <crypt.h> <br>
#include <pwd.h> <br>
#include <time.h> <br>
#include <sys/wait.h> <br>
#include <netinet/in.h> <br>
#include <arpa/inet.h> <br>
#include <sys/ioctl.h> <br>
#include <utime.h> <br>
#include <stdlib.h> <br>
#include <signal.h> <br>
#include <ctype.h> <br>
#include <malloc.h> <br>
#include <sys/file.h> <br>
#include <errno.h> <br>
#include <stdarg.h> <br>
#include <sys/stat.h> <br>
#include <fcntl.h> <br>
#include <sys/socket.h> <br>
#include <netdb.h> <br>
#include <unistd.h> <br>
#include <string.h> <br>
#include <stdio.h> <br>
#include <sys/unistd.h> <br>
#include <limits.h> <br>
#define BUFSIZE (1024) <br>
#define ERRS(x) outs("550 %s: " x, param) <br>
typedef unsigned short int uint16_t; <br>
typedef unsigned int uint32_t; <br>
typedef unsigned int socklen_t; <br>
//buffer and string <br>
char inbuf[BUFSIZE]; <br>
char genbuf[BUFSIZE]; <br>
char hostname[BUFSIZE]; <br>
char path[PATH_MAX]; <br>
char rename_file[PATH_MAX]; <br>
char username[100]; <br>
char basedir[PATH_MAX]; <br>
//system arguments <br>
unsigned int ftp_port = 21; <br>
unsigned int max_conn = 65535; <br>
unsigned int timeout = 300; <br>
unsigned int file_rest = 0; <br>
char transfer_type='i'; <br>
int system_uid; <br>
//boolean <br>
int user_valid = 0; <br>
int input_user = 0; <br>
int anonymous_login = 0; <br>
int pasv_mode = 0; <br>
int transfer = 0; <br>
int listenfd; <br>
int connfd; <br>
int pasvfd; <br>
FILE *file; <br>
int data_pid = 0; <br>
FILE *data_file; <br>
#define NO_CHECK 1 <br>
#define NEED_PARAM 2 <br>
#define NO_PARAM 4 <br>
#define CHECK_LOGIN 8 <br>
#define CHECK_NOLOGIN 16 <br>
struct _cmd_list { <br>
char *cmd; <br>
void (*func)(char *param); <br>
int check; <br>
}; <br>
struct _port { <br>
uint32_t host; <br>
uint16_t port; <br>
} remote_port, local_port; <br>
int port_base = 3072; <br>
#endif //__FTPD_H__include "FTPd.h" <br>
void do_child(); <br>
void outs(char *fmt, ...) <br>
{ <br>
static char tmp[80]; <br>
va_list ap; <br>
va_start(ap, fmt); <br>
sprintf(tmp, "%s\r\n", fmt); <br>
vsprintf(genbuf, tmp, ap); <br>
send(connfd, genbuf, strlen(genbuf), 0); <br>
va_end(ap); <br>
}; <br>
void explode(char *buf, char **cmd, char **param) <br>
{ <br>
char *p; <br>
char *p; <br>
while ((p = &buf[strlen(buf)-1]) && (*p == '\r' || *p == '\n')) *p = 0; <br>
p = strchr(buf, ' '); <br>
*cmd = buf; <br>
if (!p) *param = NULL; <br>
else { <br>
*p = 0; <br>
*param = p+1; <br>
}; <br>
}; <br>
int MakePath(char *new_path, char* path, char* filename) <br>
{ <br>
return sprintf(new_path, "%s%s/%s", basedir, path, filename); <br>
}; <br>
void Error(char *param) <br>
{ <br>
switch (errno) { <br>
case ENOTEMPTY: <br>
ERRS("Directory not empty"); <br>
break; <br>
case ENOSPC: <br>
ERRS("disk full"); <br>
break; <br>
break; <br>
case EEXIST: <br>
ERRS("File exists"); <br>
break; <br>
case ENAMETOOLONG: <br>
ERRS("path is too long"); <br>
break; <br>
case ENOENT: <br>
ERRS("No such file or directory"); <br>
break; <br>
case ENOTDIR: <br>
ERRS("Not a directory"); <br>
break; <br>
case EISDIR: <br>
ERRS("Is a directory"); <br>
default: <br>
ERRS("Permission denied"); <br>
}; <br>
} <br>
int Check(char *cmd, char *param, int check) <br>
{ <br>
if (check & CHECK_LOGIN && !user_valid) { <br>
outs("530 Please login with USER and PASS"); <br>
return 0; <br>
}; <br>
if (check & CHECK_NOLOGIN && user_valid) { <br>
outs("503 You are already logged in!"); <br>
return 0; <br>
}; <br>
if (check & NEED_PARAM) { <br>
if (!param) outs("501 Invalid number of arguments, check more arguments."); <br>
return (param != NULL); <br>
}; <br>
if (check & NO_PARAM) { <br>
if (param) outs("501 Invalid number of arguments."); <br>
return (param == NULL); <br>
}; <br>
return 1; <br>
}; <br>
void DataConnection(int mode, int transfer_type, char *filename) <br>
{ <br>
int datafd; <br>
struct sockaddr_in sa; <br>
socklen_t len = sizeof(sa); <br>
char buf[BUFSIZE], *p; <br>
int readlen, ret; <br>
FILE *tmp; <br>
if (data_pid != 0) { <br>
ret = waitpid(data_pid, NULL, WNOHANG|WUNTRACED); <br>
if (kill(data_pid, 0) == 0) { <br>
outs("425 Try later, data connection in use."); <br>
return; <br>
}; <br>
}; <br>
if ((data_pid = fork()) == 0) { <br>
if (pasv_mode) { <br>
if ((datafd = accept(pasvfd, (struct sockaddr *)&sa, &len)) == -1) { <br>
close(pasvfd); <br>
outs("425 Transfer error."); <br>
exit(-1); <br>
}; <br>
outs("150 Opening %s mode data connection for %s.", (transfer_type == 'i')?" <br>
BINARY":"ASCII", filename); <br>
} else { <br>
memset(&sa, 0, len); <br>
sa.sin_family = AF_INET; <br>
sa.sin_addr.s_addr = remote_port.host; <br>
sa.sin_port = remote_port.port; <br>
outs("150 Opening %s mode data connection for %s.", (transfer_type == 'i')?" <br>
BINARY":"ASCII", filename); <br>
if ((datafd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || connect(datafd, (str <br>
uct sockaddr *)&sa, len) == -1) { <br>
outs("425 Transfer error."); <br>
exit(-1); <br>
}; <br>
}; <br>
if (mode) { <br>
/* write */ <br>
if (transfer_type == 'i') { <br>
while ((readlen = fread(buf, 1, BUFSIZE, data_file)) >0 ) { <br>
send(datafd, buf, readlen, 0); <br>
}; <br>
} else { <br>
while ((fgets(buf, BUFSIZE, data_file) != NULL)) { <br>
while ((p = &buf[strlen(buf)-1]) && (*p == '\r' || *p == '\n')) *p = 0; <br>
strcat(buf, "\r\n"); <br>
send(datafd, buf, strlen(buf), 0); <br>
}; <br>
}; <br>
}; <br>
} else { <br>
/* read */ <br>
if (transfer_type == 'i') { <br>
while ((readlen = recv(datafd, buf, BUFSIZE, 0)) >0 ) { <br>
if (fwrite(buf, 1, readlen, data_file) == -1) break; <br>
}; <br>
} else { <br>
tmp = fdopen(datafd, "r"); <br>
while ((fgets(buf, BUFSIZE, tmp) != NULL)) { <br>
while ((p = &buf[strlen(buf)-1]) && (*p == '\r' || *p == '\n')) *p = 0; <br>
strcat(buf, "\n"); <br>
if (fwrite(buf, 1, strlen(buf), data_file) == -1) break; <br>
}; <br>
}; <br>
}; <br>
close(datafd); <br>
outs("226 Transfer complete."); <br>
exit(0); <br>
}; <br>
fclose(data_file); <br>
if (pasv_mode) close(pasvfd); <br>
pasv_mode = 0; <br>
pasv_mode = 0; <br>
file_rest = 0; <br>
}; <br>
void Help(char *param) <br>
{ <br>
if (!param) { <br>
outs("214-The following commands are recognized (* =>'s unimplemented)."); <br>
outs(" USER PASS ACCT* CWD XCWD CDUP XCUP SMNT* "); <br>
outs(" QUIT REIN* PORT PASV TYPE STRU* MODE* RETR "); <br>
outs(" STOR STOU* APPE ALLO* REST RNFR RNTO ABOR "); <br>
outs(" DELE MDTM RMD XRMD MKD XMKD PWD XPWD "); <br>
outs(" SIZE LIST NLST SITE SYST STAT HELP NOOP "); <br>
outs("214 Direct comments to nolove@263.net"); <br>
} else { <br>
outs("214 Sorry, I haven't write the topic help."); <br>
}; <br>
}; <br>
void User(char *param) <br>
{ <br>
if (user_valid) { <br>
outs("503 You are already logged in!"); <br>
return; <br>
}; <br>
}; <br>
if (!param) { <br>
outs("500 \'USER\': command requires a parameter."); <br>
return; <br>
}; <br>
strncpy(username, param, 100); <br>
if (strcasecmp(username, "anonymous") == 0) { <br>
anonymous_login = 1; <br>
strncpy(username, "ftp", 100); <br>
outs("331 Anonymous login ok, send your complete e-mail address as password. <br>
"); <br>
} else outs("331 Password required for %s", username); <br>
input_user = 1; <br>
}; <br>
void Pass(char *param) <br>
{ <br>
struct passwd *pw; <br>
struct spwd *spw; <br>
char *passwd, salt[13]; <br>
char *curuser = getlogin(); <br>
if (!input_user) { <br>
outs("503 Login with USER first."); <br>
return; <br>
return; <br>
}; <br>
/* judge and chdir to its home directory */ <br>
if (!anonymous_login) { <br>
/* <br>
if (system_uid != 0) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
if ((pw = getpwnam(username)) == NULL) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
passwd = pw->pw_passwd; <br>
if (passwd == NULL || strcmp(passwd, "x") == 0) { <br>
spw = getspnam(username); <br>
if (spw == NULL || (passwd = spw->sp_pwdp) == NULL) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
}; <br>
}; <br>
strncpy(salt, passwd, 12); <br>
if (strcmp(passwd, crypt(param, salt)) != 0) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
strcpy(path, ""); <br>
setuid(pw->pw_uid); <br>
*/ <br>
if (curuser && strcmp(curuser, username) != 0) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
if ((pw = getpwnam(username)) == NULL) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
if (pw->pw_dir) strncpy(path, pw->pw_dir, PATH_MAX); <br>
else strcpy(path, "/"); <br>
outs("230 User %s logged in.", username); <br>
chdir(path); <br>
getcwd(path, PATH_MAX); <br>
user_valid = 1; <br>
} else { <br>
if ((pw = getpwuid(system_uid)) == NULL) { <br>
outs("530 Login incorrect."); <br>
input_user = 0; <br>
return; <br>
}; <br>
if (pw->pw_dir) strncpy(basedir, pw->pw_dir, PATH_MAX); <br>
else strcpy(basedir, ""); <br>
strcpy(path, "/"); <br>
chdir(basedir); <br>
getcwd(basedir, PATH_MAX); <br>
user_valid = 1; <br>
outs("230 Anonymous access granted, restrictions apply."); <br>
}; <br>
}; <br>
void Pwd(char *param) <br>
{ <br>
outs("257 \"%s\" is current directory.", path); <br>
}; <br>
void Cwd(char *param) <br>
{ <br>
char tmp[PATH_MAX]; <br>
if (param[0] == '/') MakePath(tmp, "", param); else MakePath(tmp, path, para <br>
m); <br>
if (chdir(tmp) == -1) { <br>
Error(param); <br>
} else { <br>
if (getcwd(tmp, PATH_MAX) == NULL) ERRS("Permission denied"); <br>
else { <br>
if (anonymous_login) { <br>
if (strncmp(basedir, tmp, strlen(basedir)) != 0) { <br>
chdir(basedir); <br>
strcpy(path, "/"); <br>
} else { <br>
strncpy(path, &tmp[strlen(basedir)], PATH_MAX); <br>
strcat(path, "/"); <br>
}; <br>
} else strcpy(path, tmp); <br>
outs("250 CWD command successful."); <br>
}; <br>
}; <br>
}; <br>
}; <br>
void Cdup(char *param) <br>
{ <br>
Cwd(".."); <br>
}; <br>
void Mkd(char *param) <br>
{ <br>
if (mkdir(param, 0755) == -1) { <br>
Error(param); <br>
} else { <br>
outs("257 \"%s/%s\" - Directory successfully created.", path, param); <br>
}; <br>
}; <br>
void Rmd(char *param) <br>
{ <br>
if (rmdir(param) == -1) { <br>
Error(param); <br>
} else { <br>
outs("250 RMD command successful."); <br>
}; <br>
}; <br>
}; <br>
void Type(char *param) <br>
{ <br>
if (strcasecmp(param, "i") == 0) { <br>
outs("200 Type set to I"); <br>
transfer_type = 'i'; <br>
return; <br>
}; <br>
if (strcasecmp(param, "a") == 0) { <br>
outs("200 Type set to A"); <br>
transfer_type = 'a'; <br>
return; <br>
}; <br>
outs("500 \'TYPE %s\' not understood.", param); <br>
}; <br>
void Size(char *param) <br>
{ <br>
struct stat s; <br>
if (stat(param, &s) == -1) { <br>
Error(param); <br>
} else { <br>
if (S_ISREG(s.st_mode)) outs("213 %d", s.st_size); <br>
else outs("550 %s: not a regular file.", param); <br>
}; <br>
}; <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -