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

📄 ftp.c.orig

📁 UNIX环境下命令行FTP/SFTP工具源代码
💻 ORIG
📖 第 1 页 / 共 3 页
字号:
        }        ftp_err("\n");    } else {        ftp_trace("--> [%s] ", ftp->url->hostname);        if(strncmp(cmd, "PASS", 4) == 0)            ftp_trace("PASS ********");        else            ftp_vtrace(cmd, ap);        ftp_trace("\n");    }}/* sends an FTP command on the control channel * returns reply status code on success or -1 on error */int ftp_cmd(const char *cmd, ...){    va_list ap;    int resp;    bool recon = false;    if(!sock_connected(ftp->ctrl)) {        ftp_err(_("No control connection\n"));        ftp->code = ctNone;        ftp->fullcode = -1;        return -1;    }    ftp_set_abort_handler();  ugly:    va_start(ap, cmd);    sock_krb_vprintf(ftp->ctrl, cmd, ap);    sock_printf(ftp->ctrl, "\r\n");    sock_flush(ftp->ctrl);    va_end(ap);    if(ferror(ftp->ctrl->sout)) {        ftp_err(_("error writing command"));        ftp_err(" (");        va_start(ap, cmd);        vfprintf(stderr, cmd, ap);        va_end(ap);        va_start(ap, cmd);        ftp_vtrace(cmd, ap);        va_end(ap);        ftp_err(")\n");        ftp->code = ctNone;        ftp->fullcode = -1;        return -1;    }    va_start(ap, cmd);    ftp_print_cmd(cmd, ap);    va_end(ap);    resp = ftp_read_reply();    ftp_set_close_handler();    if(resp == 421) { /* server is closing control connection! */        ftp_err(_("Server closed control connection\n"));        if(gvAutoReconnect && ftp_loggedin() && strcasecmp(cmd, "QUIT") != 0) {            if(recon) {                ftp_err(_("Reconnect failed\n"));            } else {                ftp_err(_("Automatic reconnect...\n"));                ftp_reopen();                recon = true;                goto ugly;            }        } else {            /*      ftp_close();*/            ftp->fullcode = 421;            ftp->code = 4;            return -1;        }    }    return resp;}void ftp_quit(void){    if(ftp_connected() && !ftp->ssh_pid) {        ftp_reply_timeout(10);        ftp_set_tmp_verbosity(vbCommand);        ftp_cmd("QUIT");    }    ftp_close();}int ftp_get_verbosity(void){    if(ftp->tmp_verbosity != vbUnset)        return ftp->tmp_verbosity;    return ftp->verbosity;}void ftp_set_verbosity(int verbosity){    ftp->verbosity = verbosity;    ftp->tmp_verbosity = vbUnset;}void ftp_set_tmp_verbosity(int verbosity){    if(ftp->verbosity <= vbError)        ftp->tmp_verbosity = verbosity;}int get_username(url_t *url, const char *guessed_username, bool isproxy){    if(!url->username) {        char *prompt, *e;        if(!ftp->getuser_hook) {            ftp->loggedin = false;            return -1;        }        if(isproxy)            asprintf(&prompt, _("Proxy login: "));        else if(guessed_username)            asprintf(&prompt, _("login (%s): "), guessed_username);        else            prompt = xstrdup(_("login (anonymous): "));        e = ftp->getuser_hook(prompt);        free(prompt);        if(e && *e == 0) {            free(e);            e = 0;        }        if(!e) {            if(guessed_username == 0) {                fprintf(stderr, _("You loose\n"));                ftp->loggedin = false;                return -1;            }            url_setusername(url, guessed_username);        } else {            url_setusername(url, e);            free(e);        }    }    return 0;}static int get_password(url_t *url, const char *anonpass, bool isproxy){    if(!url->password) {        char *e;        if(url_isanon(url) && isproxy == false) {            char *prompt;            e = 0;            if(ftp->getuser_hook) {                if(anonpass && isproxy == false)                    asprintf(&prompt, _("password (%s): "), anonpass);                else                    prompt = xstrdup(_("password: "));                e = ftp->getuser_hook(prompt);                free(prompt);            }            if(!e || !*e) {                free(e);                e = xstrdup(anonpass);            }        } else {            if(!ftp->getpass_hook)                return -1;            e = ftp->getpass_hook(isproxy ? _("Proxy password: ")                                  : _("password: "));        }        if(!e) {            fprintf(stderr, _("You loose\n"));            return -1;        }        url_setpassword(url, e);        free(e);    }    return 0;}#ifdef SECFTPstatic const char *secext_name(const char *mech){    static struct {        const char *short_name;        const char *real_name;    } names[] = {        {"krb4", "KERBEROS_V4"},        {"krb5", "GSSAPI"},        {"gssapi", "GSSAPI"},/*      {"ssl", "SSL"},*/        {"none", "none"},        {0, 0}    };    int i;    for(i = 0; names[i].short_name; i++) {        if(strcasecmp(mech, names[i].short_name) == 0)            return names[i].real_name;    }    return 0;}static bool mech_unsupported(const char *mech){#ifndef HAVE_KRB4    if(strcasecmp(mech, "KERBEROS_V4") == 0)        return true;#endif#ifndef HAVE_KRB5    if(strcasecmp(mech, "GSSAPI") == 0)        return true;#endif#ifndef USE_SSL    if(strcasecmp(mech, "SSL") == 0)        return true;#endif    return false;}#endif /* SECFTP */int ftp_login(const char *guessed_username, const char *anonpass){    int ptype, r;    static url_t *purl = 0;    if(!ftp_connected())        return 1;    if(!ftp->url)        return -1;    if(ftp->ssh_pid)        /* login authentication is performed by the ssh program */        return 0;    ptype = proxy_type(ftp->url);    if(purl) {        url_destroy(purl);        purl = 0;    }    if(ptype > 0)        purl = url_clone(gvProxyUrl);    r = get_username(ftp->url, guessed_username, false);    if(r != 0)        return r;    if(ptype > 1) {        r = get_username(purl, 0, true);        if(r != 0)            return r;    }#ifdef SECFTP    ftp->sec_complete = false;    ftp->data_prot = prot_clear;    /* don't use secure stuff if anonymous     */    if(!url_isanon(ftp->url)) {        list *mechlist;        /* request a protection level         */        if(ftp->url->protlevel) {            if(sec_request_prot(ftp->url->protlevel) != 0)                ftp_err(_("Invalid protection level '%s'\n"),                        ftp->url->protlevel);        }        /* get list of mechanisms to try         */        mechlist = ftp->url->mech ? ftp->url->mech : gvDefaultMechanism;        if(mechlist) {            listitem *li = mechlist->first;            int ret = 0;            for(; li; li=li->next) {                const char *mech_name;                mech_name = secext_name((char *)li->data);                if(mech_name == 0) {                    ftp_err(_("unknown mechanism '%s'\n"), (char *)li->data);                    continue;                }                if(mech_unsupported(mech_name)) {                    ftp_err(_("Yafc was not compiled with support for %s\n"),                            mech_name);                    continue;                }                ret = sec_login(ftp->host->hostname, mech_name);                if(ret == -1) {                    if(ftp->code == ctError                       && ftp->fullcode != 504 && ftp->fullcode != 534)                        url_setmech(ftp->url, "none");                }                if(ret != 1)                    break;            }        }        if(ftp->sec_complete)            ftp_err(_("Authentication successful.\n"));        else            ftp_err(_("*** Using plaintext username"                      " and password ***\n"));    }#endif    if(url_isanon(ftp->url))        fprintf(stderr, _("logging in anonymously...\n"));    ftp_set_tmp_verbosity(ftp->url->password ? vbError : vbCommand);    switch(ptype) {      case 0:      default:        ftp_cmd("USER %s", ftp->url->username);        break;      case 1:        ftp_cmd("USER %s@%s", ftp->url->username, ftp->url->hostname);        break;      case 2:      case 3:      case 4:        ftp_cmd("USER %s", purl->username);        if(ftp->code == ctContinue) {            r = get_password(purl, 0, true);            if(r != 0)                return 0;            ftp_cmd("PASS %s", purl->password);            /* FIXME: what reply code do we expect now? */            if(ftp->code < ctTransient) {                if(ptype == 2) {                    ftp_cmd("USER %s@%s",                            ftp->url->username, ftp->url->hostname);                } else {                    if(ptype == 3)                        ftp_cmd("SITE %s", purl->hostname);                    else                        ftp_cmd("OPEN %s", purl->hostname);                    if(ftp->code < ctTransient)                        ftp_cmd("USER %s", ftp->url->username);                }            }        }        break;      case 5:        ftp_cmd("USER %s@%s@%s",                ftp->url->username, purl->username, ftp->url->hostname);        break;      case 6:        ftp_cmd("USER %s@%s", purl->username, ftp->url->hostname);        if(ftp->code == ctContinue) {            r = get_password(purl, 0, true);            if(r != 0)                return 0;            ftp_cmd("PASS %s", purl->password);            if(ftp->code < ctTransient)                ftp_cmd("USER %s", ftp->url->username);        }        break;    }    if(ftp->code == ctContinue) {        ftp->loggedin = false;        r = get_password(ftp->url, anonpass, false);        if(r != 0)            return r;        if(ptype == 5) {            r = get_password(purl, 0, true);            if(r != 0) {                url_destroy(purl);                purl = 0;                return 0;            }        }        ftp_set_tmp_verbosity(vbCommand);        switch(ptype) {          default:          case 0:          case 1:          case 2:          case 3:          case 4:          case 6:            ftp_cmd("PASS %s", ftp->url->password);            break;          case 5:            ftp_cmd("PASS %s@%s", ftp->url->password, purl->password);            break;        }    }    url_destroy(purl);    purl = 0;    if(ftp->code > ctContinue) {        if(ftp->fullcode == 530 && ftp_loggedin()) {            /* this probable means '530 Already logged in' */            return 2;        }        ftp->loggedin = false;        return 1;    }    if(ftp->code == ctComplete) {        ftp->loggedin = true;#ifdef SECFTP        /* we are logged in, now set the requested data protection level         * requested from the autologin information in the config file,         * if any, else uses default protection level 'clear', ie         * no protection on the data channel         */        if(ftp->sec_complete) {            sec_set_protection_level();            fprintf(stderr, _("Data protection is %s\n"),                    level_to_name(ftp->data_prot));        }#endif        ftp->homedir = ftp_getcurdir();        ftp->curdir = xstrdup(ftp->homedir);        ftp->prevdir = xstrdup(ftp->homedir);        if(ftp->url->directory)            ftp_chdir(ftp->url->directory);        ftp_get_feat();        return 0;    }    if(ftp->code == ctTransient)        return 1;    return -1;}bool ftp_loggedin(void){    return (ftp_connected() && ftp->loggedin);}bool ftp_connected(void){    return (ftp->connected && (sock_connected(ftp->ctrl) || ftp->ssh_pid));}char *ftp_getcurdir(void){    if(ftp->ssh_pid)        return ssh_getcurdir();    ftp_set_tmp_verbosity(vbNone);    ftp_cmd("PWD");    if(ftp->code == ctComplete) {        char *beg, *end, *ret;        beg = strchr(ftp->reply, '\"');        if(!beg)            return xstrdup("CWD?");        beg++;        end = strchr(beg, '\"');        if(!end)            return xstrdup("CWD?");        ret = (char *)xmalloc(end-beg+1);        strncpy(ret, beg, end-beg);        stripslash(ret);        /* path shouldn't include any quoted chars */        path_dos2unix(ret);        return ret;    }    return xstrdup("CWD?");}void ftp_update_curdir_x(const char *p){    free(ftp->prevdir);    ftp->prevdir = ftp->curdir;    ftp->curdir = xstrdup(p);    path_dos2unix(ftp->curdir);}static void ftp_update_curdir(void){    free(ftp->prevdir);    ftp->prevdir = ftp->curdir;    ftp->curdir = ftp_getcurdir();}int ftp_chdir(const char *path){    if(ftp->ssh_pid)        return ssh_chdir(path);    ftp_set_tmp_verbosity(vbCommand);    ftp_cmd("CWD %s", path);    if(ftp->code == ctComplete) {        /* Now, try to be smart ;-)         * Many ftp servers include the current directory in the CWD reply         * try to parse it, so we don't need to issue a PWD command         */        if(strncasecmp(ftp->reply, "250 Changed to ", 15) == 0) {            /* this is what Troll-ftpd replies: 250 Changed to /foo/bar */            ftp_update_curdir_x(ftp->reply+15);            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);        } else if(strncasecmp(ftp->reply,                              "250 OK. Current directory is ", 29) == 0) {            /* PureFTPd responds: "250 OK. Current directory is /foo/bar */            ftp_update_curdir_x(ftp->reply+29);            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);        } else if(strstr(ftp->reply, " is current directory") != 0) {            /* WarFTPD answers: 250 "/foo/bar/" is current directory */            char *edq;            char *sdq = strchr(ftp->reply, '\"');            if(sdq) {                edq = strchr(sdq+1, '\"');                if(edq) {                    char *e = xstrndup(sdq+1, edq-sdq-1);                    stripslash(e);                    ftp_update_curdir_x(e);                    free(e);                    ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);                }            }        } else if(strncasecmp(ftp->reply,                              "250 Directory changed to ", 25) == 0) {            /* Serv-U FTP Server for WinSock */            ftp_update_curdir_x(ftp->reply + 25);            ftp_trace("Parsed cwd '%s' from reply\n", ftp->curdir);        } else            ftp_update_curdir();        return 0;    }    return -1;}int ftp_cdup(void){    if(ftp->ssh_pid)        return ssh_cdup();    ftp_set_tmp_verbosity(vbCommand);    ftp_cmd("CDUP");    if(ftp->code == ctComplete) {        ftp_update_curdir();        return 0;    }    return -1;}static int ftp_mkdir_verb(const char *path, verbose_t verb){    char *p;    if(ftp->ssh_pid)        return ssh_mkdir_verb(path, verb);    p = xstrdup(path);    stripslash(p);    ftp_set_tmp_verbosity(verb);    ftp_cmd("MKD %s", p);    if(ftp->code == ctComplete)        ftp_cache_flush_mark_for(p);    free(p);    return ftp->code == ctComplete ? 0 : -1;}int ftp_mkdir(const char *path){    return ftp_mkdir_verb(path, vbError);}int ftp_rmdir(const char *path){    char *p;    if(ftp->ssh_pid)        return ssh_rmdir(path);    p = xstrdup(path);    stripslash(p);    ftp_set_tmp_verbosity(vbError);    ftp_cmd("RMD %s", p);    if(ftp->code == ctComplete) {        ftp_cache_flush_mark(p);        ftp_cache_flush_mark_for(p);    }    free(p);    return ftp->code == ctComplete ? 0 : -1;}int ftp_unlink(const char *path){    if(ftp->ssh_pid)        return ssh_unlink(path);    ftp_cmd("DELE %s", path);    if(ftp->code == ctComplete) {        ftp_cache_flush_mark_for(path);        return 0;    }    return -1;}int ftp_chmod(const char *path, const char *mode){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -