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 / +138 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 = basename(p);
78
			    || strlen(base ? basename(p) : p) != flen) {
71
			if (strncmp(q, base_name, bnlen) != 0
72
			    || strlen(q) != bnlen) {
79
				free(p);
73
				free(p);
80
				continue;
74
				continue;
81
			}
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[PATH_MAX+1];
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
82
			if ((atom = atom_explode(pkg)) == NULL) {
114
			if ((atom = atom_explode(pkg)) == NULL) {
83
				warn("invalid atom %s", pkg);
115
				warn("invalid atom %s", pkg);
84
				free(p);
85
				continue;
116
				continue;
86
			}
117
			}
87
			printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE,
118
			printf("%s%s/%s%s%s", BOLD, atom->CATEGORY, BLUE,
Lines 90-99 Link Here
90
			if (quiet)
121
			if (quiet)
91
				puts("");
122
				puts("");
92
			else
123
			else
93
				printf(" (%s)\n", p);
124
				printf(" (%s)\n", e->name);
94
125
95
			atom_implode(atom);
126
			atom_implode(atom);
96
			free(p);
97
			found++;
127
			found++;
98
		}
128
		}
99
		fclose(fp);
129
		fclose(fp);
Lines 108-113 Link Here
108
	struct dirent *dentry;
138
	struct dirent *dentry;
109
	int i;
139
	int i;
110
	char *p;
140
	char *p;
141
	char ** basenames;
142
	char ** dirnames;
143
	char ** realdirnames;
144
	char * pwd;
111
145
112
	DBG("argc=%d argv[0]=%s argv[1]=%s",
146
	DBG("argc=%d argv[0]=%s argv[1]=%s",
113
	    argc, argv[0], argc > 1 ? argv[1] : "NULL?");
147
	    argc, argv[0], argc > 1 ? argv[1] : "NULL?");
Lines 122-148 Link Here
122
	if (argc == optind)
156
	if (argc == optind)
123
		qfile_usage(EXIT_FAILURE);
157
		qfile_usage(EXIT_FAILURE);
124
158
159
	// For each argument, we store its basename, its dirname,
160
	// and the realpath of its dirname.
161
	basenames = malloc((argc-optind) * sizeof(char*));
162
	dirnames = malloc((argc-optind) * sizeof(char*));
163
	realdirnames = malloc((argc-optind) * sizeof(char*));
164
	if ((pwd = getenv("PWD")) != NULL) {
165
		int pwdlen = strlen(pwd);
166
		if ((pwdlen > 0) && (pwd[pwdlen-1] == '/'))
167
			pwd[pwdlen-1] = '\0';
168
	}
169
	for (i = 0; i < (argc-optind); ++i) {
170
		char tmppath[PATH_MAX+1];
171
		char abspath[PATH_MAX+1];
172
173
		basenames[i] = NULL;
174
		dirnames[i] = NULL;
175
		realdirnames[i] = NULL;
176
177
		// Record basename, but if it is "." or ".."
178
		strncpy(tmppath, basename(argv[i+optind]), PATH_MAX);
179
		if ((strlen(tmppath) > 2) || strncmp(tmppath, "..", strlen(tmppath))) {
180
			basenames[i] = xstrdup(tmppath);
181
			// If there is no "/" in the argument, then it's over.
182
			// (we are searching a simple file name)
183
			if (strchr(argv[i+optind], '/') == NULL)
184
				continue;
185
		}
186
187
		// Make sure we have an absolute path available
188
		if (argv[i+optind][0] == '/')
189
			strncpy(abspath, argv[i+optind], PATH_MAX);
190
		else if (pwd != NULL)
191
			snprintf(abspath, PATH_MAX, "%s/%s", pwd, argv[i+optind]);
192
		else {
193
			err("$PWD not found in environment.");
194
			err("Skipping query item \"%s\".", argv[i+optind]);
195
			continue;
196
		}
197
198
		if (basenames[i] != NULL) {
199
			// Get both the dirname and its realpath
200
			dirnames[i] = xstrdup(dirname(abspath));
201
			errno = 0;
202
			realpath(dirnames[i], tmppath);
203
			if (errno != 0) {
204
				if (verbose) {
205
					warn("Could not read real path of \"%s\": %s", dirnames[i], strerror(errno));
206
					warn("Results for query item \"%s\" may not be accurate.", argv[i+optind]);
207
				}
208
			} else if (strcmp(dirnames[i], tmppath))
209
				realdirnames[i] = xstrdup(tmppath);
210
		} else {
211
			// No basename means we are looking for something like "/foo/bar/.."
212
			// Dirname is meaningless here, we can only get realpath of the full 
213
			// path and then split it.
214
			errno = 0;
215
			realpath(tmppath, abspath);
216
			if (errno != 0) {
217
				err("Could not read real path of \"%s\": %s", tmppath, strerror(errno));
218
				err("Skipping query item \"%s\".", argv[i+optind]);
219
				continue;
220
			}
221
			basenames[i] = xstrdup(basename(tmppath));
222
			realdirnames[i] = xstrdup(dirname(tmppath));
223
		}
224
	}
225
125
	if (chdir(portroot))
226
	if (chdir(portroot))
126
		errp("could not chdir(%s) for ROOT", portroot);
227
		errp("could not chdir(%s) for ROOT", portroot);
127
228
128
	if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL)
229
	if (chdir(portvdb) != 0 || (dir = opendir(".")) == NULL)
129
		return EXIT_FAILURE;
230
		return EXIT_FAILURE;
130
231
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 */
232
	/* open /var/db/pkg */
139
	while ((dentry = q_vdb_get_next_dir(dir))) {
233
	while ((dentry = q_vdb_get_next_dir(dir))) {
140
		xasprintf(&p, "%s%s/%s", portroot, portvdb, dentry->d_name);
234
		xasprintf(&p, "%s%s/%s", portroot, portvdb, dentry->d_name);
141
		for (i = optind; i < argc; ++i)
235
		for (i = 0; i < (argc-optind); ++i) {
142
			qfile(p, argv[i]);
236
			if (basenames[i] != NULL)
237
				qfile(p, basenames[i], dirnames[i], realdirnames[i]);
238
		}
143
		free(p);
239
		free(p);
144
	}
240
	}
145
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
146
	return (found ? EXIT_SUCCESS : EXIT_FAILURE);
249
	return (found ? EXIT_SUCCESS : EXIT_FAILURE);
147
}
250
}
148
251

Return to bug 130004