wmusic: Bump to version 2.1.0
[dockapps.git] / wmmenu / utils.c
blobf9e592168413e7ec60cdf37d5769bd57b8717b8a
1 #define _POSIX_SOURCE
2 #define _POSIX_C_SOURCE 199309L
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <errno.h>
8 #include <assert.h>
9 /* POSIX */
10 #include <unistd.h>
12 #include "utils.h"
13 #include "error.h"
14 #include "types.h"
16 static char * ReadAll (FILE * f, int offset)
18 char buf [10*1024] ;
19 size_t iRead, nRead ;
20 char * ret ;
22 clearerr (f) ;
24 iRead = 0 ;
25 nRead = 0 ;
26 while (iRead < sizeof buf)
28 nRead = fread (buf+iRead, 1, (sizeof buf)-iRead, f) ;
29 if (nRead <= 0) break ;
30 iRead += nRead ;
33 if (nRead > 0)
35 assert (iRead == sizeof buf) ;
36 ret = ReadAll (f, offset+iRead) ;
38 else
39 if (ferror (f) != 0)
41 error ("read file: %s", strerror (errno)) ;
42 ret = NULL ;
44 else
46 ret = malloc (offset+iRead+1) ;
47 if (ret == NULL) error ("failed to allocate memory") ;
48 ret[offset+iRead] = EOS ;
50 memcpy (ret+offset, buf, iRead) ;
52 return ret ;
55 extern char * File_ReadAll (FILE * f)
57 assert (f != NULL) ;
58 return ReadAll (f, 0) ;
61 static const char * getHome (void)
63 static char homeDir [80] = "" ;
64 static int initialized = 0 ;
65 if (! initialized)
67 const char * env ;
68 env = getenv ("HOME") ;
69 if (env != NULL && env[0] != EOS)
71 sprintf (homeDir, "%.*s", (int)(sizeof homeDir)-1, env) ;
73 initialized = 1 ;
75 return homeDir[0] != EOS ? homeDir : NULL ;
78 extern bool File_FindInPath (char * out, int outSz,
79 const char * path, const char * basename)
81 char name [FILENAME_MAX] ;
82 int len ;
84 assert (path != NULL) ;
85 assert (basename != NULL) ;
86 assert (out != NULL) ;
88 /* regular path */
89 if (access (basename, F_OK) == 0)
91 sprintf (out, "%.*s", outSz-1, basename) ;
92 return true ;
94 else
95 /* relative to home directory */
96 if (strncmp (basename, "~/", 2) == 0 && getHome () != NULL)
98 sprintf (name, "%s%s", getHome (), basename+1) ;
99 if (access (name, F_OK) == 0)
101 sprintf (out, "%.*s", outSz-1, name) ;
102 return true ;
104 else
106 return false ;
109 else
110 /* forbid relative to PATH just like shell */
111 /* NB: absolute non-existent files also drop here */
112 if (strchr (basename, '/') != NULL)
114 return false ;
116 else
118 while (*path != EOS)
120 len = strcspn (path, ":") ;
122 if (strncmp (path, "~/", 2) == 0)
124 sprintf (name, "%s%.*s/%s",
125 getHome (), len-1, path+1, basename) ;
127 else
129 sprintf (name, "%.*s/%s", len, path, basename) ;
132 if (access (name, F_OK) == 0)
134 sprintf (out, "%.*s", outSz-1, name) ;
135 return true ;
138 path += len ;
139 while (*path == ':') path++ ;
142 return false ;
146 extern char * File_ReadOutputFromCommand (const char * cmd)
148 FILE * out ;
149 char * ret ;
151 if ((out = popen (cmd, "r")) == NULL)
153 error ("when calling command: %s, error: ",
154 cmd, strerror (errno)) ;
155 ret = NULL ;
157 else
159 ret = File_ReadAll (out) ;
160 pclose (out) ;
162 /* if return value is correct, remove trailing whitespace */
163 if (ret != NULL)
165 char *lastNotWhite, *cursor ;
166 char c ;
168 cursor = lastNotWhite = ret ;
170 while ((c = *cursor++) != EOS)
172 if (strchr (" \t\n", c) == NULL)
174 lastNotWhite = cursor ;
178 *lastNotWhite = EOS ;
182 return ret ;