diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2011-12-14 04:38:30 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2011-12-14 04:38:30 +0000 |
commit | 1648441d6e2cfa2f5f8a7665d5c92bf9744399f9 (patch) | |
tree | ca9260bf6b14e5d37259f715b5c4094b2dec03c9 /apps/plugins | |
parent | 3b00460701f35edd99b8401c4edb2ddbcc8e1a11 (diff) | |
download | rockbox-1648441d6e2cfa2f5f8a7665d5c92bf9744399f9.tar.gz rockbox-1648441d6e2cfa2f5f8a7665d5c92bf9744399f9.zip |
disktidy: simplify
support filenames beginning with '#' by escaping them in config
example: "\##MUSIC#: no"
it is a limitation of settings_parseline to recognize comments
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31238 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/disktidy.c | 528 |
1 files changed, 163 insertions, 365 deletions
diff --git a/apps/plugins/disktidy.c b/apps/plugins/disktidy.c index cedb117304..f3717fd47c 100644 --- a/apps/plugins/disktidy.c +++ b/apps/plugins/disktidy.c | |||
@@ -23,25 +23,18 @@ | |||
23 | 23 | ||
24 | 24 | ||
25 | static int removed = 0; /* number of items removed */ | 25 | static int removed = 0; /* number of items removed */ |
26 | static bool abort; | ||
26 | 27 | ||
27 | /* function return values */ | ||
28 | enum tidy_return | ||
29 | { | ||
30 | TIDY_RETURN_OK = 0, | ||
31 | TIDY_RETURN_ERROR = 1, | ||
32 | TIDY_RETURN_USB = 2, | ||
33 | TIDY_RETURN_ABORT = 3, | ||
34 | }; | ||
35 | |||
36 | #define MAX_TYPES 64 | ||
37 | struct tidy_type { | 28 | struct tidy_type { |
38 | char filestring[64]; | 29 | char filestring[64]; |
39 | int pre; | 30 | int pre; |
40 | int post; | 31 | int post; |
41 | bool directory; | 32 | bool directory; |
42 | bool remove; | 33 | bool remove; |
43 | } tidy_types[MAX_TYPES]; | 34 | } tidy_types[64]; |
44 | int tidy_type_count; | 35 | |
36 | static size_t tidy_type_count; | ||
37 | |||
45 | bool tidy_loaded_and_changed = false; | 38 | bool tidy_loaded_and_changed = false; |
46 | 39 | ||
47 | #define DEFAULT_FILES PLUGIN_APPS_DATA_DIR "/disktidy.config" | 40 | #define DEFAULT_FILES PLUGIN_APPS_DATA_DIR "/disktidy.config" |
@@ -49,8 +42,7 @@ bool tidy_loaded_and_changed = false; | |||
49 | 42 | ||
50 | static void add_item(const char* name, int index) | 43 | static void add_item(const char* name, int index) |
51 | { | 44 | { |
52 | char *a; | 45 | struct tidy_type *entry = &tidy_types[index]; |
53 | struct tidy_type *entry = tidy_types + index; | ||
54 | rb->strcpy(entry->filestring, name); | 46 | rb->strcpy(entry->filestring, name); |
55 | if (name[rb->strlen(name)-1] == '/') | 47 | if (name[rb->strlen(name)-1] == '/') |
56 | { | 48 | { |
@@ -59,7 +51,8 @@ static void add_item(const char* name, int index) | |||
59 | } | 51 | } |
60 | else | 52 | else |
61 | entry->directory = false; | 53 | entry->directory = false; |
62 | a = rb->strchr(entry->filestring, '*'); | 54 | |
55 | char *a = rb->strchr(entry->filestring, '*'); | ||
63 | if (a) | 56 | if (a) |
64 | { | 57 | { |
65 | entry->pre = a - entry->filestring; | 58 | entry->pre = a - entry->filestring; |
@@ -75,7 +68,7 @@ static void add_item(const char* name, int index) | |||
75 | static int find_file_string(const char *file, char *last_group) | 68 | static int find_file_string(const char *file, char *last_group) |
76 | { | 69 | { |
77 | char temp[MAX_PATH]; | 70 | char temp[MAX_PATH]; |
78 | int i = 0, idx_last_group = -1; | 71 | int idx_last_group = -1; |
79 | bool folder = false; | 72 | bool folder = false; |
80 | rb->strcpy(temp, file); | 73 | rb->strcpy(temp, file); |
81 | if (temp[rb->strlen(temp)-1] == '/') | 74 | if (temp[rb->strlen(temp)-1] == '/') |
@@ -83,107 +76,89 @@ static int find_file_string(const char *file, char *last_group) | |||
83 | folder = true; | 76 | folder = true; |
84 | temp[rb->strlen(temp)-1] = '\0'; | 77 | temp[rb->strlen(temp)-1] = '\0'; |
85 | } | 78 | } |
86 | while (i<tidy_type_count) | 79 | |
87 | { | 80 | for (unsigned i = 0; i < tidy_type_count; i++) |
88 | if (!rb->strcmp(tidy_types[i].filestring, temp) && | 81 | if (!rb->strcmp(tidy_types[i].filestring, temp) && folder == tidy_types[i].directory) |
89 | folder == tidy_types[i].directory) | ||
90 | return i; | 82 | return i; |
91 | else if (!rb->strcmp(tidy_types[i].filestring, last_group)) | 83 | else if (!rb->strcmp(tidy_types[i].filestring, last_group)) |
92 | idx_last_group = i; | 84 | idx_last_group = i; |
93 | i++; | 85 | |
94 | } | 86 | if (file[0] == '<' || idx_last_group == -1) |
87 | return tidy_type_count; | ||
88 | |||
89 | |||
95 | /* not found, so insert it into its group */ | 90 | /* not found, so insert it into its group */ |
96 | if (file[0] != '<' && idx_last_group != -1) | 91 | for (unsigned i=idx_last_group; i<tidy_type_count; i++) |
97 | { | 92 | if (tidy_types[i].filestring[0] == '<') |
98 | for (i=idx_last_group; i<tidy_type_count; i++) | ||
99 | { | 93 | { |
100 | if (tidy_types[i].filestring[0] == '<') | 94 | idx_last_group = i; |
101 | { | 95 | break; |
102 | idx_last_group = i; | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | /* shift items up one */ | ||
107 | for (i=tidy_type_count;i>idx_last_group;i--) | ||
108 | { | ||
109 | rb->memcpy(&tidy_types[i], &tidy_types[i-1], sizeof(struct tidy_type)); | ||
110 | } | 96 | } |
111 | tidy_type_count++; | 97 | |
112 | add_item(file, idx_last_group+1); | 98 | /* shift items up one */ |
113 | return idx_last_group+1; | 99 | for (int i=tidy_type_count;i>idx_last_group;i--) |
114 | } | 100 | rb->memcpy(&tidy_types[i], &tidy_types[i-1], sizeof(struct tidy_type)); |
115 | return i; | 101 | |
102 | tidy_type_count++; | ||
103 | add_item(file, idx_last_group+1); | ||
104 | return idx_last_group+1; | ||
116 | } | 105 | } |
117 | 106 | ||
118 | static bool tidy_load_file(const char* file) | 107 | static void tidy_load_file(const char* file) |
119 | { | 108 | { |
120 | int fd = rb->open(file, O_RDONLY), i; | 109 | int fd = rb->open(file, O_RDONLY); |
121 | char buf[MAX_PATH], *str, *remove; | 110 | char buf[MAX_PATH], *str, *remove; |
122 | char last_group[MAX_PATH] = ""; | 111 | char last_group[MAX_PATH] = ""; |
123 | bool new; | ||
124 | if (fd < 0) | 112 | if (fd < 0) |
125 | return false; | 113 | return; |
126 | while ((tidy_type_count < MAX_TYPES) && | 114 | |
127 | rb->read_line(fd, buf, MAX_PATH)) | 115 | while ((tidy_type_count < sizeof(tidy_types) / sizeof(tidy_types[0])) && rb->read_line(fd, buf, MAX_PATH)) |
128 | { | 116 | { |
129 | if (rb->settings_parseline(buf, &str, &remove)) | 117 | if (!rb->settings_parseline(buf, &str, &remove)) |
118 | continue; | ||
119 | |||
120 | if (*str == '\\') /* escape first character ? */ | ||
121 | str++; | ||
122 | unsigned i = find_file_string(str, last_group); | ||
123 | |||
124 | tidy_types[i].remove = rb->strcmp(remove, "yes"); | ||
125 | |||
126 | if (i >= tidy_type_count) | ||
130 | { | 127 | { |
131 | i = find_file_string(str, last_group); | 128 | i = tidy_type_count; |
132 | new = (i >= tidy_type_count); | 129 | add_item(str, i); |
133 | if (!rb->strcmp(remove, "yes")) | 130 | tidy_type_count++; |
134 | tidy_types[i].remove = true; | ||
135 | else tidy_types[i].remove = false; | ||
136 | if (new) | ||
137 | { | ||
138 | i = tidy_type_count; | ||
139 | add_item(str, i); | ||
140 | tidy_type_count++; | ||
141 | } | ||
142 | if (str[0] == '<') | ||
143 | rb->strcpy(last_group, str); | ||
144 | } | 131 | } |
132 | if (str[0] == '<') | ||
133 | rb->strcpy(last_group, str); | ||
145 | } | 134 | } |
146 | rb->close(fd); | 135 | rb->close(fd); |
147 | return true; | ||
148 | } | 136 | } |
149 | 137 | ||
150 | static bool match(struct tidy_type *tidy_type, char *string, int len) | 138 | static bool match(struct tidy_type *tidy_type, const char *string, int len) |
151 | { | 139 | { |
152 | char *pattern = tidy_type->filestring; | 140 | char *pattern = tidy_type->filestring; |
153 | if (tidy_type->pre < 0) | 141 | |
154 | { | 142 | if (tidy_type->pre < 0) /* no '*', just compare. */ |
155 | /* no '*', just compare. */ | 143 | return !rb->strcmp(pattern, string); |
156 | return (rb->strcmp(pattern, string) == 0); | 144 | |
157 | } | ||
158 | /* pattern is too long for the string. avoid 'ab*bc' matching 'abc'. */ | 145 | /* pattern is too long for the string. avoid 'ab*bc' matching 'abc'. */ |
159 | if (len < tidy_type->pre + tidy_type->post) | 146 | if (len < tidy_type->pre + tidy_type->post) |
160 | return false; | 147 | return false; |
148 | |||
161 | /* pattern has '*', compare former part of '*' to the begining of | 149 | /* pattern has '*', compare former part of '*' to the begining of |
162 | the string and compare next part of '*' to the end of string. */ | 150 | the string and compare next part of '*' to the end of string. */ |
163 | return (rb->strncmp(pattern, string, tidy_type->pre) == 0 && | 151 | return !rb->strncmp(pattern, string, tidy_type->pre) && |
164 | rb->strcmp(pattern + tidy_type->pre + 1, | 152 | !rb->strcmp(pattern + tidy_type->pre + 1, string + len - tidy_type->post); |
165 | string + len - tidy_type->post) == 0); | ||
166 | } | 153 | } |
167 | 154 | ||
168 | static bool tidy_remove_item(char *item, int attr) | 155 | static bool tidy_remove_item(const char *item, int attr) |
169 | { | 156 | { |
170 | int i; | 157 | for (struct tidy_type *t = &tidy_types[0]; t < &tidy_types[tidy_type_count]; t++) |
171 | int len; | 158 | if (match(t, item, rb->strlen(item))) |
172 | bool ret = false; | 159 | return t->remove && ((!!(attr&ATTR_DIRECTORY)) == t->directory); |
173 | len = rb->strlen(item); | 160 | |
174 | for (i=0; ret == false && i < tidy_type_count; i++) | 161 | return false; |
175 | { | ||
176 | if (match(&tidy_types[i], item, len)) | ||
177 | { | ||
178 | if (!tidy_types[i].remove) | ||
179 | return false; | ||
180 | if (attr&ATTR_DIRECTORY) | ||
181 | ret = tidy_types[i].directory; | ||
182 | else | ||
183 | ret = !tidy_types[i].directory; | ||
184 | } | ||
185 | } | ||
186 | return ret; | ||
187 | } | 162 | } |
188 | 163 | ||
189 | static void tidy_lcd_status(const char *name) | 164 | static void tidy_lcd_status(const char *name) |
@@ -203,11 +178,11 @@ static int tidy_path_append_entry(char *path, struct dirent *entry, int *path_le | |||
203 | int name_len = rb->strlen(entry->d_name); | 178 | int name_len = rb->strlen(entry->d_name); |
204 | /* for the special case of path="/" this is one bigger but it's not a problem */ | 179 | /* for the special case of path="/" this is one bigger but it's not a problem */ |
205 | int new_length = *path_length + name_len + 1; | 180 | int new_length = *path_length + name_len + 1; |
206 | 181 | ||
207 | /* check overflow (keep space for trailing zero) */ | 182 | /* check overflow (keep space for trailing zero) */ |
208 | if(new_length >= MAX_PATH) | 183 | if(new_length >= MAX_PATH) |
209 | return 0; | 184 | return 0; |
210 | 185 | ||
211 | /* special case for path <> "/" */ | 186 | /* special case for path <> "/" */ |
212 | if(rb->strcmp(path, "/") != 0) | 187 | if(rb->strcmp(path, "/") != 0) |
213 | { | 188 | { |
@@ -216,10 +191,10 @@ static int tidy_path_append_entry(char *path, struct dirent *entry, int *path_le | |||
216 | } | 191 | } |
217 | /* strcat is unsafe but the previous check normally avoid any problem */ | 192 | /* strcat is unsafe but the previous check normally avoid any problem */ |
218 | /* use path_length to optimise */ | 193 | /* use path_length to optimise */ |
219 | 194 | ||
220 | rb->strcat(path + *path_length, entry->d_name); | 195 | rb->strcat(path + *path_length, entry->d_name); |
221 | *path_length += name_len; | 196 | *path_length += name_len; |
222 | 197 | ||
223 | return 1; | 198 | return 1; |
224 | } | 199 | } |
225 | 200 | ||
@@ -229,200 +204,91 @@ static void tidy_path_remove_entry(char *path, int old_path_length, int *path_le | |||
229 | *path_length = old_path_length; | 204 | *path_length = old_path_length; |
230 | } | 205 | } |
231 | 206 | ||
232 | /* Removes the directory specified by 'path'. This includes recursively | 207 | /* path is assumed to be array of size MAX_PATH. */ |
233 | removing all files and directories in that directory. | 208 | static enum plugin_status tidy_clean(char *path, int *path_length, bool rmdir) |
234 | path is assumed to be array of size MAX_PATH. | ||
235 | */ | ||
236 | static enum tidy_return tidy_removedir(char *path, int *path_length) | ||
237 | { | 209 | { |
238 | /* delete directory */ | ||
239 | struct dirent *entry; | ||
240 | enum tidy_return status = TIDY_RETURN_OK; | ||
241 | int button; | ||
242 | DIR *dir; | ||
243 | int old_path_length = *path_length; | 210 | int old_path_length = *path_length; |
244 | 211 | ||
245 | /* display status text */ | ||
246 | tidy_lcd_status(path); | 212 | tidy_lcd_status(path); |
247 | 213 | ||
248 | rb->yield(); | 214 | DIR *dir = rb->opendir(path); |
215 | if (!dir) | ||
216 | return PLUGIN_ERROR; | ||
249 | 217 | ||
250 | dir = rb->opendir(path); | 218 | struct dirent *entry; |
251 | if (dir) | 219 | while ((entry = rb->readdir(dir))) |
252 | { | 220 | { |
253 | while((status == TIDY_RETURN_OK) && ((entry = rb->readdir(dir)) != 0)) | 221 | /* check for user input and usb connect */ |
254 | /* walk directory */ | 222 | int button = rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK); |
223 | if (button == ACTION_STD_CANCEL) | ||
255 | { | 224 | { |
256 | /* check for user input and usb connect */ | 225 | rb->closedir(dir); |
257 | button = rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK); | 226 | abort = true; |
258 | if (button == ACTION_STD_CANCEL) | 227 | return PLUGIN_OK; |
259 | { | 228 | } |
260 | rb->closedir(dir); | 229 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) |
261 | return TIDY_RETURN_ABORT; | 230 | { |
262 | } | 231 | rb->closedir(dir); |
263 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | 232 | return PLUGIN_USB_CONNECTED; |
264 | { | ||
265 | rb->closedir(dir); | ||
266 | return TIDY_RETURN_USB; | ||
267 | } | ||
268 | |||
269 | rb->yield(); | ||
270 | |||
271 | /* get absolute path */ | ||
272 | /* returns an error if path is too long */ | ||
273 | if(!tidy_path_append_entry(path, entry, path_length)) | ||
274 | /* silent error */ | ||
275 | continue; | ||
276 | |||
277 | struct dirinfo info = rb->dir_get_info(dir, entry); | ||
278 | if (info.attribute & ATTR_DIRECTORY) | ||
279 | { | ||
280 | /* dir ignore "." and ".." */ | ||
281 | if ((rb->strcmp(entry->d_name, ".") != 0) && \ | ||
282 | (rb->strcmp(entry->d_name, "..") != 0)) | ||
283 | { | ||
284 | status = tidy_removedir(path, path_length); | ||
285 | } | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | /* file */ | ||
290 | removed++; | ||
291 | rb->remove(path); | ||
292 | } | ||
293 | |||
294 | /* restore path */ | ||
295 | tidy_path_remove_entry(path, old_path_length, path_length); | ||
296 | } | 233 | } |
297 | rb->closedir(dir); | ||
298 | /* rmdir */ | ||
299 | removed++; | ||
300 | rb->rmdir(path); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | status = TIDY_RETURN_ERROR; | ||
305 | } | ||
306 | return status; | ||
307 | } | ||
308 | 234 | ||
309 | /* path is assumed to be array of size MAX_PATH */ | 235 | rb->yield(); |
310 | static enum tidy_return tidy_clean(char *path, int *path_length) | ||
311 | { | ||
312 | /* deletes junk files and dirs left by system */ | ||
313 | struct dirent *entry; | ||
314 | enum tidy_return status = TIDY_RETURN_OK; | ||
315 | int button; | ||
316 | DIR *dir; | ||
317 | int old_path_length = *path_length; | ||
318 | 236 | ||
319 | /* display status text */ | 237 | struct dirinfo info = rb->dir_get_info(dir, entry); |
320 | tidy_lcd_status(path); | 238 | if (!rmdir && !tidy_remove_item(entry->d_name, info.attribute)) |
239 | continue; | ||
321 | 240 | ||
322 | rb->yield(); | 241 | /* get absolute path, returns an error if path is too long */ |
242 | if(!tidy_path_append_entry(path, entry, path_length)) | ||
243 | continue; /* silent error */ | ||
323 | 244 | ||
324 | dir = rb->opendir(path); | 245 | if (info.attribute & ATTR_DIRECTORY) |
325 | if (dir) | 246 | { |
326 | { | 247 | /* dir ignore "." and ".." */ |
327 | while((status == TIDY_RETURN_OK) && ((entry = rb->readdir(dir)) != 0)) | 248 | if (rb->strcmp(entry->d_name, ".") && rb->strcmp(entry->d_name, "..")) |
328 | /* walk directory */ | 249 | tidy_clean(path, path_length, true); |
250 | } | ||
251 | else | ||
329 | { | 252 | { |
330 | struct dirinfo info = rb->dir_get_info(dir, entry); | 253 | removed++; |
331 | /* check for user input and usb connect */ | 254 | rb->remove(path); |
332 | button = rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK); | ||
333 | if (button == ACTION_STD_CANCEL) | ||
334 | { | ||
335 | rb->closedir(dir); | ||
336 | return TIDY_RETURN_ABORT; | ||
337 | } | ||
338 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | ||
339 | { | ||
340 | rb->closedir(dir); | ||
341 | return TIDY_RETURN_USB; | ||
342 | } | ||
343 | |||
344 | rb->yield(); | ||
345 | |||
346 | if (info.attribute & ATTR_DIRECTORY) | ||
347 | { | ||
348 | /* directory ignore "." and ".." */ | ||
349 | if ((rb->strcmp(entry->d_name, ".") != 0) && \ | ||
350 | (rb->strcmp(entry->d_name, "..") != 0)) | ||
351 | { | ||
352 | /* get absolute path */ | ||
353 | /* returns an error if path is too long */ | ||
354 | if(!tidy_path_append_entry(path, entry, path_length)) | ||
355 | /* silent error */ | ||
356 | continue; | ||
357 | |||
358 | if (tidy_remove_item(entry->d_name, info.attribute)) | ||
359 | { | ||
360 | /* delete dir */ | ||
361 | status = tidy_removedir(path, path_length); | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | /* dir not deleted so clean it */ | ||
366 | status = tidy_clean(path, path_length); | ||
367 | } | ||
368 | |||
369 | /* restore path */ | ||
370 | tidy_path_remove_entry(path, old_path_length, path_length); | ||
371 | } | ||
372 | } | ||
373 | else | ||
374 | { | ||
375 | /* file */ | ||
376 | if (tidy_remove_item(entry->d_name, info.attribute)) | ||
377 | { | ||
378 | /* get absolute path */ | ||
379 | /* returns an error if path is too long */ | ||
380 | if(!tidy_path_append_entry(path, entry, path_length)) | ||
381 | /* silent error */ | ||
382 | continue; | ||
383 | |||
384 | removed++; /* increment removed files counter */ | ||
385 | /* delete file */ | ||
386 | if (rb->remove(path) != 0) | ||
387 | DEBUGF("Could not delete file %s\n", path); | ||
388 | |||
389 | /* restore path */ | ||
390 | tidy_path_remove_entry(path, old_path_length, path_length); | ||
391 | } | ||
392 | } | ||
393 | } | 255 | } |
394 | rb->closedir(dir); | 256 | |
395 | return status; | 257 | /* restore path */ |
258 | tidy_path_remove_entry(path, old_path_length, path_length); | ||
396 | } | 259 | } |
397 | else | 260 | rb->closedir(dir); |
261 | |||
262 | if (rmdir) | ||
398 | { | 263 | { |
399 | return TIDY_RETURN_ERROR; | 264 | removed++; |
265 | rb->rmdir(path); | ||
400 | } | 266 | } |
267 | |||
268 | return PLUGIN_OK; | ||
401 | } | 269 | } |
402 | 270 | ||
403 | static enum tidy_return tidy_do(void) | 271 | static enum plugin_status tidy_do(void) |
404 | { | 272 | { |
405 | /* clean disk and display num of items removed */ | 273 | /* clean disk and display num of items removed */ |
406 | enum tidy_return status; | ||
407 | char path[MAX_PATH]; | 274 | char path[MAX_PATH]; |
408 | int path_length; | ||
409 | 275 | ||
410 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 276 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
411 | rb->cpu_boost(true); | 277 | rb->cpu_boost(true); |
412 | #endif | 278 | #endif |
413 | 279 | ||
414 | rb->strcpy(path, "/"); | 280 | rb->strcpy(path, "/"); |
415 | path_length = rb->strlen(path); | 281 | int path_length = rb->strlen(path); |
416 | status = tidy_clean(path, &path_length); | 282 | enum plugin_status status = tidy_clean(path, &path_length, false); |
417 | 283 | ||
418 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 284 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
419 | rb->cpu_boost(false); | 285 | rb->cpu_boost(false); |
420 | #endif | 286 | #endif |
421 | 287 | ||
422 | if ((status == TIDY_RETURN_OK) || (status == TIDY_RETURN_ABORT)) | 288 | if (status == PLUGIN_OK) |
423 | { | 289 | { |
424 | rb->lcd_clear_display(); | 290 | rb->lcd_clear_display(); |
425 | if (status == TIDY_RETURN_ABORT) | 291 | if (abort) |
426 | { | 292 | { |
427 | rb->splash(HZ, "User aborted"); | 293 | rb->splash(HZ, "User aborted"); |
428 | rb->lcd_clear_display(); | 294 | rb->lcd_clear_display(); |
@@ -458,123 +324,80 @@ static const char* get_name(int selected_item, void * data, | |||
458 | 324 | ||
459 | static int list_action_callback(int action, struct gui_synclist *lists) | 325 | static int list_action_callback(int action, struct gui_synclist *lists) |
460 | { | 326 | { |
461 | if (action == ACTION_STD_OK) | 327 | if (action != ACTION_STD_OK) |
328 | return action; | ||
329 | |||
330 | unsigned selection = rb->gui_synclist_get_sel_pos(lists); | ||
331 | if (tidy_types[selection].filestring[0] == '<') | ||
462 | { | 332 | { |
463 | int selection = rb->gui_synclist_get_sel_pos(lists); | 333 | bool all = !rb->strcmp(tidy_types[selection].filestring, "< ALL >"); |
464 | if (tidy_types[selection].filestring[0] == '<') | 334 | bool none= !rb->strcmp(tidy_types[selection].filestring, "< NONE >"); |
335 | |||
336 | if (all || none) | ||
465 | { | 337 | { |
466 | int i; | 338 | for (unsigned i=0; i<tidy_type_count; i++) |
467 | if (!rb->strcmp(tidy_types[selection].filestring, "< ALL >")) | 339 | if (tidy_types[i].filestring[0] != '<') |
468 | { | 340 | tidy_types[i].remove = all; |
469 | for (i=0; i<tidy_type_count; i++) | ||
470 | { | ||
471 | if (tidy_types[i].filestring[0] != '<') | ||
472 | tidy_types[i].remove = true; | ||
473 | } | ||
474 | } | ||
475 | else if (!rb->strcmp(tidy_types[selection].filestring, "< NONE >")) | ||
476 | { | ||
477 | for (i=0; i<tidy_type_count; i++) | ||
478 | { | ||
479 | if (tidy_types[i].filestring[0] != '<') | ||
480 | tidy_types[i].remove = false; | ||
481 | } | ||
482 | } | ||
483 | else /* toggle all untill the next <> */ | ||
484 | { | ||
485 | selection++; | ||
486 | while (selection < tidy_type_count && | ||
487 | tidy_types[selection].filestring[0] != '<') | ||
488 | { | ||
489 | tidy_types[selection].remove = !tidy_types[selection].remove; | ||
490 | selection++; | ||
491 | } | ||
492 | } | ||
493 | } | 341 | } |
494 | else | 342 | else /* toggle all untill the next <> */ |
495 | tidy_types[selection].remove = !tidy_types[selection].remove; | 343 | while (++selection < tidy_type_count && tidy_types[selection].filestring[0] != '<') |
496 | tidy_loaded_and_changed = true; | 344 | tidy_types[selection].remove = !tidy_types[selection].remove; |
497 | return ACTION_REDRAW; | ||
498 | } | 345 | } |
499 | return action; | 346 | else |
347 | tidy_types[selection].remove = !tidy_types[selection].remove; | ||
348 | tidy_loaded_and_changed = true; | ||
349 | return ACTION_REDRAW; | ||
500 | } | 350 | } |
501 | 351 | ||
502 | static enum tidy_return tidy_lcd_menu(void) | 352 | static void tidy_lcd_menu(void) |
503 | { | 353 | { |
504 | int selection = 0; | 354 | int selection = 0; |
505 | enum tidy_return status = TIDY_RETURN_OK; | 355 | struct simplelist_info list; |
506 | bool menu_quit = false; | ||
507 | 356 | ||
508 | MENUITEM_STRINGLIST(menu, "Disktidy Menu", NULL, | 357 | MENUITEM_STRINGLIST(menu, "Disktidy Menu", NULL, "Start Cleaning", |
509 | "Start Cleaning", "Files to Clean", | 358 | "Files to Clean", "Quit"); |
510 | "Quit"); | ||
511 | 359 | ||
512 | while (!menu_quit) | 360 | for(;;) |
513 | { | ||
514 | switch(rb->do_menu(&menu, &selection, NULL, false)) | 361 | switch(rb->do_menu(&menu, &selection, NULL, false)) |
515 | { | 362 | { |
516 | case 0: | 363 | default: |
517 | menu_quit = true; /* start cleaning */ | 364 | abort = true; |
518 | break; | 365 | case 0: |
519 | 366 | return; /* start cleaning */ | |
520 | case 1: | 367 | |
521 | { | 368 | case 1: |
522 | struct simplelist_info list; | 369 | rb->simplelist_info_init(&list, "Files to Clean", tidy_type_count, NULL); |
523 | rb->simplelist_info_init(&list, "Files to Clean", | 370 | list.get_icon = get_icon; |
524 | tidy_type_count, NULL); | 371 | list.get_name = get_name; |
525 | list.get_icon = get_icon; | 372 | list.action_callback = list_action_callback; |
526 | list.get_name = get_name; | 373 | rb->simplelist_show_list(&list); |
527 | list.action_callback = list_action_callback; | ||
528 | rb->simplelist_show_list(&list); | ||
529 | } | ||
530 | break; | 374 | break; |
531 | |||
532 | default: | ||
533 | status = TIDY_RETURN_ABORT; /* exit plugin */ | ||
534 | menu_quit = true; | ||
535 | break; | ||
536 | } | 375 | } |
537 | } | ||
538 | return status; | ||
539 | } | 376 | } |
540 | 377 | ||
541 | /* Creates a file and writes information about what files to | 378 | /* Creates a file and writes information about what files to |
542 | delete and what to keep to it. | 379 | delete and what to keep to it. |
543 | Returns true iff the file was successfully created. | ||
544 | */ | 380 | */ |
545 | static bool save_config(const char *file_name) | 381 | static void save_config(void) |
546 | { | 382 | { |
547 | int fd, i; | 383 | int fd = rb->creat(CUSTOM_FILES, 0666); |
548 | bool result; | 384 | if (fd < 0) |
549 | 385 | return; | |
550 | fd = rb->creat(file_name, 0666); | ||
551 | result = (fd >= 0); | ||
552 | 386 | ||
553 | if (result) | 387 | for (unsigned i=0; i<tidy_type_count; i++) |
554 | { | 388 | rb->fdprintf(fd, "%s%s%s: %s\n", |
555 | for (i=0; i<tidy_type_count; i++) | 389 | tidy_types[i].filestring[0] == '#' ? "\\" : "", |
556 | { | 390 | tidy_types[i].filestring, |
557 | rb->fdprintf(fd, "%s%s: %s\n", tidy_types[i].filestring, | ||
558 | tidy_types[i].directory ? "/" : "", | 391 | tidy_types[i].directory ? "/" : "", |
559 | tidy_types[i].remove ? "yes" : "no"); | 392 | tidy_types[i].remove ? "yes" : "no"); |
560 | } | 393 | rb->close(fd); |
561 | rb->close(fd); | ||
562 | } | ||
563 | else | ||
564 | { | ||
565 | DEBUGF("Could not create file %s\n", file_name); | ||
566 | } | ||
567 | |||
568 | return result; | ||
569 | } | 394 | } |
570 | 395 | ||
571 | /* this is the plugin entry point */ | 396 | /* this is the plugin entry point */ |
572 | enum plugin_status plugin_start(const void* parameter) | 397 | enum plugin_status plugin_start(const void* parameter) |
573 | { | 398 | { |
574 | enum tidy_return status; | ||
575 | (void)parameter; | 399 | (void)parameter; |
576 | 400 | ||
577 | tidy_type_count = 0; | ||
578 | tidy_load_file(DEFAULT_FILES); | 401 | tidy_load_file(DEFAULT_FILES); |
579 | tidy_load_file(CUSTOM_FILES); | 402 | tidy_load_file(CUSTOM_FILES); |
580 | if (tidy_type_count == 0) | 403 | if (tidy_type_count == 0) |
@@ -582,34 +405,9 @@ enum plugin_status plugin_start(const void* parameter) | |||
582 | rb->splash(3*HZ, "Missing disktidy.config file"); | 405 | rb->splash(3*HZ, "Missing disktidy.config file"); |
583 | return PLUGIN_ERROR; | 406 | return PLUGIN_ERROR; |
584 | } | 407 | } |
585 | status = tidy_lcd_menu(); | 408 | tidy_lcd_menu(); |
586 | if (tidy_loaded_and_changed) | 409 | if (tidy_loaded_and_changed) |
587 | { | 410 | save_config(); |
588 | save_config(CUSTOM_FILES); | ||
589 | } | ||
590 | if (status == TIDY_RETURN_ABORT) | ||
591 | return PLUGIN_OK; | ||
592 | while (true) | ||
593 | { | ||
594 | status = tidy_do(); | ||
595 | |||
596 | switch (status) | ||
597 | { | ||
598 | case TIDY_RETURN_OK: | ||
599 | return PLUGIN_OK; | ||
600 | case TIDY_RETURN_ERROR: | ||
601 | return PLUGIN_ERROR; | ||
602 | case TIDY_RETURN_USB: | ||
603 | return PLUGIN_USB_CONNECTED; | ||
604 | case TIDY_RETURN_ABORT: | ||
605 | return PLUGIN_OK; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | if (rb->default_event_handler(rb->button_get(false)) == SYS_USB_CONNECTED) | ||
610 | return PLUGIN_USB_CONNECTED; | ||
611 | 411 | ||
612 | rb->yield(); | 412 | return abort ? PLUGIN_OK : tidy_do(); |
613 | |||
614 | return PLUGIN_OK; | ||
615 | } | 413 | } |