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; }
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; }
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; }