Beispiel #1
0
void ftp_flush_reply(void)
{
    fd_set ready;
    struct timeval poll;

    if(!ftp_connected())
        return;

#ifdef HAVE_LIBSSH
    if (ftp->session)
        return;
#endif

/*  ftp_set_signal(SIGINT, SIG_IGN);*/
    fprintf(stderr, "flushing replies...\r");

/*  ftp_reply_timeout(10);*/

    while(ftp_connected()) {
        poll.tv_sec = 1;
        poll.tv_usec = 0;
        FD_ZERO(&ready);
        int handle = sock_handle(ftp->ctrl);
        FD_SET(handle, &ready);
        if(select(handle+1, &ready, 0, 0, &poll) == 1)
            ftp_read_reply();
        else
            break;
    }
#if 0
    if(ftp_loggedin())
        ftp_chdir(ftp->curdir);
#endif
    ftp_set_close_handler();
}
Beispiel #2
0
Datei: ftp.c Projekt: cpages/yafc
void ftp_flush_reply(void)
{
    if(!ftp_connected())
        return;

#ifdef HAVE_LIBSSH
    if (ftp->session)
        return;
#endif

/*  ftp_set_signal(SIGINT, SIG_IGN);*/
    fprintf(stderr, "flushing replies...\r");

/*  ftp_reply_timeout(10);*/

    while(ftp_connected()) {
        if (sock_check_pending(ftp->ctrl, false) == 1)
            ftp_read_reply();
        else
            break;
    }
#if 0
    if(ftp_loggedin())
        ftp_chdir(ftp->curdir);
#endif
    ftp_set_close_handler();
}
Beispiel #3
0
void print_xterm_title(void)
{
	char *xterm_title = expand_prompt(ftp_connected()
									  ? (ftp_loggedin() ? gvXtermTitle3
										 : gvXtermTitle2)
									  : gvXtermTitle1);
	print_xterm_title_string(xterm_title);
	free(xterm_title);
}
Beispiel #4
0
Datei: ftp.c Projekt: cpages/yafc
char* ftp_connected_user()
{
  if (!ftp_loggedin())
    return NULL;

#ifdef HAVE_LIBSSH
  if (ftp->session)
    return ssh_connected_user();

  return ftp->url->username ? xstrdup(ftp->url->username) : NULL;
#endif
}
Beispiel #5
0
void cmd_status(int argc, char **argv)
{
	OPT_HELP_NEW(_("Show status."), "status [options]", NULL);

	maxargs(optind - 1);

	if(ftp_connected())
		printf(_("connected to '%s'\n"), host_getoname(ftp->host));
	else
		puts(_("not connected"));
	if(ftp_loggedin())
		printf(_("logged in as '%s'\n"), ftp->url->username);
#ifdef HAVE_KERBEROS
	if(ftp_connected())
		sec_status();
#endif
	if(list_numitem(gvFtpList) > 1 || ftp_connected())
		printf(_("There are totally %u connections open\n"),
			   list_numitem(gvFtpList));
}
Beispiel #6
0
void cmd_status(int argc, char **argv)
{
	OPT_HELP("Show status.  Usage:\n"
			 "  status [options]\n"
			 "Options:\n"
			 "  -h, --help    show this help\n");

	maxargs(optind - 1);

	if(ftp_connected())
		printf(_("connected to '%s'\n"), ftp->host->ohostname);
	else
		puts(_("not connected"));
	if(ftp_loggedin())
		printf(_("logged in as '%s'\n"), ftp->url->username);
#ifdef HAVE_KERBEROS
	if(ftp_connected())
		sec_status();
#endif
	if(list_numitem(gvFtpList) > 1 || ftp_connected())
		printf(_("There are totally %u connections open\n"),
			   list_numitem(gvFtpList));
}
Beispiel #7
0
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;

#ifdef HAVE_LIBSSH
    if (ftp->session)
        /* login authentication is performed by the ssh program */
        return 0;
