Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 84734 Details for
Bug 130004
app-portage/portage-utils: improve qfile behavior with symlinks
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
qfile-0.1.15-path_checking_enhancements.patch
qfile-0.1.15-path_checking_enhancements.patch (text/plain), 6.97 KB, created by
TGL
on 2006-04-15 13:09:37 UTC
(
hide
)
Description:
qfile-0.1.15-path_checking_enhancements.patch
Filename:
MIME Type:
Creator:
TGL
Created:
2006-04-15 13:09:37 UTC
Size:
6.97 KB
patch
obsolete
>--- qfile.c.orig 2006-04-15 22:04:12.000000000 +0200 >+++ qfile.c 2006-04-15 21:30:18.000000000 +0200 >@@ -21,40 +21,30 @@ > static char qfile_rcsid[] = "$Id: qfile.c,v 1.26 2006/01/26 02:32:04 vapier Exp $"; > #define qfile_usage(ret) usage(ret, QFILE_FLAGS, qfile_long_opts, qfile_opts_help, lookup_applet_idx("qfile")) > >-void qfile(char *path, char *fullname); >-void qfile(char *path, char *fullname) >+void qfile(char *path, char *base_name, char *dir_name, char *real_dir_name); >+void qfile(char *path, char *base_name, char *dir_name, char *real_dir_name) > { > FILE *fp; > DIR *dir; > struct dirent *dentry; > char *p; >- size_t flen; >- int base = 0; >- char fname[_Q_PATH_MAX]; >+ char *q; >+ size_t bnlen; >+ size_t dnlen = 0; >+ size_t rdnlen = 0; > char buf[1024]; > char pkg[126]; > depend_atom *atom; > >- strncpy(fname, fullname, sizeof(fname)); >- >- if ((fname[0] == '.') && ((p = getenv("PWD")) != NULL)) { >- char tmp[PATH_MAX]; >- snprintf(tmp, sizeof(fname), "%s/%s", p, fullname); >- errno = 0; >- realpath(tmp, fname); >- assert(errno == 0); >- } >- >- flen = strlen(fname); >+ bnlen = strlen(base_name); >+ if (dir_name != NULL) >+ dnlen = strlen(dir_name); >+ if (real_dir_name != NULL) >+ rdnlen = strlen(real_dir_name); > > if (chdir(path) != 0 || (dir = opendir(".")) == NULL) > return; > >- if (!strchr(fname, '/')) >- base = 1; >- else >- base = 0; >- > while ((dentry = readdir(dir))) { > if (dentry->d_name[0] == '.') > continue; >@@ -68,20 +58,61 @@ > snprintf(pkg, sizeof(pkg), "%s/%s", basename(path), dentry->d_name); > while ((fgets(buf, sizeof(buf), fp)) != NULL) { > contents_entry *e; >+ int path_ok = 0; >+ if (dir_name == NULL && real_dir_name == NULL) >+ path_ok = 1; > > e = contents_parse_line(buf); > if (!e) > continue; > > p = xstrdup(e->name); >- if (strncmp(base ? basename(p) : p, fname, flen) != 0 >- || strlen(base ? basename(p) : p) != flen) { >+ q = basename(p); >+ if (strncmp(q, base_name, bnlen) != 0 >+ || strlen(q) != bnlen) { > free(p); > continue; > } >+ free(p); >+ >+ if (!path_ok) { >+ // check the full filepath... >+ p = xstrdup(e->name); >+ q = xstrdup(dirname(p)); >+ free(p); >+ if (dnlen == strlen(q) >+ && strncmp(q, dir_name, dnlen) == 0) >+ // dir_name == dirname(CONTENTS) >+ path_ok = 1; >+ else if (rdnlen == strlen(q) >+ && strncmp(q, real_dir_name, rdnlen) == 0) >+ // real_dir_name == dirname(CONTENTS) >+ path_ok = 1; >+ else { >+ char rpath[PATH_MAX+1]; >+ errno = 0; >+ realpath(q, rpath); >+ if (errno != 0) { >+ if (verbose) { >+ warn("Could not read real path of \"%s\": %s", q, strerror(errno)); >+ warn("We'll never know whether it was a result for your query..."); >+ } >+ } else if (dnlen == strlen(rpath) >+ && strncmp(rpath, dir_name, dnlen) == 0) >+ // dir_name == realpath(dirname(CONTENTS)) >+ path_ok = 1; >+ else if (rdnlen == strlen(rpath) >+ && strncmp(rpath, real_dir_name, rdnlen) == 0) >+ // real_dir_name == realpath(dirname(CONTENTS)) >+ path_ok = 1; >+ } >+ free(q); >+ } >+ if (!path_ok) >+ continue; >+ > if ((atom = atom_explode(pkg)) == NULL) { > warn("invalid atom %s", pkg); >- free(p); > continue; > } > printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE, >@@ -90,10 +121,9 @@ > if (quiet) > puts(""); > else >- printf(" (%s)\n", p); >+ printf(" (%s)\n", e->name); > > atom_implode(atom); >- free(p); > found++; > } > fclose(fp); >@@ -108,6 +138,10 @@ > struct dirent *dentry; > int i; > char *p; >+ char ** basenames; >+ char ** dirnames; >+ char ** realdirnames; >+ char * pwd; > > DBG("argc=%d argv[0]=%s argv[1]=%s", > argc, argv[0], argc > 1 ? argv[1] : "NULL?"); >@@ -122,27 +156,96 @@ > if (argc == optind) > qfile_usage(EXIT_FAILURE); > >+ // For each argument, we store its basename, its dirname, >+ // and the realpath of its dirname. >+ basenames = malloc((argc-optind) * sizeof(char*)); >+ dirnames = malloc((argc-optind) * sizeof(char*)); >+ realdirnames = malloc((argc-optind) * sizeof(char*)); >+ if ((pwd = getenv("PWD")) != NULL) { >+ int pwdlen = strlen(pwd); >+ if ((pwdlen > 0) && (pwd[pwdlen-1] == '/')) >+ pwd[pwdlen-1] = '\0'; >+ } >+ for (i = 0; i < (argc-optind); ++i) { >+ char tmppath[PATH_MAX+1]; >+ char abspath[PATH_MAX+1]; >+ >+ basenames[i] = NULL; >+ dirnames[i] = NULL; >+ realdirnames[i] = NULL; >+ >+ // Record basename, but if it is "." or ".." >+ strncpy(tmppath, basename(argv[i+optind]), PATH_MAX); >+ if ((strlen(tmppath) > 2) || strncmp(tmppath, "..", strlen(tmppath))) { >+ basenames[i] = xstrdup(tmppath); >+ // If there is no "/" in the argument, then it's over. >+ // (we are searching a simple file name) >+ if (strchr(argv[i+optind], '/') == NULL) >+ continue; >+ } >+ >+ // Make sure we have an absolute path available >+ if (argv[i+optind][0] == '/') >+ strncpy(abspath, argv[i+optind], PATH_MAX); >+ else if (pwd != NULL) >+ snprintf(abspath, PATH_MAX, "%s/%s", pwd, argv[i+optind]); >+ else { >+ err("$PWD not found in environment."); >+ err("Skipping query item \"%s\".", argv[i+optind]); >+ continue; >+ } >+ >+ if (basenames[i] != NULL) { >+ // Get both the dirname and its realpath >+ dirnames[i] = xstrdup(dirname(abspath)); >+ errno = 0; >+ realpath(dirnames[i], tmppath); >+ if (errno != 0) { >+ if (verbose) { >+ warn("Could not read real path of \"%s\": %s", dirnames[i], strerror(errno)); >+ warn("Results for query item \"%s\" may not be accurate.", argv[i+optind]); >+ } >+ } else if (strcmp(dirnames[i], tmppath)) >+ realdirnames[i] = xstrdup(tmppath); >+ } else { >+ // No basename means we are looking for something like "/foo/bar/.." >+ // Dirname is meaningless here, we can only get realpath of the full >+ // path and then split it. >+ errno = 0; >+ realpath(tmppath, abspath); >+ if (errno != 0) { >+ err("Could not read real path of \"%s\": %s", tmppath, strerror(errno)); >+ err("Skipping query item \"%s\".", argv[i+optind]); >+ continue; >+ } >+ basenames[i] = xstrdup(basename(tmppath)); >+ realdirnames[i] = xstrdup(dirname(tmppath)); >+ } >+ } >+ > if (chdir(portroot)) > errp("could not chdir(%s) for ROOT", portroot); > > if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) > return EXIT_FAILURE; > >- /* CONTENTS stores dir names w/out trailing / so clean up input */ >- for (i = optind; i < argc; ++i) { >- p = argv[i] + strlen(argv[i]) - 1; >- if (*p == '/') >- *p = '\0'; >- } >- > /* open /var/db/pkg */ > while ((dentry = q_vdb_get_next_dir(dir))) { > xasprintf(&p, "%s%s/%s", portroot, portvdb, dentry->d_name); >- for (i = optind; i < argc; ++i) >- qfile(p, argv[i]); >+ for (i = 0; i < (argc-optind); ++i) { >+ if (basenames[i] != NULL) >+ qfile(p, basenames[i], dirnames[i], realdirnames[i]); >+ } > free(p); > } > >+ for (i = 0; i < (argc-optind); ++i) { >+ if (basenames[i] != NULL) free(basenames[i]); >+ if (dirnames[i] != NULL) free(dirnames[i]); >+ if (realdirnames[i] != NULL) free(realdirnames[i]); >+ } >+ free(basenames); free(dirnames); free(realdirnames); >+ > return (found ? EXIT_SUCCESS : EXIT_FAILURE); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 130004
:
84676
|
84734
|
86743
|
88898
|
91296