Mercurial > geeqie
annotate src/ui_fileops.c @ 440:3d16af3b133a
rm as external delete command is too dangerous, even for testing
author | nadvornik |
---|---|
date | Sun, 20 Apr 2008 09:53:37 +0000 |
parents | 6802aeeed196 |
children | 4b2d7f9af171 |
rev | line source |
---|---|
9 | 1 /* |
2 * (SLIK) SimpLIstic sKin functions | |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
3 * (C) 2006 John Ellis |
9 | 4 * |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
12 #ifdef HAVE_CONFIG_H | |
13 # include "config.h" | |
14 #endif | |
15 | |
16 #include <pwd.h> | |
17 #include <stdio.h> | |
18 #include <stdlib.h> | |
19 #include <string.h> | |
20 #include <unistd.h> | |
21 #include <sys/param.h> | |
22 #include <dirent.h> | |
23 #include <utime.h> | |
24 | |
25 #include <glib.h> | |
26 #include <gtk/gtk.h> /* for locale warning dialog */ | |
27 | |
281 | 28 #include "main.h" |
9 | 29 #include "ui_fileops.h" |
30 | |
31 #include "ui_utildlg.h" /* for locale warning dialog */ | |
32 | |
33 /* | |
34 *----------------------------------------------------------------------------- | |
35 * generic file information and manipulation routines (public) | |
36 *----------------------------------------------------------------------------- | |
37 */ | |
38 | |
39 | |
40 | |
41 void print_term(const gchar *text_utf8) | |
42 { | |
43 gchar *text_l; | |
44 | |
45 text_l = g_locale_from_utf8(text_utf8, -1, NULL, NULL, NULL); | |
46 printf((text_l) ? text_l : text_utf8); | |
47 g_free(text_l); | |
48 } | |
49 | |
50 static void encoding_dialog(const gchar *path); | |
51 | |
52 static gint encoding_dialog_idle(gpointer data) | |
53 { | |
54 gchar *path = data; | |
55 | |
56 encoding_dialog(path); | |
57 g_free(path); | |
58 | |
59 return FALSE; | |
60 } | |
61 | |
62 static gint encoding_dialog_delay(gpointer data) | |
63 { | |
64 g_idle_add(encoding_dialog_idle, data); | |
65 | |
66 return 0; | |
67 } | |
68 | |
69 static void encoding_dialog(const gchar *path) | |
70 { | |
71 static gint warned_user = FALSE; | |
72 GenericDialog *gd; | |
73 GString *string; | |
74 const gchar *lc; | |
75 const gchar *bf; | |
76 | |
77 /* check that gtk is initialized (loop is level > 0) */ | |
78 if (gtk_main_level() == 0) | |
79 { | |
80 /* gtk not initialized */ | |
81 gtk_init_add(encoding_dialog_delay, g_strdup(path)); | |
82 return; | |
83 } | |
84 | |
85 if (warned_user) return; | |
86 warned_user = TRUE; | |
87 | |
88 lc = getenv("LANG"); | |
89 bf = getenv("G_BROKEN_FILENAMES"); | |
90 warned_user = TRUE; | |
91 | |
92 string = g_string_new(""); | |
93 g_string_append(string, "One or more filenames are not encoded with the preferred locale character set.\n"); | |
94 g_string_append_printf(string, "Operations on, and display of these files with %s may not succeed.\n\n", PACKAGE); | |
95 g_string_append(string, "If your filenames are not encoded in utf-8, try setting\n"); | |
96 g_string_append(string, "the environment variable G_BROKEN_FILENAMES=1\n"); | |
97 g_string_append_printf(string, "It appears G_BROKEN_FILENAMES is %s%s\n\n", | |
98 (bf) ? "set to " : "not set.", (bf) ? bf : ""); | |
99 g_string_append_printf(string, "The locale appears to be set to \"%s\"\n(set by the LANG environment variable)\n", (lc) ? lc : "undefined"); | |
100 if (lc && (strstr(lc, "UTF-8") || strstr(lc, "utf-8"))) | |
101 { | |
102 gchar *name; | |
103 name = g_convert(path, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL); | |
104 string = g_string_append(string, "\nPreferred encoding appears to be UTF-8, however the file:\n"); | |
105 g_string_append_printf(string, "\"%s\"\n%s encoded in valid UTF-8.\n", | |
106 (name) ? name : "[name not displayable]", | |
107 (g_utf8_validate(path, -1, NULL)) ? "is": "is NOT"); | |
108 g_free(name); | |
109 } | |
110 | |
111 gd = generic_dialog_new("Filename encoding locale mismatch", | |
254
9faf34f047b1
Make the wmclass value unique among the code by defining
zas_
parents:
138
diff
changeset
|
112 GQ_WMCLASS, "locale warning", NULL, TRUE, NULL, NULL); |
9 | 113 generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE); |
114 | |
115 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING, | |
116 "Filename encoding locale mismatch", string->str); | |
117 | |
118 gtk_widget_show(gd->dialog); | |
119 | |
120 g_string_free(string, TRUE); | |
121 } | |
122 | |
123 gchar *path_to_utf8(const gchar *path) | |
124 { | |
125 gchar *utf8; | |
126 GError *error = NULL; | |
127 | |
128 if (!path) return NULL; | |
129 | |
130 utf8 = g_filename_to_utf8(path, -1, NULL, NULL, &error); | |
131 if (error) | |
132 { | |
133 printf("Unable to convert filename to UTF-8:\n%s\n%s\n", path, error->message); | |
134 g_error_free(error); | |
135 encoding_dialog(path); | |
136 } | |
137 if (!utf8) | |
138 { | |
139 /* just let it through, but bad things may happen */ | |
140 utf8 = g_strdup(path); | |
141 } | |
142 | |
143 return utf8; | |
144 } | |
145 | |
146 gchar *path_from_utf8(const gchar *utf8) | |
147 { | |
148 gchar *path; | |
149 GError *error = NULL; | |
150 | |
151 if (!utf8) return NULL; | |
152 | |
153 path = g_filename_from_utf8(utf8, -1, NULL, NULL, &error); | |
154 if (error) | |
155 { | |
156 printf("Unable to convert filename to locale from UTF-8:\n%s\n%s\n", utf8, error->message); | |
157 g_error_free(error); | |
158 } | |
159 if (!path) | |
160 { | |
161 /* if invalid UTF-8, text probaby still in original form, so just copy it */ | |
162 path = g_strdup(utf8); | |
163 } | |
164 | |
165 return path; | |
166 } | |
167 | |
168 /* first we try the HOME environment var, if that doesn't work, we try getpwuid(). */ | |
169 const gchar *homedir(void) | |
170 { | |
171 static gchar *home = NULL; | |
172 | |
173 if (!home) | |
174 { | |
175 home = path_to_utf8(getenv("HOME")); | |
176 } | |
177 if (!home) | |
178 { | |
179 struct passwd *pw = getpwuid(getuid()); | |
180 if (pw) home = path_to_utf8(pw->pw_dir); | |
181 } | |
182 | |
183 return home; | |
184 } | |
185 | |
186 gint stat_utf8(const gchar *s, struct stat *st) | |
187 { | |
188 gchar *sl; | |
189 gint ret; | |
190 | |
191 if (!s) return FALSE; | |
192 sl = path_from_utf8(s); | |
193 ret = (stat(sl, st) == 0); | |
194 g_free(sl); | |
195 | |
196 return ret; | |
197 } | |
198 | |
40
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
199 gint lstat_utf8(const gchar *s, struct stat *st) |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
200 { |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
201 gchar *sl; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
202 gint ret; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
203 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
204 if (!s) return FALSE; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
205 sl = path_from_utf8(s); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
206 ret = (lstat(sl, st) == 0); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
207 g_free(sl); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
208 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
209 return ret; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
210 } |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
211 |
9 | 212 gint isname(const gchar *s) |
213 { | |
214 struct stat st; | |
215 | |
216 return stat_utf8(s, &st); | |
217 } | |
218 | |
219 gint isfile(const gchar *s) | |
220 { | |
221 struct stat st; | |
222 | |
223 return (stat_utf8(s, &st) && S_ISREG(st.st_mode)); | |
224 } | |
225 | |
226 gint isdir(const gchar *s) | |
227 { | |
228 struct stat st; | |
229 | |
230 return (stat_utf8(s ,&st) && S_ISDIR(st.st_mode)); | |
231 } | |
232 | |
40
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
233 gint islink(const gchar *s) |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
234 { |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
235 struct stat st; |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
236 |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
237 return (lstat_utf8(s ,&st) && S_ISLNK(st.st_mode)); |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
238 } |
dcc04a6a58bf
Sat Apr 16 12:29:42 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
239 |
9 | 240 gint64 filesize(const gchar *s) |
241 { | |
242 struct stat st; | |
243 | |
244 if (!stat_utf8(s, &st)) return 0; | |
245 return (gint)st.st_size; | |
246 } | |
247 | |
248 time_t filetime(const gchar *s) | |
249 { | |
250 struct stat st; | |
251 | |
252 if (!stat_utf8(s, &st)) return 0; | |
253 return st.st_mtime; | |
254 } | |
255 | |
256 gint filetime_set(const gchar *s, time_t tval) | |
257 { | |
258 gint ret = FALSE; | |
259 | |
260 if (tval > 0) | |
261 { | |
262 struct utimbuf ut; | |
263 gchar *sl; | |
264 | |
265 ut.actime = ut.modtime = tval; | |
266 | |
267 sl = path_from_utf8(s); | |
268 ret = (utime(sl, &ut) == 0); | |
269 g_free(sl); | |
270 } | |
271 | |
272 return ret; | |
273 } | |
274 | |
275 gint access_file(const gchar *s, int mode) | |
276 { | |
277 gchar *sl; | |
278 gint ret; | |
279 | |
280 if (!s) return FALSE; | |
281 | |
282 sl = path_from_utf8(s); | |
283 ret = (access(sl, mode) == 0); | |
284 g_free(sl); | |
285 | |
286 return ret; | |
287 } | |
288 | |
289 gint unlink_file(const gchar *s) | |
290 { | |
291 gchar *sl; | |
292 gint ret; | |
293 | |
294 if (!s) return FALSE; | |
295 | |
296 sl = path_from_utf8(s); | |
297 ret = (unlink(sl) == 0); | |
298 g_free(sl); | |
299 | |
300 return ret; | |
301 } | |
302 | |
303 gint symlink_utf8(const gchar *source, const gchar *target) | |
304 { | |
305 gchar *sl; | |
306 gchar *tl; | |
307 gint ret; | |
308 | |
309 if (!source || !target) return FALSE; | |
310 | |
311 sl = path_from_utf8(source); | |
312 tl = path_from_utf8(target); | |
313 | |
314 ret = (symlink(sl, tl) == 0); | |
315 | |
316 g_free(sl); | |
317 g_free(tl); | |
318 | |
319 return ret; | |
320 } | |
321 | |
322 gint mkdir_utf8(const gchar *s, int mode) | |
323 { | |
324 gchar *sl; | |
325 gint ret; | |
326 | |
327 if (!s) return FALSE; | |
328 | |
329 sl = path_from_utf8(s); | |
330 ret = (mkdir(sl, mode) == 0); | |
331 g_free(sl); | |
332 return ret; | |
333 } | |
334 | |
335 gint rmdir_utf8(const gchar *s) | |
336 { | |
337 gchar *sl; | |
338 gint ret; | |
339 | |
340 if (!s) return FALSE; | |
341 | |
342 sl = path_from_utf8(s); | |
343 ret = (rmdir(sl) == 0); | |
344 g_free(sl); | |
345 | |
346 return ret; | |
347 } | |
348 | |
349 gint copy_file_attributes(const gchar *s, const gchar *t, gint perms, gint mtime) | |
350 { | |
351 struct stat st; | |
352 gchar *sl, *tl; | |
353 gint ret = FALSE; | |
354 | |
355 if (!s || !t) return FALSE; | |
356 | |
357 sl = path_from_utf8(s); | |
358 tl = path_from_utf8(t); | |
359 | |
360 if (stat(sl, &st) == 0) | |
361 { | |
362 struct utimbuf tb; | |
363 | |
364 ret = TRUE; | |
365 | |
366 /* set the dest file attributes to that of source (ignoring errors) */ | |
367 | |
368 if (perms && chown(tl, st.st_uid, st.st_gid) < 0) ret = FALSE; | |
369 if (perms && chmod(tl, st.st_mode) < 0) ret = FALSE; | |
370 | |
371 tb.actime = st.st_atime; | |
372 tb.modtime = st.st_mtime; | |
373 if (mtime && utime(tl, &tb) < 0) ret = FALSE; | |
374 } | |
375 | |
376 g_free(sl); | |
377 g_free(tl); | |
378 | |
379 return ret; | |
380 } | |
381 | |
382 /* paths are in filesystem encoding */ | |
383 static gint hard_linked(const gchar *a, const gchar *b) | |
384 { | |
385 struct stat sta; | |
386 struct stat stb; | |
387 | |
388 if (stat(a, &sta) != 0 || stat(b, &stb) != 0) return FALSE; | |
389 | |
390 return (sta.st_dev == stb.st_dev && | |
391 sta.st_ino == stb.st_ino); | |
392 } | |
393 | |
394 gint copy_file(const gchar *s, const gchar *t) | |
395 { | |
396 FILE *fi = NULL; | |
397 FILE *fo = NULL; | |
398 gchar *sl, *tl; | |
399 gchar buf[4096]; | |
400 gint b; | |
401 | |
402 sl = path_from_utf8(s); | |
403 tl = path_from_utf8(t); | |
404 | |
405 if (hard_linked(sl, tl)) | |
406 { | |
407 g_free(sl); | |
408 g_free(tl); | |
409 return TRUE; | |
410 } | |
411 | |
412 fi = fopen(sl, "rb"); | |
413 if (fi) | |
414 { | |
415 fo = fopen(tl, "wb"); | |
416 if (!fo) | |
417 { | |
418 fclose(fi); | |
419 fi = NULL; | |
420 } | |
421 } | |
422 | |
423 g_free(sl); | |
424 g_free(tl); | |
425 | |
426 if (!fi || !fo) return FALSE; | |
427 | |
435 | 428 while((b = fread(buf, sizeof(char), sizeof(buf), fi)) && b != 0) |
9 | 429 { |
430 if (fwrite(buf, sizeof(char), b, fo) != b) | |
431 { | |
432 fclose(fi); | |
433 fclose(fo); | |
434 return FALSE; | |
435 } | |
436 } | |
437 | |
438 fclose(fi); | |
439 fclose(fo); | |
440 | |
441 copy_file_attributes(s, t, TRUE, TRUE); | |
442 | |
443 return TRUE; | |
444 } | |
445 | |
446 gint move_file(const gchar *s, const gchar *t) | |
447 { | |
448 gchar *sl, *tl; | |
449 gint ret = TRUE; | |
450 | |
451 if (!s || !t) return FALSE; | |
452 | |
453 sl = path_from_utf8(s); | |
454 tl = path_from_utf8(t); | |
455 if (rename(sl, tl) < 0) | |
456 { | |
457 /* this may have failed because moving a file across filesystems | |
458 was attempted, so try copy and delete instead */ | |
459 if (copy_file(s, t)) | |
460 { | |
461 if (unlink(sl) < 0) | |
462 { | |
463 /* err, now we can't delete the source file so return FALSE */ | |
464 ret = FALSE; | |
465 } | |
466 } | |
467 else | |
468 { | |
469 ret = FALSE; | |
470 } | |
471 } | |
472 g_free(sl); | |
473 g_free(tl); | |
474 | |
475 return ret; | |
476 } | |
477 | |
478 gint rename_file(const gchar *s, const gchar *t) | |
479 { | |
480 gchar *sl, *tl; | |
481 gint ret; | |
482 | |
483 if (!s || !t) return FALSE; | |
484 | |
485 sl = path_from_utf8(s); | |
486 tl = path_from_utf8(t); | |
487 ret = (rename(sl, tl) == 0); | |
488 g_free(sl); | |
489 g_free(tl); | |
490 | |
491 return ret; | |
492 } | |
493 | |
494 gchar *get_current_dir(void) | |
495 { | |
496 gchar *pathl; | |
497 gchar *path8; | |
498 | |
499 pathl = g_get_current_dir(); | |
500 path8 = path_to_utf8(pathl); | |
501 g_free(pathl); | |
502 | |
503 return path8; | |
504 } | |
505 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
506 static gint path_list_real(const gchar *path, GList **files, GList **dirs, |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
507 gint follow_links) |
9 | 508 { |
509 DIR *dp; | |
510 struct dirent *dir; | |
511 GList *f_list = NULL; | |
512 GList *d_list = NULL; | |
513 gchar *pathl; | |
514 | |
515 if (!path) return FALSE; | |
516 | |
517 pathl = path_from_utf8(path); | |
518 dp = opendir(pathl); | |
519 if (!dp) | |
520 { | |
521 /* dir not found */ | |
522 g_free(pathl); | |
523 return FALSE; | |
524 } | |
525 | |
526 /* root dir fix */ | |
527 if (pathl[0] == '/' && pathl[1] == '\0') | |
528 { | |
529 g_free(pathl); | |
530 pathl = g_strdup(""); | |
531 } | |
532 | |
533 while ((dir = readdir(dp)) != NULL) | |
534 { | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
535 struct stat st_buf; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
536 gchar *name; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
537 gchar *filepath; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
538 gint result; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
539 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
540 name = dir->d_name; |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
541 filepath = g_strconcat(pathl, "/", name, NULL); |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
542 |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
543 if (follow_links) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
544 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
545 result = stat(filepath, &st_buf); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
546 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
547 else |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
548 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
549 result = lstat(filepath, &st_buf); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
550 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
551 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
552 if (result == 0) |
9 | 553 { |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
554 gchar *path8; |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
555 gchar *name8; |
9 | 556 |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
557 name8 = path_to_utf8(name); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
558 path8 = g_strconcat(path, "/", name8, NULL); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
559 g_free(name8); |
9 | 560 |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
561 if (dirs && S_ISDIR(st_buf.st_mode) && |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
562 !(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ) |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
563 { |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
564 d_list = g_list_prepend(d_list, path8); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
565 path8 = NULL; |
9 | 566 } |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
567 else if (files && |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
568 (S_ISREG(st_buf.st_mode) || (!follow_links && S_ISLNK(st_buf.st_mode))) ) |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
569 { |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
570 f_list = g_list_prepend(f_list, path8); |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
571 path8 = NULL; |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
572 } |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
573 g_free(path8); |
9 | 574 } |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
575 |
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
576 g_free(filepath); |
9 | 577 } |
69
31759d770628
Fri Oct 13 10:27:22 2006 John Ellis <johne@verizon.net>
gqview
parents:
40
diff
changeset
|
578 |
9 | 579 closedir(dp); |
580 | |
581 g_free(pathl); | |
582 | |
583 if (dirs) *dirs = g_list_reverse(d_list); | |
584 if (files) *files = g_list_reverse(f_list); | |
585 | |
586 return TRUE; | |
587 } | |
588 | |
112
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
589 gint path_list(const gchar *path, GList **files, GList **dirs) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
590 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
591 return path_list_real(path, files, dirs, TRUE); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
592 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
593 |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
594 gint path_list_lstat(const gchar *path, GList **files, GList **dirs) |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
595 { |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
596 return path_list_real(path, files, dirs, FALSE); |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
597 } |
b15d4c18168f
Fri Nov 17 19:06:19 2006 John Ellis <johne@verizon.net>
gqview
parents:
69
diff
changeset
|
598 |
9 | 599 void path_list_free(GList *list) |
600 { | |
601 g_list_foreach(list, (GFunc)g_free, NULL); | |
602 g_list_free(list); | |
603 } | |
604 | |
605 GList *path_list_copy(GList *list) | |
606 { | |
607 GList *new_list = NULL; | |
608 GList *work; | |
609 | |
610 work = list; | |
611 while (work) | |
612 { | |
613 gchar *path; | |
614 | |
615 path = work->data; | |
616 work = work->next; | |
617 | |
618 new_list = g_list_prepend(new_list, g_strdup(path)); | |
619 } | |
620 | |
621 return g_list_reverse(new_list); | |
622 } | |
623 | |
624 long checksum_simple(const gchar *path) | |
625 { | |
626 gchar *path8; | |
627 FILE *f; | |
628 long sum = 0; | |
629 gint c; | |
630 | |
631 path8 = path_from_utf8(path); | |
632 f = fopen(path8, "r"); | |
633 g_free(path8); | |
634 if (!f) return -1; | |
635 | |
636 while((c = fgetc(f)) != EOF) | |
637 { | |
638 sum += c; | |
639 } | |
640 | |
641 fclose(f); | |
642 | |
643 return sum; | |
644 } | |
645 | |
646 gchar *unique_filename(const gchar *path, const gchar *ext, const gchar *divider, gint pad) | |
647 { | |
648 gchar *unique; | |
649 gint n = 1; | |
650 | |
651 if (!ext) ext = ""; | |
652 if (!divider) divider = ""; | |
653 | |
654 unique = g_strconcat(path, ext, NULL); | |
655 while (isname(unique)) | |
656 { | |
657 g_free(unique); | |
658 if (pad) | |
659 { | |
660 unique = g_strdup_printf("%s%s%03d%s", path, divider, n, ext); | |
661 } | |
662 else | |
663 { | |
664 unique = g_strdup_printf("%s%s%d%s", path, divider, n, ext); | |
665 } | |
666 n++; | |
667 if (n > 999) | |
668 { | |
669 /* well, we tried */ | |
670 g_free(unique); | |
671 return NULL; | |
672 } | |
673 } | |
674 | |
675 return unique; | |
676 } | |
677 | |
678 gchar *unique_filename_simple(const gchar *path) | |
679 { | |
680 gchar *unique; | |
681 const gchar *name; | |
682 const gchar *ext; | |
683 | |
684 if (!path) return NULL; | |
685 | |
686 name = filename_from_path(path); | |
687 if (!name) return NULL; | |
688 | |
689 ext = extension_from_path(name); | |
690 | |
691 if (!ext) | |
692 { | |
693 unique = unique_filename(path, NULL, "_", TRUE); | |
694 } | |
695 else | |
696 { | |
697 gchar *base; | |
698 | |
699 base = remove_extension_from_path(path); | |
700 unique = unique_filename(base, ext, "_", TRUE); | |
701 g_free(base); | |
702 } | |
703 | |
704 return unique; | |
705 } | |
706 | |
707 const gchar *filename_from_path(const gchar *path) | |
708 { | |
709 const gchar *base; | |
710 | |
711 if (!path) return NULL; | |
712 | |
713 base = strrchr(path, '/'); | |
714 if (base) return base + 1; | |
715 | |
716 return path; | |
717 } | |
718 | |
719 gchar *remove_level_from_path(const gchar *path) | |
720 { | |
721 gchar *new_path; | |
722 const gchar *ptr = path; | |
723 gint p; | |
724 | |
725 if (!path) return NULL; | |
726 | |
727 p = strlen(path) - 1; | |
728 if (p < 0) return NULL; | |
729 while(ptr[p] != '/' && p > 0) p--; | |
730 if (p == 0 && ptr[p] == '/') p++; | |
731 new_path = g_strndup(path, (guint)p); | |
732 return new_path; | |
733 } | |
734 | |
735 gchar *concat_dir_and_file(const gchar *base, const gchar *name) | |
736 { | |
737 if (!base || !name) return NULL; | |
738 | |
739 if (strcmp(base, "/") == 0) return g_strconcat(base, name, NULL); | |
740 | |
741 return g_strconcat(base, "/", name, NULL); | |
742 } | |
743 | |
744 const gchar *extension_from_path(const gchar *path) | |
745 { | |
746 if (!path) return NULL; | |
747 return strrchr(path, '.'); | |
748 } | |
749 | |
750 gint file_extension_match(const gchar *path, const gchar *ext) | |
751 { | |
752 gint p; | |
753 gint e; | |
754 | |
755 if (!path) return FALSE; | |
756 if (!ext) return TRUE; | |
757 | |
758 p = strlen(path); | |
759 e = strlen(ext); | |
760 | |
761 return (p > e && strncasecmp(path + p - e, ext, e) == 0); | |
762 } | |
763 | |
764 gchar *remove_extension_from_path(const gchar *path) | |
765 { | |
766 gchar *new_path; | |
767 const gchar *ptr = path; | |
768 gint p; | |
769 | |
770 if (!path) return NULL; | |
771 if (strlen(path) < 2) return g_strdup(path); | |
772 | |
773 p = strlen(path) - 1; | |
774 while(ptr[p] != '.' && p > 0) p--; | |
775 if (p == 0) p = strlen(path) - 1; | |
776 new_path = g_strndup(path, (guint)p); | |
777 return new_path; | |
778 } | |
779 | |
780 void parse_out_relatives(gchar *path) | |
781 { | |
782 gint s, t; | |
783 | |
784 if (!path) return; | |
785 | |
786 s = t = 0; | |
787 | |
788 while (path[s] != '\0') | |
789 { | |
790 if (path[s] == '/' && path[s+1] == '.' && (path[s+2] == '/' || path[s+2] == '\0') ) | |
791 { | |
792 s += 2; | |
793 } | |
794 else if (path[s] == '/' && path[s+1] == '.' && path[s+2] == '.' && (path[s+3] == '/' || path[s+3] == '\0') ) | |
795 { | |
796 s += 3; | |
797 if (t > 0) t--; | |
798 while (path[t] != '/' && t > 0) t--; | |
799 } | |
800 else | |
801 { | |
802 if (s != t) path[t] = path[s]; | |
803 t++; | |
804 s++; | |
805 } | |
806 } | |
807 if (t == 0 && path[t] == '/') t++; | |
808 if (t > 1 && path[t-1] == '/') t--; | |
809 path[t] = '\0'; | |
810 } | |
811 | |
812 gint file_in_path(const gchar *name) | |
813 { | |
814 gchar *path; | |
815 gchar *namel; | |
816 gint p, l; | |
817 gint ret = FALSE; | |
818 | |
819 if (!name) return FALSE; | |
820 path = g_strdup(getenv("PATH")); | |
821 if (!path) return FALSE; | |
822 namel = path_from_utf8(name); | |
823 | |
824 p = 0; | |
825 l = strlen(path); | |
826 while (p < l && !ret) | |
827 { | |
828 gchar *f; | |
829 gint e = p; | |
830 while (path[e] != ':' && path[e] != '\0') e++; | |
831 path[e] = '\0'; | |
832 e++; | |
833 f = g_strconcat(path + p, "/", namel, NULL); | |
834 if (isfile(f)) ret = TRUE; | |
835 g_free(f); | |
836 p = e; | |
837 } | |
838 g_free(namel); | |
839 g_free(path); | |
840 | |
841 return ret; | |
842 } | |
843 |