File: | file-utils.c |
Warning: | line 624, column 52 Access to field 'message' results in a dereference of a null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ | |||
2 | ||||
3 | /* | |||
4 | * Grapa | |||
5 | * | |||
6 | * Copyright (C) 2001, 2003 Free Software Foundation, Inc. | |||
7 | * | |||
8 | * This program is free software; you can redistribute it and/or modify | |||
9 | * it under the terms of the GNU General Public License as published by | |||
10 | * the Free Software Foundation; either version 2 of the License, or | |||
11 | * (at your option) any later version. | |||
12 | * | |||
13 | * This program is distributed in the hope that it will be useful, | |||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
16 | * GNU General Public License for more details. | |||
17 | * | |||
18 | * You should have received a copy of the GNU General Public License | |||
19 | * along with this program; if not, write to the Free Software | |||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||
21 | */ | |||
22 | ||||
23 | #define _XOPEN_SOURCE700 700 | |||
24 | ||||
25 | #include <config.h> | |||
26 | #include <pwd.h> | |||
27 | #include <stdio.h> | |||
28 | #include <stdlib.h> | |||
29 | #include <string.h> | |||
30 | #include <strings.h> | |||
31 | #include <ctype.h> | |||
32 | #include <time.h> | |||
33 | #include <unistd.h> | |||
34 | #include <sys/param.h> | |||
35 | #include <sys/stat.h> | |||
36 | #include <sys/time.h> | |||
37 | #include <sys/types.h> | |||
38 | #include <dirent.h> | |||
39 | ||||
40 | #include <glib.h> | |||
41 | #include <gio/gio.h> | |||
42 | #include "file-utils.h" | |||
43 | #include "glib-utils.h" | |||
44 | #include "fr-init.h" | |||
45 | ||||
46 | ||||
47 | #define SPECIAL_DIR(x)((strcmp ((x), "..") == 0) || (strcmp ((x), ".") == 0)) ((strcmp ((x), "..") == 0) || (strcmp ((x), ".") == 0)) | |||
48 | ||||
49 | ||||
50 | gboolean | |||
51 | uri_exists (const char *uri) | |||
52 | { | |||
53 | GFile *file; | |||
54 | gboolean exists; | |||
55 | ||||
56 | if (uri == NULL((void*)0)) | |||
57 | return FALSE(0); | |||
58 | ||||
59 | file = g_file_new_for_uri (uri); | |||
60 | exists = g_file_query_exists (file, NULL((void*)0)); | |||
61 | g_object_unref (file); | |||
62 | ||||
63 | return exists; | |||
64 | } | |||
65 | ||||
66 | ||||
67 | static gboolean | |||
68 | uri_is_filetype (const char *uri, | |||
69 | GFileType file_type) | |||
70 | { | |||
71 | gboolean result = FALSE(0); | |||
72 | GFile *file; | |||
73 | GFileInfo *info; | |||
74 | GError *error = NULL((void*)0); | |||
75 | ||||
76 | file = g_file_new_for_uri (uri); | |||
77 | ||||
78 | if (! g_file_query_exists (file, NULL((void*)0))) { | |||
79 | g_object_unref (file); | |||
80 | return FALSE(0); | |||
81 | } | |||
82 | ||||
83 | info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE"standard::type", 0, NULL((void*)0), &error); | |||
84 | if (error == NULL((void*)0)) { | |||
85 | result = (g_file_info_get_file_type (info) == file_type); | |||
86 | } | |||
87 | else { | |||
88 | g_warning ("Failed to get file type for uri %s: %s", uri, error->message); | |||
89 | g_error_free (error); | |||
90 | } | |||
91 | ||||
92 | g_object_unref (info); | |||
93 | g_object_unref (file); | |||
94 | ||||
95 | return result; | |||
96 | } | |||
97 | ||||
98 | ||||
99 | gboolean | |||
100 | uri_is_file (const char *uri) | |||
101 | { | |||
102 | return uri_is_filetype (uri, G_FILE_TYPE_REGULAR); | |||
103 | } | |||
104 | ||||
105 | ||||
106 | gboolean | |||
107 | uri_is_dir (const char *uri) | |||
108 | { | |||
109 | return uri_is_filetype (uri, G_FILE_TYPE_DIRECTORY); | |||
110 | } | |||
111 | ||||
112 | ||||
113 | gboolean | |||
114 | path_is_dir (const char *path) | |||
115 | { | |||
116 | char *uri; | |||
117 | gboolean result; | |||
118 | ||||
119 | uri = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
120 | result = uri_is_dir (uri); | |||
121 | g_free (uri); | |||
122 | ||||
123 | return result; | |||
124 | } | |||
125 | ||||
126 | gboolean | |||
127 | uri_is_local (const char *uri) | |||
128 | { | |||
129 | return strncmp (uri, "file://", 7) == 0; | |||
130 | } | |||
131 | ||||
132 | ||||
133 | gboolean | |||
134 | dir_is_empty (const char *uri) | |||
135 | { | |||
136 | GFile *file; | |||
137 | GFileEnumerator *file_enum; | |||
138 | GFileInfo *info; | |||
139 | GError *error = NULL((void*)0); | |||
140 | int n = 0; | |||
141 | ||||
142 | file = g_file_new_for_uri (uri); | |||
143 | ||||
144 | if (! g_file_query_exists (file, NULL((void*)0))) { | |||
145 | g_object_unref (file); | |||
146 | return TRUE(!(0)); | |||
147 | } | |||
148 | ||||
149 | file_enum = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME"standard::name", 0, NULL((void*)0), &error); | |||
150 | if (error != NULL((void*)0)) { | |||
151 | g_warning ("Failed to enumerate children of %s: %s", uri, error->message); | |||
152 | g_error_free (error); | |||
153 | g_object_unref (file_enum); | |||
154 | g_object_unref (file); | |||
155 | return TRUE(!(0)); | |||
156 | } | |||
157 | ||||
158 | while ((n == 0) && ((info = g_file_enumerator_next_file (file_enum, NULL((void*)0), &error)) != NULL((void*)0))) { | |||
159 | if (error != NULL((void*)0)) { | |||
160 | g_warning ("Encountered error while enumerating children of %s (ignoring): %s", uri, error->message); | |||
161 | g_error_free (error); | |||
162 | } | |||
163 | else if (! SPECIAL_DIR (g_file_info_get_name (info))((strcmp ((g_file_info_get_name (info)), "..") == 0) || (strcmp ((g_file_info_get_name (info)), ".") == 0))) | |||
164 | n++; | |||
165 | g_object_unref (info); | |||
166 | } | |||
167 | ||||
168 | g_object_unref (file); | |||
169 | g_object_unref (file_enum); | |||
170 | ||||
171 | return (n == 0); | |||
172 | } | |||
173 | ||||
174 | ||||
175 | gboolean | |||
176 | dir_contains_one_object (const char *uri) | |||
177 | { | |||
178 | GFile *file; | |||
179 | GFileEnumerator *file_enum; | |||
180 | GFileInfo *info; | |||
181 | GError *err = NULL((void*)0); | |||
182 | int n = 0; | |||
183 | ||||
184 | file = g_file_new_for_uri (uri); | |||
185 | ||||
186 | if (! g_file_query_exists (file, NULL((void*)0))) { | |||
187 | g_object_unref (file); | |||
188 | return FALSE(0); | |||
189 | } | |||
190 | ||||
191 | file_enum = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME"standard::name", 0, NULL((void*)0), &err); | |||
192 | if (err != NULL((void*)0)) { | |||
193 | g_warning ("Failed to enumerate children of %s: %s", uri, err->message); | |||
194 | g_error_free (err); | |||
195 | g_object_unref (file_enum); | |||
196 | g_object_unref (file); | |||
197 | return FALSE(0); | |||
198 | } | |||
199 | ||||
200 | while ((info = g_file_enumerator_next_file (file_enum, NULL((void*)0), &err)) != NULL((void*)0)) { | |||
201 | const char *name; | |||
202 | ||||
203 | if (err != NULL((void*)0)) { | |||
204 | g_warning ("Encountered error while enumerating children of %s, ignoring: %s", uri, err->message); | |||
205 | g_error_free (err); | |||
206 | g_object_unref (info); | |||
207 | continue; | |||
208 | } | |||
209 | ||||
210 | name = g_file_info_get_name (info); | |||
211 | if (strcmp (name, ".") == 0 || strcmp (name, "..") == 0) { | |||
212 | g_object_unref (info); | |||
213 | continue; | |||
214 | } | |||
215 | ||||
216 | g_object_unref (info); | |||
217 | ||||
218 | if (++n > 1) | |||
219 | break; | |||
220 | } | |||
221 | ||||
222 | g_object_unref (file); | |||
223 | g_object_unref (file_enum); | |||
224 | ||||
225 | return (n == 1); | |||
226 | } | |||
227 | ||||
228 | ||||
229 | char * | |||
230 | get_dir_content_if_unique (const char *uri) | |||
231 | { | |||
232 | GFile *file; | |||
233 | GFileEnumerator *file_enum; | |||
234 | GFileInfo *info; | |||
235 | GError *err = NULL((void*)0); | |||
236 | char *content_uri = NULL((void*)0); | |||
237 | ||||
238 | file = g_file_new_for_uri (uri); | |||
239 | ||||
240 | if (! g_file_query_exists (file, NULL((void*)0))) { | |||
241 | g_object_unref (file); | |||
242 | return NULL((void*)0); | |||
243 | } | |||
244 | ||||
245 | file_enum = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME"standard::name", 0, NULL((void*)0), &err); | |||
246 | if (err != NULL((void*)0)) { | |||
247 | g_warning ("Failed to enumerate children of %s: %s", uri, err->message); | |||
248 | g_error_free (err); | |||
249 | return NULL((void*)0); | |||
250 | } | |||
251 | ||||
252 | while ((info = g_file_enumerator_next_file (file_enum, NULL((void*)0), &err)) != NULL((void*)0)) { | |||
253 | const char *name; | |||
254 | ||||
255 | if (err != NULL((void*)0)) { | |||
256 | g_warning ("Failed to get info while enumerating children: %s", err->message); | |||
257 | g_clear_error (&err); | |||
258 | g_object_unref (info); | |||
259 | continue; | |||
260 | } | |||
261 | ||||
262 | name = g_file_info_get_name (info); | |||
263 | if ((strcmp (name, ".") == 0) || (strcmp (name, "..") == 0)) { | |||
264 | g_object_unref (info); | |||
265 | continue; | |||
266 | } | |||
267 | ||||
268 | if (content_uri != NULL((void*)0)) { | |||
269 | g_free (content_uri); | |||
270 | g_object_unref (info); | |||
271 | content_uri = NULL((void*)0); | |||
272 | break; | |||
273 | } | |||
274 | ||||
275 | content_uri = build_uri (uri, name, NULL((void*)0)); | |||
276 | g_object_unref (info); | |||
277 | } | |||
278 | ||||
279 | if (err != NULL((void*)0)) { | |||
280 | g_warning ("Failed to get info after enumerating children: %s", err->message); | |||
281 | g_clear_error (&err); | |||
282 | } | |||
283 | ||||
284 | g_object_unref (file_enum); | |||
285 | g_object_unref (file); | |||
286 | ||||
287 | return content_uri; | |||
288 | } | |||
289 | ||||
290 | ||||
291 | /* Check whether the dirname is contained in filename */ | |||
292 | gboolean | |||
293 | path_in_path (const char *dirname, | |||
294 | const char *filename) | |||
295 | { | |||
296 | int dirname_l, filename_l, separator_position; | |||
297 | ||||
298 | if ((dirname == NULL((void*)0)) || (filename == NULL((void*)0))) | |||
299 | return FALSE(0); | |||
300 | ||||
301 | dirname_l = strlen (dirname); | |||
302 | filename_l = strlen (filename); | |||
303 | ||||
304 | if ((dirname_l == filename_l + 1) | |||
305 | && (dirname[dirname_l - 1] == '/')) | |||
306 | return FALSE(0); | |||
307 | ||||
308 | if ((filename_l == dirname_l + 1) | |||
309 | && (filename[filename_l - 1] == '/')) | |||
310 | return FALSE(0); | |||
311 | ||||
312 | if (dirname[dirname_l - 1] == '/') | |||
313 | separator_position = dirname_l - 1; | |||
314 | else | |||
315 | separator_position = dirname_l; | |||
316 | ||||
317 | return ((filename_l > dirname_l) | |||
318 | && (strncmp (dirname, filename, dirname_l) == 0) | |||
319 | && (filename[separator_position] == '/')); | |||
320 | } | |||
321 | ||||
322 | ||||
323 | goffset | |||
324 | get_file_size (const char *uri) | |||
325 | { | |||
326 | goffset size = 0; | |||
327 | GFile *file; | |||
328 | GFileInfo *info; | |||
329 | GError *err = NULL((void*)0); | |||
330 | ||||
331 | if ((uri == NULL((void*)0)) || (*uri == '\0')) | |||
332 | return 0; | |||
333 | ||||
334 | file = g_file_new_for_uri (uri); | |||
335 | info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE"standard::size", 0, NULL((void*)0), &err); | |||
336 | if (err == NULL((void*)0)) { | |||
337 | size = g_file_info_get_size (info); | |||
338 | } | |||
339 | else { | |||
340 | g_warning ("Failed to get file size for %s: %s", uri, err->message); | |||
341 | g_error_free (err); | |||
342 | } | |||
343 | ||||
344 | g_object_unref (info); | |||
345 | g_object_unref (file); | |||
346 | ||||
347 | return size; | |||
348 | } | |||
349 | ||||
350 | ||||
351 | goffset | |||
352 | get_file_size_for_path (const char *path) | |||
353 | { | |||
354 | char *uri; | |||
355 | goffset result; | |||
356 | ||||
357 | uri = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
358 | result = get_file_size (uri); | |||
359 | g_free (uri); | |||
360 | ||||
361 | return result; | |||
362 | } | |||
363 | ||||
364 | ||||
365 | static time_t | |||
366 | get_file_time_type (const char *uri, | |||
367 | const char *type) | |||
368 | { | |||
369 | time_t result = 0; | |||
370 | GFile *file; | |||
371 | GFileInfo *info; | |||
372 | GError *err = NULL((void*)0); | |||
373 | ||||
374 | if ((uri == NULL((void*)0)) || (*uri == '\0')) | |||
375 | return 0; | |||
376 | ||||
377 | file = g_file_new_for_uri (uri); | |||
378 | info = g_file_query_info (file, type, 0, NULL((void*)0), &err); | |||
379 | if (err == NULL((void*)0)) { | |||
380 | result = (time_t) g_file_info_get_attribute_uint64 (info, type); | |||
381 | } | |||
382 | else { | |||
383 | g_warning ("Failed to get %s: %s", type, err->message); | |||
384 | g_error_free (err); | |||
385 | result = 0; | |||
386 | } | |||
387 | ||||
388 | g_object_unref (info); | |||
389 | g_object_unref (file); | |||
390 | ||||
391 | return result; | |||
392 | } | |||
393 | ||||
394 | ||||
395 | time_t | |||
396 | get_file_mtime (const char *uri) | |||
397 | { | |||
398 | return get_file_time_type (uri, G_FILE_ATTRIBUTE_TIME_MODIFIED"time::modified"); | |||
399 | } | |||
400 | ||||
401 | ||||
402 | time_t | |||
403 | get_file_mtime_for_path (const char *path) | |||
404 | { | |||
405 | char *uri; | |||
406 | time_t result; | |||
407 | ||||
408 | uri = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
409 | result = get_file_mtime (uri); | |||
410 | g_free (uri); | |||
411 | ||||
412 | return result; | |||
413 | } | |||
414 | ||||
415 | ||||
416 | time_t | |||
417 | get_file_ctime (const char *uri) | |||
418 | { | |||
419 | return get_file_time_type (uri, G_FILE_ATTRIBUTE_TIME_CREATED"time::created"); | |||
420 | } | |||
421 | ||||
422 | ||||
423 | gboolean | |||
424 | file_is_hidden (const gchar *name) | |||
425 | { | |||
426 | if (name[0] != '.') return FALSE(0); | |||
427 | if (name[1] == '\0') return FALSE(0); | |||
428 | if ((name[1] == '.') && (name[2] == '\0')) return FALSE(0); | |||
429 | ||||
430 | return TRUE(!(0)); | |||
431 | } | |||
432 | ||||
433 | ||||
434 | /* like g_path_get_basename but does not warn about NULL and does not | |||
435 | * alloc a new string. */ | |||
436 | const gchar* file_name_from_path(const gchar *file_name) | |||
437 | { | |||
438 | register char *base; | |||
439 | register gssize last_char; | |||
440 | ||||
441 | if (file_name == NULL((void*)0)) | |||
442 | return NULL((void*)0); | |||
443 | ||||
444 | if ((file_name[0] == '\0') || (strlen (file_name) == 0)) | |||
445 | return ""; | |||
446 | ||||
447 | last_char = strlen (file_name) - 1; | |||
448 | ||||
449 | if (file_name [last_char] == G_DIR_SEPARATOR'/') | |||
450 | return ""; | |||
451 | ||||
452 | base = g_utf8_strrchr (file_name, -1, G_DIR_SEPARATOR'/'); | |||
453 | if (! base) | |||
454 | return file_name; | |||
455 | ||||
456 | return base + 1; | |||
457 | } | |||
458 | ||||
459 | ||||
460 | char * | |||
461 | dir_name_from_path (const gchar *path) | |||
462 | { | |||
463 | register gssize base; | |||
464 | register gssize last_char; | |||
465 | ||||
466 | if (path == NULL((void*)0)) | |||
467 | return NULL((void*)0); | |||
468 | ||||
469 | if (path[0] == '\0') | |||
470 | return g_strdup ("")g_strdup_inline (""); | |||
471 | ||||
472 | last_char = strlen (path) - 1; | |||
473 | if (path[last_char] == G_DIR_SEPARATOR'/') | |||
474 | last_char--; | |||
475 | ||||
476 | base = last_char; | |||
477 | while ((base >= 0) && (path[base] != G_DIR_SEPARATOR'/')) | |||
478 | base--; | |||
479 | ||||
480 | return g_strndup (path + base + 1, last_char - base); | |||
481 | } | |||
482 | ||||
483 | ||||
484 | gchar * | |||
485 | remove_level_from_path (const gchar *path) | |||
486 | { | |||
487 | int p; | |||
488 | const char *ptr = path; | |||
489 | char *new_path; | |||
490 | ||||
491 | if (path == NULL((void*)0)) | |||
492 | return NULL((void*)0); | |||
493 | ||||
494 | p = strlen (path) - 1; | |||
495 | if (p < 0) | |||
496 | return NULL((void*)0); | |||
497 | ||||
498 | while ((p > 0) && (ptr[p] != '/')) | |||
499 | p--; | |||
500 | if ((p == 0) && (ptr[p] == '/')) | |||
501 | p++; | |||
502 | new_path = g_strndup (path, (guint)p); | |||
503 | ||||
504 | return new_path; | |||
505 | } | |||
506 | ||||
507 | ||||
508 | char * | |||
509 | remove_ending_separator (const char *path) | |||
510 | { | |||
511 | gint len, copy_len; | |||
512 | ||||
513 | if (path == NULL((void*)0)) | |||
514 | return NULL((void*)0); | |||
515 | ||||
516 | copy_len = len = strlen (path); | |||
517 | if ((len > 1) && (path[len - 1] == '/')) | |||
518 | copy_len--; | |||
519 | ||||
520 | return g_strndup (path, copy_len); | |||
521 | } | |||
522 | ||||
523 | ||||
524 | char * | |||
525 | build_uri (const char *base, ...) | |||
526 | { | |||
527 | va_list args; | |||
528 | const char *child; | |||
529 | GString *uri; | |||
530 | ||||
531 | uri = g_string_new (base); | |||
532 | ||||
533 | va_start (args, base)__builtin_va_start(args, base); | |||
534 | while ((child = va_arg (args, const char *)__builtin_va_arg(args, const char *)) != NULL((void*)0)) { | |||
535 | if (! g_str_has_suffix (uri->str, "/")(__builtin_constant_p ("/")? __extension__ ({ const char * const __str = (uri->str); const char * const __suffix = ("/"); gboolean __result = (0); if (__str == ((void*)0) || __suffix == ((void *)0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (uri->str, "/") ) && ! g_str_has_prefix (child, "/")(__builtin_constant_p ("/")? __extension__ ({ const char * const __str = (child); const char * const __prefix = ("/"); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void *)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0; } __result; }) : (g_str_has_prefix) (child, "/") )) | |||
536 | g_string_append (uri, "/")(__builtin_constant_p ("/") ? __extension__ ({ const char * const __val = ("/"); g_string_append_len_inline (uri, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val))) : (gssize ) -1); }) : g_string_append_len_inline (uri, "/", (gssize) -1 )); | |||
537 | g_string_append (uri, child)(__builtin_constant_p (child) ? __extension__ ({ const char * const __val = (child); g_string_append_len_inline (uri, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (uri, child , (gssize) -1)); | |||
538 | } | |||
539 | va_end (args)__builtin_va_end(args); | |||
540 | ||||
541 | return g_string_free (uri, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((uri) , ((0))) : g_string_free_and_steal (uri)) : (g_string_free) ( (uri), ((0)))); | |||
542 | } | |||
543 | ||||
544 | ||||
545 | gchar * | |||
546 | remove_extension_from_path (const gchar *path) | |||
547 | { | |||
548 | int len; | |||
549 | int p; | |||
550 | const char *ptr = path; | |||
551 | char *new_path; | |||
552 | ||||
553 | if (! path) | |||
554 | return NULL((void*)0); | |||
555 | ||||
556 | len = strlen (path); | |||
557 | if (len == 1) | |||
558 | return g_strdup (path)g_strdup_inline (path); | |||
559 | ||||
560 | p = len - 1; | |||
561 | while ((p > 0) && (ptr[p] != '.')) | |||
562 | p--; | |||
563 | if (p == 0) | |||
564 | p = len; | |||
565 | new_path = g_strndup (path, (guint) p); | |||
566 | ||||
567 | return new_path; | |||
568 | } | |||
569 | ||||
570 | ||||
571 | gboolean | |||
572 | make_directory_tree (GFile *dir, | |||
573 | mode_t mode, | |||
574 | GError **error) | |||
575 | { | |||
576 | gboolean success = TRUE(!(0)); | |||
577 | GFile *parent; | |||
578 | ||||
579 | if ((dir == NULL((void*)0)) || g_file_query_exists (dir, NULL((void*)0))) | |||
580 | return TRUE(!(0)); | |||
581 | ||||
582 | parent = g_file_get_parent (dir); | |||
583 | if (parent != NULL((void*)0)) { | |||
584 | success = make_directory_tree (parent, mode, error); | |||
585 | g_object_unref (parent); | |||
586 | if (! success) | |||
587 | return FALSE(0); | |||
588 | } | |||
589 | ||||
590 | success = g_file_make_directory (dir, NULL((void*)0), error); | |||
591 | if ((error
| |||
592 | g_clear_error (error); | |||
593 | success = TRUE(!(0)); | |||
594 | } | |||
595 | ||||
596 | if (success) | |||
597 | g_file_set_attribute_uint32 (dir, | |||
598 | G_FILE_ATTRIBUTE_UNIX_MODE"unix::mode", | |||
599 | mode, | |||
600 | 0, | |||
601 | NULL((void*)0), | |||
602 | NULL((void*)0)); | |||
603 | ||||
604 | return success; | |||
605 | } | |||
606 | ||||
607 | ||||
608 | gboolean | |||
609 | ensure_dir_exists (const char *uri, | |||
610 | mode_t mode, | |||
611 | GError **error) | |||
612 | { | |||
613 | GFile *dir; | |||
614 | GError *priv_error = NULL((void*)0); | |||
615 | ||||
616 | if (uri == NULL((void*)0)) | |||
617 | return FALSE(0); | |||
618 | ||||
619 | if (error == NULL((void*)0)) | |||
620 | error = &priv_error; | |||
621 | ||||
622 | dir = g_file_new_for_uri (uri); | |||
623 | if (! make_directory_tree (dir, mode, error)) { | |||
624 | g_warning ("could create directory %s: %s", uri, (*error)->message); | |||
| ||||
625 | if (priv_error != NULL((void*)0)) | |||
626 | g_clear_error (&priv_error); | |||
627 | return FALSE(0); | |||
628 | } | |||
629 | ||||
630 | return TRUE(!(0)); | |||
631 | } | |||
632 | ||||
633 | ||||
634 | gboolean | |||
635 | make_directory_tree_from_path (const char *path, | |||
636 | mode_t mode, | |||
637 | GError **error) | |||
638 | { | |||
639 | char *uri; | |||
640 | gboolean result; | |||
641 | ||||
642 | uri = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
643 | result = ensure_dir_exists (uri, mode, error); | |||
| ||||
644 | g_free (uri); | |||
645 | ||||
646 | return result; | |||
647 | } | |||
648 | ||||
649 | ||||
650 | const char * | |||
651 | get_file_extension (const char *filename) | |||
652 | { | |||
653 | const char *ptr = filename; | |||
654 | int len; | |||
655 | int p; | |||
656 | const char *ext; | |||
657 | ||||
658 | if (filename == NULL((void*)0)) | |||
659 | return NULL((void*)0); | |||
660 | ||||
661 | len = strlen (filename); | |||
662 | if (len <= 1) | |||
663 | return NULL((void*)0); | |||
664 | ||||
665 | p = len - 1; | |||
666 | while ((p >= 0) && (ptr[p] != '.')) | |||
667 | p--; | |||
668 | if (p < 0) | |||
669 | return NULL((void*)0); | |||
670 | ||||
671 | ext = filename + p; | |||
672 | if (ext - 4 > filename) { | |||
673 | const char *test = ext - 4; | |||
674 | if (strncmp (test, ".tar", 4) == 0) | |||
675 | ext = ext - 4; | |||
676 | } | |||
677 | return ext; | |||
678 | } | |||
679 | ||||
680 | ||||
681 | gboolean | |||
682 | file_extension_is (const char *filename, | |||
683 | const char *ext) | |||
684 | { | |||
685 | int filename_l, ext_l; | |||
686 | ||||
687 | filename_l = strlen (filename); | |||
688 | ext_l = strlen (ext); | |||
689 | ||||
690 | if (filename_l < ext_l) | |||
691 | return FALSE(0); | |||
692 | return strcasecmp (filename + filename_l - ext_l, ext) == 0; | |||
693 | } | |||
694 | ||||
695 | ||||
696 | gboolean | |||
697 | is_mime_type (const char *mime_type, | |||
698 | const char *pattern) | |||
699 | { | |||
700 | return (strcasecmp (mime_type, pattern) == 0); | |||
701 | } | |||
702 | ||||
703 | ||||
704 | const char* | |||
705 | get_file_mime_type (const char *uri, | |||
706 | gboolean fast_file_type) | |||
707 | { | |||
708 | GFile *file; | |||
709 | GFileInfo *info; | |||
710 | GError *err = NULL((void*)0); | |||
711 | const char *result = NULL((void*)0); | |||
712 | ||||
713 | file = g_file_new_for_uri (uri); | |||
714 | info = g_file_query_info (file, | |||
715 | fast_file_type ? | |||
716 | G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE"standard::fast-content-type" : | |||
717 | G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE"standard::content-type", | |||
718 | 0, NULL((void*)0), &err); | |||
719 | if (info == NULL((void*)0)) { | |||
720 | g_warning ("could not get content type for %s: %s", uri, err->message); | |||
721 | g_clear_error (&err); | |||
722 | } | |||
723 | else { | |||
724 | result = get_static_string (g_file_info_get_content_type (info)); | |||
725 | g_object_unref (info); | |||
726 | } | |||
727 | ||||
728 | g_object_unref (file); | |||
729 | ||||
730 | return result; | |||
731 | } | |||
732 | ||||
733 | ||||
734 | const char* | |||
735 | get_file_mime_type_for_path (const char *filename, | |||
736 | gboolean fast_file_type) | |||
737 | { | |||
738 | char *uri; | |||
739 | const char *mime_type; | |||
740 | ||||
741 | uri = g_filename_to_uri (filename, NULL((void*)0), NULL((void*)0)); | |||
742 | mime_type = get_file_mime_type (uri, fast_file_type); | |||
743 | g_free (uri); | |||
744 | ||||
745 | return mime_type; | |||
746 | } | |||
747 | ||||
748 | ||||
749 | void | |||
750 | path_list_free (GList *path_list) | |||
751 | { | |||
752 | if (path_list == NULL((void*)0)) | |||
753 | return; | |||
754 | g_list_free_full (path_list, g_free); | |||
755 | } | |||
756 | ||||
757 | ||||
758 | GList * | |||
759 | path_list_dup (GList *path_list) | |||
760 | { | |||
761 | GList *new_list = NULL((void*)0); | |||
762 | GList *scan; | |||
763 | ||||
764 | for (scan = path_list; scan; scan = scan->next) | |||
765 | new_list = g_list_prepend (new_list, g_strdup (scan->data)g_strdup_inline (scan->data)); | |||
766 | ||||
767 | return g_list_reverse (new_list); | |||
768 | } | |||
769 | ||||
770 | ||||
771 | guint64 | |||
772 | get_dest_free_space (const char *path) | |||
773 | { | |||
774 | guint64 freespace = 0; | |||
775 | GFile *file; | |||
776 | GFileInfo *info; | |||
777 | GError *err = NULL((void*)0); | |||
778 | ||||
779 | file = g_file_new_for_path (path); | |||
780 | info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_FREE"filesystem::free", NULL((void*)0), &err); | |||
781 | if (info != NULL((void*)0)) { | |||
782 | freespace = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE"filesystem::free"); | |||
783 | g_object_unref (info); | |||
784 | } | |||
785 | else { | |||
786 | g_warning ("Could not get filesystem free space on volume that contains %s: %s", path, err->message); | |||
787 | g_error_free (err); | |||
788 | } | |||
789 | g_object_unref (file); | |||
790 | ||||
791 | return freespace; | |||
792 | } | |||
793 | ||||
794 | ||||
795 | static gboolean | |||
796 | delete_directory_recursive (GFile *dir, | |||
797 | GError **error) | |||
798 | { | |||
799 | char *uri; | |||
800 | GFileEnumerator *file_enum; | |||
801 | GFileInfo *info; | |||
802 | gboolean error_occurred = FALSE(0); | |||
803 | ||||
804 | if (error != NULL((void*)0)) | |||
805 | *error = NULL((void*)0); | |||
806 | ||||
807 | file_enum = g_file_enumerate_children (dir, | |||
808 | G_FILE_ATTRIBUTE_STANDARD_NAME"standard::name" "," | |||
809 | G_FILE_ATTRIBUTE_STANDARD_TYPE"standard::type", | |||
810 | 0, NULL((void*)0), error); | |||
811 | ||||
812 | uri = g_file_get_uri (dir); | |||
813 | while (! error_occurred && (info = g_file_enumerator_next_file (file_enum, NULL((void*)0), error)) != NULL((void*)0)) { | |||
814 | char *child_uri; | |||
815 | GFile *child; | |||
816 | ||||
817 | child_uri = build_uri (uri, g_file_info_get_name (info), NULL((void*)0)); | |||
818 | child = g_file_new_for_uri (child_uri); | |||
819 | ||||
820 | switch (g_file_info_get_file_type (info)) { | |||
821 | case G_FILE_TYPE_DIRECTORY: | |||
822 | if (! delete_directory_recursive (child, error)) | |||
823 | error_occurred = TRUE(!(0)); | |||
824 | break; | |||
825 | default: | |||
826 | if (! g_file_delete (child, NULL((void*)0), error)) | |||
827 | error_occurred = TRUE(!(0)); | |||
828 | break; | |||
829 | } | |||
830 | ||||
831 | g_object_unref (child); | |||
832 | g_free (child_uri); | |||
833 | g_object_unref (info); | |||
834 | } | |||
835 | g_free (uri); | |||
836 | ||||
837 | if (! error_occurred && ! g_file_delete (dir, NULL((void*)0), error)) | |||
838 | error_occurred = TRUE(!(0)); | |||
839 | ||||
840 | g_object_unref (file_enum); | |||
841 | ||||
842 | return ! error_occurred; | |||
843 | } | |||
844 | ||||
845 | ||||
846 | gboolean | |||
847 | remove_directory (const char *uri) | |||
848 | { | |||
849 | GFile *dir; | |||
850 | gboolean result; | |||
851 | GError *error = NULL((void*)0); | |||
852 | ||||
853 | dir = g_file_new_for_uri (uri); | |||
854 | result = delete_directory_recursive (dir, &error); | |||
855 | if (! result) { | |||
856 | g_warning ("Cannot delete %s: %s", uri, error->message); | |||
857 | g_clear_error (&error); | |||
858 | } | |||
859 | g_object_unref (dir); | |||
860 | ||||
861 | return result; | |||
862 | } | |||
863 | ||||
864 | ||||
865 | gboolean | |||
866 | remove_local_directory (const char *path) | |||
867 | { | |||
868 | char *uri; | |||
869 | gboolean result; | |||
870 | ||||
871 | if (path == NULL((void*)0)) | |||
872 | return TRUE(!(0)); | |||
873 | ||||
874 | uri = g_filename_to_uri (path, NULL((void*)0), NULL((void*)0)); | |||
875 | result = remove_directory (uri); | |||
876 | g_free (uri); | |||
877 | ||||
878 | return result; | |||
879 | } | |||
880 | ||||
881 | ||||
882 | static const char *try_folder[] = { "cache", "~", "tmp", NULL((void*)0) }; | |||
883 | ||||
884 | ||||
885 | static char * | |||
886 | ith_temp_folder_to_try (int n) | |||
887 | { | |||
888 | const char *folder; | |||
889 | ||||
890 | folder = try_folder[n]; | |||
891 | if (strcmp (folder, "cache") == 0) | |||
892 | folder = g_get_user_cache_dir (); | |||
893 | else if (strcmp (folder, "~") == 0) | |||
894 | folder = g_get_home_dir (); | |||
895 | else if (strcmp (folder, "tmp") == 0) | |||
896 | folder = g_get_tmp_dir (); | |||
897 | ||||
898 | return g_strdup (folder)g_strdup_inline (folder); | |||
899 | } | |||
900 | ||||
901 | ||||
902 | char * | |||
903 | get_temp_work_dir (const char *parent_folder) | |||
904 | { | |||
905 | guint64 max_size = 0; | |||
906 | char *best_folder = NULL((void*)0); | |||
907 | char *template; | |||
908 | char *result = NULL((void*)0); | |||
909 | ||||
910 | if (parent_folder == NULL((void*)0)) { | |||
911 | /* find the folder with more free space. */ | |||
912 | ||||
913 | int i; | |||
914 | ||||
915 | for (i = 0; try_folder[i] != NULL((void*)0); i++) { | |||
916 | char *folder; | |||
917 | guint64 size; | |||
918 | ||||
919 | folder = ith_temp_folder_to_try (i); | |||
920 | size = get_dest_free_space (folder); | |||
921 | if (max_size < size) { | |||
922 | max_size = size; | |||
923 | g_free (best_folder); | |||
924 | best_folder = folder; | |||
925 | } | |||
926 | else | |||
927 | g_free (folder); | |||
928 | } | |||
929 | } | |||
930 | else | |||
931 | best_folder = g_strdup (parent_folder)g_strdup_inline (parent_folder); | |||
932 | ||||
933 | if (best_folder == NULL((void*)0)) | |||
934 | return NULL((void*)0); | |||
935 | ||||
936 | template = g_strconcat (best_folder, "/.fr-XXXXXX", NULL((void*)0)); | |||
937 | result = mkdtemp (template); | |||
938 | ||||
939 | if ((result == NULL((void*)0)) || (*result == '\0')) { | |||
940 | g_free (template); | |||
941 | result = NULL((void*)0); | |||
942 | } | |||
943 | ||||
944 | return result; | |||
945 | } | |||
946 | ||||
947 | ||||
948 | gboolean | |||
949 | is_temp_work_dir (const char *dir) | |||
950 | { | |||
951 | int i; | |||
952 | char *folder = NULL((void*)0); | |||
953 | ||||
954 | if (strncmp (dir, "file://", 7) == 0) | |||
955 | dir = dir + 7; | |||
956 | else if (dir[0] != '/') | |||
957 | return FALSE(0); | |||
958 | ||||
959 | for (i = 0; try_folder[i] != NULL((void*)0); i++) { | |||
960 | folder = ith_temp_folder_to_try (i); | |||
961 | if (strncmp (dir, folder, strlen (folder)) == 0) | |||
962 | if (strncmp (dir + strlen (folder), "/.fr-", 5) == 0) { | |||
963 | g_free (folder); | |||
964 | return TRUE(!(0)); | |||
965 | } | |||
966 | g_free (folder); | |||
967 | } | |||
968 | ||||
969 | return FALSE(0); | |||
970 | } | |||
971 | ||||
972 | ||||
973 | gboolean | |||
974 | is_temp_dir (const char *dir) | |||
975 | { | |||
976 | if (strncmp (dir, "file://", 7) == 0) | |||
977 | dir = dir + 7; | |||
978 | if (strcmp (g_get_tmp_dir (), dir) == 0) | |||
979 | return TRUE(!(0)); | |||
980 | if (path_in_path (g_get_tmp_dir (), dir)) | |||
981 | return TRUE(!(0)); | |||
982 | else | |||
983 | return is_temp_work_dir (dir); | |||
984 | } | |||
985 | ||||
986 | ||||
987 | /* file list utils */ | |||
988 | ||||
989 | ||||
990 | gboolean | |||
991 | file_list__match_pattern (const char *line, | |||
992 | const char *pattern) | |||
993 | { | |||
994 | const char *l = line, *p = pattern; | |||
995 | ||||
996 | for (; (*p != 0) && (*l != 0); p++, l++) { | |||
997 | if (*p != '%') { | |||
998 | if (*p != *l) | |||
999 | return FALSE(0); | |||
1000 | } | |||
1001 | else { | |||
1002 | p++; | |||
1003 | switch (*p) { | |||
1004 | case 'a': | |||
1005 | break; | |||
1006 | case 'n': | |||
1007 | if (!isdigit (*l)((*__ctype_b_loc ())[(int) ((*l))] & (unsigned short int) _ISdigit)) | |||
1008 | return FALSE(0); | |||
1009 | break; | |||
1010 | case 'c': | |||
1011 | if (!isalpha (*l)((*__ctype_b_loc ())[(int) ((*l))] & (unsigned short int) _ISalpha)) | |||
1012 | return FALSE(0); | |||
1013 | break; | |||
1014 | default: | |||
1015 | return FALSE(0); | |||
1016 | } | |||
1017 | } | |||
1018 | } | |||
1019 | ||||
1020 | return (*p == 0); | |||
1021 | } | |||
1022 | ||||
1023 | ||||
1024 | int | |||
1025 | file_list__get_index_from_pattern (const char *line, | |||
1026 | const char *pattern) | |||
1027 | { | |||
1028 | int line_l, pattern_l; | |||
1029 | const char *l; | |||
1030 | ||||
1031 | line_l = strlen (line); | |||
1032 | pattern_l = strlen (pattern); | |||
1033 | ||||
1034 | if ((pattern_l == 0) || (line_l == 0)) | |||
1035 | return -1; | |||
1036 | ||||
1037 | for (l = line; *l != 0; l++) | |||
1038 | if (file_list__match_pattern (l, pattern)) | |||
1039 | return (l - line); | |||
1040 | ||||
1041 | return -1; | |||
1042 | } | |||
1043 | ||||
1044 | ||||
1045 | char* | |||
1046 | file_list__get_next_field (const char *line, | |||
1047 | int start_from, | |||
1048 | int field_n) | |||
1049 | { | |||
1050 | const char *f_start, *f_end; | |||
1051 | ||||
1052 | line = line + start_from; | |||
1053 | ||||
1054 | f_start = line; | |||
1055 | while ((*f_start == ' ') && (*f_start != *line)) | |||
1056 | f_start++; | |||
1057 | f_end = f_start; | |||
1058 | ||||
1059 | while ((field_n > 0) && (*f_end != 0)) { | |||
1060 | if (*f_end == ' ') { | |||
1061 | field_n--; | |||
1062 | if (field_n != 0) { | |||
1063 | while ((*f_end == ' ') && (*f_end != *line)) | |||
1064 | f_end++; | |||
1065 | f_start = f_end; | |||
1066 | } | |||
1067 | } else | |||
1068 | f_end++; | |||
1069 | } | |||
1070 | ||||
1071 | return g_strndup (f_start, f_end - f_start); | |||
1072 | } | |||
1073 | ||||
1074 | ||||
1075 | char* | |||
1076 | file_list__get_prev_field (const char *line, | |||
1077 | int start_from, | |||
1078 | int field_n) | |||
1079 | { | |||
1080 | const char *f_start, *f_end; | |||
1081 | ||||
1082 | f_start = line + start_from - 1; | |||
1083 | while ((*f_start == ' ') && (*f_start != *line)) | |||
1084 | f_start--; | |||
1085 | f_end = f_start; | |||
1086 | ||||
1087 | while ((field_n > 0) && (*f_start != *line)) { | |||
1088 | if (*f_start == ' ') { | |||
1089 | field_n--; | |||
1090 | if (field_n != 0) { | |||
1091 | while ((*f_start == ' ') && (*f_start != *line)) | |||
1092 | f_start--; | |||
1093 | f_end = f_start; | |||
1094 | } | |||
1095 | } else | |||
1096 | f_start--; | |||
1097 | } | |||
1098 | ||||
1099 | return g_strndup (f_start + 1, f_end - f_start); | |||
1100 | } | |||
1101 | ||||
1102 | ||||
1103 | gboolean | |||
1104 | check_permissions (const char *uri, | |||
1105 | int mode) | |||
1106 | { | |||
1107 | GFile *file; | |||
1108 | gboolean result; | |||
1109 | ||||
1110 | file = g_file_new_for_uri (uri); | |||
1111 | result = check_file_permissions (file, mode); | |||
1112 | ||||
1113 | g_object_unref (file); | |||
1114 | ||||
1115 | return result; | |||
1116 | } | |||
1117 | ||||
1118 | ||||
1119 | gboolean | |||
1120 | check_file_permissions (GFile *file, | |||
1121 | int mode) | |||
1122 | { | |||
1123 | gboolean result = TRUE(!(0)); | |||
1124 | GFileInfo *info; | |||
1125 | GError *err = NULL((void*)0); | |||
1126 | gboolean default_permission_when_unknown = TRUE(!(0)); | |||
1127 | ||||
1128 | info = g_file_query_info (file, "access::*", 0, NULL((void*)0), &err); | |||
1129 | if (err != NULL((void*)0)) { | |||
1130 | g_clear_error (&err); | |||
1131 | result = FALSE(0); | |||
1132 | } | |||
1133 | else { | |||
1134 | if ((mode & R_OK4) == R_OK4) { | |||
1135 | if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ"access::can-read")) | |||
1136 | result = (result && g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ"access::can-read")); | |||
1137 | else | |||
1138 | result = (result && default_permission_when_unknown); | |||
1139 | } | |||
1140 | ||||
1141 | if ((mode & W_OK2) == W_OK2) { | |||
1142 | if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE"access::can-write")) | |||
1143 | result = (result && g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE"access::can-write")); | |||
1144 | else | |||
1145 | result = (result && default_permission_when_unknown); | |||
1146 | } | |||
1147 | ||||
1148 | if ((mode & X_OK1) == X_OK1) { | |||
1149 | if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE"access::can-execute")) | |||
1150 | result = (result && g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE"access::can-execute")); | |||
1151 | else | |||
1152 | result = (result && default_permission_when_unknown); | |||
1153 | } | |||
1154 | ||||
1155 | g_object_unref (info); | |||
1156 | } | |||
1157 | ||||
1158 | return result; | |||
1159 | } | |||
1160 | ||||
1161 | ||||
1162 | gboolean | |||
1163 | is_program_in_path (const char *filename) | |||
1164 | { | |||
1165 | char *str; | |||
1166 | char *value; | |||
1167 | int result = FALSE(0); | |||
1168 | ||||
1169 | value = g_hash_table_lookup (ProgramsCache, filename); | |||
1170 | if (value != NULL((void*)0)) { | |||
1171 | result = (strcmp (value, "1") == 0); | |||
1172 | return result; | |||
1173 | } | |||
1174 | ||||
1175 | str = g_find_program_in_path (filename); | |||
1176 | if (str != NULL((void*)0)) { | |||
1177 | g_free (str); | |||
1178 | result = TRUE(!(0)); | |||
1179 | } | |||
1180 | ||||
1181 | g_hash_table_insert (ProgramsCache, | |||
1182 | g_strdup (filename)g_strdup_inline (filename), | |||
1183 | result ? "1" : "0"); | |||
1184 | ||||
1185 | return result; | |||
1186 | } | |||
1187 | ||||
1188 | ||||
1189 | gboolean | |||
1190 | is_program_available (const char *filename, | |||
1191 | gboolean check) | |||
1192 | { | |||
1193 | return ! check || is_program_in_path (filename); | |||
1194 | } | |||
1195 | ||||
1196 | ||||
1197 | const char * | |||
1198 | get_home_uri (void) | |||
1199 | { | |||
1200 | static char *home_uri = NULL((void*)0); | |||
1201 | if (home_uri == NULL((void*)0)) | |||
1202 | home_uri = g_filename_to_uri (g_get_home_dir (), NULL((void*)0), NULL((void*)0)); | |||
1203 | return home_uri; | |||
1204 | } | |||
1205 | ||||
1206 | ||||
1207 | char * | |||
1208 | get_home_relative_uri (const char *partial_uri) | |||
1209 | { | |||
1210 | return g_strconcat (get_home_uri (), | |||
1211 | "/", | |||
1212 | partial_uri, | |||
1213 | NULL((void*)0)); | |||
1214 | } | |||
1215 | ||||
1216 | ||||
1217 | GFile * | |||
1218 | get_home_relative_file (const char *partial_uri) | |||
1219 | { | |||
1220 | GFile *file; | |||
1221 | char *uri; | |||
1222 | ||||
1223 | uri = g_strconcat (get_home_uri (), "/", partial_uri, NULL((void*)0)); | |||
1224 | file = g_file_new_for_uri (uri); | |||
1225 | g_free (uri); | |||
1226 | ||||
1227 | return file; | |||
1228 | } | |||
1229 | ||||
1230 | ||||
1231 | GFile * | |||
1232 | get_user_config_subdirectory (const char *child_name, | |||
1233 | gboolean create_child) | |||
1234 | { | |||
1235 | char *full_path; | |||
1236 | GFile *file; | |||
1237 | GError *error = NULL((void*)0); | |||
1238 | ||||
1239 | full_path = g_strconcat (g_get_user_config_dir (), "/", child_name, NULL((void*)0)); | |||
1240 | file = g_file_new_for_path (full_path); | |||
1241 | g_free (full_path); | |||
1242 | ||||
1243 | if (create_child && ! make_directory_tree (file, 0700, &error)) { | |||
1244 | g_warning ("%s", error->message); | |||
1245 | g_error_free (error); | |||
1246 | g_object_unref (file); | |||
1247 | file = NULL((void*)0); | |||
1248 | } | |||
1249 | ||||
1250 | return file; | |||
1251 | } | |||
1252 | ||||
1253 | ||||
1254 | const char * | |||
1255 | remove_host_from_uri (const char *uri) | |||
1256 | { | |||
1257 | const char *idx, *sep; | |||
1258 | ||||
1259 | if (uri == NULL((void*)0)) | |||
1260 | return NULL((void*)0); | |||
1261 | ||||
1262 | idx = strstr (uri, "://"); | |||
1263 | if (idx == NULL((void*)0)) | |||
1264 | return uri; | |||
1265 | idx += 3; | |||
1266 | if (*idx == '\0') | |||
1267 | return "/"; | |||
1268 | sep = strstr (idx, "/"); | |||
1269 | if (sep == NULL((void*)0)) | |||
1270 | return idx; | |||
1271 | return sep; | |||
1272 | } | |||
1273 | ||||
1274 | ||||
1275 | char * | |||
1276 | get_uri_host (const char *uri) | |||
1277 | { | |||
1278 | const char *idx; | |||
1279 | ||||
1280 | idx = strstr (uri, "://"); | |||
1281 | if (idx == NULL((void*)0)) | |||
1282 | return NULL((void*)0); | |||
1283 | idx = strstr (idx + 3, "/"); | |||
1284 | if (idx == NULL((void*)0)) | |||
1285 | return NULL((void*)0); | |||
1286 | return g_strndup (uri, (idx - uri)); | |||
1287 | } | |||
1288 | ||||
1289 | ||||
1290 | char * | |||
1291 | get_uri_root (const char *uri) | |||
1292 | { | |||
1293 | char *host; | |||
1294 | char *root; | |||
1295 | ||||
1296 | host = get_uri_host (uri); | |||
1297 | if (host == NULL((void*)0)) | |||
1298 | return NULL((void*)0); | |||
1299 | root = g_strconcat (host, "/", NULL((void*)0)); | |||
1300 | g_free (host); | |||
1301 | ||||
1302 | return root; | |||
1303 | } | |||
1304 | ||||
1305 | ||||
1306 | int | |||
1307 | uricmp (const char *uri1, | |||
1308 | const char *uri2) | |||
1309 | { | |||
1310 | return strcmp_null_tolerant (uri1, uri2); | |||
1311 | } | |||
1312 | ||||
1313 | ||||
1314 | char * | |||
1315 | get_alternative_uri (const char *folder, | |||
1316 | const char *name) | |||
1317 | { | |||
1318 | char *new_uri = NULL((void*)0); | |||
1319 | int n = 1; | |||
1320 | ||||
1321 | do { | |||
1322 | g_free (new_uri); | |||
1323 | if (n == 1) | |||
1324 | new_uri = g_strconcat (folder, "/", name, NULL((void*)0)); | |||
1325 | else | |||
1326 | new_uri = g_strdup_printf ("%s/%s%%20(%d)", folder, name, n); | |||
1327 | n++; | |||
1328 | } while (uri_exists (new_uri)); | |||
1329 | ||||
1330 | return new_uri; | |||
1331 | } | |||
1332 | ||||
1333 | ||||
1334 | char * | |||
1335 | get_alternative_uri_for_uri (const char *uri) | |||
1336 | { | |||
1337 | char *base_uri; | |||
1338 | char *new_uri; | |||
1339 | ||||
1340 | base_uri = remove_level_from_path (uri); | |||
1341 | new_uri = get_alternative_uri (base_uri, file_name_from_path (uri)); | |||
1342 | g_free (base_uri); | |||
1343 | ||||
1344 | return new_uri; | |||
1345 | } | |||
1346 | ||||
1347 | ||||
1348 | GList * | |||
1349 | gio_file_list_dup (GList *l) | |||
1350 | { | |||
1351 | GList *r = NULL((void*)0), *scan; | |||
1352 | for (scan = l; scan; scan = scan->next) | |||
1353 | r = g_list_prepend (r, g_file_dup ((GFile*)scan->data)); | |||
1354 | return g_list_reverse (r); | |||
1355 | } | |||
1356 | ||||
1357 | ||||
1358 | void | |||
1359 | gio_file_list_free (GList *l) | |||
1360 | { | |||
1361 | GList *scan; | |||
1362 | for (scan = l; scan; scan = scan->next) | |||
1363 | g_object_unref (scan->data); | |||
1364 | g_list_free (l); | |||
1365 | } | |||
1366 | ||||
1367 | ||||
1368 | GList * | |||
1369 | gio_file_list_new_from_uri_list (GList *uris) | |||
1370 | { | |||
1371 | GList *r = NULL((void*)0), *scan; | |||
1372 | for (scan = uris; scan; scan = scan->next) | |||
1373 | r = g_list_prepend (r, g_file_new_for_uri ((char*)scan->data)); | |||
1374 | return g_list_reverse (r); | |||
1375 | } | |||
1376 | ||||
1377 | ||||
1378 | void | |||
1379 | g_key_file_save (GKeyFile *key_file, | |||
1380 | GFile *file) | |||
1381 | { | |||
1382 | char *file_data; | |||
1383 | gsize size; | |||
1384 | GError *error = NULL((void*)0); | |||
1385 | ||||
1386 | file_data = g_key_file_to_data (key_file, &size, &error); | |||
1387 | if (error != NULL((void*)0)) { | |||
1388 | g_warning ("Could not save options: %s\n", error->message); | |||
1389 | g_clear_error (&error); | |||
1390 | } | |||
1391 | else { | |||
1392 | GFileOutputStream *stream; | |||
1393 | ||||
1394 | stream = g_file_replace (file, NULL((void*)0), FALSE(0), 0, NULL((void*)0), &error); | |||
1395 | if (stream == NULL((void*)0)) { | |||
1396 | g_warning ("Could not save options: %s\n", error->message); | |||
1397 | g_clear_error (&error); | |||
1398 | } | |||
1399 | else if (! g_output_stream_write_all (G_OUTPUT_STREAM (stream)((((GOutputStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stream)), ((g_output_stream_get_type ())))))), file_data, size, NULL((void*)0), NULL((void*)0), &error)) { | |||
1400 | g_warning ("Could not save options: %s\n", error->message); | |||
1401 | g_clear_error (&error); | |||
1402 | } | |||
1403 | else if (! g_output_stream_close (G_OUTPUT_STREAM (stream)((((GOutputStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((stream)), ((g_output_stream_get_type ())))))), NULL((void*)0), &error)) { | |||
1404 | g_warning ("Could not save options: %s\n", error->message); | |||
1405 | g_clear_error (&error); | |||
1406 | } | |||
1407 | ||||
1408 | g_object_unref (stream); | |||
1409 | } | |||
1410 | ||||
1411 | g_free (file_data); | |||
1412 | } |