Esempio n. 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();
}
Esempio n. 2
0
File: ftp.c Progetto: 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();
}
Esempio n. 3
0
/* just gets the file SRC and store in local file DEST
 * doesn't parse any LIST output
 * returns 0 on success, else -1
 */
static int do_the_get(const char *src, const char *dest,
                      putmode_t how, unsigned opt)
{
    char *fulldest;
    char *tmp;
    transfer_mode_t type;

    type = ascii_transfer(src) ? tmAscii : gvDefaultType;
    if(test(opt, GET_ASCII))
        type = tmAscii;
    else if(test(opt, GET_BINARY))
        type = tmBinary;

    tmp = getcwd(NULL, 0);
    if (tmp == (char *)NULL)
        return -1;

    fulldest = path_absolute(dest, tmp, 0);

#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
    if(gvUseEnvString && ftp_connected())
        setproctitle("%s, get %s", ftp->url->hostname, src);
#endif

    int r = ftp_getfile(src, dest, how, type,
                        test(opt, GET_VERBOSE)
                        && !gvSighupReceived
                        && !test(opt, GET_NOHUP) ? transfer : 0);

    if(r == 0 && (test(opt, GET_NOHUP) || gvSighupReceived)) {
        fprintf(stderr, "%s [%sb of ",
                src, human_size(ftp->ti.size));
        fprintf(stderr, "%sb]\n", human_size(ftp->ti.total_size));
    }
    if(test(opt, GET_NOHUP)) {
        if(r == 0)
            transfer_mail_msg(_("received %s\n"), src);
        else
            transfer_mail_msg(_("failed to receive %s: %s\n"),
                              src, ftp_getreply(false));
    }
    free(fulldest);
#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
    if(gvUseEnvString && ftp_connected())
        setproctitle("%s", ftp->url->hostname);
#endif

    free(tmp);

    return r;
}
Esempio n. 4
0
void ftp_quit(void)
{
#ifdef HAVE_LIBSSH
	if (ftp_connected() && !ftp->session)
#else
	if (ftp_connected())
#endif
	{
		ftp_reply_timeout(10);
    ftp_set_tmp_verbosity(vbCommand);
    ftp_cmd("QUIT");
  }
  ftp_close();
}
Esempio n. 5
0
static bool ftp_pasv(bool ipv6, unsigned char* result, unsigned short* ipv6_port)
{
  if (!ftp->has_pasv_command) {
    ftp_err(_("Host doesn't support passive mode\n"));
    return false;
  }
  ftp_set_tmp_verbosity(vbNone);

  /* request passive mode */
  if (!ipv6)
    ftp_cmd("PASV");
#ifdef HAVE_IPV6
  else if (ipv6)
    ftp_cmd("EPSV");
#endif
  else
    return false;

  if (!ftp_connected())
    return false;

  if (ftp->code != ctComplete) {
    ftp_err(_("Unable to enter passive mode\n"));
    if(ftp->code == ctError) /* no use try it again */
      ftp->has_pasv_command = false;
    return false;
  }

  const char* e = ftp_getreply(false);
  while (e && !isdigit((int)*e))
    e++;

  if (!e)
  {
    ftp_err(_("Error parsing EPSV/PASV reply: '%s'\n"), ftp_getreply(false));
    return false;
  }

  if (!ipv6)
  {
    if (sscanf(e, "%hhu,%hhu,%hhu,%hhu,%hhu,%hhu", &result[0], &result[1],
          &result[2], &result[3], &result[4], &result[5]) != 6)
    {
      ftp_err(_("Error parsing PASV reply: '%s'\n"), ftp_getreply(false));
      return false;
    }
  }
#ifdef HAVE_IPV6
  else
  {
    if (sscanf(e, "%hu", ipv6_port) != 1)
    {
      ftp_err(_("Error parsing EPSV reply: '%s'\n"), ftp_getreply(false));
      return false;
    }
  }
#endif

  return true;
}
Esempio n. 6
0
/*
** Function:    time_t ftp_filetime(const char *filename)
**
** Description: User routine for attempting to obtain a remote file's
**      modification time in Universal Coordinated Time (GMT).
**
** Returns; Either -1 upon failure or the time_t file modification
**      time upon success.
*/
time_t ftp_filetime(const char *filename)
{
    struct tm ts;

    if(!ftp_connected())
        return -1;

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

    if(!ftp->has_mdtm_command)
        return -1;

    memset(&ts, 0, sizeof(ts));
    ftp_set_tmp_verbosity(vbNone);
    ftp_cmd("MDTM %s", filename);
    if (ftp->fullcode == 202) {
        ftp->has_mdtm_command = false;
        return -1;
    }
    if (ftp->fullcode != 213)
        return -1;
    /* time is Universal Coordinated Time */
    sscanf(ftp->reply, "%*s %04d%02d%02d%02d%02d%02d", &ts.tm_year,
           &ts.tm_mon, &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
    ts.tm_year -= 1900;
    ts.tm_mon--;
    return gmt_mktime(&ts);
}
Esempio n. 7
0
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(Socket* fp)
{
	char buf[4096];

#ifdef HAVE_LIBSSH
	if(ftp->session)
		/* FIXME: what? */
		return 0;
#endif

	if(!ftp_connected())
		return -1;

	ftp_set_close_handler();

	if (sock_check_pending(fp, false) == 1) {
		ftp_trace("There is data on the control channel, won't send ABOR\n");
		/* read remaining bytes from connection */
		while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
			/* LOOP */ ;
		return 0;
	}

	ftp->ti.interrupted = true;
	ftp_err(_("Waiting for remote to finish abort...\n"));

	ftp_trace("--> telnet interrupt\n");
	if(sock_telnet_interrupt(ftp->ctrl) != 0)
		ftp_err("telnet interrupt: %s\n", strerror(errno));

	/* ftp_cmd("ABOR") won't work here,
	 * we must flush data between the ABOR command and ftp_read_reply()
	 */
	sock_krb_printf(ftp->ctrl, "ABOR");
	sock_printf(ftp->ctrl, "\r\n");
	sock_flush(ftp->ctrl);
	if(ftp_get_verbosity() == vbDebug)
		ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
	else
		ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
	while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
		/* LOOP */ ;

	/* we expect a 426 or 226 reply here... */
	ftp_read_reply();
	if(ftp->fullcode != 426 && ftp->fullcode != 226)
		ftp_trace("Huh!? Expected a 426 or 226 reply\n");

	/* ... and a 226 or 225 reply here, respectively */
	/* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
	ftp_read_reply();
	if(ftp->fullcode != 226 && ftp->fullcode != 225)
		ftp_trace("Huh!? Expected a 226 or 225 reply\n");

	return -1;
}
Esempio n. 8
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);
}
Esempio n. 9
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));
}
Esempio n. 10
0
File: fxp.c Progetto: Celelibi/yafc
static int do_the_fxp(Ftp *srcftp, const char *src,
					  Ftp *destftp, const char *dest,
					  fxpmode_t how, unsigned opt)
{
	transfer_mode_t type;

	if(test(opt, FXP_NOHUP))
		fprintf(stderr, "%s\n", src);

	type = ascii_transfer(src) ? tmAscii : gvDefaultType;
	if(test(opt, FXP_ASCII))
		type = tmAscii;
	else if(test(opt, FXP_BINARY))
		type = tmBinary;

#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
	if(gvUseEnvString && ftp_connected())
		setproctitle("%s, fxp %s", srcftp->url->hostname, src);
#endif
	if(test(opt, FXP_VERBOSE)) {
		printf("%s\n", src);
	}
	const int r = ftp_fxpfile(srcftp, src, destftp, dest, how, type);
#if 0 && (defined(HAVE_SETPROCTITLE) || defined(linux))
	if(gvUseEnvString && ftp_connected())
		setproctitle("%s", srcftp->url->hostname);
#endif

	if(test(opt, FXP_NOHUP)) {
		if(r == 0)
			transfer_mail_msg(_("sent %s\n"), src);
		else
			transfer_mail_msg(_("failed to send %s: %s\n"),
							  src, ftp_getreply(false));
	}

	return r;
}
Esempio n. 11
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));
}
Esempio n. 12
0
static int ftp_init_transfer(void)
{
    struct sockaddr_in sa;
    unsigned char *a, *p;
    unsigned char pac[6];

    if(!ftp_connected())
        goto err0;

    if (!(ftp->data = sock_create())) {
        goto err0;
    }
    sock_copy(ftp->data, ftp->ctrl);

    if(ftp_is_passive()) {
        if(ftp_pasv(pac) != 0) {
            goto err1;
        }

        sock_getsockname(ftp->ctrl, &sa);
        memcpy(&sa.sin_addr, pac, (size_t)4);
        memcpy(&sa.sin_port, pac+4, (size_t)2);
        if(sock_connect_addr(ftp->data, &sa) == -1)
            goto err1;
    } else {
        sock_listen(ftp->data);

        a = (unsigned char *)&ftp->data->local_addr.sin_addr;
        p = (unsigned char *)&ftp->data->local_addr.sin_port;

        ftp_set_tmp_verbosity(vbError);
        ftp_cmd("PORT %d,%d,%d,%d,%d,%d",
                a[0], a[1], a[2], a[3], p[0], p[1]);
        if(ftp->code != ctComplete)
            goto err1;
    }

    sock_throughput(ftp->data);

    return 0;

err1:
    sock_destroy(ftp->data);
err0:
    return -1;
}
Esempio n. 13
0
int ftp_list(const char *cmd, const char *param, FILE *fp)
{
  if (!cmd || !fp || !ftp_connected())
    return -1;

#ifdef HAVE_LIBSSH
  if (ftp->session)
    return ssh_list(cmd, param, fp);
#endif

  reset_transfer_info();
  foo_hookf = NULL;

#if 0 /* don't care about transfer type, binary should work well... */
  ftp_type(tmAscii);
#endif

  if (ftp_init_transfer() != 0) {
    ftp_err(_("transfer initialization failed"));
    return -1;
  }

  ftp_set_tmp_verbosity(vbNone);
  if (param)
    ftp_cmd("%s %s", cmd, param);
  else
    ftp_cmd("%s", cmd);
  if (ftp->code != ctPrelim)
    return -1;

  if (!sock_accept(ftp->data, "r", ftp_is_passive())) {
    perror("accept()");
    return -1;
  }

  if (FILE_recv_ascii(ftp->data, fp) != 0)
    return -1;

  sock_destroy(ftp->data);
  ftp->data = NULL;

  ftp_read_reply();

  return ftp->code == ctComplete ? 0 : -1;
}
Esempio n. 14
0
static int ftp_pasv(unsigned char result[6])
{
    int pa[6];
    char *e;
    int i;

    if(!ftp->has_pasv_command) {
        ftp_err(_("Host doesn't support passive mode\n"));
        return -1;
    }
    ftp_set_tmp_verbosity(vbNone);

    /* request passive mode */
    ftp_cmd("PASV");

    if(!ftp_connected())
        return -1;

    if(ftp->code != ctComplete) {
        ftp_err(_("Unable to enter passive mode\n"));
        if(ftp->code == ctError) /* no use try it again */
            ftp->has_pasv_command = false;
        return -1;
    }

    e = ftp->reply + 4;
    while(!isdigit((int)*e))
        e++;

    if(sscanf(e, "%d,%d,%d,%d,%d,%d",
              &pa[0], &pa[1], &pa[2], &pa[3], &pa[4], &pa[5]) != 6) {
        ftp_err(_("Error parsing PASV reply: '%s'\n"),
                ftp_getreply(false));
        return -1;
    }
    for(i=0; i<6; i++)
        result[i] = (unsigned char)(pa[i] & 0xFF);

    return 0;
}
Esempio n. 15
0
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(FILE *fp)
{
    char buf[4096];
    fd_set ready;
    struct timeval poll;

    if(ftp->ssh_pid)
        /* FIXME: what? */
        return 0;

    if(!ftp_connected())
        return -1;

    ftp_set_close_handler();

    poll.tv_sec = poll.tv_usec = 0;
    FD_ZERO(&ready);
    FD_SET(ftp->ctrl->handle, &ready);
    if(select(ftp->ctrl->handle+1, &ready, 0, 0, &poll) == 1) {
        ftp_trace("There is data on the control channel, won't send ABOR\n");
        /* read remaining bytes from connection */
        while(fp && fread(buf, 1, 4096, fp) > 0)
            /* LOOP */ ;
        return 0;
    }

    ftp->ti.interrupted = true;
    ftp_err(_("Waiting for remote to finish abort...\n"));

    ftp_trace("--> telnet interrupt\n");
    if(sock_telnet_interrupt(ftp->ctrl) != 0)
        ftp_err("telnet interrupt: %s\n", strerror(errno));

    /* ftp_cmd("ABOR") won't work here,
     * we must flush data between the ABOR command and ftp_read_reply()
     */
    sock_krb_printf(ftp->ctrl, "ABOR");
    sock_printf(ftp->ctrl, "\r\n");
    sock_flush(ftp->ctrl);
    if(ftp_get_verbosity() == vbDebug)
        ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
    else
        ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
    while(fp && fread(buf, 1, 4096, fp) > 0)
        /* LOOP */ ;

    /* we expect a 426 or 226 reply here... */
    ftp_read_reply();
    if(ftp->fullcode != 426 && ftp->fullcode != 226)
        ftp_trace("Huh!? Expected a 426 or 226 reply\n");

    /* ... and a 226 or 225 reply here, respectively */
    /* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
    ftp_read_reply();
    if(ftp->fullcode != 226 && ftp->fullcode != 225)
        ftp_trace("Huh!? Expected a 226 or 225 reply\n");

    return -1;
}
Esempio n. 16
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;
}
Esempio n. 17
0
static int ftp_init_transfer(void)
{
	struct sockaddr_storage sa;
	unsigned char *a, *p;

	if(!ftp_connected())
		return -1;

	if (!(ftp->data = sock_create())) {
		return -1;
	}
	sock_copy(ftp->data, ftp->ctrl);

	if (ftp_is_passive())
  {
    memcpy(&sa, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));

    unsigned char pac[6];
    unsigned short ipv6_port;
		if (!ftp_pasv(sa.ss_family != AF_INET, pac, &ipv6_port))
			goto err1;

    socklen_t len = sizeof(struct sockaddr_in);
    if (sa.ss_family == AF_INET)
    {
      memcpy(&((struct sockaddr_in*)&sa)->sin_addr, pac, (size_t)4);
		  memcpy(&((struct sockaddr_in*)&sa)->sin_port, pac+4, (size_t)2);
    }
#ifdef HAVE_IPV6
    else if (sa.ss_family == AF_INET6)
    {
      ((struct sockaddr_in6*)&sa)->sin6_port = htons(ipv6_port);
      len = sizeof(struct sockaddr_in6);
    }
#endif
    else
      return -1;

    struct sockaddr_storage tmp;
    memcpy(&tmp, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));
		if (is_reserved((struct sockaddr*) &sa) ||
			   is_multicast((struct sockaddr*) &sa)  ||
			   (is_private((struct sockaddr*) &sa) != is_private((struct sockaddr*) &tmp)) ||
			   (is_loopback((struct sockaddr*) &sa) != is_loopback((struct sockaddr*) &tmp)))
		{
			// Invalid address returned by PASV. Replace with address from control
			// socket.
			ftp_err(_("Address returned by PASV seems to be incorrect.\n"));
			((struct sockaddr_in*)&sa)->sin_addr = ((struct sockaddr_in*)&tmp)->sin_addr;
		}

		if (!sock_connect_addr(ftp->data, (struct sockaddr*) &sa, len))
    {
      perror("connect()");
			goto err1;
    }
	} else {
    const struct sockaddr* local = sock_local_addr(ftp->data);
		sock_listen(ftp->data, local->sa_family);

    if (local->sa_family == AF_INET)
    {
      struct sockaddr_in* tmp = (struct sockaddr_in*)local;
  		a = (unsigned char *)&tmp->sin_addr;
	  	p = (unsigned char *)&tmp->sin_port;

		  ftp_set_tmp_verbosity(vbError);
		  ftp_cmd("PORT %d,%d,%d,%d,%d,%d",
				  a[0], a[1], a[2], a[3], p[0], p[1]);
    }
#ifdef HAVE_IPV6
    else if (local->sa_family == AF_INET6)
    {
      char* addr = printable_address(local);

      ftp_set_tmp_verbosity(vbError);
		  ftp_cmd("EPRT |2|%s|%u", addr, ntohs(((struct sockaddr_in6*)local)->sin6_port));
      free(addr);
    }
#endif
    else
      goto err1;

		if(ftp->code != ctComplete)
			goto err1;
	}

	sock_throughput(ftp->data);

	return 0;

 err1:
	sock_destroy(ftp->data);
	ftp->data = 0;
	return -1;
}
Esempio n. 18
0
static int ftp_init_transfer(void)
{
  if (!ftp_connected())
    return -1;

  if (!sock_dup(ftp->ctrl, &ftp->data))
    return -1;

  if (ftp_is_passive())
  {
    ftp_trace("Initializing passive connection.\n");

    struct sockaddr_storage sa;
    memcpy(&sa, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));

    unsigned char pac[6] = { 0 };
    unsigned short ipv6_port = { 0 };
    if (!ftp_pasv(sa.ss_family != AF_INET, pac, &ipv6_port))
    {
      ftp_trace("PASV/EPSV failed.\n");
      sock_destroy(ftp->data);
      ftp->data = NULL;
      return -1;
    }

    socklen_t len = sizeof(struct sockaddr_in);
    if (sa.ss_family == AF_INET)
    {
      memcpy(&((struct sockaddr_in*)&sa)->sin_addr, pac, (size_t)4);
      memcpy(&((struct sockaddr_in*)&sa)->sin_port, pac+4, (size_t)2);
    }
#ifdef HAVE_IPV6
    else if (sa.ss_family == AF_INET6)
    {
      ((struct sockaddr_in6*)&sa)->sin6_port = htons(ipv6_port);
      len = sizeof(struct sockaddr_in6);
    }
#endif
    else
    {
      ftp_trace("Do not know how to handle family %d.\n", sa.ss_family);
      sock_destroy(ftp->data);
      ftp->data = NULL;
      return -1;
    }

    struct sockaddr_storage tmp;
    memcpy(&tmp, sock_remote_addr(ftp->ctrl), sizeof(struct sockaddr_storage));
    if (is_reserved((struct sockaddr*) &sa) ||
         is_multicast((struct sockaddr*) &sa)  ||
         (is_private((struct sockaddr*) &sa) != is_private((struct sockaddr*) &tmp)) ||
         (is_loopback((struct sockaddr*) &sa) != is_loopback((struct sockaddr*) &tmp)))
    {
      // Invalid address returned by PASV. Replace with address from control
      // socket.
      ftp_err(_("Address returned by PASV seems to be incorrect.\n"));
      ((struct sockaddr_in*)&sa)->sin_addr = ((struct sockaddr_in*)&tmp)->sin_addr;
    }

    if (!sock_connect_addr(ftp->data, (struct sockaddr*) &sa, len))
    {
      ftp_trace("Could not connect to address from PASV/EPSV.\n");
      perror("connect()");
      sock_destroy(ftp->data);
      ftp->data = NULL;
      return -1;
    }
  } else {
    ftp_trace("Initializing active connection.\n");

    const struct sockaddr* local = sock_local_addr(ftp->data);
    sock_listen(ftp->data, local->sa_family);

    if (local->sa_family == AF_INET)
    {
      struct sockaddr_in* tmp = (struct sockaddr_in*)local;
      unsigned char* a = (unsigned char *)&tmp->sin_addr;
      unsigned char* p = (unsigned char *)&tmp->sin_port;

      ftp_set_tmp_verbosity(vbError);
      ftp_cmd("PORT %d,%d,%d,%d,%d,%d",
          a[0], a[1], a[2], a[3], p[0], p[1]);
    }
#ifdef HAVE_IPV6
    else if (local->sa_family == AF_INET6)
    {
      char* addr = printable_address(local);

      ftp_set_tmp_verbosity(vbError);
      ftp_cmd("EPRT |2|%s|%u|", addr, ntohs(((struct sockaddr_in6*)local)->sin6_port));
      free(addr);
    }
#endif
    else
    {
      ftp_trace("Do not know how to handle family %d.\n", local->sa_family);
      sock_destroy(ftp->data);
      ftp->data = NULL;
      return -1;
    }

    if(ftp->code != ctComplete)
    {
      ftp_trace("PORT/EPRT not successful\n");
      sock_destroy(ftp->data);
      ftp->data = NULL;
      return -1;
    }
  }

  sock_throughput(ftp->data);
  return 0;
}
Esempio n. 19
0
bool ftp_loggedin(void)
{
    return (ftp_connected() && ftp->loggedin);
}
Esempio n. 20
0
static void getfiles(list *gl, unsigned int opt, const char *output)
{
    listitem *li;
    rfile *fp, *lnfp;
    const char *opath, *ofile;
    char *link = 0;

    list_sort(gl, get_sort_func, false);

    li = gl->first;
    while(li && !get_quit) {
        fp = (rfile *)li->data;

        if(!ftp_connected())
            return;

        if(gvSighupReceived) {
            if(!test(opt, GET_RESUME))
                opt |= GET_UNIQUE;
            opt |= GET_FORCE;
        }

        opath = fp->path;
        ofile = base_name_ptr(opath);

        if(strcmp(ofile, ".")==0 || strcmp(ofile, "..")==0) {
            transfer_nextfile(gl, &li, true);
            continue;
        }

        if(test(opt, GET_INTERACTIVE) && !get_batch && !gvSighupReceived) {
						char* sp = shortpath(opath, 42, ftp->homedir);
            int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
                        _("Get '%s'?"), sp);
						free(sp);
            if(a == ASKNO) {
                transfer_nextfile(gl, &li, true);
                continue;
            }
            if(a == ASKCANCEL) {
                get_quit = true;
                break;
            }
            if(a == ASKALL)
                get_batch = true;
            /* else a==ASKYES */
        }


        if(rislink(fp)) {
            link_to_link__duh:
            if(test(opt, GET_NO_DEREFERENCE)) {
                /* link the file, don't copy */
                const int r = getfile(fp, opt, output, ofile);
                transfer_nextfile(gl, &li, r == 0);
                continue;
            }

            {
                char *xcurdir = base_dir_xptr(opath);
                link = path_absolute(fp->link, xcurdir, ftp->homedir);
                stripslash(link);
                free(xcurdir);
                ftp_trace("found link: '%s' -> '%s'\n", opath, link);
            }

            lnfp = ftp_get_file(link);
            if(lnfp == 0) {
                /* couldn't dereference the link, try to RETR it */
                ftp_trace("unable to dereference link\n");
                const int r = getfile(fp, opt, output, ofile);
                transfer_nextfile(gl, &li, r == 0);
                continue;
            }

            if(strncmp(opath, lnfp->path, strlen(lnfp->path)) == 0) {
                ftp_trace("opath == '%s', lnfp->path == '%s'\n", opath,
                          lnfp->path);
								char* sp = shortpath(lnfp->path, 42, ftp->homedir);
                fprintf(stderr, _("%s: circular link -- skipping\n"), sp);
								free(sp);
                transfer_nextfile(gl, &li, true);
                continue;
            }

            fp = lnfp;

            if(rislink(fp))
                /* found a link pointing to another link
                 */
                /* forgive me father, for I have goto'ed */
                goto link_to_link__duh;
        }

        if(risdir(fp)) {
            if(test(opt, GET_RECURSIVE)) {
                char *recurs_output;
                char *recurs_mask;
                list *rgl;


                if((get_dir_glob_mask && fnmatch(get_dir_glob_mask,
                                                 base_name_ptr(fp->path),
                                                 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
                   || (get_dir_rx_mask_set && regexec(&get_dir_rx_mask,
                                                      base_name_ptr(fp->path),
                                                      0, 0, 0) == REG_NOMATCH)
#endif
                    )
                    {
                    } else {
                        char *q_recurs_mask;

                        bool success = true;
                        if(!test(opt, GET_PARENTS))
                            success = asprintf(&recurs_output, "%s/%s",
                                     output ? output : ".", ofile) != -1;
                        else
                            success = asprintf(&recurs_output, "%s",
                                     output ? output : ".") != -1;
                        if (!success)
                        {
                          fprintf(stderr, _("Failed to allocate memory.\n"));
                          transfer_nextfile(gl, &li, true);
			                    continue;
                        }
                        if (asprintf(&recurs_mask, "%s/*", opath) == -1)
                        {
                          free(recurs_output);
                          fprintf(stderr, _("Failed to allocate memory.\n"));
                          transfer_nextfile(gl, &li, true);
                          continue;
                        }
                        rgl = rglob_create();
                        q_recurs_mask = backslash_quote(recurs_mask);
                        rglob_glob(rgl, q_recurs_mask, true, true, get_exclude_func);
                        free(q_recurs_mask);
                        if(list_numitem(rgl) > 0)
                            getfiles(rgl, opt, recurs_output);
                        if(test(opt, GET_PRESERVE))
                            get_preserve_attribs(fp, recurs_output);
                        rglob_destroy(rgl);
                        free(recurs_output);
                    }
            } else if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(opath, 42, ftp->homedir);
							fprintf(stderr, _("%s: omitting directory\n"), sp);
							free(sp);
            }
            transfer_nextfile(gl, &li, true);
            continue;
        }
        if(!risreg(fp)) {
            if(test(opt, GET_VERBOSE)) {
							char* sp = shortpath(opath, 42, ftp->homedir);
                fprintf(stderr, _("%s: not a regular file\n"), sp);
								free(sp);
						}
            transfer_nextfile(gl, &li, true);
            continue;
        }
        const int r = getfile(fp, opt, output, ofile);

        transfer_nextfile(gl, &li, r == 0);

        if(gvInterrupted) {
            gvInterrupted = false;
            if(li && !get_quit && ftp_connected() && !gvSighupReceived)
            {
                int a = ask(ASKYES|ASKNO, ASKYES,
                            _("Continue transfer?"));
                if(a == ASKNO) {
                    get_quit = true;
                    break;
                }
                /* else a == ASKYES */
                fprintf(stderr, _("Excellent!!!\n"));
            }
        }
    }
}
Esempio n. 21
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;
}
Esempio n. 22
0
static void putfiles(list *gl, unsigned opt, const char *output)
{
	struct stat sb;
	char *path = 0;
	const char *file;
	listitem *li;

	list_sort(gl, put_sort_func, false);

	for(li=gl->first; li && !put_quit; li=li->next) {

		if(!ftp_connected())
			return;

		if(gvSighupReceived) {
			if(!test(opt, PUT_RESUME))
				opt |= PUT_UNIQUE;
			opt |= PUT_FORCE;
		}

		path = (char *)li->data;
		file = base_name_ptr(path);

		if(strcmp(file, ".") == 0 || strcmp(file, "..") == 0)
			continue;

		if(test(opt, PUT_INTERACTIVE) && !put_batch) {
			int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
						_("Put '%s'?"),
						shortpath(path, 42, gvLocalHomeDir));
			if(a == ASKNO)
				continue;
			if(a == ASKCANCEL) {
				put_quit = true;
				break;
			}
			if(a == ASKALL)
				put_batch = true;
			/* else a==ASKYES */
		}

		if(stat(path, &sb) != 0) {
			perror(path);
			continue;
		}

		if(S_ISDIR(sb.st_mode)) {
			if(test(opt, PUT_RECURSIVE)) {
				char *recurs_output;
				char *recurs_mask;
				list *rgl;
				int r;

				if((put_dir_glob_mask
					&& fnmatch(put_dir_glob_mask,
							   base_name_ptr(path),
							   FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
				   || (put_dir_rx_mask_set
					   && regexec(&put_dir_rx_mask,
								  base_name_ptr(path),
								  0, 0, 0) == REG_NOMATCH)
#endif
					)
					{
						/*printf("skipping %s\n", path);*/
					} else {
						if(!test(opt, PUT_PARENTS)) {
							asprintf(&recurs_output, "%s/%s",
									 output ? output : ".", file);
						} else
							recurs_output = xstrdup(output ? output : ".");

						asprintf(&recurs_mask, "%s/*", path);
						rgl = lglob_create();
						r = lglob_glob(rgl, recurs_mask, true,
									   put_exclude_func);
						free(recurs_mask);

						if(list_numitem(rgl) > 0)
							putfiles(rgl, opt, recurs_output);
						free(recurs_output);
					}
			} else
				fprintf(stderr, _("%s: omitting directory\n"),
					   shortpath(path, 42, gvLocalHomeDir));
			continue;
		}
		if(!S_ISREG(sb.st_mode)) {
			fprintf(stderr, _("%s: not a regular file\n"),
					shortpath(path, 42, gvLocalHomeDir));
			continue;
		}
		putfile(path, &sb, opt, output);

		if(gvInterrupted) {
			gvInterrupted = false;
			if(li->next && !put_quit && ftp_connected() && !gvSighupReceived)
			{
				int a = ask(ASKYES|ASKNO, ASKYES,
							_("Continue transfer?"));
				if(a == ASKNO) {
					put_quit = true;
					break;
				}
				/* else a == ASKYES */
				fprintf(stderr, _("Excellent!!!\n"));
			}
		}
	}
}