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