Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / findfile.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/*
9af1c6c4 dan1998-10-21 14:43:47 +00002 * Window Maker miscelaneous function library
6830b057 dan2004-10-12 21:28:27 +00003 *
4153e2fd dan2003-01-16 23:30:45 +00004 * Copyright (c) 1997-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00005 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
882b9a8e kojima2001-07-23 20:31:32 +000021#include "wconfig.h"
22
9d2e6ef9 scottc1998-09-29 22:36:29 +000023#include "WUtil.h"
24
25#include <stdlib.h>
26#include <unistd.h>
27#include <string.h>
28#include <pwd.h>
29#include <limits.h>
30
31#ifndef PATH_MAX
32#define PATH_MAX 1024
33#endif
34
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020035char *wgethomedir()
9d2e6ef9 scottc1998-09-29 22:36:29 +000036{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020037 char *home = getenv("HOME");
38 struct passwd *user;
39
40 if (home)
41 return home;
42
43 user = getpwuid(getuid());
44 if (!user) {
45 wsyserror(_("could not get password entry for UID %i"), getuid());
46 return "/";
47 }
48 if (!user->pw_dir) {
49 return "/";
50 } else {
51 return user->pw_dir;
52 }
9d2e6ef9 scottc1998-09-29 22:36:29 +000053}
54
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020055static char *getuserhomedir(char *username)
9d2e6ef9 scottc1998-09-29 22:36:29 +000056{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020057 struct passwd *user;
58
59 user = getpwnam(username);
60 if (!user) {
61 wsyserror(_("could not get password entry for user %s"), username);
62 return NULL;
63 }
64 if (!user->pw_dir) {
65 return "/";
66 } else {
67 return user->pw_dir;
68 }
9d2e6ef9 scottc1998-09-29 22:36:29 +000069}
70
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020071char *wexpandpath(char *path)
9d2e6ef9 scottc1998-09-29 22:36:29 +000072{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020073 char buffer2[PATH_MAX + 2];
74 char buffer[PATH_MAX + 2];
75 int i;
76
77 memset(buffer, 0, PATH_MAX + 2);
78
79 if (*path == '~') {
80 char *home;
81
82 path++;
83 if (*path == '/' || *path == 0) {
84 home = wgethomedir();
85 strcat(buffer, home);
86 } else {
87 int j;
88 j = 0;
89 while (*path != 0 && *path != '/') {
90 buffer2[j++] = *path;
91 buffer2[j] = 0;
92 path++;
93 }
94 home = getuserhomedir(buffer2);
95 if (!home)
96 return NULL;
97 strcat(buffer, home);
98 }
99 }
100
101 i = strlen(buffer);
102
103 while (*path != 0) {
104 char *tmp;
105
106 if (*path == '$') {
107 int j = 0;
108 path++;
109 /* expand $(HOME) or $HOME style environment variables */
110 if (*path == '(') {
111 path++;
112 while (*path != 0 && *path != ')') {
113 buffer2[j++] = *(path++);
114 buffer2[j] = 0;
115 }
116 if (*path == ')')
117 path++;
118 tmp = getenv(buffer2);
119 if (!tmp) {
120 buffer[i] = 0;
121 strcat(buffer, "$(");
122 strcat(buffer, buffer2);
123 strcat(buffer, ")");
124 i += strlen(buffer2) + 3;
125 } else {
126 strcat(buffer, tmp);
127 i += strlen(tmp);
128 }
129 } else {
130 while (*path != 0 && *path != '/') {
131 buffer2[j++] = *(path++);
132 buffer2[j] = 0;
133 }
134 tmp = getenv(buffer2);
135 if (!tmp) {
136 strcat(buffer, "$");
137 strcat(buffer, buffer2);
138 i += strlen(buffer2) + 1;
139 } else {
140 strcat(buffer, tmp);
141 i += strlen(tmp);
142 }
143 }
144 } else {
145 buffer[i++] = *path;
146 path++;
147 }
148 }
149
150 return wstrdup(buffer);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000151}
152
365556b6 dan2002-01-02 17:45:40 +0000153/* return address of next char != tok or end of string whichever comes first */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200154static char *skipchar(char *string, char tok)
365556b6 dan2002-01-02 17:45:40 +0000155{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200156 while (*string != 0 && *string == tok)
157 string++;
365556b6 dan2002-01-02 17:45:40 +0000158
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200159 return string;
365556b6 dan2002-01-02 17:45:40 +0000160}
161
365556b6 dan2002-01-02 17:45:40 +0000162/* return address of next char == tok or end of string whichever comes first */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200163static char *nextchar(char *string, char tok)
365556b6 dan2002-01-02 17:45:40 +0000164{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200165 while (*string != 0 && *string != tok)
166 string++;
365556b6 dan2002-01-02 17:45:40 +0000167
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200168 return string;
365556b6 dan2002-01-02 17:45:40 +0000169}
170
9d2e6ef9 scottc1998-09-29 22:36:29 +0000171/*
172 *----------------------------------------------------------------------
173 * findfile--
6830b057 dan2004-10-12 21:28:27 +0000174 * Finds a file in a : separated list of paths. ~ expansion is also
9d2e6ef9 scottc1998-09-29 22:36:29 +0000175 * done.
6830b057 dan2004-10-12 21:28:27 +0000176 *
9d2e6ef9 scottc1998-09-29 22:36:29 +0000177 * Returns:
178 * The complete path for the file (in a newly allocated string) or
179 * NULL if the file was not found.
6830b057 dan2004-10-12 21:28:27 +0000180 *
9d2e6ef9 scottc1998-09-29 22:36:29 +0000181 * Side effects:
182 * A new string is allocated. It must be freed later.
6830b057 dan2004-10-12 21:28:27 +0000183 *
184 *----------------------------------------------------------------------
9d2e6ef9 scottc1998-09-29 22:36:29 +0000185 */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200186char *wfindfile(char *paths, char *file)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000187{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200188 char *path;
189 char *tmp, *tmp2;
190 int len, flen;
191 char *fullpath;
192
193 if (!file)
194 return NULL;
195
196 if (*file == '/' || *file == '~' || *file == '$' || !paths || *paths == 0) {
197 if (access(file, F_OK) < 0) {
198 fullpath = wexpandpath(file);
199 if (!fullpath)
200 return NULL;
201
202 if (access(fullpath, F_OK) < 0) {
203 wfree(fullpath);
204 return NULL;
205 } else {
206 return fullpath;
207 }
208 } else {
209 return wstrdup(file);
210 }
211 }
212
213 flen = strlen(file);
214 tmp = paths;
215 while (*tmp) {
216 tmp = skipchar(tmp, ':');
217 if (*tmp == 0)
218 break;
219 tmp2 = nextchar(tmp, ':');
220 len = tmp2 - tmp;
221 path = wmalloc(len + flen + 2);
222 path = memcpy(path, tmp, len);
223 path[len] = 0;
224 if (path[len - 1] != '/')
225 strcat(path, "/");
226 strcat(path, file);
227 fullpath = wexpandpath(path);
228 wfree(path);
229 if (fullpath) {
230 if (access(fullpath, F_OK) == 0) {
231 return fullpath;
232 }
233 wfree(fullpath);
234 }
235 tmp = tmp2;
236 }
237
238 return NULL;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000239}
240
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200241char *wfindfileinlist(char **path_list, char *file)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000242{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200243 int i;
244 char *path;
245 int len, flen;
246 char *fullpath;
247
248 if (!file)
249 return NULL;
250
251 if (*file == '/' || *file == '~' || !path_list) {
252 if (access(file, F_OK) < 0) {
253 fullpath = wexpandpath(file);
254 if (!fullpath)
255 return NULL;
256
257 if (access(fullpath, F_OK) < 0) {
258 wfree(fullpath);
259 return NULL;
260 } else {
261 return fullpath;
262 }
263 } else {
264 return wstrdup(file);
265 }
266 }
267
268 flen = strlen(file);
269 for (i = 0; path_list[i] != NULL; i++) {
270 len = strlen(path_list[i]);
271 path = wmalloc(len + flen + 2);
272 path = memcpy(path, path_list[i], len);
273 path[len] = 0;
274 strcat(path, "/");
275 strcat(path, file);
276 /* expand tilde */
277 fullpath = wexpandpath(path);
278 wfree(path);
279 if (fullpath) {
280 /* check if file exists */
281 if (access(fullpath, F_OK) == 0) {
282 return fullpath;
283 }
284 wfree(fullpath);
285 }
286 }
287 return NULL;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000288}
289
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200290char *wfindfileinarray(WMPropList * array, char *file)
c56756dc dan1999-03-14 22:35:50 +0000291{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200292 int i;
293 char *path;
294 int len, flen;
295 char *fullpath;
296
297 if (!file)
298 return NULL;
299
300 if (*file == '/' || *file == '~' || !array) {
301 if (access(file, F_OK) < 0) {
302 fullpath = wexpandpath(file);
303 if (!fullpath)
304 return NULL;
305
306 if (access(fullpath, F_OK) < 0) {
307 wfree(fullpath);
308 return NULL;
309 } else {
310 return fullpath;
311 }
312 } else {
313 return wstrdup(file);
314 }
315 }
316
317 flen = strlen(file);
318 for (i = 0; i < WMGetPropListItemCount(array); i++) {
319 WMPropList *prop;
320 char *p;
321
322 prop = WMGetFromPLArray(array, i);
323 if (!prop)
324 continue;
325 p = WMGetFromPLString(prop);
326
327 len = strlen(p);
328 path = wmalloc(len + flen + 2);
329 path = memcpy(path, p, len);
330 path[len] = 0;
331 strcat(path, "/");
332 strcat(path, file);
333 /* expand tilde */
334 fullpath = wexpandpath(path);
335 wfree(path);
336 if (fullpath) {
337 /* check if file exists */
338 if (access(fullpath, F_OK) == 0) {
339 return fullpath;
340 }
341 wfree(fullpath);
342 }
343 }
344 return NULL;
c56756dc dan1999-03-14 22:35:50 +0000345}