今天研究了一下很常有的一个工具,ftp!在linux下文本模式下,如果你使用ftp就只能ftp ip了。谁知道这个程序是怎么完成的吗?估计没几个人关心,呵呵!我也是闲的无聊,来研究一下!现在开始看看他是怎么工作的!
先把ftp的程序下来,然后看看代码。呵呵
ftp的文件主要有5个文件!这个程序的最后更新日期为1999年
现在一个文件一个文件分析!
从主程序开始吧!里面有main.c和main.h先看头文件里写的什么!
#include
#include
extern int suppressint;
extern volatile int intpending;
extern int intrnewline;
extern struct obstack mainobstack;
extern struct obstack lineobstack;
#ifdef __GNUC__
void intr(int) __attribute__ ((noreturn));
#else
void intr(int);
#endif
#define INTOFF suppressint++;
#define INTON do { if (--suppressint == 0 && intpending) intr(SIGINT); } \
while(0)
#define CHECKINT do { if (suppressint == 1 && intpending) { \
suppressint = 0; intr(SIGINT); }} while(0)
呵呵,我慢慢来能吧!反正也是很清闲,不过一点,这个程序没注释,所以需要自己看!
当你看窗体下打入 ftp -help 时候,会出现:
Usage: { ftp | pftp } [-pinegvtd] [hostname]
-p: enable passive mode (default for pftp)
-i: turn off prompting during mget
-n: inhibit auto-login
-e: disable readline support, if present
-g: disable filename globbing
-v: verbose mode
-t: enable packet tracing [nonfunctional]
-d: enable debugging
而它在程序的定义就在前面的一个函数中:
static
void
usage(void)
{
printf("\n\tUsage: { ftp | pftp } [-pinegvtd] [hostname]\n");
printf("\t -p: enable passive mode (default for pftp)\n");
printf("\t -i: turn off prompting during mget\n");
printf("\t -n: inhibit auto-login\n");
printf("\t -e: disable readline support, if present\n");
printf("\t -g: disable filename globbing\n");
printf("\t -v: verbose mode\n");
printf("\t -t: enable packet tracing [nonfunctional]\n");
printf("\t -d: enable debugging\n");
printf("\n");
}
接下来看ftp的主程序main:
int
main(volatile int argc, char **volatile argv)
{
register char *cp;
struct servent *sp;
int top;
struct passwd *pw = NULL;
char homedir[MAXPATHLEN];
sigjmp_buf jmploc;
tick = 0;
sp = getservbyname("ftp", "tcp");
if (sp == 0) {
fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
exit(1);
}
ftp_port = sp->s_port;
doglob = 1;
interactive = 1;
autologin = 1;
passivemode = 0;
cp = strrchr(argv[0], '/');
cp = (cp == NULL) ? argv[0] : cp+1;
if (strcmp(cp, "pftp") == 0)
passivemode = 1;
argc--, argv++;
while (argc > 0 && **argv == '-') {
for (cp = *argv + 1; *cp; cp++)
switch (*cp) {
case 'd':
options |= SO_DEBUG;
debug++;
break;
case 'v':
verbose++;
break;
case 't':
traceflag++;
break;
case 'i':
interactive = 0;
break;
case 'n':
autologin = 0;
break;
case 'p':
passivemode = 1;
break;
case 'g':
doglob = 0;
break;
case 'e':
rl_inhibit = 1;
break;
case 'h':
usage();
exit(0);
default:
fprintf(stdout,
"ftp: %c: unknown option\n", *cp);
exit(1);
}
argc--, argv++;
}
fromatty = isatty(fileno(stdin));
#ifdef __USE_READLINE__
/*
* Set terminal type so libreadline can parse .inputrc correctly
*/
if (fromatty && !rl_inhibit) {
rl_terminal_name = getenv("TERM");
}
#endif
if (fromatty)
verbose++;
cpend = 0; /* no pending replies */
proxy = 0; /* proxy not active */
crflag = 1; /* strip c.r. on ascii gets */
sendport = -1; /* not using ports */
qcflag = isatty(fileno(stdout));
/*
* Set up the home directory in case we're globbing.
*/
cp = getlogin();
if (cp != NULL) {
pw = getpwnam(cp);
}
if (pw == NULL)
pw = getpwuid(getuid());
if (pw != NULL) {
strncpy(homedir, pw->pw_dir, sizeof(homedir));
homedir[sizeof(homedir)-1] = 0;
home = homedir;
}
/*
* We need this since we want to return from unsafe library calls ASAP
* when a SIGINT happens.
*/
siginterrupt(SIGINT, 1);
toplevel = &jmploc;
obstack_init(&mainobstack);
obstack_init(&lineobstack);
if (argc > 0) {
if (sigsetjmp(jmploc, 1))
exit(0);
(void) signal(SIGINT, inthandler);
(void) signal(SIGPIPE, SIG_IGN);
setpeer(argc + 1, argv - 1);
resetstack(&mainobstack);
resetstack(&lineobstack);
}
top = sigsetjmp(jmploc, 1) == 0;
if (top) {
(void) signal(SIGINT, inthandler);
(void) signal(SIGPIPE, SIG_IGN);
} else {
INTOFF;
resetstack(&mainobstack);
resetstack(&lineobstack);
INTON;
pswitch(0);
}
for (;;) {
cmdscanner(top);
top = 1;
}
}
这个函数getservbyname获取系统的ftp服务,端口等信息,因为ftp是标准服务,所以这个函数可以获取相关信息。
阅读(1376) | 评论(0) | 转发(0) |