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

Return to bug 130004