📄 204.htm
字号:
******************************************************* <br>
******************************************************* <br>
ftp client 的头文件 <br>
/* Writen by Pacific,2000/11/23 <br>
Support command: <br>
Commands may be abbreviated. Commands are: <br>
! site passive binary reget <br>
? delete send help rhelp <br>
dir put size ls rmdir <br>
disconnect mkdir pwd user recv <br>
append exit quit newer rstatus <br>
ascii quote system bye cdup <br>
cd idle nlist rename modtime <br>
chmod lcd open restart close <br>
get <br>
*/ <br>
#ifndef __FTPD_H__ <br>
#define __FTPD_H__ <br>
//#define _XOPEN_SOURCE <br>
#include <stdio.h> <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>
/* <br>
#include <readline/readline.h> <br>
#include <readline/history.h> <br>
#include <readline/chardefs.h> <br>
#include <readline/keymaps.h> <br>
#include <readline/tilde.h> <br>
*/ <br>
#define BUFSIZE (1024) <br>
#define ERRS(x) outs("%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 genbuf[BUFSIZE]; <br>
char hostname[BUFSIZE]; <br>
char path[PATH_MAX]; <br>
char username[100]; <br>
char *prompt = "PacificFTP:>"; <br>
//system arguments <br>
unsigned int ftp_port = 21; <br>
unsigned int file_rest = 0; <br>
char transfer_type='i'; <br>
int port; <br>
//boolean <br>
int user_valid = 0; <br>
int pasv_mode = 0; <br>
int connected = 0; <br>
int sockfd; <br>
int listenfd; <br>
FILE *cout, *cin; <br>
struct _cmd_list { <br>
char *cmd; <br>
char *ftpcmd; <br>
void (*func)(char *param); <br>
char* param1; <br>
char* param2; <br>
char* usage; <br>
}; <br>
struct _port { <br>
uint32_t host; <br>
uint16_t port; <br>
} remote_port, local_port; <br>
#endif //__FTPD_H__ <br>
#include "client.h" <br>
void outs(char *fmt, ...) <br>
{ <br>
va_list ap; <br>
if (fmt == NULL) return; <br>
va_start(ap, fmt); <br>
vprintf(fmt, ap); <br>
va_end(ap); <br>
printf("\r\n"); <br>
}; <br>
char *readline(char *prompt) <br>
{ <br>
char *p, *buf; <br>
buf = malloc(BUFSIZE); <br>
printf(prompt); <br>
fgets(buf, BUFSIZE, stdin); <br>
if (strlen(buf) > 0) while ((p = &buf[strlen(buf)-1]) && (*p == '\r' || *p = <br>
= '\n')) *p = 0; <br>
return buf; <br>
}; <br>
void ftpouts(char *fmt, ...) <br>
{ <br>
va_list ap; <br>
va_list ap; <br>
if (cout == NULL) { <br>
outs("No control connection for command."); <br>
connected = 0; <br>
if (cin) fclose(cin); <br>
if (cout) fclose(cout); <br>
cin = NULL; <br>
cout = NULL; <br>
close(sockfd); <br>
return; <br>
} <br>
va_start(ap, fmt); <br>
vfprintf(cout, fmt, ap); <br>
va_end(ap); <br>
fprintf(cout, "\r\n"); <br>
(void) fflush(cout); <br>
}; <br>
int ftpgets() <br>
{ <br>
if (fgets(genbuf, BUFSIZE, cin) == NULL) { <br>
outs("421 Service not available, remote server has closed connection"); <br>
connected = 0; <br>
if (cin) fclose(cin); <br>
if (cout) fclose(cout); <br>
cin = NULL; <br>
cout = NULL; <br>
close(sockfd); <br>
return -1; <br>
}; <br>
fputs(genbuf, stdout); <br>
return atoi(genbuf); <br>
}; <br>
int ftpcmd(const char *fmt, ...) <br>
{ <br>
va_list ap; <br>
long arg; <br>
int okay; <br>
if (cout == NULL) { <br>
outs("No control connection for command"); <br>
connected = 0; <br>
if (cin) fclose(cin); <br>
if (cout) fclose(cout); <br>
cin = NULL; <br>
cout = NULL; <br>
close(sockfd); <br>
close(sockfd); <br>
return 0; <br>
} <br>
va_start(ap, fmt); <br>
vfprintf(cout, fmt, ap); <br>
va_end(ap); <br>
fprintf(cout, "\r\n"); <br>
(void) fflush(cout); <br>
return ftpgets(); <br>
} <br>
void explode(char *buf, char **cmd, char **param) <br>
{ <br>
char *p; <br>
if (!buf) { <br>
*cmd = NULL; <br>
*param = NULL; <br>
return; <br>
}; <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>
else { <br>
*p = 0; <br>
*param = p+1; <br>
if (*param[0] == 0) *param = NULL; <br>
}; <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>
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 transfer(FILE *in, char mode, FILE *out) <br>
{ <br>
int t; <br>
if (mode == 'i') { <br>
/* binary */ <br>
while ((t = fread(genbuf, 1, BUFSIZE, in)) > 0) { <br>
fwrite(genbuf, 1, t, out); <br>
} <br>
} else { <br>
/* ascii */ <br>
while (fgets(genbuf, BUFSIZE, in) != NULL) { <br>
fputs(genbuf, out); <br>
}; <br>
}; <br>
}; <br>
int DataConnection(int mode, int transfer_type, FILE *files) <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 *tmpin, *tmpout; <br>
if (!pasv_mode) { <br>
ret = ftpgets(); <br>
if (ret != 150 || (datafd = accept(listenfd, (struct sockaddr *)&sa, &len)) <br>
== -1) { <br>
close(listenfd); <br>
return ret; <br>
}; <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>
if ((datafd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || connect(datafd, (str <br>
uct sockaddr *)&sa, len) == -1) { <br>
return; <br>
}; <br>
ret = ftpgets(); <br>
}; <br>
if (ret == 150) { <br>
tmpin = fdopen(datafd, "r"); <br>
tmpout = fdopen(datafd, "w"); <br>
setbuf(tmpin, (char *)0); <br>
setbuf(tmpout, (char *)0); <br>
if (mode) { <br>
/* write */ <br>
transfer(files, transfer_type, tmpout); <br>
} else { <br>
/* read */ <br>
transfer(tmpin, transfer_type, files); <br>
}; <br>
fclose(tmpin); <br>
fclose(tmpout); <br>
ret = ftpgets(); <br>
}; <br>
close(datafd); <br>
if (files != stdout) fclose(files); <br>
return ret; <br>
}; <br>
void Help(char *param) <br>
{ <br>
if (!param) { <br>
outs("Commands may be abbreviated. Commands are:"); <br>
outs(""); <br>
outs("! site passive binary reget "); <br>
outs("? delete send help rhelp "); <br>
outs("dir put size ls rmdir "); <br>
outs("disconnect mkdir pwd user recv "); <br>
outs("append exit quit newer rstatus "); <br>
outs("ascii quote system bye cdup "); <br>
outs("cd idle nlist rename modtime "); <br>
outs("chmod lcd open restart close "); <br>
outs("get "); <br>
} else { <br>
outs("Sorry, I haven't write the topic help."); <br>
}; <br>
}; <br>
}; <br>
void Lcd(char *param) <br>
{ <br>
char tmp[PATH_MAX]; <br>
if (param) { <br>
if (chdir(param) == -1) Error(param); <br>
else if (getcwd(path, PATH_MAX) == NULL) ERRS("Permission denied"); <br>
}; <br>
outs("Local directory now %s", path); <br>
}; <br>
void Ascii(char *param) <br>
{ <br>
if (ftpcmd("TYPE A") != 220) transfer_type = 'a'; <br>
}; <br>
void Binary(char *param) <br>
{ <br>
if (ftpcmd("TYPE I") != 220) transfer_type = 'i'; <br>
}; <br>
int PreConnection() <br>
{ <br>
int n, i, len = 1, port = 3072; <br>
struct sockaddr_in sa; <br>
char *ptr, *ptrhost; <br>
char tmp[30], t2[10]; <br>
int okay; <br>
if (pasv_mode) { <br>
if (ftpcmd("PASV") != 227) { <br>
outs("Passive mode error!"); <br>
pasv_mode = 0; <br>
return -1; <br>
} <br>
ptr = strchr(genbuf, '('); <br>
okay = 0; <br>
if (ptr != NULL) { <br>
ptrhost = (char *)&remote_port; <br>
for (i=0; i<6; i++) { <br>
okay = 0; <br>
ptr++; <br>
*ptrhost = (char)atoi(ptr); <br>
if (*ptrhost == 0 && ptr[0]!='0') break; <br>
ptrhost++; <br>
okay = 1; <br>
ptr = strchr(ptr, ','); <br>
if (ptr == NULL) break; <br>
}; <br>
}; <br>
if (i < 5 || !okay) { <br>
outs("Passive mode error!"); <br>
pasv_mode = 0; <br>
return -1; <br>
} <br>
} else { <br>
/* init network */ <br>
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 || setsockopt(listenf <br>
d, SOL_SOCKET, SO_REUSEADDR, (const char *)&len, sizeof(int)) == -1) <br>
{ <br>
outs("Network failed..."); <br>
return -1; <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("Can\'t bind any port."); <br>
return -1; <br>
}; <br>
sa.sin_port = htons(port); <br>
} while (bind(listenfd, (struct sockaddr *)&sa, sizeof(sa)) == -1 || listen( <br>
listenfd, 1) == -1); <br>
local_port.port = htons(port); <br>
memset(tmp, 0, 30); <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>
if (ftpcmd("PORT %s", tmp) != 200) return -1; <br>
}; <br>
if (file_rest != 0 && ftpcmd("REST %d", file_rest) != 220) file_rest = 0; <br>
}; <br>
void List(char *param) <br>
{ <br>
if (PreConnection() == -1) return; <br>
if (param) ftpouts("LIST %s", param); else ftpouts("LIST"); <br>
DataConnection(0, 'a', stdout); <br>
}; <br>
}; <br>
void Nlist(char *param) <br>
{ <br>
if (PreConnection() == -1) return; <br>
if (param) ftpouts("NLST %s", param); else ftpouts("NLST"); <br>
DataConnection(0, 'a', stdout); <br>
}; <br>
void Get(char *param) <br>
{ <br>
FILE *f; <br>
char *p1, *p2, *p3, *p4; <br>
explode(param, &p3, &p4); <br>
if (p3 != NULL) { <br>
p1 = strdup(p3); <br>
if (p4 == NULL) p2 = strdup(p1); else p2 = strdup(p4); <br>
} else { <br>
p1 = readline("(remote-file) "); <br>
if (p1 == NULL) { <br>
outs("usage: get remote-file [ local-file ]"); <br>
return; <br>
}; <br>
p2 = readline("(local-file) "); <br>
if (p2 == NULL) { <br>
outs("usage: get remote-file [ local-file ]"); <br>
free(p1); <br>
return; <br>
}; <br>
}; <br>
outs("local: %s remote: %s", p2, p1); <br>
if ((f = fopen(p2, "w")) == NULL) { <br>
Error(p2); <br>
} else { <br>
if (PreConnection() == -1) return; <br>
ftpouts("RETR %s", p1); <br>
DataConnection(0, transfer_type, f); <br>
}; <br>
free(p1); <br>
free(p2); <br>
}; <br>
void Reget(char *param) <br>
{ <br>
FILE *f; <br>
char *p1, *p2, *p3, *p4; <br>
struct stat s; <br>
explode(param, &p3, &p4); <br>
if (p3 != NULL) { <br>
p1 = strdup(p3); <br>
if (p4 == NULL) p2 = strdup(p1); else p2 = strdup(p4); <br>
} else { <br>
p1 = readline("(remote-file) "); <br>
if (p1 == NULL) { <br>
outs("usage: reget remote-file [ local-file ]"); <br>
return; <br>
}; <br>
p2 = readline("(local-file) "); <br>
if (p2 == NULL) { <br>
outs("usage: reget remote-file [ local-file ]"); <br>
free(p1); <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -