--- orig/apps/plugins/CATEGORIES 2007-10-05 23:20:40.000000000 +0200 +++ dev/apps/plugins/CATEGORIES 2007-10-06 11:15:27.000000000 +0200 @@ -53,6 +53,7 @@ reversi,games robotfindskitten,games rockblox,games +rockbox_upgrade_files,apps rockbox_flash,viewers rockboy,viewers rocklife,games --- orig/apps/plugins/rockbox_upgrade_files.c 1970-01-01 01:00:00.000000000 +0100 +++ dev/apps/plugins/rockbox_upgrade_files.c 2007-10-06 11:15:27.000000000 +0200 @@ -0,0 +1,365 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: rockbox_upgrade_files.c + * + * Copyright (C) 2007 Henrik Backe + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "plugin.h" + +/* + * + * Creates ROCKBOX_USER directory structures and copies + * files from their old places + * + */ + +PLUGIN_HEADER + +/* Globals */ +static struct plugin_api* rb; +size_t bufsize; +char *buf; + +/* prototypes */ +void create_folders(void); +void copy_save_files(void); +void check_copy_dirs(void); +void copy_file(char*,char*); +void copy_dir(char*,char*); + + +struct triple_char { + char* cur_dir; + char* cur_name; + char* old_name; +}; + +struct double_char { + char* new; + char* old; +}; + +struct single_char { + char* name; +}; + +const struct single_char rockbox_user[] = +{ + {ROCKBOX_USER_DATA}, + {ROCKBOX_USER "/cue"}, + {ROCKBOX_USER "/playlists"}, + {WPS_DIR_USER}, +#ifdef HAVE_LCD_COLOR + {THEME_DIR_USER}, +#endif +#if LCD_DEPTH > 1 + {BACKDROP_DIR_USER}, +#endif +#if CONFIG_CODEC == SWCODEC + {EQS_DIR_USER}, +#endif +#if CONFIG_TUNER + {ROCKBOX_USER"/fmpresets"}, +#endif +#if defined(HAVE_LCD_BITMAP) + {FONT_DIR_USER}, + {ICON_DIR_USER}, + {ROCKBOX_USER_GAMES}, + {ROCKBOX_USER_GAMES"/sokoban"}, + {ROCKBOX_USER_GAMES"/sudoku"}, +#endif +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) \ + || defined(IAUDIO_M5) || (CONFIG_KEYPAD == RECORDER_PAD) + {ROCKBOX_USER_GAMES"/rockboy"}, +#endif +#if defined(HAVE_LCD_COLOR) || defined(IRIVER_H100_SERIES) \ + || defined(IAUDIO_M5) + {ROCKBOX_USER_GAMES"/pacman"}, +#endif +#if defined(HAVE_LCD_COLOR) || (LCD_DEPTH == 2) && !defined(ARCHOS_AV300) + {ROCKBOX_USER_GAMES"/doom"}, + {ROCKBOX_USER_GAMES"/doom/addons"}, + {ROCKBOX_USER_GAMES"/doom/demos"}, +#endif +#if CONFIG_CODEC == SWCODEC + {ROCKBOX_USER"/patchset"}, +#endif +#ifdef HAVE_RECORDING + {ROCKBOX_USER"/recpresets"}, +#endif + {NULL}, +}; + +const struct single_char old_dirs[] = +{ + {PLUGIN_GAMES_DIR}, + {VIEWERS_DIR}, + {PLUGIN_APPS_DIR}, + {PLUGIN_DEMOS_DIR}, + {PLUGIN_DIR}, + {ROCKBOX_DIR}, + {ROCKBOX_DIR"/pacman"}, + {"/games"}, + {NULL}, +}; + +const struct double_char dirs[] = +{ + {ROCKBOX_USER_GAMES"/doom", ROCKBOX_DIR"/doom" }, + {ROCKBOX_USER_GAMES"/doom/addons", ROCKBOX_DIR"/doom/addons"}, + {ROCKBOX_USER_GAMES"/doom/demos", ROCKBOX_DIR"/doom/demos" }, + {ROCKBOX_USER_GAMES"/rockboy", ROCKBOX_DIR"/rockboy" }, + {ROCKBOX_USER"/cue", ROCKBOX_DIR"/cue" }, + {ROCKBOX_USER"/fmpresets", ROCKBOX_DIR"/fmpresets" }, + {ROCKBOX_USER"/patchset", ROCKBOX_DIR"/patchset" }, + {ROCKBOX_USER"/playlists", "/playlists" }, + {ROCKBOX_USER"/recpresets", ROCKBOX_DIR"/recpresets" }, + {NULL, NULL }, +}; + +const struct triple_char checklist[] = +{ + {ROCKBOX_USER, "config.cfg", NULL }, + {ROCKBOX_USER, "fixed.cfg", NULL }, + {ROCKBOX_USER, "tagnavi_custom.config", NULL }, + {ROCKBOX_USER_DATA, ".memo", "memo" }, + {ROCKBOX_USER_DATA, "blackjack.save", NULL }, + {ROCKBOX_USER_DATA, "blackjack.score", NULL }, + {ROCKBOX_USER_DATA, "bubbles.save", NULL }, + {ROCKBOX_USER_DATA, "bubbles.score", NULL }, + {ROCKBOX_USER_DATA, "chessbox.log", NULL }, + {ROCKBOX_USER_DATA, "chessbox.pgn", NULL }, + {ROCKBOX_USER_DATA, "chessbox.save", NULL }, + {ROCKBOX_USER_DATA, "chopper.save", "chopper.cfg" }, + {ROCKBOX_USER_DATA, "clock.dat", ".clock_settings" }, + {ROCKBOX_USER_DATA, "database_changelog.txt", NULL }, + {ROCKBOX_USER_DATA, "dict.desc", NULL }, + {ROCKBOX_USER_DATA, "dict.index", NULL }, + {ROCKBOX_USER_DATA, "dice.save", "dice.cfg" }, + {ROCKBOX_USER_DATA, "folder_advance_dir.txt", NULL }, + {ROCKBOX_USER_DATA, "folder_advance_list.dat", NULL }, + {ROCKBOX_USER_DATA, "invadrox.score", "invadrox.high" }, + {ROCKBOX_USER_DATA, "jewels.save", NULL }, + {ROCKBOX_USER_DATA, "jewels.score", NULL }, + {ROCKBOX_USER_DATA, "most-recent.bmark", NULL }, + {ROCKBOX_USER_DATA, "mpegplayer.save", "mpegplayer.cfg" }, + {ROCKBOX_USER_DATA, "oscilloscope.save", "oscilloscope.cfg" }, + {ROCKBOX_USER_DATA, "playlist_catalog.config", NULL }, + {ROCKBOX_USER_DATA, "rockblox.score", NULL }, + {ROCKBOX_USER_DATA, "snake2.score", "snake2.hs" }, + {ROCKBOX_USER_DATA, "spacerocks.score", "astrorocks.hs" }, + {ROCKBOX_USER_DATA, "viewer.bookmarks.dat", "viewer_bookmarks.dat" }, + {ROCKBOX_USER_DATA, "viewer.dat", NULL }, + {ROCKBOX_USER_DATA, "vu_meter.dat", ".vu_meter" }, + {ROCKBOX_USER_DATA, "wormlet.save", "wormlet.cfg" }, + {ROCKBOX_USER_DATA, "zxboxq.z80", NULL }, + {ROCKBOX_USER_GAMES"/sudoku", "sudoku.ss", NULL }, + {ROCKBOX_USER_GAMES"/pacman", "pacbox.save", "pacbox.cfg" }, + {ROCKBOX_USER_GAMES"/sokoban","sokoban.save", NULL }, + {NULL, NULL, NULL }, +}; + +/* this is the plugin entry point */ +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) +{ + (void)parameter; + rb = api; + + create_folders(); + + buf = rb->plugin_get_buffer(&bufsize); + if (buf == NULL || bufsize < 512) + return PLUGIN_ERROR; + bufsize &= ~0x1ff; + + copy_save_files(); + check_copy_dirs(); + + return PLUGIN_OK; +} + +/* create ROCKBOX_USER directory structure */ +void create_folders(void) +{ + DIR *dir; + int i = 0; + + while (rockbox_user[i].name) + { + dir = rb->opendir(rockbox_user[i].name); + if (!dir) + { + rb->mkdir(rockbox_user[i].name); + rb->lcd_clear_display(); + rb->splash(HZ,"%s created",rockbox_user[i].name); + } + rb->closedir(dir); + i++; + } +} + +/* copy old save files to new structure */ +void copy_save_files(void) +{ + char new[MAX_PATH+1]; + char old[MAX_PATH+1]; + char *name; + int i,j,fd; + + i=0; + while (checklist[i].cur_dir) + { + rb->snprintf(new,MAX_PATH,"%s/%s", + checklist[i].cur_dir,checklist[i].cur_name); + fd=rb->open(new, O_RDONLY); + if (fd>=0) + { + rb->close(fd); + i++; + continue; + } + + if (checklist[i].old_name) + name=checklist[i].old_name; + else + name=checklist[i].cur_name; + j=0; + while (old_dirs[j].name) + { + rb->snprintf(old,MAX_PATH,"%s/%s",old_dirs[j].name,name); + fd=rb->open(old, O_RDONLY); + if (fd>=0) + { + rb->close(fd); + copy_file(new,old); + j++; + break; + } + rb->close(fd); + j++; + } + i++; + } +} + +/* check dirs that should be copied to the new structure */ +void check_copy_dirs(void) +{ + int i = 0; + DIR *dir; + + while (dirs[i].new) + { + dir = rb->opendir(dirs[i].old); + if (dir) + { + rb->closedir(dir); + dir = rb->opendir(dirs[i].new); + if (dir) + { + rb->closedir(dir); + copy_dir(dirs[i].new,dirs[i].old); + } + } + rb->closedir(dir); + i++; + } +} + +/* copy a file */ +void copy_file(char* out, char* in) +{ + int fd_in, fd_out; + int size, read, written; + + rb->lcd_clear_display(); + rb->splash(HZ/2,"copy: %s to: %s",in,out); + + fd_in=rb->open(in, O_RDONLY); + if (fd_in <0) + { + rb->close(fd_in); + return; + } + + fd_out=rb->creat(out); + size=rb->filesize(fd_in); + + if (fd_out <0 || size <= 0) + { + rb->close(fd_in); + rb->close(fd_out); + return; + } + + read=0; + while(size > 0) + { + read = rb->read(fd_in, buf, bufsize); + + if (read < 0) + break; + + size=size-read; + + written=0; + while(read > 0) + { + written = rb->write(fd_out, buf, read); + if (written < 0) + break; + read=read-written; + } + if (written < 0) + break; + } + + rb->close(fd_in); + rb->close(fd_out); + + if (size > 0 || read > 0) + rb->remove(out); + + return; +} + +/* copy a directory */ +void copy_dir(char* out, char* in) +{ + DIR *dir; + int fd; + struct dirent* entry; + char new[MAX_PATH+1]; + char old[MAX_PATH+1]; + + dir = rb->opendir(in); + entry=rb->readdir(dir); + while (entry) + { + if (!(entry->attribute & ATTR_DIRECTORY)) + { + rb->snprintf(new,MAX_PATH,"%s/%s",out,entry->d_name); + fd=rb->open(new, O_RDONLY); + if (fd<0) + { + rb->snprintf(old,MAX_PATH,"%s/%s",in,entry->d_name); + copy_file(new,old); + } + rb->close(fd); + } + entry=rb->readdir(dir); + } + rb->closedir(dir); +}