📄 204.htm
字号:
void Stat(char *param) <br>
{ <br>
FILE *f; <br>
static char tmp[PATH_MAX], tmp2[PATH_MAX]; <br>
static char statbuf[BUFSIZE]; <br>
outs("211-status of \"%s\":", param); <br>
if (strchr(param, ' ') != NULL) sprintf(tmp2, "\"%s\"", param); <br>
else sprintf(tmp2, "%s", param); <br>
sprintf(tmp, "/bin/ls -l %s", tmp2); <br>
if ((f = popen(tmp, "r")) != NULL) { <br>
while (fgets(statbuf, BUFSIZE, f) != NULL) { <br>
if (statbuf[0] == 't') continue; <br>
send(connfd, statbuf, strlen(statbuf), 0); <br>
}; <br>
pclose(f); <br>
}; <br>
outs("211 End of Status"); <br>
}; <br>
void Dele(char *param) <br>
{ <br>
{ <br>
if (unlink(param) == -1) { <br>
Error(param); <br>
} else { <br>
outs("250 DELE command successful."); <br>
}; <br>
}; <br>
void Quit(char *param) <br>
{ <br>
outs("221 Goodbye"); <br>
fclose(file); <br>
exit(0); <br>
}; <br>
void Noop(char *param) <br>
{ <br>
outs("200 NOOP command successful"); <br>
}; <br>
void DoList(char *param, char *cmd) <br>
{ <br>
char tmp[PATH_MAX], tmp2[PATH_MAX]; <br>
char *mode = "r"; <br>
MakePath(tmp, path, param); <br>
if (param) { <br>
if (param) { <br>
if (strchr(param, ' ') != NULL) sprintf(tmp2, "\"%s\"", param); <br>
else sprintf(tmp2, "%s", param); <br>
} else strcpy(tmp2, ""); <br>
sprintf(tmp, "/bin/ls %s %s", cmd, tmp2); <br>
if ((data_file = popen(tmp, mode)) == NULL) { <br>
Error("LIST"); <br>
return; <br>
}; <br>
DataConnection(1, 'a', "/bin/ls"); <br>
}; <br>
void List(char *param) <br>
{ <br>
if (param) DoList(param, "-l"); else DoList("", "-l"); <br>
}; <br>
void Nlst(char *param) <br>
{ <br>
if (param) DoList(param, "-1"); else DoList("", "-1"); <br>
}; <br>
void PreConnection(char *param, char open_mode, int data_mode) <br>
{ <br>
char tmp[PATH_MAX]; <br>
char mode[3]; <br>
char mode[3]; <br>
struct stat s; <br>
MakePath(tmp, path, param); <br>
mode[0] = open_mode; <br>
if (transfer_type == 'i') mode[1] = 'b'; else mode[1] = 't'; <br>
mode[2] = 0; <br>
if (data_mode && stat(tmp, &s) == -1) <br>
{ <br>
Error(param); <br>
return; <br>
}; <br>
if ((data_file = fopen(tmp, mode)) == NULL) { <br>
Error(param); <br>
return; <br>
}; <br>
if (open_mode != 'a') fseek(data_file, file_rest, SEEK_SET); <br>
if (data_mode) { <br>
sprintf(tmp, "%s (%d bytes)", param, s.st_size - file_rest); <br>
} else { <br>
strcpy(tmp, param); <br>
}; <br>
DataConnection(data_mode, transfer_type, tmp); <br>
}; <br>
}; <br>
void Retr(char *param) <br>
{ <br>
PreConnection(param, 'r', 1); <br>
}; <br>
void Stor(char *param) <br>
{ <br>
PreConnection(param, 'w', 0); <br>
}; <br>
void Appe(char *param) <br>
{ <br>
PreConnection(param, 'a', 0); <br>
}; <br>
void Abor(char *param) <br>
{ <br>
if (data_pid != 0) { <br>
kill(data_pid, SIGTERM); <br>
}; <br>
outs("226 ABOR command successful."); <br>
}; <br>
void Mdtm(char *param) <br>
{ <br>
struct stat s; <br>
struct stat s; <br>
struct tm *tms; <br>
if (stat(param, &s) == -1) { <br>
Error(param); <br>
} else { <br>
tms = localtime((const time_t *)&s.st_mtime); <br>
outs("213 %04d%02d%02d%02d%02d%02d", tms->tm_year, tms->tm_mon, tms->tm_mday <br>
, tms->tm_hour, tms->tm_min, tms->tm_sec); <br>
}; <br>
}; <br>
void Syst(char *param) <br>
{ <br>
outs("215 UNIX Type: L8"); <br>
}; <br>
void Rest(char *param) <br>
{ <br>
int r; <br>
r = atoi(param); <br>
if (r < 0 || (r == 0 && param[0] != '0')) { <br>
outs("501 REST requires a value greater than or equal to 0."); <br>
return; <br>
}; <br>
file_rest = r; <br>
file_rest = r; <br>
outs("350 Restarting at %u. Send STORE or RETRIEVE to initiate transfer.", f <br>
ile_rest); <br>
}; <br>
void Rnfr(char *param) <br>
{ <br>
char tmp[PATH_MAX]; <br>
struct stat s; <br>
MakePath(tmp, path, param); <br>
if (stat(tmp, &s) == -1) { <br>
Error(tmp); <br>
} else { <br>
outs("350 File or directory exists, ready for destination name."); <br>
strncpy(rename_file, param, PATH_MAX); <br>
}; <br>
}; <br>
void Rnto(char *param) <br>
{ <br>
char tmp[PATH_MAX]; <br>
if (strcmp(rename_file, "") == 0) { <br>
outs("503 Bad sequence of commands."); <br>
return; <br>
}; <br>
}; <br>
MakePath(tmp, path, param); <br>
if (rename(rename_file, tmp) == -1) { <br>
Error(tmp); <br>
} else { <br>
outs("250 RNTO command successful."); <br>
strcpy(rename_file, ""); <br>
}; <br>
}; <br>
void Site(char *param) <br>
{ <br>
int i, mode; <br>
static char buf[BUFSIZE] = "250 "; <br>
FILE *f; <br>
char *p1, *p2, *p3, *p4, tmp[PATH_MAX], tmp2[PATH_MAX]; <br>
explode(param, &p1, &p2); <br>
if (p1 == NULL || p2 == NULL || strncasecmp(p1, "CHMOD", 5) != 0) { <br>
outs("501 SITE option not supported."); <br>
return; <br>
}; <br>
explode(p2, &p3, &p4); <br>
if (p3 == NULL || p4 == NULL) { <br>
outs("501 SITE option not supported."); <br>
return; <br>
}; <br>
mode = strtol(p3, (char **)NULL, 8); <br>
if (chmod(p4, mode) == -1) { <br>
outs("501 SITE option not supported."); <br>
} else { <br>
outs("250 SITE command successful."); <br>
}; <br>
}; <br>
void Port(char *param) <br>
{ <br>
int i; <br>
struct _port tmp; <br>
unsigned char r, *ptr = (unsigned char *)&tmp; <br>
char *p, *ori = param; <br>
for (i=0;i<6;i++) { <br>
r = atoi(ori); <br>
if (r == 0 && *ori != '0') { <br>
outs("501 Syntax error in parameters or arguments."); <br>
return; <br>
}; <br>
ptr = r; <br>
ptr = r; <br>
p = strchr(ori, ','); <br>
if (p == NULL) { <br>
if (i != 5) { <br>
outs("501 Syntax error in parameters or arguments."); <br>
return; <br>
}; <br>
} else { <br>
*p = 0; <br>
ori = p+1; <br>
}; <br>
}; <br>
memcpy(&remote_port, &tmp, sizeof(remote_port)); <br>
pasv_mode = 0; <br>
outs("200 PORT Command successful."); <br>
}; <br>
void Pasv(char *param) <br>
{ <br>
int port = port_base; <br>
struct sockaddr_in sa; <br>
char tmp[30], t2[10]; <br>
int len, i; <br>
len = 1; <br>
len = 1; <br>
close(pasvfd); <br>
if ((pasvfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || setsockopt(pasvfd, S <br>
OL_SOCKET, SO_REUSEADDR, (const char *)&len, sizeof(int)) == -1) <br>
{ <br>
outs("550 PASV command failed."); <br>
return; <br>
}; <br>
memset(&sa, 0, sizeof(sa)); <br>
sa.sin_family = AF_INET; <br>
sa.sin_addr.s_addr = htonl(INADDR_ANY); <br>
do { <br>
port++; <br>
if (port == 65535) { <br>
outs("550 Can\'t bind any port."); <br>
return; <br>
}; <br>
sa.sin_port = htons(port); <br>
} while (bind(pasvfd, (struct sockaddr *)&sa, sizeof(sa)) == -1 || listen(pa <br>
svfd, 1) == -1); <br>
local_port.port = htons(port); <br>
memset(tmp, 0, 18); <br>
for (i=0;i<6;i++) { <br>
sprintf(t2, "%u", ((unsigned char *)&local_port)); <br>
strcat(tmp, t2); <br>
if (i!=5) strcat(tmp, ","); <br>
}; <br>
pasv_mode = 1; <br>
outs("227 Entering Passive Mode (%s)", tmp); <br>
}; <br>
struct _cmd_list cmd_list[] = { <br>
{"USER", User, CHECK_NOLOGIN | NEED_PARAM }, <br>
{"PASS", Pass, CHECK_NOLOGIN }, <br>
{"ACCT"}, <br>
{"CWD", Cwd, CHECK_LOGIN | NEED_PARAM }, <br>
{"XCWD", Cwd, CHECK_LOGIN | NEED_PARAM }, <br>
{"CDUP", Cdup, CHECK_LOGIN | NO_PARAM }, <br>
{"XCUP", Cdup, CHECK_LOGIN | NO_PARAM }, <br>
{"SMNT"}, <br>
{"QUIT", Quit, NO_CHECK }, <br>
{"REIN"}, <br>
{"PORT", Port, CHECK_LOGIN | NEED_PARAM }, <br>
{"PASV", Pasv, CHECK_LOGIN | NO_PARAM }, <br>
{"TYPE", Type, CHECK_LOGIN | NEED_PARAM }, <br>
{"STRU"}, <br>
{"STRU"}, <br>
{"MODE"}, <br>
{"RETR", Retr, CHECK_LOGIN | NEED_PARAM }, <br>
{"STOR", Stor, CHECK_LOGIN | NEED_PARAM }, <br>
{"STOU"}, <br>
{"APPE", Appe, CHECK_LOGIN | NEED_PARAM }, <br>
{"ALLO"}, <br>
{"REST", Rest, CHECK_LOGIN | NEED_PARAM }, <br>
{"RNFR", Rnfr, CHECK_LOGIN | NEED_PARAM }, <br>
{"RNTO", Rnto, CHECK_LOGIN | NEED_PARAM }, <br>
{"ABOR", Abor, CHECK_LOGIN | NO_PARAM }, <br>
{"DELE", Dele, CHECK_LOGIN | NEED_PARAM }, <br>
{"MDTM", Mdtm, CHECK_LOGIN | NEED_PARAM }, <br>
{"RMD", Rmd, CHECK_LOGIN | NEED_PARAM }, <br>
{"XRMD", Rmd, CHECK_LOGIN | NEED_PARAM }, <br>
{"MKD", Mkd, CHECK_LOGIN | NEED_PARAM }, <br>
{"XMKD", Mkd, CHECK_LOGIN | NEED_PARAM }, <br>
{"PWD", Pwd, CHECK_LOGIN | NO_PARAM }, <br>
{"XPWD", Pwd, CHECK_LOGIN | NO_PARAM }, <br>
{"SIZE", Size, CHECK_LOGIN | NEED_PARAM }, <br>
{"LIST", List, CHECK_LOGIN }, <br>
{"NLST", List, CHECK_LOGIN }, <br>
{"SITE", Site, CHECK_LOGIN | NEED_PARAM }, <br>
{"SYST", Syst, CHECK_LOGIN }, <br>
{"STAT", Stat, CHECK_LOGIN | NEED_PARAM }, <br>
{"HELP", Help, NO_CHECK }, <br>
{"NOOP", Noop, NO_CHECK }, <br>
{""} <br>
}; <br>
void do_alarm() <br>
{ <br>
outs("421 No Transfer Timeout (%d seconds): closing control connection", tim <br>
eout); <br>
fclose(file); <br>
close(connfd); <br>
exit(0); <br>
}; <br>
void do_child() <br>
{ <br>
int pid, ret; <br>
while (waitpid(-1, &ret, WNOHANG|WUNTRACED) > 0); <br>
}; <br>
void do_term() <br>
{ <br>
outs("425 Transfer aborted."); <br>
exit(0); <br>
}; <br>
int init() <br>
{ <br>
int n, i; <br>
struct sockaddr_in sa; <br>
struct hostent *host; <br>
struct in_addr ia; <br>
/* register the signal handler */ <br>
signal(SIGCHLD, do_child); <br>
signal(SIGTERM, do_term); <br>
/* init network */ <br>
memset(&sa, 0, sizeof(sa)); <br>
sa.sin_family = AF_INET; <br>
sa.sin_addr.s_addr = htonl(INADDR_ANY); <br>
sa.sin_port = htons(ftp_port); <br>
if (gethostname(hostname, BUFSIZE) == -1) strcpy(hostname, ""); <br>
i = 1; <br>
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || setsockopt(listenf <br>
d, SOL_SOCKET, SO_REUSEADDR, (const char *)&i, sizeof(int)) == -1) <br>
{ <br>
perror("Pacific FTP:"); <br>
return -1; <br>
}; <br>
if (bind(listenfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { <br>
fprintf(stderr, "Pacific FTP: Can not bind port %d\n", ftp_port); <br>
return -1; <br>
}; <br>
if (listen(listenfd, max_conn) == -1) { <br>
perror("Pacific FTP:"); <br>
return -1; <br>
}; <br>
/* set the program a daemon */ <br>
if(fork()) exit(0); <br>
for (n = 0; n<3; n++) close(n); <br>
open("/dev/null", O_RDONLY); <br>
dup2(0,1); <br>
dup2(0,2); <br>
/* <br>
if((n=open("/dev/tty",O_RDWR)) > 0) { <br>
ioctl(n, TIOCNOTTY, 0) ; <br>
close(n); <br>
} <br>
setsid(); <br>
setsid(); <br>
*/ <br>
if(fork()) exit(0); <br>
/* get the uid */ <br>
system_uid = getuid(); <br>
} <br>
int main(int argc, char **argv) <br>
{ <br>
struct sockaddr_in sa; <br>
int len, cur; <br>
int okay=1, i; <br>
char *cmd, *param; <br>
/* get the param */ <br>
for (i=1; i<argc; i++) { <br>
if (argv[0] != '-' || argv[2] != ':') okay = 0; <br>
switch (argv[1]) { <br>
case 'p': <br>
ftp_port = atoi(&argv[3]); <br>
if (ftp_port == 0) okay = 0; <br>
break; <br>
case 'm': <br>
max_conn = atoi(&argv[3]); <br>
if (max_conn == 0) okay = 0; <br>
break; <br>
case 't': <br>
timeout = atoi(&argv[3]); <br>
if (timeout == 0) okay = 0; <br>
break; <br>
default: <br>
okay = 0; <br>
}; <br>
if (!okay) break; <br>
}; <br>
if (!okay) { <br>
printf("Usage: %s [-p:port] [-m:maxconn] [-t:timeout]\n\tport: default is 21 <br>
.\n\tmaxconn: the max client num connected.\n", argv[0]); <br>
return -1; <br>
}; <br>
if (init() == -1) return -1; <br>
/* main loop */ <br>
while (1) <br>
{ <br>
len = sizeof(sa); <br>
connfd = accept(listenfd, (struct sockaddr *)&sa, &len); <br>
if (connfd == -1) continue; <br>
if (fork() == 0) <br>
{ <br>
len = sizeof(sa); <br>
getsockname(connfd, (struct sockaddr *)&sa, &len); <br>
local_port.host = sa.sin_addr.s_addr; <br>
file = fdopen(connfd, "rt+"); <br>
setbuf(file, (char *)0); <br>
getcwd(path, PATH_MAX); <br>
outs("220 PacificFTP ready, hostname: %s", hostname); <br>
signal(SIGALRM, do_alarm); <br>
alarm(timeout); <br>
/* child process's main loop */ <br>
while (fgets(inbuf, BUFSIZE, file) != NULL) <br>
{ <br>
explode(inbuf, &cmd, ?m); <br>
if (strcmp(cmd, "") == 0) continue; <br>
//Make cmd UPPERCASE <br>
for (i=0;i<strlen(cmd);i++) cmd=toupper(cmd); <br>
cur = 0; <br>
okay = 0; <br>
while (strcmp(cmd_list[cur].cmd, "") != 0) <br>
{ <br>
{ <br>
if (strcmp(cmd_list[cur].cmd, cmd) == 0) { <br>
if (cmd_list[cur].func == NULL) outs("502 %s command unimplemented.", cmd); <br>
else <br>
if ((cmd_list[cur].check & NO_CHECK) || Check(cmd, param, cmd_list[cur].chec <br>
k)) <br>
(*cmd_list[cur].func)(param); <br>
okay = 1; <br>
break; <br>
}; <br>
cur++; <br>
}; <br>
if (!okay) outs("500 %s not understood", cmd); <br>
}; <br>
fclose(file); <br>
exit(0); <br>
}; <br>
close(connfd); <br>
}; <br>
} <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -