Esempio n. 1
0
static int wait_for_data(Socket* fp, bool wait_for_read)
{
  errno = 0;
	const int r = sock_check_pending(fp, !wait_for_read);
#if 0
	if(r < 0 && errno == EINTR && gvSigStopReceived && ftp_sigints() == 0) {
		gvSigStopReceived = false;
		r = 0;
	}
#endif
	if(r < 0) {
/*		perror("\nselect");*/
		if(errno == EINTR) {
			if(gvSighupReceived)
				return 1;
			if(gvInterrupted)
				return -1;
			if(ftp_sigints() == 0)
				/* assume it is a SIGSTOP/SIGCONT signal */
				return 0;
		}
		return -1;
	}

	if(r)
		ftp->ti.stalled = 0;
	else
		ftp->ti.stalled++;

	return r;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
static int wait_for_data(FILE *fd, bool wait_for_read)
{
	fd_set fds;
	struct timeval tv;
	int r;

	/* watch fd to see if it has input */
	FD_ZERO(&fds);
	FD_SET(fileno(fd), &fds);
	/* wait max 1 second */
	tv.tv_sec = 10;
	tv.tv_usec = 0;

	if(wait_for_read)
		r = select(fileno(fd)+1, &fds, 0, 0, &tv);
	else /* wait for write */
		r = select(fileno(fd)+1, 0, &fds, 0, &tv);
#if 0
	if(r < 0 && errno == EINTR && gvSigStopReceived && ftp_sigints() == 0) {
		gvSigStopReceived = false;
		r = 0;
	}
#endif
	if(r < 0) {
/*		perror("\nselect");*/
		if(errno == EINTR) {
			if(gvSighupReceived)
				return 1;
			if(gvInterrupted)
				return -1;
			if(ftp_sigints() == 0)
				/* assume it is a SIGSTOP/SIGCONT signal */
				return 0;
		}
		return -1;
	}

	if(r)
		ftp->ti.stalled = 0;
	else
		ftp->ti.stalled++;

	return r;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;

}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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);
}