예제 #1
0
static char *ftplist_completion_function(const char *text, int state)
{
	static int len;
	static listitem *lip = 0;

	if(!state) {
		len = strlen(text);
		lip = gvFtpList->first;
	}

	while(lip) {
		char *name;
		Ftp *f = (Ftp *)lip->data;
		lip = lip->next;
		if(f->url == 0)
			/* Ftp not connected */
			continue;
		name = f->url->alias ? f->url->alias : f->url->hostname;
		if(strncmp(name, text, len) == 0)
			return bash_backslash_quote(name);
	}
	return 0;
}
예제 #2
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;
}
예제 #3
0
파일: put.c 프로젝트: wmene/yafc-1.1.2
static void putfile(const char *path, struct stat *sb,
					unsigned opt, const char *output)
{
	putmode_t how = putNormal;
	bool file_exists = false;
	char *dest, *dpath;
	int r;
	bool dir_created;
	char *dest_dir, *q_dest_dir;

	if((put_glob_mask && fnmatch(put_glob_mask, base_name_ptr(path),
								 FNM_EXTMATCH) == FNM_NOMATCH)
#ifdef HAVE_REGEX
	   || (put_rx_mask_set && regexec(&put_rx_mask, base_name_ptr(path),
									  0, 0, 0) == REG_NOMATCH)
#endif
		)
		return;

	if(!output)
		output = ".";

	if(test(opt, PUT_PARENTS)) {
		char *p = base_dir_xptr(path);
		asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(path));
		free(p);
	} else if(test(opt, PUT_OUTPUT_FILE))
		dest = xstrdup(output);
	else
		asprintf(&dest, "%s/%s", output, base_name_ptr(path));

	path_collapse(dest);

	/* make sure destination directory exists */
	dpath = base_dir_xptr(dest);
	dest_dir = ftp_path_absolute(dpath);
	q_dest_dir = bash_backslash_quote(dest_dir);
	r = ftp_mkpath(q_dest_dir);
	free(q_dest_dir);
	free(dest_dir);
	if(r == -1) {
		transfer_mail_msg(_("failed to create directory %s\n"), dest_dir);
		free(dpath);
		free(dest);
		return;
	}
	dir_created = (r == 1);

	if(!dir_created && !test(opt, PUT_UNIQUE) && !test(opt, PUT_FORCE)) {
		rfile *f;
		f = ftp_get_file(dest);
		file_exists = (f != 0);
		if(f && risdir(f)) {
			/* can't overwrite a directory */
			printf(_("%s: is a directory\n"), dest);
			free(dest);
			return;
		}
	}

	if(test(opt, PUT_APPEND)) {
		how = putAppend;
	} else if(file_exists) {
		if(test(opt, PUT_SKIP_EXISTING)) {
			printf(_("Remote file '%s' exists, skipping...\n"),
				   shortpath(dest, 42, ftp->homedir));
			free(dest);
			return;
		}
		else if(test(opt, PUT_NEWER)) {
			time_t ft = ftp_filetime(dest);
			if(ft != (time_t)-1 && ft >= sb->st_mtime) {
				printf(_("Remote file '%s' is newer than local, skipping...\n"),
					   shortpath(dest, 42, ftp->homedir));
				free(dest);
				return;
			}
		}
		else if(!test(opt, PUT_RESUME)) {
			if(!put_owbatch) {
				struct tm *fan = gmtime(&sb->st_mtime);
				time_t ft;
				int a;
				rfile *f;
				char *e;

				f = ftp_get_file(dest);
				ft = ftp_filetime(f->path);
				sb->st_mtime = gmt_mktime(fan);
				e = xstrdup(ctime(&sb->st_mtime));
				a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
						ASKRESUME,
						_("Remote file '%s' exists\nLocal: %lld bytes, %sRemote: %lld bytes, %sOverwrite?"),
						shortpath(dest, 42, ftp->homedir),
						(unsigned long long) sb->st_size, e ? e : "unknown size",
						ftp_filesize(f->path), ctime(&ft));
				free(e);
				if(a == ASKCANCEL) {
					put_quit = true;
					free(dest);
					return;
				}
				else if(a == ASKNO) {
					free(dest);
					return;
				}
				else if(a == ASKUNIQUE)
					opt |= PUT_UNIQUE; /* for this file only */
				else if(a == ASKALL)
					put_owbatch = true;
				else if(a == ASKRESUME)
					opt |= PUT_RESUME; /* for this file only */
				/* else a == ASKYES */
			}
		}
	}

	if(test(opt, PUT_RESUME))
		how = putResume;
	if(test(opt, PUT_UNIQUE))
		how = putUnique;

	r = do_the_put(path, dest, how, opt);
	free(dest);
	if(r != 0)
		return;

	if(test(opt, PUT_PRESERVE)) {
		if(ftp->has_site_chmod_command)
			ftp_chmod(ftp->ti.local_name, get_mode_string(sb->st_mode));
	}

	if(test(opt, PUT_DELETE_AFTER)) {
		bool dodel = false;

		if(!test(opt, PUT_FORCE) && !put_delbatch) {
			int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
						_("Delete local file '%s'?"),
						shortpath(path, 42, gvLocalHomeDir));
			if(a == ASKALL) {
				put_delbatch = true;
				dodel = true;
			}
			else if(a == ASKCANCEL)
				put_quit = true;
			else if(a != ASKNO)
				dodel = true;
		} else
			dodel = true;

		if(dodel) {
			if(unlink(path) == 0)
				printf(_("%s: deleted\n"),
					   shortpath(path, 42, gvLocalHomeDir));
			else
				printf(_("error deleting '%s': %s\n"),
					   shortpath(path, 42, gvLocalHomeDir),
					   strerror(errno));
		}
	}
}
예제 #4
0
파일: bashline.c 프로젝트: casualuser/yafc
/* Quote a filename using double quotes, single quotes, or backslashes
   depending on the value of completion_quoting_style.  If we're
   completing using backslashes, we need to quote some additional
   characters (those that readline treats as word breaks), so we call
   quote_word_break_chars on the result. */
