Mercurial > geeqie
annotate src/pan-util.c @ 1808:6c61c246506b
Fix a small issue with strptime
strptime do not initialize all fields. So the undefined fields could end
in crash later on.
author | mow |
---|---|
date | Sun, 28 Feb 2010 15:17:12 +0000 |
parents | 956aab097ea7 |
children |
rev | line source |
---|---|
105 | 1 /* |
196 | 2 * Geeqie |
105 | 3 * (C) 2006 John Ellis |
1802 | 4 * Copyright (C) 2008 - 2010 The Geeqie Team |
105 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
281 | 13 #include "main.h" |
105 | 14 #include "pan-types.h" |
15 | |
16 #include "ui_fileops.h" | |
17 | |
18 | |
19 /* | |
20 *----------------------------------------------------------------------------- | |
21 * date functions | |
22 *----------------------------------------------------------------------------- | |
23 */ | |
24 | |
1434 | 25 gboolean pan_date_compare(time_t a, time_t b, PanDateLengthType length) |
105 | 26 { |
27 struct tm ta; | |
28 struct tm tb; | |
29 | |
30 if (length == PAN_DATE_LENGTH_EXACT) return (a == b); | |
31 | |
32 if (!localtime_r(&a, &ta) || | |
33 !localtime_r(&b, &tb)) return FALSE; | |
34 | |
35 if (ta.tm_year != tb.tm_year) return FALSE; | |
36 if (length == PAN_DATE_LENGTH_YEAR) return TRUE; | |
37 | |
38 if (ta.tm_mon != tb.tm_mon) return FALSE; | |
39 if (length == PAN_DATE_LENGTH_MONTH) return TRUE; | |
40 | |
41 if (length == PAN_DATE_LENGTH_WEEK) return (ta.tm_yday / 7 == tb.tm_yday / 7); | |
42 | |
43 if (ta.tm_mday != tb.tm_mday) return FALSE; | |
44 if (length == PAN_DATE_LENGTH_DAY) return TRUE; | |
45 | |
46 return (ta.tm_hour == tb.tm_hour); | |
47 } | |
48 | |
49 gint pan_date_value(time_t d, PanDateLengthType length) | |
50 { | |
51 struct tm td; | |
52 | |
53 if (!localtime_r(&d, &td)) return -1; | |
54 | |
55 switch (length) | |
56 { | |
57 case PAN_DATE_LENGTH_DAY: | |
58 return td.tm_mday; | |
59 break; | |
60 case PAN_DATE_LENGTH_WEEK: | |
61 return td.tm_wday; | |
62 break; | |
63 case PAN_DATE_LENGTH_MONTH: | |
64 return td.tm_mon + 1; | |
65 break; | |
66 case PAN_DATE_LENGTH_YEAR: | |
67 return td.tm_year + 1900; | |
68 break; | |
69 case PAN_DATE_LENGTH_EXACT: | |
70 default: | |
71 break; | |
72 } | |
73 | |
74 return -1; | |
75 } | |
76 | |
77 gchar *pan_date_value_string(time_t d, PanDateLengthType length) | |
78 { | |
79 struct tm td; | |
80 gchar buf[128]; | |
81 gchar *format = NULL; | |
82 | |
83 if (!localtime_r(&d, &td)) return g_strdup(""); | |
84 | |
85 switch (length) | |
86 { | |
87 case PAN_DATE_LENGTH_DAY: | |
88 return g_strdup_printf("%d", td.tm_mday); | |
89 break; | |
90 case PAN_DATE_LENGTH_WEEK: | |
91 format = "%A %e"; | |
92 break; | |
93 case PAN_DATE_LENGTH_MONTH: | |
94 format = "%B %Y"; | |
95 break; | |
96 case PAN_DATE_LENGTH_YEAR: | |
97 return g_strdup_printf("%d", td.tm_year + 1900); | |
98 break; | |
99 case PAN_DATE_LENGTH_EXACT: | |
100 default: | |
101 return g_strdup(text_from_time(d)); | |
102 break; | |
103 } | |
104 | |
105 | |
106 if (format && strftime(buf, sizeof(buf), format, &td) > 0) | |
107 { | |
108 gchar *ret = g_locale_to_utf8(buf, -1, NULL, NULL, NULL); | |
109 if (ret) return ret; | |
110 } | |
111 | |
112 return g_strdup(""); | |
113 } | |
114 | |
115 time_t pan_date_to_time(gint year, gint month, gint day) | |
116 { | |
117 struct tm lt; | |
118 | |
119 lt.tm_sec = 0; | |
120 lt.tm_min = 0; | |
121 lt.tm_hour = 0; | |
122 lt.tm_mday = (day >= 1 && day <= 31) ? day : 1; | |
123 lt.tm_mon = (month >= 1 && month <= 12) ? month - 1 : 0; | |
124 lt.tm_year = year - 1900; | |
125 lt.tm_isdst = 0; | |
126 | |
127 return mktime(<); | |
128 } | |
129 | |
130 | |
131 /* | |
132 *----------------------------------------------------------------------------- | |
133 * folder validation | |
134 *----------------------------------------------------------------------------- | |
135 */ | |
136 | |
1434 | 137 gboolean pan_is_link_loop(const gchar *s) |
105 | 138 { |
139 gchar *sl; | |
140 struct stat st; | |
1434 | 141 gboolean ret = FALSE; |
105 | 142 |
143 sl = path_from_utf8(s); | |
144 | |
145 if (lstat(sl, &st) == 0 && S_ISLNK(st.st_mode)) | |
146 { | |
147 gchar *buf; | |
148 gint l; | |
149 | |
150 buf = g_malloc(st.st_size + 1); | |
151 l = readlink(sl, buf, st.st_size); | |
152 if (l == st.st_size) | |
153 { | |
154 buf[l] = '\0'; | |
155 | |
156 parse_out_relatives(buf); | |
157 l = strlen(buf); | |
158 | |
159 parse_out_relatives(sl); | |
160 | |
726 | 161 if (buf[0] == G_DIR_SEPARATOR) |
105 | 162 { |
163 if (strncmp(sl, buf, l) == 0 && | |
726 | 164 (sl[l] == '\0' || sl[l] == G_DIR_SEPARATOR || l == 1)) ret = TRUE; |
105 | 165 } |
166 else | |
167 { | |
168 gchar *link_path; | |
169 | |
702
e07895754e65
Drop concat_dir_and_file() and use g_build_filename() instead.
zas_
parents:
475
diff
changeset
|
170 link_path = g_build_filename(sl, buf, NULL); |
105 | 171 parse_out_relatives(link_path); |
172 | |
173 if (strncmp(sl, link_path, l) == 0 && | |
726 | 174 (sl[l] == '\0' || sl[l] == G_DIR_SEPARATOR || l == 1)) ret = TRUE; |
105 | 175 |
176 g_free(link_path); | |
177 } | |
178 } | |
179 | |
180 g_free(buf); | |
181 } | |
182 | |
183 g_free(sl); | |
184 | |
185 return ret; | |
186 } | |
187 | |
1434 | 188 gboolean pan_is_ignored(const gchar *s, gboolean ignore_symlinks) |
105 | 189 { |
190 struct stat st; | |
191 const gchar *n; | |
192 | |
193 if (!lstat_utf8(s, &st)) return TRUE; | |
194 | |
195 #if 0 | |
196 /* normal filesystems have directories with some size or block allocation, | |
197 * special filesystems (like linux /proc) set both to zero. | |
198 * enable this check if you enable listing the root "/" folder | |
199 */ | |
200 if (st.st_size == 0 && st.st_blocks == 0) return TRUE; | |
201 #endif | |
202 | |
203 if (S_ISLNK(st.st_mode) && (ignore_symlinks || pan_is_link_loop(s))) return TRUE; | |
204 | |
205 n = filename_from_path(s); | |
283 | 206 if (n && strcmp(n, GQ_RC_DIR) == 0) return TRUE; |
105 | 207 |
208 return FALSE; | |
209 } | |
210 | |
1434 | 211 GList *pan_list_tree(FileData *dir_fd, SortType sort, gboolean ascend, |
212 gboolean ignore_symlinks) | |
105 | 213 { |
780
44128da39e13
Drop initialization to NULL since filelist_read() will take care of it.
zas_
parents:
726
diff
changeset
|
214 GList *flist; |
44128da39e13
Drop initialization to NULL since filelist_read() will take care of it.
zas_
parents:
726
diff
changeset
|
215 GList *dlist; |
105 | 216 GList *result; |
217 GList *folders; | |
218 | |
783 | 219 filelist_read(dir_fd, &flist, &dlist); |
105 | 220 if (sort != SORT_NONE) |
221 { | |
222 flist = filelist_sort(flist, sort, ascend); | |
223 dlist = filelist_sort(dlist, sort, ascend); | |
224 } | |
225 | |
226 result = flist; | |
227 folders = dlist; | |
228 while (folders) | |
229 { | |
230 FileData *fd; | |
231 | |
232 fd = folders->data; | |
233 folders = g_list_remove(folders, fd); | |
234 | |
235 if (!pan_is_ignored(fd->path, ignore_symlinks) && | |
783 | 236 filelist_read(fd, &flist, &dlist)) |
105 | 237 { |
238 if (sort != SORT_NONE) | |
239 { | |
240 flist = filelist_sort(flist, sort, ascend); | |
241 dlist = filelist_sort(dlist, sort, ascend); | |
242 } | |
243 | |
244 result = g_list_concat(result, flist); | |
245 folders = g_list_concat(dlist, folders); | |
246 } | |
247 | |
138 | 248 file_data_unref(fd); |
105 | 249 } |
250 | |
251 return result; | |
252 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
783
diff
changeset
|
253 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |