Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 130004 | Differences between
and this patch

Collapse All | Expand All

(-)qfile.c.orig (-36 / +149 lines)
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

Return to bug 130004