rfile *rfile_clone(const rfile *f) { rfile *nf = rfile_create(); nf->perm = xstrdup(f->perm); nf->owner = xstrdup(f->owner); nf->group = xstrdup(f->group); nf->color = xstrdup(f->color); nf->date = xstrdup(f->date); nf->link = xstrdup(f->link); nf->path = xstrdup(f->path); nf->size = f->size; nf->nhl = f->nhl; nf->mtime = f->mtime; return nf; }
int rdir_parse(rdirectory *rdir, FILE *fp, const char *path, bool is_mlsd) { char tmp[257]; rfile *f; int r; bool failed = false; free(rdir->path); rdir->path = 0; list_clear(rdir->files); rdir->timestamp = time(0); f = rfile_create(); ftp_trace("*** start parsing directory listing of '%s' ***\n", path); while(!feof(fp)) { if(fgets(tmp, 256, fp) == 0) break; strip_trailing_chars(tmp, "\r\n"); if(tmp[0] == 0) break; ftp_trace("%s\n", tmp); rfile_clear(f); r = rfile_parse(f, tmp, path, is_mlsd); if(r == -1) { ftp_err("parsing failed on '%s'\n", tmp); list_clear(rdir->files); failed = true; } else if(r == 0) list_additem(rdir->files, (void *)rfile_clone(f)); /* else r == 1, ie a 'total ###' line, which isn't an error */ } ftp_trace("*** end parsing directory listing ***\n"); if(failed) { if(list_numitem(rdir->files) == 0) { ftp_err("directory parsing failed completely\n"); return -1; } } rdir->path = xstrdup(path); return 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; }
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 *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; }