Chinaunix首页 | 论坛 | 博客
  • 博客访问: 77667
  • 博文数量: 17
  • 博客积分: 761
  • 博客等级: 军士长
  • 技术积分: 206
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-13 15:29
文章分类

全部博文(17)

文章存档

2010年(9)

2009年(8)

我的朋友

分类:

2009-06-16 20:15:38

今天研究了一下很常有的一个工具,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是标准服务,所以这个函数可以获取相关信息。

阅读(1318) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~