char *bash_quote_filename (char *s, int rtype, char *qcp)
{
  char *rtext, *mtext, *ret;
  int rlen, cs;

  rtext = (char *)NULL;

  /* If RTYPE == MULT_MATCH, it means that there is
     more than one match.  In this case, we do not add
     the closing quote or attempt to perform tilde
     expansion.  If RTYPE == SINGLE_MATCH, we try
     to perform tilde expansion, because single and double
     quotes inhibit tilde expansion by the shell. */

  mtext = s;
  if (mtext[0] == '~' && rtype == SINGLE_MATCH)
    mtext = tilde_expand_home (s, gvLocalHomeDir);

  cs = completion_quoting_style;
  /* Might need to modify the default completion style based on *qcp,
     since it's set to any user-provided opening quote. */
  if (*qcp == '"')
    cs = COMPLETE_DQUOTE;
  else if (*qcp == '\'')
    cs = COMPLETE_SQUOTE;
#if defined (BANG_HISTORY)
  else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE &&
	   history_expansion_inhibited == 0 && strchr (mtext, '!'))
    cs = COMPLETE_BSQUOTE;

  if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE &&
        history_expansion_inhibited == 0 && strchr (mtext, '!'))
    {
      cs = COMPLETE_BSQUOTE;
      *qcp = '\0';
    }
#endif

  switch (cs)
    {
    case COMPLETE_DQUOTE:
      rtext = bash_double_quote (mtext);
      break;
    case COMPLETE_SQUOTE:
      rtext = bash_single_quote (mtext);
      break;
    case COMPLETE_BSQUOTE:
      rtext = bash_backslash_quote (mtext);
      break;
    }

  if (mtext != s)
    free (mtext);

  /* We may need to quote additional characters: those that readline treats
     as word breaks that are not quoted by backslash_quote. */
  if (rtext && cs == COMPLETE_BSQUOTE)
    {
      mtext = quote_word_break_chars (rtext);
      free (rtext);
      rtext = mtext;
    }

  /* Leave the opening quote intact.  The readline completion code takes
     care of avoiding doubled opening quotes. */
  rlen = strlen (rtext);
  ret = xmalloc (rlen + 1);
  strcpy (ret, rtext);

  /* If there are multiple matches, cut off the closing quote. */
  if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE)
    ret[rlen - 1] = '\0';
  free (rtext);
  return ret;
}