#endif

    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 && ptype < 7) {
        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(host_getname(ftp->host), 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;
      case 7:
        ftp_cmd("USER %s@%s:%i", ftp->url->username, ftp->url->hostname, ftp->url->port);
        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;
}
Beispiel #8
0
/* 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(sock_sout(ftp->ctrl))) {
        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;
}
Beispiel #9
0
static char *remote_completion_function(const char *text, int state)
{
    static int len;            /* length of unquoted */
    static char *dir = NULL;   /* any initial directory in text */
    static char *unquoted = NULL; /* the unquoted filename (or beginning of it) */
    static listitem *lip = NULL;
    static rdirectory *rdir = NULL; /* the cached remote directory */
    static char merge_fmt[] = "%s/%s";

    if (!ftp_loggedin())
        return 0;

    /* this is not really true, this is for local filename completion,
     * but it works here too (sort of), and it looks nicer, since
     * the whole path is not printed by readline, ie
     * only foo is printed and not /bar/fu/foo (if cwd == /bar/fu)
     * readline appends a class character (ie /,@,*) in _local_ filenames
     */
    rl_filename_completion_desired = 1;
#ifndef HAVE_LIBEDIT
    rl_filename_quoting_desired = 1;
#endif

    if (!state) {
        dir = base_dir_xptr(text);
        if (dir) {
            stripslash(dir);
            char* e = strchr(dir, 0);
            if (e[-1]=='\"')
                e[-1] = '\0';
            unquote(dir);
            if (strcmp(dir, "/") == 0)
                strlcpy(merge_fmt, "%s%s", sizeof(merge_fmt));
            else
                strlcpy(merge_fmt, "%s/%s", sizeof(merge_fmt));
        }
#ifndef HAVE_LIBEDIT
        if(gvWaitingDots) {
            rl_insert_text("..."); /* show dots while waiting, like ncftp */
            rl_redisplay();
        }
#endif

        char* ap = ftp_path_absolute(dir);
        rdir = ftp_cache_get_directory(ap);
        const bool dir_is_cached = (rdir != 0);
        if (!rdir)
            rdir = ftp_read_directory(ap);
        free(ap);

#ifndef HAVE_LIBEDIT
        if (gvWaitingDots)
            rl_do_undo(); /* remove the dots */
#endif

        if (!dir_is_cached && ftp_get_verbosity() >= vbCommand)
            rl_forced_update_display();

        if (!rdir) {
            free(dir);
            return 0;
        }
        unquoted = dequote_filename(base_name_ptr(text), 0);
        if (!unquoted)
            unquoted = (char *)xmalloc(1);
        len = strlen(unquoted);
        lip = rdir->files->first;
    }

    while (lip) {
        rfile* fp = (rfile *)lip->data;
        lip = lip->next;

        /* 0 = not dir, 1 = dir, 2 = link (maybe dir) */
        const int isdir = ftp_maybe_isdir(fp);
        if (remote_dir_only && isdir == 0)
            continue;

        const char* name = base_name_ptr(fp->path);
        /* skip dotdirs in completion */
        if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
            continue;

        if (strncmp(name, unquoted, len) == 0) {
            char *ret;
            if (dir)
            {
                if (asprintf(&ret, merge_fmt, dir, name) == -1)
                {
                    fprintf(stderr, _("Failed to allocate memory.\n"));
                    free(unquoted);
                    free(dir);
                    return NULL;
                }
            }
            else
                ret = xstrdup(name);
            if (isdir == 1) {
                rl_completion_append_character = '/';
            } else {
                rl_completion_append_character = ' ';
            }
            return ret;
        }
    }
    free(unquoted);
    free(dir);
    return NULL;
}
Beispiel #10
0
char *expand_prompt(const char *fmt)
{
	unsigned maxlen;
	char *ins, *e;
	bool freeins;
	char *tmp;


	if(!fmt)
		return 0;

	char* prompt = (char *)xmalloc(strlen(fmt)+1);
	char* cp = prompt;

	while(fmt && *fmt) {
		if(*fmt == '%') {
			fmt++;
			ins = 0;
			freeins = false;
			maxlen = (unsigned)-1;
			if(isdigit((int)*fmt)) {
				maxlen = (unsigned)atoi(fmt);
				while(isdigit((int)*fmt))
					fmt++;
			}
			switch(*fmt) {
			  case 'c':
				if (asprintf(&ins, "%u", list_numitem(gvFtpList)) == -1)
        {
          fprintf(stderr, _("Failed to allocate memory.\n"));
          free(prompt);
          return NULL;
        }
				freeins = true;
				break;
			  case 'C':
				if (asprintf(&ins, "%u", connection_number()) == -1)
        {
          fprintf(stderr, _("Failed to allocate memory.\n"));
          free(prompt);
          return NULL;
        }
				freeins = true;
				break;
			  case 'u': /* username */
				ins = ftp_loggedin() ? ftp->url->username : "******";
				break;
			  case 'h': /* remote hostname (as passed to cmd_open()) */
				ins = ftp_connected() ? ftp->url->hostname : "?";
				break;
			  case 'H': /* %h up to first '.' */
				if(!ftp_connected()) {
					ins = "?";
					break;
				}
				e = strchr(ftp->url->hostname, '.');
				if(e) {
					ins = xstrndup(ftp->url->hostname, e - ftp->url->hostname);
					freeins = true;
				} else
					ins = ftp->url->hostname;
				break;
			  case 'm':
				/* remote machine name (as returned from gethostbynmame) */
				ins = xstrdup(ftp_connected() ? host_getoname(ftp->host) : "?");
        freeins = true;
				break;
			  case 'M': /* %m up to first '.' */
				if(!ftp_connected()) {
					ins = "?";
					break;
				}
				e = strchr(host_getoname(ftp->host), '.');
				if(e) {
					ins = xstrndup(host_getoname(ftp->host),
								   e - host_getoname(ftp->host));
				} else
					ins = xstrdup(host_getoname(ftp->host));
        freeins = true;
				break;
			case 'n': /* remote ip number */
				ins = xstrdup(ftp_connected() ? host_getoname(ftp->host) : "?");
        freeins = true;
				break;
			case 'w': /* current remote directory */
				if(!ftp_loggedin()) {
					ins = "?";
					break;
				}
				ins = shortpath(ftp->curdir, maxlen, 0);
				freeins = true;
				break;
			case 'W': /* basename(%w) */
				if(!ftp_loggedin()) {
					ins = "?";
					break;
				}
				ins = (char *)base_name_ptr(ftp->curdir);
				break;
			case '~': /* %w but homedir replaced with '~' */
				if(!ftp_loggedin()) {
					ins = "?";
					break;
				}
				ins = shortpath(ftp->curdir, maxlen, ftp->homedir);
				freeins = true;
				break;
			case 'l': /* current local directory */
				tmp = getcwd(NULL, 0);
				ins = shortpath(tmp, maxlen, 0);
				freeins = true;
				free(tmp);
				break;
			case 'L': /* basename(%l) */
				tmp = getcwd(NULL, 0);
				ins = (char *)base_name_ptr(tmp);
				free(tmp);
				break;
			case '%': /* percent sign */
				ins = "%";
				break;
			case '#': /* local user == root ? '#' : '$' */
				ins = getuid() == 0 ? "#" : "$";
				break;
			case '{': /* begin non-printable character string */
#ifdef HAVE_LIBREADLINE
				ins = "\001\001"; /* \001 + RL_PROMPT_START_IGNORE */
#endif
				break;
			case '}': /* end non-printable character string */
#ifdef HAVE_LIBREADLINE
				ins = "\001\002"; /* \001 + RL_PROMPT_END_IGNORE */
#endif
				break;
			case 'e': /* escape (0x1B) */
				ins = "\x1B";
				break;
			default: /* illegal format specifier */
				break;
			}

			if(ins) {
        const size_t len = strlen(prompt) + strlen(ins) + strlen(fmt+1) + 1;
				char* tmp = xmalloc(len);
				strlcpy(tmp, prompt, len);
				strlcat(tmp, ins, len);
				cp = tmp + strlen(prompt) + strlen(ins);
				free(prompt);
				prompt = tmp;
				if(freeins)
					free(ins);
			}
		} else
			*cp++ = *fmt;

		fmt++;
	}
	unquote_escapes(prompt);
	return prompt;
}
Beispiel #11
0
void auto_create_bookmark(void)
{
	listitem *li;
	int a;
	bool auto_create, had_passwd = false;
	bool update = false;

	if(gvAutoBookmark == 0 && gvAutoBookmarkUpdate == 0)
		return;

	if(!ftp_loggedin() || gvSighupReceived)
		return;

	auto_create = (gvAutoBookmark == 1);

	/* check if bookmark already exists */
	li = list_search(gvBookmarks, (listsearchfunc)urlcmp, ftp->url);
	if(li) {
		if(!should_update_bookmark((url_t *)li->data))
			return;

		/* bookmark already exist, update it */
		if(gvAutoBookmarkUpdate == 2) {
			a = ask(ASKYES|ASKNO, ASKYES,
					_("Do you want to update the bookmark for this site?"));
			if(a == ASKNO)
				return;
		}

		update = true;
		auto_create = true;
		had_passwd = (((url_t *)li->data)->password != 0);
	}

	if(gvAutoBookmark == 2 && !auto_create) {
		a = ask(ASKYES|ASKNO, ASKYES,
				_("Do you want to create a bookmark for this site?"));
		if(a == ASKNO)
			return;
		create_bookmark(0);
	} else { /* auto autobookmark... */
		url_t* url = url_clone(ftp->url);
		char* a = guess_alias(ftp->url);
		url_setalias(url, a);
		free(a);

		li = list_search(gvBookmarks, (listsearchfunc)urlcmp, url);
		if(li) {
			/* bookmark already exist, overwrite it */
			while(true) {
				url_t *xurl = (url_t *)li->data;

				if(xurl->alias && (strcmp(xurl->alias, url->alias) == 0)
				   && (strcmp(xurl->hostname, url->hostname) != 0))
				{
					/* create a new version of the alias, since guessed alias
					 * already exists but for another host
					 */

					update = false;
					char* par = strrchr(url->alias, '(');
          int ver = 1;
          if (par)
					{
						*par = 0;
						ver = atoi(par + 1);
					}
          if (asprintf(&a, "%s(%d)", url->alias, ver + 1) == -1)
          {
            fprintf(stderr, _("Failed to allocate memory.\n"));
            url_destroy(url);
            return;
          }
					url_setalias(url, a);
					free(a);
				} else {
					update = true;
					had_passwd = (xurl->password != 0);
					break;
				}
				li = list_search(gvBookmarks, (listsearchfunc)urlcmp, url);
				if(li == 0)
					break;
			}
			if(li) /* overwrite bookmark (ie, delete old and create a new) */
				list_delitem(gvBookmarks, li);
			if(!url_isanon(url) && gvAutoBookmarkSavePasswd == false
			   && !had_passwd)
				url_setpassword(url, 0);
		} else {
			if(!url_isanon(url) && gvAutoBookmarkSavePasswd == false)
				url_setpassword(url, 0);
		}
		create_the_bookmark(url);
		if(!gvAutoBookmarkSilent) {
			if(update)
				printf(_("updated bookmark %s\n"), url->alias);
			else
				printf(_("created bookmark %s\n"), url->alias);
		}
	}
}