コード例 #1
0
ファイル: ftpsend.c プロジェクト: casualuser/yafc
static int FILE_recv_binary(FILE *in, FILE *out)
{
	size_t n;
	char *buf;
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	clearerr(out);

	buf = (char *)xmalloc(FTP_BUFSIZ);
	while(!feof(in)) {

		if(wait_for_input() != 0) {
			ftp_trace("wait_for_input() returned non-zero\n");
			break;
		}
#ifdef SECFTP
		n = sec_read(fileno(in), buf, FTP_BUFSIZ);
#else
		n = fread(buf, sizeof(char), FTP_BUFSIZ, in);
#endif
		if(n <= 0)
			break;

		if(ftp_sigints() > 0) {
			ftp_trace("break due to sigint\n");
			break;
		}

		if(fwrite(buf, sizeof(char), n, out) != n)
			break;

		ftp->ti.size += n;

		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	free(buf);
	ftp_set_close_handler();

	return maybe_abort(in, out);
}
コード例 #2
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static int FILE_recv_binary(Socket* in, FILE *out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	sock_clearerr_in(in);
	clearerr(out);

	char* buf = xmalloc(FTP_BUFSIZ);
	while (!sock_eof(in)) {
		if(wait_for_input() != 0) {
			ftp_trace("wait_for_input() returned non-zero\n");
			break;
		}

    const ssize_t n = sock_read(in, buf, FTP_BUFSIZ);
		if (n <= 0)
			break;

		if(ftp_sigints() > 0) {
			ftp_trace("break due to sigint\n");
			break;
		}

		if(fwrite(buf, sizeof(char), n, out) != n)
			break;

		ftp->ti.size += n;

		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	free(buf);
	ftp_set_close_handler();

	return maybe_abort_in(in, out);
}
コード例 #3
0
ファイル: ftp.c プロジェクト: 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();
}
コード例 #4
0
ファイル: ftpsend.c プロジェクト: wmene/yafc-1.1.2
static int maybe_abort(FILE *in, FILE *out)
{
    unsigned i;

    i = ftp_sigints();
    ftp_set_close_handler();

    ftp->ti.finished = true;

    if(ftp->ti.interrupted)
        i++;

    if(i > 0 || ferror(in) || ferror(out)) {
        if(ferror(in)) {
            ftp_err(_("read error: %s\n"), strerror(errno));
            ftp->ti.ioerror = true;
        }
        else if(ferror(out)) {
            ftp_err(_("write error: %s\n"), strerror(errno));
            ftp->ti.ioerror = true;
        }
        return ftp_abort(ftp->ti.transfer_is_put ? out : in);
    }
    return 0;
}
コード例 #5
0
ファイル: ftp.c プロジェクト: casualuser/yafc
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();
}
コード例 #6
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
/* 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;
}
コード例 #7
0
ファイル: ftpsend.c プロジェクト: casualuser/yafc
static int FILE_recv_ascii(FILE *in, FILE *out)
{
	char *buf = (char *)xmalloc(FTP_BUFSIZ);
	int c;
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	clearerr(out);

	while((c = krb_getc(in)) != EOF) {
		if(ftp_sigints() > 0)
			break;

		if(wait_for_input() != 0)
			break;

		if(c == '\n')
			ftp->ti.barelfs++;
		else if(c == '\r') {
			c = krb_getc(in);
			if(c == EOF)
				break;
			if(c != '\n') {
				ungetc(c, in);
				c = '\r';
			}
		}
		if(fputc(c, out) == EOF)
			break;

		ftp->ti.size++;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	free(buf);

	return maybe_abort(in, out);
}
コード例 #8
0
ファイル: ftpsend.c プロジェクト: casualuser/yafc
static int FILE_send_binary(FILE *in, FILE *out)
{
	size_t n;
	char *buf;
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	clearerr(out);

	buf = (char *)xmalloc(FTP_BUFSIZ);
	while(!feof(in)) {
		n = fread(buf, sizeof(char), FTP_BUFSIZ, in);
		if(n <= 0)
			break;

		if(ftp_sigints() > 0)
			break;

		if(wait_for_output() != 0)
			break;
#ifdef SECFTP
		if(sec_write(fileno(out), buf, n) != n)
			break;
#else
		if(fwrite(buf, sizeof(char), n, out) != n)
			break;
#endif
		ftp->ti.size += n;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}
#ifdef SECFTP
	sec_fflush(out);
#endif

	free(buf);

	return maybe_abort(in, out);
}
コード例 #9
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static int FILE_send_binary(FILE *in, Socket *out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	sock_clearerr_out(out);

	char* buf = xmalloc(FTP_BUFSIZ);
	while(!feof(in)) {
		ssize_t n = fread(buf, sizeof(char), FTP_BUFSIZ, in);
		if(n <= 0)
			break;

		if(ftp_sigints() > 0)
			break;

		if(wait_for_output() != 0)
			break;

    if (sock_write(out, buf, n) != n)
      break;
		ftp->ti.size += n;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}
	sock_flush(out);
	free(buf);

	return maybe_abort_out(in, out);
}
コード例 #10
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static int FILE_send_ascii(FILE* in, Socket* out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	sock_clearerr_out(out);

  int c;
	while((c = fgetc(in)) != EOF) {
		if(ftp_sigints() > 0)
			break;

		if(wait_for_output() != 0)
			break;

		if(c == '\n') {
			if(sock_put(out, '\r') == EOF)
				break;
			ftp->ti.size++;
		}
		if(sock_put(out, c) == EOF)
			break;
		ftp->ti.size++;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	return maybe_abort_out(in, out);
}
コード例 #11
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static int maybe_abort_out(FILE *in, Socket *out)
{
	unsigned int i = ftp_sigints();
	ftp_set_close_handler();

	ftp->ti.finished = true;

	if(ftp->ti.interrupted)
		i++;

	if(i > 0 || ferror(in) || sock_error_out(out)) {
		if(ferror(in)) {
			ftp_err(_("read error: %s\n"), strerror(errno));
			ftp->ti.ioerror = true;
		}
		else if (sock_error_out(out)) {
			ftp_err(_("write error: %s\n"), strerror(errno));
			ftp->ti.ioerror = true;
		}
		return ftp_abort(out);
	}
	return 0;
}
コード例 #12
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
static int do_write(const char* path, FILE* fp, ftp_transfer_func hookf,
                    uint64_t offset)
{
  /* try to set up a scp connection */
  if (gvSSHTrySCP && !offset)
  {
    ssh_scp scp = ssh_scp_new(ftp->session, SSH_SCP_WRITE, path);
    if (scp != NULL)
    {
      int rc = ssh_scp_init(scp);
      if (rc == SSH_OK)
        return do_scp_write(scp, path, fp, hookf);
      ssh_scp_free(scp);
    }
  }

  time_t then = time(NULL) - 1;
  ftp_set_close_handler();

  if (hookf)
    hookf(&ftp->ti);
  ftp->ti.begin = false;

  struct stat sb;
  errno = 0;
  if (fstat(fileno(fp), &sb) == -1)
  {
    ftp_err(_("Couldn't fstat local file: %s\n"), strerror(errno));
    return -1;
  }

  /* open remote file */
  sftp_file file = sftp_open(ftp->sftp_session, path, O_WRONLY | O_CREAT |
      (offset == 0u ? O_TRUNC : 0), sb.st_mode);
  if (!file)
  {
    ftp_err(_("Cannot open file for writing: %s\n"), ssh_get_error(ftp->session));
    return -1;
  }

  /* seek to offset */
  int r = sftp_seek64(file, offset);
  if (r != SSH_OK)
  {
    ftp_err(_("Failed to seek: %s\n"), ssh_get_error(ftp->session));
    sftp_close(file);
    return -1;
  }

  /* read file */
  char buffer[SSH_BUFSIZ];
  ssize_t nbytes = 0;
  errno = 0;
  while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), fp)) > 0)
  {
    if (ftp_sigints() > 0)
    {
      ftp_trace("break due to sigint\n");
      break;
    }

    ssize_t nwritten = sftp_write(file, buffer, nbytes);
    if (nwritten != nbytes)
    {
      ftp_err(_("Error while writing to file: %s\n"), ssh_get_error(ftp->session));
      sftp_close(file);
      return -1;
    }

    ftp->ti.size += nbytes;
    if (hookf)
    {
      time_t now = time(NULL);
      if (now > then)
      {
        hookf(&ftp->ti);
        then = now;
      }
    }
    errno = 0;
  }

  if (ferror(fp))
  {
    ftp_err(_("Failed to read from file: %s\n"), strerror(errno));
    r = -1;
  }

  sftp_close(file);
  return r;

}
コード例 #13
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
static int do_scp_write(ssh_scp scp, const char* path, FILE* fp,
                        ftp_transfer_func hookf)
{
  time_t then = time(NULL) - 1;
  ftp_set_close_handler();

  if (hookf)
    hookf(&ftp->ti);
  ftp->ti.begin = false;

  struct stat sb;
  errno = 0;
  if (fstat(fileno(fp), &sb) == -1)
  {
    ftp_err(_("Couldn't fstat local file: %s\n"), strerror(errno));
    ssh_scp_free(scp);
    return -1;
  }

  int rc = ssh_scp_push_file(scp, path, sb.st_size, sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
  if (rc != SSH_OK)
  {
    ftp_err(_("Failed to start scp upload: %s\n"),
            ssh_get_error(ftp->session));
    ssh_scp_close(scp);
    ssh_scp_free(scp);
    return -1;
  }

  /* read file */
  char buffer[SSH_BUFSIZ];
  ssize_t nbytes = 0;
  errno = 0;
  while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), fp)) > 0)
  {
    if (ftp_sigints() > 0)
    {
      ftp_trace("break due to sigint\n");
      break;
    }

    rc = ssh_scp_write(scp, buffer, nbytes);
    if (rc != SSH_OK)
    {
      ftp_err(_("Error while writing to file: %s\n"), ssh_get_error(ftp->session));
      ssh_scp_close(scp);
      ssh_scp_free(scp);
      return -1;
    }

    ftp->ti.size += nbytes;
    if (hookf)
    {
      time_t now = time(NULL);
      if (now > then)
      {
        hookf(&ftp->ti);
        then = now;
      }
    }
    errno = 0;
  }

  if (ferror(fp))
  {
    ftp_err(_("Failed to read from file: %s\n"), strerror(errno));
    rc = -1;
  }

  ssh_scp_close(scp);
  ssh_scp_free(scp);
  return rc;
}
コード例 #14
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
static int do_read(const char* infile, FILE* fp, getmode_t mode,
                   ftp_transfer_func hookf, uint64_t offset)
{
  if (gvSSHTrySCP && !offset)
  {
    char* escaped = bash_backslash_quote(infile);
    /* try to set up a scp connection */
    ssh_scp scp = ssh_scp_new(ftp->session, SSH_SCP_READ, escaped);
    free(escaped);
    if (scp != NULL)
    {
      int rc = ssh_scp_init(scp);
      if (rc == SSH_OK)
        return do_scp_read(scp, infile, fp, mode, hookf);
      ssh_scp_free(scp);
    }
  }

  time_t then = time(NULL) - 1;
  ftp_set_close_handler();

  if (hookf)
    hookf(&ftp->ti);
  ftp->ti.begin = false;

  /* check if remote file is not a directory */
  sftp_attributes attrib = sftp_stat(ftp->sftp_session, infile);
  if (!attrib)
    return -1;

  if (S_ISDIR(attrib->permissions))
  {
    ftp_err(_("Cannot download a directory: %s\n"), infile);
    sftp_attributes_free(attrib);
    return -1;
  }
  sftp_attributes_free(attrib);

  /* open remote file */
  sftp_file file = sftp_open(ftp->sftp_session, infile, O_RDONLY, 0);
  if (!file)
  {
    ftp_err(_("Cannot open file for reading: %s\n"), ssh_get_error(ftp->session));
    return -1;
  }

  /* seek to offset */
  int r = sftp_seek64(file, offset);
  if (r != SSH_OK)
  {
    ftp_err(_("Failed to seek: %s\n"), ssh_get_error(ftp->session));
    sftp_close(file);
    return -1;
  }

  /* read file */
  char buffer[SSH_BUFSIZ];
  ssize_t nbytes = 0;
  while ((nbytes = sftp_read(file, buffer, sizeof(buffer))) > 0)
  {
    if (ftp_sigints() > 0)
    {
      ftp_trace("break due to sigint\n");
      break;
    }

    errno = 0;
    if (fwrite(buffer, nbytes, 1, fp) != 1)
    {
      ftp_err(_("Error while writing to file: %s\n"), strerror(errno));
      ftp->ti.ioerror = true;
      sftp_close(file);
      return -1;
    }

    ftp->ti.size += nbytes;
    if (hookf)
    {
      time_t now = time(NULL);
      if (now > then)
      {
        hookf(&ftp->ti);
        then = now;
      }
    }
  }

  if (nbytes < 0)
  {
    ftp_err(_("Error while reading from file: %s\n"), ssh_get_error(ftp->session));
    r = -1;
  }

  sftp_close(file);
  return r;
}
コード例 #15
0
ファイル: ssh_cmd.c プロジェクト: casualuser/yafc
static int do_scp_read(ssh_scp scp, const char* infile, FILE* fp,
                       getmode_t mode, ftp_transfer_func hookf)
{
  time_t then = time(NULL) - 1;
  ftp_set_close_handler();

  if (hookf)
    hookf(&ftp->ti);
  ftp->ti.begin = false;

  int rc = ssh_scp_pull_request(scp);
  if (rc != SSH_SCP_REQUEST_NEWFILE)
  {
    ftp_err(_("Failed to start scp download: %s\n"),
            ssh_get_error(ftp->session));
    ssh_scp_close(scp);
    ssh_scp_free(scp);
    return -1;
  }

  size_t size = ssh_scp_request_get_size(scp);
  ssh_scp_accept_request(scp);

  /* read file */
  char buffer[SSH_BUFSIZ];
  int r = 0;
  while (size && (r = ssh_scp_read(scp, buffer, MIN(SSH_BUFSIZ, size))) != SSH_ERROR)
  {
    if (ftp_sigints() > 0)
    {
      ftp_trace("break due to sigint\n");
      break;
    }

    errno = 0;
    if (fwrite(buffer, r, 1, fp) != 1)
    {
      ftp_err(_("Error while writing to file: %s\n"), strerror(errno));
      ssh_scp_close(scp);
      ssh_scp_free(scp);
      return -1;
    }

    ftp->ti.size += r;
    if (hookf)
    {
      time_t now = time(NULL);
      if (now > then)
      {
        hookf(&ftp->ti);
        then = now;
      }
    }
    size -= r;
  }

  if (r == SSH_ERROR)
  {
    ftp_err(_("Error while reading from file: %s\n"), ssh_get_error(ftp->session));
    r = -1;
  }
  else
  {
    r = ssh_scp_pull_request(scp);
    if (r != SSH_SCP_REQUEST_EOF)
      ftp_err(_("Unexpected request: %s %lu\n"), ssh_get_error(ftp->session), size);
    else
      r = 0;
  }

  ssh_scp_close(scp);
  ssh_scp_free(scp);
  return r;
}
コード例 #16
0
ファイル: ftpsend.c プロジェクト: sebastinas/yafc
static int FILE_recv_ascii(Socket* in, FILE *out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	sock_clearerr_in(in);
	clearerr(out);

  bool next = true;
  int nc = 0;
	while (true)
  {
    int c = 0;
    if (next)
    {
      c = sock_get(in);
      if (c == EOF)
        break;
    }
    else
    {
      c = nc;
      next = true;
    }

		if (ftp_sigints() > 0 || wait_for_input() != 0)
			break;

		if (c == '\n')
			ftp->ti.barelfs++;
		else if (c == '\r')
    {
			nc = sock_get(in);
			if (nc == EOF)
				break;
			if (nc != '\n')
        next = false;
      else
        c = nc;
		}
		if (fputc(c, out) == EOF)
			break;

		ftp->ti.size++;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}

	return maybe_abort_in(in, out);
}
コード例 #17
0
ファイル: ftp.c プロジェクト: casualuser/yafc
/* 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;
}
コード例 #18
0
ファイル: ftpsend.c プロジェクト: wmene/yafc-1.1.2
/* 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;
}