예제 #1
0
파일: ssh_cmd.c 프로젝트: casualuser/yafc
int ssh_send(const char *path, FILE *fp, putmode_t how,
       transfer_mode_t mode, ftp_transfer_func hookf)
{
  uint64_t offset = ftp->restart_offset;

  reset_transfer_info();
  ftp->ti.size = ftp->ti.restart_size = offset;
  ftp->restart_offset = 0L;

  ftp->ti.transfer_is_put = true;

  if(how == putUnique) {
    ftp_err(_("Unique put with SSH not implemented yet\n"));
    return -1;
  }

  char* p = ftp_path_absolute(path);
  stripslash(p);
  ftp_cache_flush_mark_for(p);

  if(how == putAppend) {
    ftp_set_tmp_verbosity(vbNone);
    offset = ftp_filesize(p);
  }

  int r = do_write(p, fp, hookf, offset);
  free(p);

  transfer_finished();
  return r;
}
예제 #2
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
static int ftp_init_receive(const char *path, transfer_mode_t mode,
							ftp_transfer_func hookf)
{
	long rp = ftp->restart_offset;
	char *e;

	ftp->restart_offset = 0L;

	foo_hookf = hookf;
	reset_transfer_info();

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

	ftp_cmd("RETR %s", path);
	if(ftp->code != ctPrelim)
		return -1;

	if(!sock_accept(ftp->data, "r", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	/* try to get the total file size */
	{
		/* see if we have cached this directory/file */
		rfile *f = ftp_cache_get_file(path);
		if(f)
			ftp->ti.total_size = f->size;
		else {
			/* try to figure out file size from RETR reply
			 * Opening BINARY mode data connection for foo.mp3 (14429793 bytes)
			 *                                                  ^^^^^^^^ aha!
			 *
			 * note: this might not be the _total_ filesize if we are RESTarting
			 */
			e = strstr(ftp->reply, " bytes");
			if(e != 0) {
				while((e > ftp->reply) && isdigit((int)e[-1]))
					e--;
				ftp->ti.total_size = strtoul(e,NULL,10);
			} /* else we don't bother */
		}
	}
	return 0;
}
예제 #3
0
파일: ssh_cmd.c 프로젝트: wmene/yafc-1.1.2
int ssh_send(const char *path, FILE *fp, putmode_t how,
			 transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long offset = ftp->restart_offset;
	char *p;

	reset_transfer_info();
	ftp->ti.size = ftp->ti.restart_size = offset;
	ftp->restart_offset = 0L;

	ftp->ti.transfer_is_put = true;

	if(how == putUnique) {
		ftp_err("Unique put with SSH not implemented yet\n");
		return -1;
#if 0
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
#endif
	}

	p = ftp_path_absolute(path);
	stripslash(p);

	ftp_cache_flush_mark_for(p);

	if(how == putAppend) {
		ftp_set_tmp_verbosity(vbNone);
		offset = ftp_filesize(p);
	}

	r = ssh_send_binary(p, fp, hookf, offset);
	free(p);

	transfer_finished();

	return 0;
}
예제 #4
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
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;
}
예제 #5
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
static int ftp_send(const char *path, FILE *fp, putmode_t how,
					transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long rp = ftp->restart_offset;
	ftp->restart_offset = 0L;

	if(how == putUnique && !ftp->has_stou_command)
		return -1;

  if (how == putTryUnique && !ftp->has_stou_command)
    how = putNormal;

	reset_transfer_info();
	ftp->ti.transfer_is_put = true;

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

  ftp_set_tmp_verbosity(vbError);
  switch (how) {
  case putAppend:
    ftp_cmd("APPE %s", path);
    break;

  case putTryUnique:
  case putUnique:
    ftp_cmd("STOU %s", path);
    if (ftp->fullcode == 502 || ftp->fullcode == 504) {
      ftp->has_stou_command = false;
      if (how == putTryUnique)
        how = putNormal;
      else
        break;
    }
    else
      break;

  default:
    ftp_cmd("STOR %s", path);
    break;
  }

	if(ftp->code != ctPrelim)
		return -1;

	if(how == putUnique) {
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
	}

	if(!sock_accept(ftp->data, "w", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	ftp_cache_flush_mark_for(path);

	if(mode == tmBinary)
		r = FILE_send_binary(fp, ftp->data);
	else
		r = FILE_send_ascii(fp, ftp->data);
	sock_flush(ftp->data);
	sock_destroy(ftp->data);
	ftp->data = 0;

	if(r == 0) {
		transfer_finished();
		ftp_read_reply();
		ftp->ti.ioerror = (ftp->code != ctComplete);
		if(ftp->code != ctComplete) {
			ftp_trace("transfer failed\n");
			return -1;
		}
	} else
		transfer_finished();

	return 0;
}
예제 #6
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
int ftp_getfile(const char *infile, const char *outfile, getmode_t how,
				transfer_mode_t mode, ftp_transfer_func hookf)
{
	FILE *fp;
	int r;
	struct stat statbuf;
	long rp = 0;
	int (*close_func)(FILE *fp);

	if(stat(outfile, &statbuf) == 0) {
		if(S_ISDIR(statbuf.st_mode)) {
			ftp_err(_("%s: is a directory\n"), outfile);
			return -1;
		}
		if(!(statbuf.st_mode & S_IWRITE)) {
			ftp_err(_("%s: permission denied\n"), outfile);
			return -1;
		}
		if(how == getResume)
			ftp->restart_offset = statbuf.st_size;
	} else
		ftp->restart_offset = 0L;

	ftp->ti.total_size = -1;

	/* we need to save this, because ftp_init_receive() sets it to zero */
	rp = ftp->restart_offset;

	reset_transfer_info();
#ifdef HAVE_LIBSSH
	if (ftp->session)
	{
		/* we need to stat the remote file, so we are sure we can read it
		 * this needs to be done before we call ssh_do_receive, because by
		 * then, the file is created, and would leave a zero-size file opon
		 * failure
		 */
		sftp_attributes a = sftp_stat(ftp->sftp_session, infile);
		if(!a) {
			ftp_err(_("Unable to stat file '%s': %s\n"), infile, ssh_get_error(ftp->session));
			return -1;
		}
		sftp_attributes_free(a);
		/* FIXME: how can we check if it will be possible to transfer
		 * the specified file?
		 */
	}
	else
#endif
	if (ftp_init_receive(infile, mode, hookf) != 0)
		return -1;

	if(how == getPipe) {
		fp = popen(outfile, "w");
		close_func = pclose;
	} else {
		fp = fopen(outfile,
				   (rp > 0L || (how == getAppend)) ? "a" : "w");
		close_func = fclose;
	}
	if(!fp) {
		ftp_err("%s: %s\n", outfile, strerror(errno));
		ftp->restart_offset = 0L;
		return -1;
	}

	if(rp > 0L) {
		if(fseek(fp, rp, SEEK_SET) != 0) {
			ftp_err(_("%s: %s, transfer cancelled\n"),
					outfile, strerror(errno));
			close_func(fp);
			ftp->restart_offset = 0L;
			return -1;
		}
	}

	free(ftp->ti.remote_name);
	free(ftp->ti.local_name);
	ftp->ti.remote_name = xstrdup(infile);
	ftp->ti.local_name = xstrdup(outfile);

	foo_hookf = hookf;

#ifdef HAVE_LIBSSH
	if(ftp->session)
		r = ssh_do_receive(infile, fp, mode, hookf);
	else
#endif
		r = ftp_do_receive(fp, mode, hookf);
	close_func(fp);
	return r;
}