Esempio n. 1
0
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;
}
Esempio n. 2
0
int ssh_mkdir_verb(const char *path, verbose_t verb)
{
	Attrib a;
	u_int status, id;
	char *abspath;

	attrib_clear(&a);
	a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
	a.perm = 0777;

	id = ftp->ssh_id++;
	abspath = ftp_path_absolute(path);
	stripslash(abspath);
	ssh_send_string_attrs_request(id, SSH2_FXP_MKDIR, abspath,
								  strlen(abspath), &a);

	status = ssh_get_status(id);
	if(status != SSH2_FX_OK) {
		ftp_err("Couldn't create directory: %s\n", fx2txt(status));
		free(abspath);
		return -1;
	}
	ftp_cache_flush_mark_for(abspath);
	free(abspath);

	return 0;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
rdirectory *ftp_get_directory(const char *path)
{
    rdirectory *rdir;
    char *ap;

    ap = ftp_path_absolute(path);
    stripslash(ap);

    rdir = ftp_cache_get_directory(ap);
    if(!rdir)
        rdir = ftp_read_directory(ap);
    free(ap);
    return rdir;
}
Esempio n. 5
0
int ssh_rename(const char *oldname, const char *newname)
{
  char* on = ftp_path_absolute(oldname);
  char* nn = ftp_path_absolute(newname);
  stripslash(on);
  stripslash(nn);

  int rc = sftp_rename(ftp->sftp_session, on, nn);
  if (rc != SSH_OK)
  {
    ftp_err(_("Couldn't rename file '%s' to '%s': %s\n"),
        on, nn, ssh_get_error(ftp->session));
    free(on);
    free(nn);
    return -1;
  }

  ftp_cache_flush_mark_for(on);
  ftp_cache_flush_mark_for(nn);
  free(on);
  free(nn);
  return 0;
}
Esempio n. 6
0
int ssh_rename(const char *oldname, const char *newname)
{
	Buffer msg;
	u_int status, id;
	char *on, *nn;

	buffer_init(&msg);

	on = ftp_path_absolute(oldname);
	nn = ftp_path_absolute(newname);
	stripslash(on);
	stripslash(nn);

	/* Send rename request */
	id = ftp->ssh_id++;
	buffer_put_char(&msg, SSH2_FXP_RENAME);
	buffer_put_int(&msg, id);
	buffer_put_cstring(&msg, on);
	buffer_put_cstring(&msg, nn);
	ssh_cmd( &msg);
	buffer_free(&msg);

	status = ssh_get_status(id);
	if(status != SSH2_FX_OK) {
		ftp_err("Couldn't rename file \"%s\" to \"%s\": %s\n",
				on, nn, fx2txt(status));
		free(on);
		free(nn);
		return -1;
	}

	ftp_cache_flush_mark_for(on);
	ftp_cache_flush_mark_for(nn);
	free(on);
	free(nn);
	return 0;
}
Esempio n. 7
0
int ssh_mkdir_verb(const char *path, verbose_t verb)
{
  char* abspath = ftp_path_absolute(path);
  stripslash(abspath);

  int rc = sftp_mkdir(ftp->sftp_session, abspath, S_IRWXU);
  if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_FILE_ALREADY_EXISTS)
  {
    ftp_err(_("Couldn't create directory: %s\n"), ssh_get_error(ftp->session));
    free(abspath);
    return rc;
  }

  ftp_cache_flush_mark_for(abspath);
  free(abspath);
  return 0;
}
Esempio n. 8
0
int ssh_chdir(const char *path)
{
  char* tmp = ftp_path_absolute(path);
  char *p = sftp_canonicalize_path(ftp->sftp_session, tmp);
  free(tmp);
  if (!p)
  {
    ftp_err("%s: %s\n", path, ssh_get_error(ftp->session));
    return -1;
  }

  bool isdir = false;

  /* First check if this file is cached and is a directory, else we
   * need to stat the file to see if it really is a directory
   */

  stripslash(p);
  isdir = (ftp_cache_get_directory(p) != 0);
  if(!isdir) {
    rfile *rf = ftp_cache_get_file(p);
    isdir = (rf && risdir(rf));
  }
  if (!isdir)
  {
    sftp_attributes attrib = sftp_stat(ftp->sftp_session, p);
    if (!attrib)
    {
      ftp_err(_("Couldn't stat directory: %s\n"), ssh_get_error(ftp->session));
      free(p);
      return -1;
    }
    if (!S_ISDIR(attrib->permissions)) {
      ftp_err(_("%s: not a directory\n"), p);
      sftp_attributes_free(attrib);
      free(p);
      return -1;
    }
    sftp_attributes_free(attrib);
  }
  ftp_update_curdir_x(p);
  free(p);

  return 0;
}
Esempio n. 9
0
int ssh_rmdir(const char *path)
{
  char* abspath = ftp_path_absolute(path);
  stripslash(abspath);

  int rc = sftp_rmdir(ftp->sftp_session, abspath);
  if (rc != SSH_OK && sftp_get_error(ftp->sftp_session) != SSH_FX_NO_SUCH_FILE)
  {
    ftp_err(_("Couldn't remove directory: %s\n"), ssh_get_error(ftp->session));
    free(abspath);
    return rc;
  }

  ftp_cache_flush_mark(abspath);
  ftp_cache_flush_mark_for(abspath);
  free(abspath);
  return 0;
}
Esempio n. 10
0
/* returns the rfile at PATH
 * if it's not in the cache, reads the directory
 * returns 0 if not found
 */
