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