Line
Link Here
|
0 |
-- qfile.c.orig |
0 |
++ qfile.c |
Lines 21-62
Link Here
|
21 |
static char qfile_rcsid[] = "$Id: qfile.c,v 1.28 2006/05/13 22:59:31 vapier Exp $"; |
21 |
static char qfile_rcsid[] = "$Id: qfile.c,v 1.28 2006/05/13 22:59:31 vapier Exp $"; |
22 |
#define qfile_usage(ret) usage(ret, QFILE_FLAGS, qfile_long_opts, qfile_opts_help, lookup_applet_idx("qfile")) |
22 |
#define qfile_usage(ret) usage(ret, QFILE_FLAGS, qfile_long_opts, qfile_opts_help, lookup_applet_idx("qfile")) |
23 |
|
23 |
|
24 |
void qfile(char *path, char *fullname); |
24 |
void qfile(char *path, char *base_name, char *dir_name, char *real_dir_name); |
25 |
void qfile(char *path, char *fullname) |
25 |
void qfile(char *path, char *base_name, char *dir_name, char *real_dir_name) |
26 |
{ |
26 |
{ |
27 |
FILE *fp; |
27 |
FILE *fp; |
28 |
DIR *dir; |
28 |
DIR *dir; |
29 |
struct dirent *dentry; |
29 |
struct dirent *dentry; |
30 |
char *p; |
30 |
char *p; |
31 |
size_t flen; |
31 |
char *q; |
32 |
int base = 0; |
32 |
size_t bnlen; |
33 |
char fname[_Q_PATH_MAX]; |
33 |
size_t dnlen = 0; |
|
|
34 |
size_t rdnlen = 0; |
34 |
char buf[1024]; |
35 |
char buf[1024]; |
35 |
char pkg[126]; |
36 |
char pkg[126]; |
36 |
depend_atom *atom; |
37 |
depend_atom *atom; |
37 |
|
38 |
|
38 |
strncpy(fname, fullname, sizeof(fname)); |
39 |
bnlen = strlen(base_name); |
39 |
|
40 |
if (dir_name != NULL) |
40 |
if ((fname[0] == '.') && ((p = getenv("PWD")) != NULL)) { |
41 |
dnlen = strlen(dir_name); |
41 |
char tmp[PATH_MAX]; |
42 |
if (real_dir_name != NULL) |
42 |
snprintf(tmp, sizeof(fname), "%s/%s", p, fullname); |
43 |
rdnlen = strlen(real_dir_name); |
43 |
/* Don't check the return value here as it is ok if |
|
|
44 |
* the function fails. Think of the case where fname |
45 |
* is '...somefile', we don't want to abort then as |
46 |
* the value in fname will be unchanged. */ |
47 |
realpath(tmp, fname); |
48 |
} |
49 |
|
50 |
flen = strlen(fname); |
51 |
|
44 |
|
52 |
if (chdir(path) != 0 || (dir = opendir(".")) == NULL) |
45 |
if (chdir(path) != 0 || (dir = opendir(".")) == NULL) |
53 |
return; |
46 |
return; |
54 |
|
47 |
|
55 |
if (!strchr(fname, '/')) |
|
|
56 |
base = 1; |
57 |
else |
58 |
base = 0; |
59 |
|
60 |
while ((dentry = readdir(dir))) { |
48 |
while ((dentry = readdir(dir))) { |
61 |
if (dentry->d_name[0] == '.') |
49 |
if (dentry->d_name[0] == '.') |
62 |
continue; |
50 |
continue; |
Lines 70-89
Link Here
|
70 |
snprintf(pkg, sizeof(pkg), "%s/%s", basename(path), dentry->d_name); |
60 |
snprintf(pkg, sizeof(pkg), "%s/%s", basename(path), dentry->d_name); |
71 |
while ((fgets(buf, sizeof(buf), fp)) != NULL) { |
61 |
while ((fgets(buf, sizeof(buf), fp)) != NULL) { |
72 |
contents_entry *e; |
62 |
contents_entry *e; |
|
|
63 |
int path_ok = 0; |
64 |
if (dir_name == NULL && real_dir_name == NULL) |
65 |
path_ok = 1; |
73 |
|
66 |
|
74 |
e = contents_parse_line(buf); |
67 |
e = contents_parse_line(buf); |
75 |
if (!e) |
68 |
if (!e) |
76 |
continue; |
69 |
continue; |
77 |
|
70 |
|
78 |
p = xstrdup(e->name); |
71 |
p = xstrdup(e->name); |
79 |
if (strncmp(base ? basename(p) : p, fname, flen) != 0 |
72 |
q = basename(p); |
80 |
|| strlen(base ? basename(p) : p) != flen) { |
73 |
if (strncmp(q, base_name, bnlen) != 0 |
|
|
74 |
|| strlen(q) != bnlen) { |
81 |
free(p); |
75 |
free(p); |
82 |
continue; |
76 |
continue; |
83 |
} |
77 |
} |
|
|
78 |
free(p); |
79 |
|
80 |
if (!path_ok) { |
81 |
// check the full filepath... |
82 |
p = xstrdup(e->name); |
83 |
q = xstrdup(dirname(p)); |
84 |
free(p); |
85 |
if (dnlen == strlen(q) |
86 |
&& strncmp(q, dir_name, dnlen) == 0) |
87 |
// dir_name == dirname(CONTENTS) |
88 |
path_ok = 1; |
89 |
else if (rdnlen == strlen(q) |
90 |
&& strncmp(q, real_dir_name, rdnlen) == 0) |
91 |
// real_dir_name == dirname(CONTENTS) |
92 |
path_ok = 1; |
93 |
else { |
94 |
char rpath[PATH_MAX+1]; |
95 |
errno = 0; |
96 |
realpath(q, rpath); |
97 |
if (errno != 0) { |
98 |
if (verbose) { |
99 |
warn("Could not read real path of \"%s\": %s", q, strerror(errno)); |
100 |
warn("We'll never know whether it was a result for your query..."); |
101 |
} |
102 |
} else if (dnlen == strlen(rpath) |
103 |
&& strncmp(rpath, dir_name, dnlen) == 0) |
104 |
// dir_name == realpath(dirname(CONTENTS)) |
105 |
path_ok = 1; |
106 |
else if (rdnlen == strlen(rpath) |
107 |
&& strncmp(rpath, real_dir_name, rdnlen) == 0) |
108 |
// real_dir_name == realpath(dirname(CONTENTS)) |
109 |
path_ok = 1; |
110 |
} |
111 |
free(q); |
112 |
} |
113 |
if (!path_ok) |
114 |
continue; |
115 |
|
84 |
if ((atom = atom_explode(pkg)) == NULL) { |
116 |
if ((atom = atom_explode(pkg)) == NULL) { |
85 |
warn("invalid atom %s", pkg); |
117 |
warn("invalid atom %s", pkg); |
86 |
free(p); |
|
|
87 |
continue; |
118 |
continue; |
88 |
} |
119 |
} |
89 |
printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE, |
120 |
printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE, |
Lines 92-101
Link Here
|
92 |
if (quiet) |
123 |
if (quiet) |
93 |
puts(""); |
124 |
puts(""); |
94 |
else |
125 |
else |
95 |
printf(" (%s)\n", p); |
126 |
printf(" (%s)\n", e->name); |
96 |
|
127 |
|
97 |
atom_implode(atom); |
128 |
atom_implode(atom); |
98 |
free(p); |
|
|
99 |
found++; |
129 |
found++; |
100 |
} |
130 |
} |
101 |
fclose(fp); |
131 |
fclose(fp); |
Lines 110-115
Link Here
|
110 |
struct dirent *dentry; |
140 |
struct dirent *dentry; |
111 |
int i; |
141 |
int i; |
112 |
char *p; |
142 |
char *p; |
|
|
143 |
char ** basenames; |
144 |
char ** dirnames; |
145 |
char ** realdirnames; |
146 |
char * pwd; |
113 |
|
147 |
|
114 |
DBG("argc=%d argv[0]=%s argv[1]=%s", |
148 |
DBG("argc=%d argv[0]=%s argv[1]=%s", |
115 |
argc, argv[0], argc > 1 ? argv[1] : "NULL?"); |
149 |
argc, argv[0], argc > 1 ? argv[1] : "NULL?"); |
Lines 124-150
Link Here
|
124 |
if (argc == optind) |
158 |
if (argc == optind) |
125 |
qfile_usage(EXIT_FAILURE); |
159 |
qfile_usage(EXIT_FAILURE); |
126 |
|
160 |
|
|
|
161 |
// For each argument, we store its basename, its dirname, |
162 |
// and the realpath of its dirname. |
163 |
basenames = malloc((argc-optind) * sizeof(char*)); |
164 |
dirnames = malloc((argc-optind) * sizeof(char*)); |
165 |
realdirnames = malloc((argc-optind) * sizeof(char*)); |
166 |
if ((pwd = getenv("PWD")) != NULL) { |
167 |
int pwdlen = strlen(pwd); |
168 |
if ((pwdlen > 0) && (pwd[pwdlen-1] == '/')) |
169 |
pwd[pwdlen-1] = '\0'; |
170 |
} |
171 |
for (i = 0; i < (argc-optind); ++i) { |
172 |
char tmppath[PATH_MAX+1]; |
173 |
char abspath[PATH_MAX+1]; |
174 |
|
175 |
basenames[i] = NULL; |
176 |
dirnames[i] = NULL; |
177 |
realdirnames[i] = NULL; |
178 |
|
179 |
// Record basename, but if it is "." or ".." |
180 |
strncpy(tmppath, basename(argv[i+optind]), PATH_MAX); |
181 |
if ((strlen(tmppath) > 2) || strncmp(tmppath, "..", strlen(tmppath))) { |
182 |
basenames[i] = xstrdup(tmppath); |
183 |
// If there is no "/" in the argument, then it's over. |
184 |
// (we are searching a simple file name) |
185 |
if (strchr(argv[i+optind], '/') == NULL) |
186 |
continue; |
187 |
} |
188 |
|
189 |
// Make sure we have an absolute path available |
190 |
if (argv[i+optind][0] == '/') |
191 |
strncpy(abspath, argv[i+optind], PATH_MAX); |
192 |
else if (pwd != NULL) |
193 |
snprintf(abspath, PATH_MAX, "%s/%s", pwd, argv[i+optind]); |
194 |
else { |
195 |
err("$PWD not found in environment."); |
196 |
err("Skipping query item \"%s\".", argv[i+optind]); |
197 |
continue; |
198 |
} |
199 |
|
200 |
if (basenames[i] != NULL) { |
201 |
// Get both the dirname and its realpath |
202 |
dirnames[i] = xstrdup(dirname(abspath)); |
203 |
errno = 0; |
204 |
realpath(dirnames[i], tmppath); |
205 |
if (errno != 0) { |
206 |
if (verbose) { |
207 |
warn("Could not read real path of \"%s\": %s", dirnames[i], strerror(errno)); |
208 |
warn("Results for query item \"%s\" may not be accurate.", argv[i+optind]); |
209 |
} |
210 |
} else if (strcmp(dirnames[i], tmppath)) |
211 |
realdirnames[i] = xstrdup(tmppath); |
212 |
} else { |
213 |
// No basename means we are looking for something like "/foo/bar/.." |
214 |
// Dirname is meaningless here, we can only get realpath of the full |
215 |
// path and then split it. |
216 |
errno = 0; |
217 |
realpath(tmppath, abspath); |
218 |
if (errno != 0) { |
219 |
err("Could not read real path of \"%s\": %s", tmppath, strerror(errno)); |
220 |
err("Skipping query item \"%s\".", argv[i+optind]); |
221 |
continue; |
222 |
} |
223 |
basenames[i] = xstrdup(basename(tmppath)); |
224 |
realdirnames[i] = xstrdup(dirname(tmppath)); |
225 |
} |
226 |
} |
227 |
|
127 |
if (chdir(portroot)) |
228 |
if (chdir(portroot)) |
128 |
errp("could not chdir(%s) for ROOT", portroot); |
229 |
errp("could not chdir(%s) for ROOT", portroot); |
129 |
|
230 |
|
130 |
if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) |
231 |
if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL) |
131 |
return EXIT_FAILURE; |
232 |
return EXIT_FAILURE; |
132 |
|
233 |
|
133 |
/* CONTENTS stores dir names w/out trailing / so clean up input */ |
|
|
134 |
for (i = optind; i < argc; ++i) { |
135 |
p = argv[i] + strlen(argv[i]) - 1; |
136 |
if (*p == '/') |
137 |
*p = '\0'; |
138 |
} |
139 |
|
140 |
/* open /var/db/pkg */ |
234 |
/* open /var/db/pkg */ |
141 |
while ((dentry = q_vdb_get_next_dir(dir))) { |
235 |
while ((dentry = q_vdb_get_next_dir(dir))) { |
142 |
xasprintf(&p, "%s%s/%s", portroot, portvdb, dentry->d_name); |
236 |
xasprintf(&p, "%s%s/%s", portroot, portvdb, dentry->d_name); |
143 |
for (i = optind; i < argc; ++i) |
237 |
for (i = 0; i < (argc-optind); ++i) { |
144 |
qfile(p, argv[i]); |
238 |
if (basenames[i] != NULL) |
|
|
239 |
qfile(p, basenames[i], dirnames[i], realdirnames[i]); |
240 |
} |
145 |
free(p); |
241 |
free(p); |
146 |
} |
242 |
} |
147 |
|
243 |
|
|
|
244 |
for (i = 0; i < (argc-optind); ++i) { |
245 |
if (basenames[i] != NULL) free(basenames[i]); |
246 |
if (dirnames[i] != NULL) free(dirnames[i]); |
247 |
if (realdirnames[i] != NULL) free(realdirnames[i]); |
248 |
} |
249 |
free(basenames); free(dirnames); free(realdirnames); |
250 |
|
148 |
return (found ? EXIT_SUCCESS : EXIT_FAILURE); |
251 |
return (found ? EXIT_SUCCESS : EXIT_FAILURE); |
149 |
} |
252 |
} |
150 |
|
253 |
|