rfile *ftp_get_file(const char *path)
{
    rfile *f;
    char *ap;

    if(!path)
        return 0;

    ap = ftp_path_absolute(path);
    stripslash(ap);

    f = ftp_cache_get_file(ap);
    if(!f) {
        char *p = base_dir_xptr(ap);
        rdirectory *rdir = ftp_get_directory(p);
        free(p);
        if(rdir)
            f = rdir_get_file(rdir, base_name_ptr(ap));
    }
    free(ap);
    return f;
}
Esempio n. 11
0
int ssh_rmdir(const char *path)
{
	char *p;
	u_int status, id;

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

	id = ftp->ssh_id++;
	ssh_send_string_request(id, SSH2_FXP_RMDIR, p, strlen(p));

	status = ssh_get_status(id);
	if(status != SSH2_FX_OK) {
		ftp_err("Couldn't remove directory: %s\n", fx2txt(status));
		free(p);
		return -1;
	}
	ftp_cache_flush_mark(p);
	ftp_cache_flush_mark_for(p);
	free(p);

	return 0;
}
Esempio n. 12
0
int ssh_chdir(const char *path)
{
	Attrib *aa;
	char *p = ftp_path_absolute(path);
	bool isdir = false;

	/* First check if this file is cached and is a directory, else we
	 * need to stat the file to see if it really is a directory
	 */

	stripslash(p);
	isdir = (ftp_cache_get_directory(p) != 0);
	if(!isdir) {
		rfile *rf = ftp_cache_get_file(p);
		isdir = (rf && risdir(rf));
	}
	if(!isdir) {
		if ((aa = ssh_stat(p)) == 0) {
			free(p);
			return -1;
		}
		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
			ftp_err("Can't change directory: Can't check target");
			free(p);
			return -1;
		}
		if (!S_ISDIR(aa->perm)) {
			ftp_err("%s: not a directory\n", p);
			free(p);
			return -1;
		}
	}
	ftp_update_curdir_x(p);

	return 0;
}
Esempio n. 13
0
File: fxp.c Progetto: Celelibi/yafc
static int fxpfile(const rfile *fi, unsigned int opt,
					const char *output, const char *destname)
{
	fxpmode_t how = fxpNormal;
	bool file_exists = false;
	char *dest, *dpath;
	bool dir_created;
	char *dest_dir, *q_dest_dir;
	Ftp *thisftp = ftp;

	if((fxp_glob_mask
		&& fnmatch(fxp_glob_mask, base_name_ptr(fi->path), 0) == FNM_NOMATCH)
#ifdef HAVE_REGEX
	   || (fxp_rx_mask_set
		   && regexec(&fxp_rx_mask,
					  base_name_ptr(fi->path), 0, 0, 0) == REG_NOMATCH)
#endif
		)
		return 0;

	if(!output)
		output = ".";

	if(test(opt, FXP_PARENTS)) {
		char *p = base_dir_xptr(fi->path);
		if (asprintf(&dest, "%s/%s/%s", output, p, base_name_ptr(fi->path)) == -1)
    {
      fprintf(stderr, _("Failed to allocate memory.\n"));
      free(p);
      return -1;
    }
		free(p);
	} else if(test(opt, FXP_OUTPUT_FILE))
		dest = xstrdup(output);
	else
		if (asprintf(&dest, "%s/%s", output, base_name_ptr(fi->path)) == -1)
    {
      fprintf(stderr, _("Failed to allocate memory.\n"));
      return -1;
    }

	path_collapse(dest);

	ftp_use(fxp_target);

	/* make sure destination directory exists */
	dpath = base_dir_xptr(dest);
	dest_dir = ftp_path_absolute(dpath);
	q_dest_dir = backslash_quote(dest_dir);
	int r = ftp_mkpath(q_dest_dir);
	free(q_dest_dir);
	free(dest_dir);
	if(r == -1) {
		transfer_mail_msg(_("Couldn't create directory: %s\n"), dest_dir);
		free(dpath);
		free(dest);
		ftp_use(thisftp);
		return -1;
	}
	dir_created = (r == 1);

	if(!dir_created && !test(opt, FXP_UNIQUE) && !test(opt, FXP_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 0;
		}
	}

	if(test(opt, FXP_APPEND)) {
		how = fxpAppend;
	} else if(file_exists) {
		if(test(opt, FXP_SKIP_EXISTING)) {
			char* sp = shortpath(dest, 42, ftp->homedir);
			printf(_("Remote file '%s' exists, skipping...\n"), sp);
			free(sp);
			free(dest);
			ftp_use(thisftp);
			return 0;
		}
		else if(test(opt, FXP_NEWER)) {
			time_t src_ft;
			time_t dst_ft;

			ftp_use(thisftp);
			src_ft = ftp_filetime(fi->path, test(opt, FXP_FORCE_NEWER));
			ftp_use(fxp_target);

			dst_ft = ftp_filetime(dest, test(opt, FXP_FORCE_NEWER));

			if(src_ft != (time_t)-1 && dst_ft != (time_t)-1 && dst_ft >= src_ft) {
				char* sp = shortpath(dest, 42, ftp->homedir);
				printf(_("Remote file '%s' is newer than local, skipping...\n"), sp);
				free(sp);
				free(dest);
				ftp_use(thisftp);
				return 0;
			}
		}
		else if(!test(opt, FXP_RESUME)) {
			if(!fxp_owbatch) {
				char* sp = shortpath(dest, 42, ftp->homedir);
				int a = ask(ASKYES|ASKNO|ASKUNIQUE|ASKCANCEL|ASKALL|ASKRESUME,
							ASKRESUME,
							_("File '%s' exists, overwrite?"),
							sp);
				free(sp);
				if(a == ASKCANCEL) {
					fxp_quit = true;
					free(dest);
					ftp_use(thisftp);
					return 0;
				}
				else if(a == ASKNO) {
					free(dest);
					ftp_use(thisftp);
					return 0;
				}
				else if(a == ASKUNIQUE)
					opt |= FXP_UNIQUE; /* for this file only */
				else if(a == ASKALL)
					fxp_owbatch = true;
				else if(a == ASKRESUME)
					opt |= FXP_RESUME; /* for this file only */
				/* else a == ASKYES */
			}
		}
	}

	if(test(opt, FXP_RESUME))
		how = fxpResume;
	if(test(opt, FXP_UNIQUE))
		how = fxpUnique;

	r = do_the_fxp(thisftp, fi->path, fxp_target, dest, how, opt);
	free(dest);
	if(r != 0) {
		ftp_use(thisftp);
		return -1;
	}

	if(test(opt, FXP_PRESERVE))
		fxp_preserve_attribs(fi, dest);

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

		ftp_use(thisftp);

		if(!test(opt, FXP_FORCE)
		   && !fxp_delbatch && !gvSighupReceived)
			{
				char* sp = shortpath(fi->path, 42, ftp->homedir);
				int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES,
							_("Delete remote file '%s'?"),
							sp);
				free(sp);
				if(a == ASKALL) {
					fxp_delbatch = true;
					dodel = true;
				}
				else if(a == ASKCANCEL)
					fxp_quit = true;
				else if(a != ASKNO)
					dodel = true;
			} else
				dodel = true;

		if(dodel) {
			ftp_unlink(fi->path);
			char* sp = shortpath(fi->path, 42, ftp->homedir);
			if(ftp->code == ctComplete)
				fprintf(stderr, _("%s: deleted\n"), sp);
			else
				fprintf(stderr, _("error deleting '%s': %s\n"), sp,
						ftp_getreply(false));
			free(sp);
		}
	}

	ftp_use(thisftp);
	return 0;
}
Esempio n. 14
0
rdirectory *ftp_read_directory(const char *path)
{
    FILE *fp = 0;
    rdirectory *rdir;
    bool is_curdir = false;
    bool _failed = false;
    char *dir;
    bool is_mlsd = false;

#ifdef HAVE_LIBSSH
    if(ftp->session)
        return ssh_read_directory(path);
#endif

    dir = ftp_path_absolute(path);
    stripslash(dir);

    is_curdir = (strcmp(dir, ftp->curdir) == 0);

    if((fp = tmpfile()) == NULL) {	/* can't create a tmpfile */
	    ftp_err("Unable to create temp file: %s\n", strerror(errno));
            free(dir);
            return 0;
    }

    /* we do a "CWD" before the listing, because: we want a listing of
     *  the directory contents, not the directory itself, and some
     *  servers misunderstand this. If the target is a link to a
     *  directory, we have to do this.
     */
    if(!is_curdir) {
        ftp_cmd("CWD %s", dir);
        if(ftp->code != ctComplete)
            goto failed;
    }

    if(ftp->has_mlsd_command) {
        is_mlsd = true;
#if 0
        /* PureFTPd (1.0.11) doesn't recognize directory arguments
         * with spaces, not even quoted, it just chops the argument
         * string after the first space, duh... so we have to CWD to
         * the directory...
         */
        char *asdf;
        asprintf(&asdf, "%s/", dir);
        /* Hack to get around issue in PureFTPd (up to version 0.98.2):
         * doing a 'MLSD link-to-dir' on PureFTPd closes the control
         * connection, however, 'MLSD link-to-dir/' works fine.
         */
        _failed = (ftp_list("MLSD", asdf, fp) != 0);
        free(asdf);
#else
        _failed = (ftp_list("MLSD", 0, fp) != 0);
#endif
        if(_failed && ftp->code == ctError)
            ftp->has_mlsd_command = false;
    }
    if(!ftp->has_mlsd_command) {
        _failed = (ftp_list("LIST", 0, fp) != 0);
        is_mlsd = false;
    }

    if(!is_curdir)
        ftp_cmd("CWD %s", ftp->curdir);

    if(_failed)
        goto failed;

    rewind(fp);

    rdir = rdir_create();
    if(rdir_parse(rdir, fp, dir, is_mlsd) != 0) {
        rdir_destroy(rdir);
        goto failed;
    }

    fclose(fp);
    ftp_trace("added directory '%s' to cache\n", dir);
    list_additem(ftp->cache, rdir);
    free(dir);
    return rdir;

  failed: /* forgive me father, for I have goto'ed */
    if (fp)
	    fclose(fp);
    free(dir);
    return 0;
}
Esempio n. 15
0
static char *remote_completion_function(const char *text, int state)
{
    static int len;            /* length of unquoted */
    static char *dir = NULL;   /* any initial directory in text */
    static char *unquoted = NULL; /* the unquoted filename (or beginning of it) */
    static listitem *lip = NULL;
    static rdirectory *rdir = NULL; /* the cached remote directory */
    static char merge_fmt[] = "%s/%s";

    if (!ftp_loggedin())
        return 0;

    /* this is not really true, this is for local filename completion,
     * but it works here too (sort of), and it looks nicer, since
     * the whole path is not printed by readline, ie
     * only foo is printed and not /bar/fu/foo (if cwd == /bar/fu)
     * readline appends a class character (ie /,@,*) in _local_ filenames
     */
    rl_filename_completion_desired = 1;
#ifndef HAVE_LIBEDIT
    rl_filename_quoting_desired = 1;
#endif

    if (!state) {
        dir = base_dir_xptr(text);
        if (dir) {
            stripslash(dir);
            char* e = strchr(dir, 0);
            if (e[-1]=='\"')
                e[-1] = '\0';
            unquote(dir);
            if (strcmp(dir, "/") == 0)
                strlcpy(merge_fmt, "%s%s", sizeof(merge_fmt));
            else
                strlcpy(merge_fmt, "%s/%s", sizeof(merge_fmt));
        }
#ifndef HAVE_LIBEDIT
        if(gvWaitingDots) {
            rl_insert_text("..."); /* show dots while waiting, like ncftp */
            rl_redisplay();
        }
#endif

        char* ap = ftp_path_absolute(dir);
        rdir = ftp_cache_get_directory(ap);
        const bool dir_is_cached = (rdir != 0);
        if (!rdir)
            rdir = ftp_read_directory(ap);
        free(ap);

#ifndef HAVE_LIBEDIT
        if (gvWaitingDots)
            rl_do_undo(); /* remove the dots */
#endif

        if (!dir_is_cached && ftp_get_verbosity() >= vbCommand)
            rl_forced_update_display();

        if (!rdir) {
            free(dir);
            return 0;
        }
        unquoted = dequote_filename(base_name_ptr(text), 0);
        if (!unquoted)
            unquoted = (char *)xmalloc(1);
        len = strlen(unquoted);
        lip = rdir->files->first;
    }

    while (lip) {
        rfile* fp = (rfile *)lip->data;
        lip = lip->next;

        /* 0 = not dir, 1 = dir, 2 = link (maybe dir) */
        const int isdir = ftp_maybe_isdir(fp);
        if (remote_dir_only && isdir == 0)
            continue;

        const char* name = base_name_ptr(fp->path);
        /* skip dotdirs in completion */
        if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
            continue;

        if (strncmp(name, unquoted, len) == 0) {
            char *ret;
            if (dir)
            {
                if (asprintf(&ret, merge_fmt, dir, name) == -1)
                {
                    fprintf(stderr, _("Failed to allocate memory.\n"));
                    free(unquoted);
                    free(dir);
                    return NULL;
                }
            }
            else
                ret = xstrdup(name);
            if (isdir == 1) {
                rl_completion_append_character = '/';
            } else {
                rl_completion_append_character = ' ';
            }
            return ret;
        }
    }
    free(unquoted);
    free(dir);
    return NULL;
}
Esempio n. 16
0
/* appends rglob items in list LP matching MASK
 * EXCLUDE_FUNC (if not 0) is called for each fileinfo item found
 * and that file is excluded if EXCLUDE_FUNC returns true
 * returns 0 if successful, -1 if failure (no files found)
 *
 * if ignore_multiples is true, a file isn't added to the list
 * if it already exists in the list
 *
 * any spaces or other strange characters in MASK should be backslash-quoted
 */
