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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
/* 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; }
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)); } } }
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; }
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; }