naspro
view naspro-core/src/posix/path.c @ 174:4f7243a606b1
Updated copyright notices and build system
| author | Stefano D'Angelo <zanga.mail@gmail.com> |
|---|---|
| date | Sat May 01 21:51:33 2010 +0300 (2010-05-01) |
| parents | d7568c8379c1 |
| children |
line source
1 /*
2 * NASPRO - NASPRO Architecture for Sound Processing
3 * Core library
4 *
5 * Copyright (C) 2007-2010 Stefano D'Angelo <zanga.mail@gmail.com>
6 *
7 * See the COPYING file for license conditions.
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
14 #include <sys/types.h>
15 #include <dirent.h>
16 #include <pwd.h>
17 #include <unistd.h>
19 #include <NASPRO/core/lib.h>
21 #include "src/path.h"
23 static char *home;
25 void
26 _nacore_path_init()
27 {
28 struct passwd *pwd;
30 home = nacore_env_get_var("HOME");
31 if (NACORE_STRING_IS_NULL_OR_EMPTY(home))
32 {
33 pwd = getpwuid(getuid());
34 if (pwd == NULL)
35 {
36 home = NULL;
37 return;
38 }
39 home = pwd->pw_dir;
40 if (NACORE_STRING_IS_NULL_OR_EMPTY(home))
41 {
42 home = NULL;
43 return;
44 }
45 }
46 }
48 void
49 _nacore_path_fini()
50 {
51 if (home != NULL)
52 nacore_env_free_var_value(home);
53 }
55 /* TODO: UTF-8 support. */
57 static void
58 scan_dir(const char *path,
59 void (*callback)(const char *file,const char *basename, void *data),
60 char (*filter)(const char *file), void *data)
61 {
62 DIR *dir;
63 struct dirent *entry;
64 char *filename, *p;
65 size_t len;
66 size_t path_len;
68 dir = opendir(path);
69 if (dir == NULL)
70 return;
72 path_len = strlen(path);
73 filename = NULL;
74 len = 0;
75 while ((entry = readdir(dir)) != NULL)
76 {
77 if (!strcmp(entry->d_name, "."))
78 continue;
79 if (!strcmp(entry->d_name, ".."))
80 continue;
82 if ((path_len + strlen(entry->d_name) + 1) > len)
83 {
84 len = path_len + strlen(entry->d_name) + 1;
85 p = realloc(filename, len + 1);
86 if (p == NULL)
87 goto end;
88 if (filename == NULL)
89 {
90 strcpy(p, path);
91 strcat(p, "/");
92 }
93 filename = p;
94 }
96 strcpy(filename + 1 + path_len, entry->d_name);
98 if (filter != NULL)
99 if (!filter(filename))
100 continue;
102 callback(filename, entry->d_name, data);
103 }
105 end:
106 if (filename != NULL)
107 free(filename);
108 closedir(dir);
109 }
111 void
112 nacore_path_for_each(const char *path,
113 void (*callback)(const char *file, const char *basename, void *data),
114 char (*filter)(const char *file), void *data)
115 {
116 char *str, *cur, *next;
118 if (path[0] == '\0')
119 return;
121 str = malloc(strlen(path) + 1);
122 if (str == NULL)
123 return;
124 strcpy(str, path);
126 for (cur = str, next = strchr(str, ':'); cur != NULL;
127 cur = next, next = (cur != NULL) ? strchr(cur, ':') : NULL)
128 {
129 if (next != NULL)
130 {
131 *next = '\0';
132 next++;
133 }
135 scan_dir((*cur == '\0') ? "." : cur, callback, filter, data);
136 }
138 free(str);
139 }
141 #if 0
142 void
143 nacore_path_for_each_in_subdir(const char *path, const char *subdir,
144 void (*callback)(const char *file, const char *basename, void *data),
145 char (*filter)(const char *file), void *data)
146 {
147 const char *cur, *next;
148 char *new_path, *p;
149 char zlen_prefix;
150 size_t subdir_len, len;
152 if (path[0] == '\0')
153 return;
155 subdir_len = strlen(subdir);
157 /* Count needed bytes to allocate a string for nacore_path_for_each() */
158 zlen_prefix = 0;
159 len = 0;
160 for (cur = path, next = strchr(path, ':'); cur != NULL;
161 cur = next, next = (cur != NULL) ? strchr(cur, ':') : NULL)
162 {
163 if (((next == (cur + 1)) && (*cur == ':')) ||
164 ((next == NULL) && (strlen(cur) == 0)))
165 {
166 if (!zlen_prefix)
167 {
168 len += subdir_len + 3;
169 zlen_prefix = 1;
170 }
172 if (next != NULL)
173 while (*next == ':')
174 next++;
176 continue;
177 }
179 if (next != NULL)
180 {
181 len += 1 + next - cur + 1 + subdir_len;
182 next++;
183 }
184 else
185 len += 1 + strlen(cur) + 1 + subdir_len;
186 }
187 /* First ':' is not wanted, but 1 more byte is needed for trailing '\0'
188 * in malloc() */
190 new_path = malloc(len);
191 if (new_path == NULL)
192 return;
194 /* Build the new path */
195 new_path[0] = '\0';
196 if (zlen_prefix)
197 {
198 strcpy(new_path, "./");
199 strcat(new_path, subdir);
200 }
202 p = new_path + strlen(new_path);
203 for (cur = path, next = strchr(path, ':'); cur != NULL;
204 cur = next, next = (cur != NULL) ? strchr(cur, ':') : NULL)
205 {
206 if (((next == (cur + 1)) && (*cur == ':')) ||
207 ((next == NULL) && (strlen(cur) == 0)))
208 {
209 if (next != NULL)
210 while (*next == ':')
211 next++;
213 continue;
214 }
216 if (new_path[0] != '\0')
217 {
218 *p = ':';
219 p++;
220 }
222 if (next != NULL)
223 {
224 strncpy(p, cur, next - cur);
225 p += next - cur;
226 *p = '/';
227 p++;
228 strcpy(p, subdir);
229 p += subdir_len;
230 while (*next == ':')
231 next++;
232 }
233 else
234 {
235 strcpy(p, cur);
236 p += strlen(p);
237 *p = '/';
238 p++;
239 strcpy(p, subdir);
240 }
241 }
243 nacore_path_for_each(new_path, callback, filter, data);
245 free(new_path);
246 }
247 #endif
249 void
250 nacore_path_home_for_each(const char *dir,
251 void (*callback)(const char *file, const char *basename, void *data),
252 char (*filter)(const char *file), void *data)
253 {
254 char *path;
256 if (home == NULL)
257 return;
259 path = malloc(strlen(home) + strlen(dir) + 3);
260 if (path == NULL)
261 return;
263 strcpy(path, home);
264 strcat(path, "/.");
265 strcat(path, dir);
267 scan_dir(path, callback, filter, data);
269 free(path);
270 }
