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

📄 204.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<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 + -