2 * Window Maker miscelaneous function library
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * 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.
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.
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.
38 static char *home
= NULL
;
51 user
= getpwuid(getuid());
53 werror(_("could not get password entry for UID %i"), getuid());
60 home
= wstrdup(user
->pw_dir
);
65 static char *getuserhomedir(const char *username
)
67 static char *home
= NULL
;
73 user
= getpwnam(username
);
75 werror(_("could not get password entry for user %s"), username
);
81 home
= wstrdup(user
->pw_dir
);
86 char *wexpandpath(char *path
)
88 char *origpath
= path
;
89 char buffer2
[PATH_MAX
+ 2];
90 char buffer
[PATH_MAX
+ 2];
93 memset(buffer
, 0, PATH_MAX
+ 2);
99 if (*path
== '/' || *path
== 0) {
100 home
= wgethomedir();
101 if (strlen(home
) > PATH_MAX
||
102 wstrlcpy(buffer
, home
, sizeof(buffer
)) >= sizeof(buffer
))
107 while (*path
!= 0 && *path
!= '/') {
110 buffer2
[j
++] = *path
;
114 home
= getuserhomedir(buffer2
);
115 if (!home
|| wstrlcat(buffer
, home
, sizeof(buffer
)) >= sizeof(buffer
))
122 while (*path
!= 0 && i
<= PATH_MAX
) {
128 /* expand $(HOME) or $HOME style environment variables */
131 while (*path
!= 0 && *path
!= ')') {
134 buffer2
[j
++] = *(path
++);
139 tmp
= getenv(buffer2
);
144 if ((i
+= strlen(buffer2
) + 2) > PATH_MAX
)
147 if (wstrlcat(buffer
, "$(", sizeof(buffer
)) >= sizeof(buffer
) ||
148 wstrlcat(buffer
, buffer2
, sizeof(buffer
)) >= sizeof(buffer
))
150 if (*(path
-1)==')') {
151 if (++i
> PATH_MAX
||
152 wstrlcat(buffer
, ")", sizeof(buffer
)) >= sizeof(buffer
))
156 if ((i
+= strlen(tmp
)) > PATH_MAX
||
157 wstrlcat(buffer
, tmp
, sizeof(buffer
)) >= sizeof(buffer
))
161 while (*path
!= 0 && *path
!= '/') {
164 buffer2
[j
++] = *(path
++);
167 tmp
= getenv(buffer2
);
169 if ((i
+= strlen(buffer2
) + 1) > PATH_MAX
||
170 wstrlcat(buffer
, "$", sizeof(buffer
)) >= sizeof(buffer
) ||
171 wstrlcat(buffer
, buffer2
, sizeof(buffer
)) >= sizeof(buffer
))
174 if ((i
+= strlen(tmp
)) > PATH_MAX
||
175 wstrlcat(buffer
, tmp
, sizeof(buffer
)) >= sizeof(buffer
))
188 return wstrdup(buffer
);
191 errno
= ENAMETOOLONG
;
192 werror(_("could not expand %s"), origpath
);
197 /* return address of next char != tok or end of string whichever comes first */
198 static char *skipchar(char *string
, char tok
)
200 while (*string
!= 0 && *string
== tok
)
206 /* return address of next char == tok or end of string whichever comes first */
207 static char *nextchar(char *string
, char tok
)
209 while (*string
!= 0 && *string
!= tok
)
216 *----------------------------------------------------------------------
218 * Finds a file in a : separated list of paths. ~ expansion is also
222 * The complete path for the file (in a newly allocated string) or
223 * NULL if the file was not found.
226 * A new string is allocated. It must be freed later.
228 *----------------------------------------------------------------------
230 char *wfindfile(char *paths
, char *file
)
240 if (*file
== '/' || *file
== '~' || *file
== '$' || !paths
|| *paths
== 0) {
241 if (access(file
, F_OK
) < 0) {
242 fullpath
= wexpandpath(file
);
246 if (access(fullpath
, F_OK
) < 0) {
253 return wstrdup(file
);
260 tmp
= skipchar(tmp
, ':');
263 tmp2
= nextchar(tmp
, ':');
265 path
= wmalloc(len
+ flen
+ 2);
266 path
= memcpy(path
, tmp
, len
);
268 if (path
[len
- 1] != '/' &&
269 wstrlcat(path
, "/", len
+ flen
+ 2) >= len
+ flen
+ 2) {
274 if (wstrlcat(path
, file
, len
+ flen
+ 2) >= len
+ flen
+ 2) {
279 fullpath
= wexpandpath(path
);
283 if (access(fullpath
, F_OK
) == 0) {
294 char *wfindfileinlist(char **path_list
, char *file
)
304 if (*file
== '/' || *file
== '~' || !path_list
) {
305 if (access(file
, F_OK
) < 0) {
306 fullpath
= wexpandpath(file
);
310 if (access(fullpath
, F_OK
) < 0) {
317 return wstrdup(file
);
322 for (i
= 0; path_list
[i
] != NULL
; i
++) {
323 len
= strlen(path_list
[i
]);
324 path
= wmalloc(len
+ flen
+ 2);
325 path
= memcpy(path
, path_list
[i
], len
);
327 if (wstrlcat(path
, "/", len
+ flen
+ 2) >= len
+ flen
+ 2 ||
328 wstrlcat(path
, file
, len
+ flen
+ 2) >= len
+ flen
+ 2) {
333 fullpath
= wexpandpath(path
);
336 /* check if file exists */
337 if (access(fullpath
, F_OK
) == 0) {
347 char *wfindfileinarray(WMPropList
* array
, char *file
)
357 if (*file
== '/' || *file
== '~' || !array
) {
358 if (access(file
, F_OK
) < 0) {
359 fullpath
= wexpandpath(file
);
363 if (access(fullpath
, F_OK
) < 0) {
370 return wstrdup(file
);
375 for (i
= 0; i
< WMGetPropListItemCount(array
); i
++) {
379 prop
= WMGetFromPLArray(array
, i
);
382 p
= WMGetFromPLString(prop
);
385 path
= wmalloc(len
+ flen
+ 2);
386 path
= memcpy(path
, p
, len
);
388 if (wstrlcat(path
, "/", len
+ flen
+ 2) >= len
+ flen
+ 2 ||
389 wstrlcat(path
, file
, len
+ flen
+ 2) >= len
+ flen
+ 2) {
394 fullpath
= wexpandpath(path
);
397 /* check if file exists */
398 if (access(fullpath
, F_OK
) == 0) {