1 /*
2  * Copyright (C) 2011 Marcin Kościelnicki <koriakin@0x04.net>
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "util.h"
26 #include <string.h>
27 
find_in_path(const char * name,const char * path,char ** pfullname)28 FILE *find_in_path(const char *name, const char *path, char **pfullname) {
29 	if (!path)
30 		return 0;
31 	while (path) {
32 		const char *npath = strchr(path, ':');
33 		size_t plen;
34 		if (npath) {
35 			plen = npath - path;
36 			npath++;
37 		} else {
38 			plen = strlen(path);
39 		}
40 		if (plen) {
41 			/* also look for .gz compressed xml: */
42 			const char *exts[] = { "", ".gz" };
43 			for (int i = 0; i < ARRAY_SIZE(exts); i++) {
44 				char *fullname;
45 
46 				int ret = asprintf(&fullname, "%.*s/%s%s", (int)plen, path, name, exts[i]);
47 				if (ret < 0)
48 					return NULL;
49 
50 				FILE *file = fopen(fullname, "r");
51 				if (file) {
52 					if (pfullname)
53 						*pfullname = fullname;
54 					else
55 						free(fullname);
56 					return file;
57 				}
58 				free(fullname);
59 			}
60 		}
61 		path = npath;
62 	}
63 	return 0;
64 }
65