int rglob_glob(list *gl, const char *mask, bool cpifnomatch,
			   bool ignore_multiples, rglobfunc exclude_func)
{
	char *path;
	char *dep, *mp;
	rdirectory *rdir;
	listitem *lip;
	rfile *fi = 0, *nfi;
	char *d;
	int found = 0;

	path = tilde_expand_home(mask, ftp->homedir);
	dep = strrchr(path, '/');
	if(!dep)
		dep = path;
	else dep++;
	mp = xstrdup(dep);
	if(mp)
		unquote(mp);
	/* note: mp might be NULL here, treat it like mp == "*" */

	/* read the directory */
	d = base_dir_xptr(path);
	if(!d) d = xstrdup(ftp->curdir);
	else unquote(d);

	rdir = ftp_get_directory(d);
	free(d);

	if(rdir) {
		lip = rdir->files->first;
		while(lip) {
			fi = (rfile *)lip->data;
			lip = lip->next;

			/* check if the mask includes this file */
			if(mp == 0 || fnmatch(mp, base_name_ptr(fi->path), 0)
			   != FNM_NOMATCH)
			{
				bool ignore_item;

				found++;

				/* call the exclude function, if any, and skip file
					if the function returns true
				*/
				if(exclude_func && exclude_func(fi))
					ignore_item = true;
				else
					ignore_item =
						(ignore_multiples &&
						 (list_search(gl, (listsearchfunc)rfile_search_path,
										  fi->path) != 0));

				if(!ignore_item) {
					nfi = rfile_clone(fi);
					list_additem(gl, (void *)nfi);
				} else
					ftp_trace("ignoring file '%s'\n", fi->path);
			}
		}
	}

	if(found == 0) {
		char *p;
		bool ignore_item;

		if(!cpifnomatch || mp == 0 || *mp == 0) {
			free(mp);
			return -1;
		}
		p = ftp_path_absolute(path);
		unquote(p);

		/* disallow multiples of the same file */
		ignore_item =
			(ignore_multiples &&
			 (list_search(gl, (listsearchfunc)rfile_search_path,
						  p)) != 0);

		if(!ignore_item) {
			nfi = rfile_create();
			rfile_fake(nfi, p);
			list_additem(gl, (void *)nfi);
		}
		free(p);
	}

	free(mp);
	free(path);
	return 0;
}
Esempio n. 17
0
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));
		}
	}
}
Esempio n. 18
0
rdirectory *ssh_read_directory(const char *path)
{
	rdirectory *rdir;
	int i;
	SFTP_DIRENT **dir;
	char *p = ftp_path_absolute(path);
	stripslash(p);

	if(ssh_readdir(p, &dir) != 0) {
		free(p);
		return 0;
	}

	rdir = rdir_create();

	ftp_trace("*** start parsing directory listing ***\n");

	for(i = 0; dir[i]; i++) {
		rfile *rf;
		char *e, *cf = dir[i]->longname;

		ftp_trace("%s\n", dir[i]->longname);

		rf = rfile_create();

		rf->perm = perm2string(dir[i]->a.perm);

		e = strqsep(&cf, ' ');  /* skip permissions */
		e = strqsep(&cf, ' ');  /* nhl? */
/*		if(ftp->ssh_version > 2) {*/
			rf->nhl = atoi(e);
/*		} else*/
/*			rf->nhl = 0;*/
#if 1
		e = strqsep(&cf, ' ');
		rf->owner = xstrdup(e);
		e = strqsep(&cf, ' ');
		rf->group = xstrdup(e);
#else
		asprintf(&rf->owner, "%d", dir[i]->a.uid);
		asprintf(&rf->group, "%d", dir[i]->a.gid);
#endif

		asprintf(&rf->path, "%s/%s", p, dir[i]->filename);
		rf->mtime = dir[i]->a.mtime;
		if(rf->mtime == 0) {
			char *m, *d, *y;
			while(e && month_number(e) == -1)
				e = strqsep(&cf, ' ');
			if(e) {
				m = e;
				d = strqsep(&cf, ' ');
				y = strqsep(&cf, ' ');
				ftp_trace("parsing time: m:%s d:%s y:%s\n", m, d, y);
				rfile_parse_time(rf, m, d, y);
			}
		}
		rf->date = time_to_string(rf->mtime);
		rf->size = dir[i]->a.size;
		rfile_parse_colors(rf);

		rf->link = 0;
		if(rislink(rf) && ftp->ssh_version > 2)
			rf->link = ssh_readlink(rf->path);

		list_additem(rdir->files, (void *)rf);
	}
	ftp_trace("*** end parsing directory listing ***\n");

	ssh_free_dirents(dir);

	rdir->path = p;

	ftp_trace("added directory '%s' to cache\n", p);
	list_additem(ftp->cache, rdir);

	return rdir;
}
Esempio n. 19
0
rdirectory *ssh_read_directory(const char *path)
{
  char *p = ftp_path_absolute(path);
  stripslash(p);

  sftp_dir dir = sftp_opendir(ftp->sftp_session, p);
  if (!dir)
  {
    free(p);
    return 0;
  }

  ftp_trace("*** start parsing directory listing ***\n");
  rdirectory* rdir = rdir_create();
  sftp_attributes attrib = NULL;
  while ((attrib = sftp_readdir(ftp->sftp_session, dir)) != NULL)
  {
    ftp_trace("%s\n", attrib->longname);

    rfile* rf = rfile_create();
    rf->perm = perm2string(attrib->permissions);

    rf->nhl = 0; // atoi(e);
    if (attrib->owner)
      rf->owner = xstrdup(attrib->owner);
    if (attrib->group)
      rf->group = xstrdup(attrib->group);

    if (asprintf(&rf->path, "%s/%s", p, attrib->name) == -1)
    {
      ftp_err(_("Failed to allocate memory.\n"));
      sftp_closedir(dir);
      free(p);
      rdir_destroy(rdir);
      rfile_destroy(rf);
    }
    rf->mtime = attrib->mtime;
    rf->date = time_to_string(rf->mtime);
    rf->size = attrib->size;
    rfile_parse_colors(rf);

    rf->link = NULL;
    if (rislink(rf) && ftp->ssh_version > 2)
      rf->link = sftp_readlink(ftp->sftp_session, rf->path);

    list_additem(rdir->files, (void *)rf);
    sftp_attributes_free(attrib);
  }
  ftp_trace("*** end parsing directory listing ***\n");

  if (!sftp_dir_eof(dir))
  {
    ftp_err(_("Couldn't list directory: %s\n"), ssh_get_error(ftp->session));
    sftp_closedir(dir);
    free(p);
    rdir_destroy(rdir);
    return NULL;
  }

  sftp_closedir(dir);
  rdir->path = p;
  ftp_trace("added directory '%s' to cache\n", p);
  list_additem(ftp->cache, rdir);

  return rdir;
}