std::string fs::get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix) { static const std::string s_dir = [] { const std::string& dir = get_config_dir() + "/data/"; if (!is_dir(dir) && !create_path(dir)) { return get_config_dir(); } return dir; }(); std::vector<u8> buf; buf.reserve(location.size() + 1); // Normalize location for (char c : location) { #ifdef _WIN32 if (c == '/' || c == '\\') #else if (c == '/') #endif { if (buf.empty() || buf.back() != '/') { buf.push_back('/'); } continue; } buf.push_back(c); } // Calculate hash u8 hash[20]; sha1(buf.data(), buf.size(), hash); // Concatenate std::string&& result = fmt::format("%s%s/%016llx%08x-%s/", s_dir, prefix, reinterpret_cast<be_t<u64>&>(hash[0]), reinterpret_cast<be_t<u32>&>(hash[8]), suffix); if (!is_dir(result)) { // Create dir if necessary if (create_path(result)) { // Acknowledge original location file(result + ".location", rewrite).write(buf); } } return result; }
void create_config_file(void) { int status; char *home_path; char config_path[STR_BUFFER_SIZE]; char config_dir[STR_BUFFER_SIZE]; /*check out $HOME in system env.*/ home_path = getenv("HOME"); if (!home_path) { fprintf(stderr, "You have to set the env:$HOME\n"); exit(EXIT_FAILURE); } get_config_path(config_path); get_config_dir(config_dir); /*check out if the config file exsit.*/ if(access(config_path, F_OK) == -1) { /*create dir.*/ status = mkdir(config_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); /*create file.`*/ status = open(config_path, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); } }
static void delete_config( void * priv, int delta ) { char* path = get_config_dir(); struct fio_file file; struct fio_dirent * dirent = FIO_FindFirstEx( path, &file ); if( IS_ERROR(dirent) ) return; do { if (file.mode & ATTR_DIRECTORY) { continue; // is a directory } char fn[0x80]; snprintf(fn, sizeof(fn), "%s%s", path, file.name); FIO_RemoveFile(fn); } while( FIO_FindNextEx( dirent, &file ) == 0); FIO_FindClose(dirent); config_deleted = 1; if (config_autosave) { /* at shutdown, config autosave may re-create the config files we just deleted */ /* => disable this feature in RAM only, until next reboot, without commiting it to card */ config_autosave = 0; } }
//------------------------------------------------------------------------------ static void get_history_file_name(char* buffer, int size) { get_config_dir(buffer, size); if (buffer[0]) { str_cat(buffer, "/.history", size); } }
//------------------------------------------------------------------------------ int set(int argc, char** argv) { int ret; // Check we're running from a Clink session. extern int g_in_clink_context; if (!g_in_clink_context) { puts("ERROR: The 'set' verb must be run from a process with Clink present"); return 1; } // Get the path where Clink's storing its settings. get_config_dir(g_settings_path, sizeof_array(g_settings_path)); str_cat(g_settings_path, "/settings", sizeof_array(g_settings_path)); // Load Clink's settings. g_settings = initialise_clink_settings(); if (g_settings == NULL) { printf("ERROR: Failed to load Clink's settings from '%s'.", g_settings_path); return 1; } // List or set Clink's settings. ret = 0; switch (argc) { case 0: case 1: ret = print_keys(); break; case 2: if (_stricmp(argv[1], "--help") == 0 || _stricmp(argv[1], "-h") == 0) { ret = 1; print_usage(); } else { ret = print_value(argv[1]); } break; default: ret = set_value(argv[1], argv[2]); if (!ret) { settings_save(g_settings, g_settings_path); } break; } settings_shutdown(g_settings); return ret; }
static MENU_UPDATE_FUNC(config_save_update) { if (config_deleted) { MENU_SET_RINFO("Undo"); } MENU_SET_HELP("%s", get_config_dir()); }
static MENU_SELECT_FUNC(config_autosave_toggle) { char autosave_flag_file[0x80]; snprintf(autosave_flag_file, sizeof(autosave_flag_file), "%sAUTOSAVE.NEG", get_config_dir()); config_flag_file_setting_save(autosave_flag_file, !!config_autosave); msleep(50); config_autosave = !config_flag_file_setting_load(autosave_flag_file); }
static MENU_UPDATE_FUNC(delete_config_update) { if (config_deleted) { MENU_SET_RINFO("Restart"); MENU_SET_WARNING(MENU_WARN_NOT_WORKING, "Restart your camera to complete the process."); } MENU_SET_HELP("Only the current preset: %s", get_config_dir()); }
bool FeSettings::mamedb_scraper( FeImporterContext &c ) { #ifndef NO_NET if ( !c.emulator.is_mame() || ( !m_scrape_snaps && !m_scrape_marquees )) return true; // // Build a map for looking up parents // ParentMapType parent_map; build_parent_map( parent_map, c.romlist, false ); const char *MAMEDB = "http://mamedb.com"; std::string emu_name = c.emulator.get_info( FeEmulatorInfo::Name ); std::string base_path = get_config_dir() + FE_SCRAPER_SUBDIR; base_path += emu_name + "/"; FeNetQueue q; int taskc( 0 ); for ( FeRomInfoListType::iterator itr=c.romlist.begin(); itr!=c.romlist.end(); ++itr ) { // ugh, this must be set for has_artwork() to correctly function (*itr).set_info( FeRomInfo::Emulator, emu_name ); // Don't scrape for a clone if its parent has the same name // if ( has_same_name_as_parent( *itr, parent_map ) ) continue; if ( m_scrape_marquees && !has_artwork( *itr, "marquee" ) ) { const char *MARQUEE = "marquee/"; std::string fname = base_path + MARQUEE + (*itr).get_info( FeRomInfo::Romname ); confirm_directory( base_path, MARQUEE ); q.add_file_task( MAMEDB, "marquees/" + (*itr).get_info( FeRomInfo::Romname ) +".png", fname ); taskc++; } if ( m_scrape_snaps && !has_image_artwork( *itr, "snap" ) ) { const char *SNAP = "snap/"; std::string fname = base_path + SNAP + (*itr).get_info( FeRomInfo::Romname ); confirm_directory( base_path, SNAP ); q.add_file_task( MAMEDB, SNAP + (*itr).get_info( FeRomInfo::Romname ) +".png", fname ); taskc++; } } return process_q_simple( q, c, taskc ); #else return true; #endif }
int Snes9xConfig::load_config_file (void) { struct stat file_info; char *pathname; xmlDoc *xml_doc = NULL; xmlNodePtr xml_root = NULL; load_defaults (); pathname = get_config_dir (); if (stat (pathname, &file_info)) { if (mkdir (pathname, 0755)) { fprintf (stderr, _("Couldn't create config directory: %s\n"), pathname); return -1; } } else { chmod (pathname, 0755); } free (pathname); pathname = get_config_file_name (); if (stat (pathname, &file_info)) { save_config_file (); } xml_doc = xmlReadFile (pathname, NULL, 0); if (!xml_doc) { fprintf (stderr, _("Couldn't open config file: %s\n"), pathname); return -2; } free (pathname); xml_root = xmlDocGetRootElement (xml_doc); parse_snes9x (xml_root); xmlFreeDoc (xml_doc); return 0; }
char * get_config_file_name (void) { char *filename; filename = get_config_dir (); filename = (char *) realloc (filename, strlen (filename) + 12); strcat (filename, "/snes9x.xml"); return filename; }
/** * Get absolute path to the specified relative path. This path will typically * point to the to client data directory (which is usually located in the user's * home/appdata directory), but depending on the specified mode, extra actions * may be performed. These ensure that if you're trying to access a file that * does not yet exist in the client data directory, it will be read from the * client installation directory instead (unless it's being appended to, in * which case it will be copied to the client data directory first). * * Generally, you should almost always use this when you need to construct a * path, or use one of the many @ref file_wrapper_functions. * @param fname * The file path. * @param mode * File mode. * @return * The absolute path. Must be freed. */ char *file_path(const char *path, const char *mode) { bool is_write, is_append; StringBuffer *sb; char version[MAX_BUF], client_path[HUGE_BUF], *new_path; HARD_ASSERT(path != NULL); HARD_ASSERT(mode != NULL); SOFT_ASSERT_RC(path[0] != '/', estrdup(path), "Path is already absolute: %s", path); sb = stringbuffer_new(); stringbuffer_append_printf(sb, "%s/.atrinik/%s/%s", get_config_dir(), package_get_version_partial(VS(version)), path); new_path = stringbuffer_sub(sb, 0, 0); is_write = is_append = false; if (strchr(mode, 'w') != NULL) { is_write = true; } else if (strchr(mode, '+') != NULL || strchr(mode, 'a') != NULL) { is_append = true; } if (is_write || is_append) { if (access(new_path, W_OK) != 0) { char *dirname; /* Ensure directories exist if we're going to use this path for * writing/appending. */ dirname = path_dirname(new_path); mkdir_recurse(dirname); efree(dirname); if (is_append) { get_data_dir_file(VS(client_path), path); copy_file(client_path, new_path); } } } else { if (access(new_path, R_OK) != 0) { get_data_dir_file(VS(client_path), path); stringbuffer_seek(sb, 0); stringbuffer_append_string(sb, client_path); } } efree(new_path); return stringbuffer_finish(sb); }
int config_parse_file(const char *filename) { char autosave_flag_file[0x80]; snprintf(autosave_flag_file, sizeof(autosave_flag_file), "%sAUTOSAVE.NEG", get_config_dir()); config_autosave = !config_flag_file_setting_load(autosave_flag_file); config_file_buf = (void*)read_entire_file(filename, &config_file_size); config_file_pos = 0; config_parse(); fio_free(config_file_buf); config_file_buf = 0; return 1; }
// this can be called from more tasks (gui, prop handler, menu), so it needs to be thread safe void config_save() { #ifdef CONFIG_CONFIG_FILE take_semaphore(config_save_sem, 0); update_disp_mode_bits_from_params(); char config_file[0x80]; snprintf(config_file, sizeof(config_file), "%smagic.cfg", get_config_dir()); config_save_file(config_file); config_menu_save_flags(); module_save_configs(); if (config_deleted) config_autosave = 1; /* this can be improved, because it's not doing a proper "undo" */ config_deleted = 0; give_semaphore(config_save_sem); #endif }
bool FeSettings::build_romlist( const std::string &emu_name, UiUpdate uiu, void *uid, int &size ) { FeEmulatorInfo *emu = m_rl.get_emulator( emu_name ); if ( emu == NULL ) return false; // // Put up the "building romlist" message at 0 percent while we get going... // if ( uiu ) uiu( uid, 0 ); std::cout << "*** Generating Collection/Rom List" << std::endl; FeRomInfoListType romlist; FeImporterContext ctx( *emu, romlist ); ctx.uiupdate = uiu; ctx.uiupdatedata = uid; build_basic_romlist( ctx ); apply_xml_import( ctx ); apply_import_extras( ctx ); apply_emulator_name( emu_name, romlist ); romlist.sort( FeRomListSorter() ); // strip duplicate entries std::cout << " - Removing any duplicate entries..." << std::endl; romlist.unique(); size = romlist.size(); std::string filename = get_config_dir(); confirm_directory( filename, FE_ROMLIST_SUBDIR ); if ( uiu ) uiu( uid, 100 ); filename += FE_ROMLIST_SUBDIR; filename += emu_name; filename += FE_ROMLIST_FILE_EXTENSION; write_romlist( filename, romlist ); return true; }
/* called at startup, after init_func's */ void config_load() { #ifdef CONFIG_CONFIG_FILE config_selected = 1; config_preset_name = config_choose_startup_preset(); if (config_preset_name) { NotifyBox(2000, "Config: %s", config_preset_name); if (!DISPLAY_IS_ON) beep(); } char config_file[0x80]; snprintf(config_file, sizeof(config_file), "%smagic.cfg", get_config_dir()); config_parse_file(config_file); #endif config_ok = 1; }
//------------------------------------------------------------------------------ void prepare_env_for_inputrc() { // Give readline a chance to find the inputrc by modifying the // environment slightly. char buffer[1024]; void* env_handle; env_block_t env_block; capture_env(&env_block); // HOME is where Readline will expand ~ to. { static const char home_eq[] = "HOME="; int size = sizeof_array(home_eq); strcpy(buffer, home_eq); get_config_dir(buffer + size - 1, sizeof_array(buffer) - size); putenv(buffer); } // INPUTRC is the path where looks for it's configuration file. { static const char inputrc_eq[] = "INPUTRC="; int size = sizeof_array(inputrc_eq); strcpy(buffer, inputrc_eq); get_dll_dir(buffer + size - 1, sizeof_array(buffer) - size); str_cat(buffer, "/clink_inputrc_base", sizeof_array(buffer)); putenv(buffer); } apply_env(&env_block); free_env(&env_block); }
/** @copydoc widgetdata::draw_func */ static void widget_draw(widgetdata *widget) { SDL_Rect box; char buf[HUGE_BUF]; size_t i; /* The list doesn't exist yet, create it. */ if (!list_mplayer) { char version[MAX_BUF]; /* Create the list and set up settings. */ list_mplayer = list_create(12, 1, 8); list_mplayer->handle_enter_func = list_handle_enter; list_mplayer->text_color_hook = list_text_color_hook; list_mplayer->surface = widget->surface; list_scrollbar_enable(list_mplayer); list_set_column(list_mplayer, 0, 130, 7, NULL, -1); list_set_font(list_mplayer, FONT_ARIAL10); /* Add default media directory songs. */ get_data_dir_file(buf, sizeof(buf), DIRECTORY_MEDIA); mplayer_list_init(list_mplayer, buf, 0); /* Now add custom ones, but ignore duplicates. */ snprintf(buf, sizeof(buf), "%s/.atrinik/%s/"DIRECTORY_MEDIA, get_config_dir(), package_get_version_partial(version, sizeof(version))); mplayer_list_init(list_mplayer, buf, 1); /* If we added any, sort the list alphabetically and add an entry * to disable background music. */ if (list_mplayer->rows) { FILE *fp; /* Allocate the blacklist. + 1 is for the last entry added * further down. It is not actually used by the blacklist as * it's not possible to toggle it on/off using the button, but * it simplifies other logic checks. */ shuffle_blacklist = ecalloc(1, sizeof(*shuffle_blacklist) * (list_mplayer->rows + 1)); /* Sort the list. */ list_sort(list_mplayer, LIST_SORT_ALPHA); /* Read the blacklist file contents. */ fp = path_fopen(FILE_MPLAYER_BLACKLIST, "r"); if (fp) { size_t row; while (fgets(buf, sizeof(buf) - 1, fp)) { for (row = 0; row < list_mplayer->rows; row++) { if (!strncmp(buf, list_mplayer->text[row][0], strlen(buf) - 1)) { shuffle_blacklist[row] = 1; break; } } } fclose(fp); } list_add(list_mplayer, list_mplayer->rows, 0, "Disable music"); } scrollbar_create(&scrollbar_progress, 130, 11, &scrollbar_progress_info.scroll_offset, &scrollbar_progress_info.num_lines, 1); scrollbar_progress.redraw = &scrollbar_progress_info.redraw; } if (widget->redraw) { const char *bg_music; box.h = 0; box.w = widget->w; text_show(widget->surface, FONT_SERIF12, "Music Player", 0, 3, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); list_set_parent(list_mplayer, widget->x, widget->y); list_show(list_mplayer, 10, 2); box.w /= 2; text_show(widget->surface, FONT_SANS10, "Currently playing:", widget->w / 2, 22, COLOR_WHITE, TEXT_ALIGN_CENTER, &box); bg_music = sound_get_bg_music_basename(); box.h = 0; box.w = widget->w / 2; /* Store the background music file name in temporary buffer and * make sure it won't overflow by truncating it if necessary. */ if (bg_music) { strncpy(buf, bg_music, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; text_truncate_overflow(FONT_SANS11, buf, 150); } /* Show the music that is being played. */ text_show(widget->surface, FONT_SANS11, bg_music ? buf : "No music", widget->w / 2 - 5, 34, COLOR_HGOLD, TEXT_ALIGN_CENTER, &box); scrollbar_progress.px = widget->x; scrollbar_progress.py = widget->y; scrollbar_show(&scrollbar_progress, widget->surface, 170, 50); box.h = 120; box.w -= 6 * 2; text_show(widget->surface, FONT_ARIAL10, "You can use the music player to play your favorite tunes from the game, or play them all one-by-one in random order (shuffle).\n\nNote that if you use the music player, in-game areas won't change your music until you click [b]Stop[/b].", widget->w / 2 + 6, 62, COLOR_WHITE, TEXT_WORD_WRAP | TEXT_MARKUP, &box); for (i = 0; i < BUTTON_NUM; i++) { buttons[i].surface = widget->surface; button_set_parent(&buttons[i], widget->x, widget->y); } buttons[BUTTON_PLAY].x = 10; buttons[BUTTON_PLAY].y = widget->h - TEXTURE_CLIENT("button")->h - 4; button_show(&buttons[BUTTON_PLAY], sound_map_background(-1) ? "Stop" : "Play"); buttons[BUTTON_SHUFFLE].x = 10 + TEXTURE_CLIENT("button")->w + 5; buttons[BUTTON_SHUFFLE].y = widget->h - TEXTURE_CLIENT("button")->h - 4; buttons[BUTTON_SHUFFLE].pressed_forced = shuffle; button_show(&buttons[BUTTON_SHUFFLE], "Shuffle"); buttons[BUTTON_BLACKLIST].x = 10 + TEXTURE_CLIENT("button")->w * 2 + 5 * 2; buttons[BUTTON_BLACKLIST].y = widget->h - TEXTURE_CLIENT("button_round")->h - 5; buttons[BUTTON_BLACKLIST].disabled = list_mplayer->row_selected == list_mplayer->rows; button_show(&buttons[BUTTON_BLACKLIST], mplayer_blacklisted(list_mplayer) ? "+" : "-"); /* Show close button. */ buttons[BUTTON_CLOSE].x = widget->w - TEXTURE_CLIENT("button_round")->w - 4; buttons[BUTTON_CLOSE].y = 4; button_show(&buttons[BUTTON_CLOSE], "X"); /* Show help button. */ buttons[BUTTON_HELP].x = widget->w - TEXTURE_CLIENT("button_round")->w * 2 - 4; buttons[BUTTON_HELP].y = 4; button_show(&buttons[BUTTON_HELP], "?"); } }
/** * Analyze /cmd type commands the player has typed in the console or bound to a * key. * Sort out the "client intern" commands and expand or pre process them for the * server. * @param cmd * Command to check * @return * 0 to send command to server, 1 to not send it */ int client_command_check(const char *cmd) { if (cmd_aliases_handle(cmd)) { return 1; } else if (strncasecmp(cmd, "/ready_spell", 12) == 0) { cmd = strchr(cmd, ' '); if (!cmd || *++cmd == '\0') { draw_info(COLOR_RED, "Usage: /ready_spell <spell name>"); return 1; } else { object *tmp; for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) { if (tmp->itype == TYPE_SPELL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) { if (!(tmp->flags & CS_FLAG_APPLIED)) { client_send_apply(tmp); } return 1; } } } draw_info(COLOR_RED, "Unknown spell."); return 1; } else if (strncasecmp(cmd, "/ready_skill", 12) == 0) { cmd = strchr(cmd, ' '); if (!cmd || *++cmd == '\0') { draw_info(COLOR_RED, "Usage: /ready_skill <skill name>"); return 1; } else { object *tmp; for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) { if (tmp->itype == TYPE_SKILL && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) { if (!(tmp->flags & CS_FLAG_APPLIED)) { client_send_apply(tmp); } return 1; } } } draw_info(COLOR_RED, "Unknown skill."); return 1; } else if (!strncmp(cmd, "/help", 5)) { cmd += 5; if (*cmd == '\0') { help_show("main"); } else { help_show(cmd + 1); } return 1; } else if (!strncmp(cmd, "/resetwidgets", 13)) { widgets_reset(); return 1; } else if (!strncmp(cmd, "/effect ", 8)) { if (!strcmp(cmd + 8, "none")) { effect_stop(); draw_info(COLOR_GREEN, "Stopped effect."); return 1; } if (effect_start(cmd + 8)) { draw_info_format(COLOR_GREEN, "Started effect %s.", cmd + 8); } else { draw_info_format(COLOR_RED, "No such effect %s.", cmd + 8); } return 1; } else if (!strncmp(cmd, "/d_effect ", 10)) { effect_debug(cmd + 10); return 1; } else if (!strncmp(cmd, "/music_pause", 12)) { sound_pause_music(); return 1; } else if (!strncmp(cmd, "/music_resume", 13)) { sound_resume_music(); return 1; } else if (!strncmp(cmd, "/party joinpassword ", 20)) { cmd += 20; if (cpl.partyjoin[0] != '\0') { char buf[MAX_BUF]; snprintf(VS(buf), "/party join %s\t%s", cpl.partyjoin, cmd); send_command(buf); } return 1; } else if (!strncmp(cmd, "/invfilter ", 11)) { inventory_filter_set_names(cmd + 11); return 1; } else if (!strncasecmp(cmd, "/screenshot", 11)) { SDL_Surface *surface_save; cmd += 11; if (!strncasecmp(cmd, " map", 4)) { surface_save = cur_widget[MAP_ID]->surface; } else { surface_save = ScreenSurface; } if (!surface_save) { draw_info(COLOR_RED, "No surface to save."); return 1; } screenshot_create(surface_save); return 1; } else if (!strncasecmp(cmd, "/console-load ", 14)) { FILE *fp; char path[HUGE_BUF], buf[HUGE_BUF * 4], *cp; StringBuffer *sb; cmd += 14; snprintf(path, sizeof(path), "%s/.atrinik/console/%s", get_config_dir(), cmd); fp = fopen(path, "r"); if (!fp) { draw_info_format(COLOR_RED, "Could not read %s.", path); return 1; } send_command("/console noinf::"); while (fgets(buf, sizeof(buf) - 1, fp)) { cp = strchr(buf, '\n'); if (cp) { *cp = '\0'; } sb = stringbuffer_new(); stringbuffer_append_string(sb, "/console noinf::"); stringbuffer_append_string(sb, buf); cp = stringbuffer_finish(sb); send_command(cp); efree(cp); } send_command("/console noinf::"); fclose(fp); return 1; } else if (strncasecmp(cmd, "/console-obj", 11) == 0) { menu_inventory_loadtoconsole(cpl.inventory_focus, NULL, NULL); return 1; } else if (strncasecmp(cmd, "/patch-obj", 11) == 0) { menu_inventory_patch(cpl.inventory_focus, NULL, NULL); return 1; } else if (string_startswith(cmd, "/cast ") || string_startswith(cmd, "/use_skill ")) { object *tmp; uint8_t type; type = string_startswith(cmd, "/cast ") ? TYPE_SPELL : TYPE_SKILL; cmd = strchr(cmd, ' ') + 1; if (string_isempty(cmd)) { return 1; } for (tmp = cpl.ob->inv; tmp; tmp = tmp->next) { if (tmp->itype == type && strncasecmp(tmp->s_name, cmd, strlen(cmd)) == 0) { client_send_fire(5, tmp->tag); return 1; } } draw_info_format(COLOR_RED, "Unknown %s.", type == TYPE_SPELL ? "spell" : "skill"); return 1; } else if (strncasecmp(cmd, "/clearcache", 11) == 0) { cmd += 12; if (string_isempty(cmd)) { return 1; } if (strcasecmp(cmd, "sound") == 0) { sound_clear_cache(); draw_info(COLOR_GREEN, "Sound cache cleared."); } else if (strcasecmp(cmd, "textures") == 0) { texture_reload(); draw_info(COLOR_GREEN, "Textures reloaded."); } return 1; } else if (string_startswith(cmd, "/droptag ") || string_startswith(cmd, "/gettag ")) { char *cps[3]; unsigned long int loc, tag, num; if (string_split(strchr(cmd, ' ') + 1, cps, arraysize(cps), ' ') != arraysize(cps)) { return 1; } loc = strtoul(cps[0], NULL, 10); tag = strtoul(cps[1], NULL, 10); num = strtoul(cps[2], NULL, 10); client_send_move(loc, tag, num); if (string_startswith(cmd, "/gettag ")) { sound_play_effect("get.ogg", 100); } else { sound_play_effect("drop.ogg", 100); } return 1; } else if (string_startswith(cmd, "/talk")) { char type[MAX_BUF], npc_name[MAX_BUF]; size_t pos; uint8_t type_num; packet_struct *packet; pos = 5; if (!string_get_word(cmd, &pos, ' ', type, sizeof(type), 0) || string_isempty(cmd + pos)) { return 1; } type_num = atoi(type); if (type_num == CMD_TALK_NPC_NAME && (!string_get_word(cmd, &pos, ' ', npc_name, sizeof(npc_name), '"') || string_isempty(cmd + pos))) { return 1; } packet = packet_new(SERVER_CMD_TALK, 64, 64); packet_append_uint8(packet, type_num); if (type_num == CMD_TALK_NPC || type_num == CMD_TALK_NPC_NAME) { if (type_num == CMD_TALK_NPC_NAME) { packet_append_string_terminated(packet, npc_name); } packet_append_string_terminated(packet, cmd + pos); } else { char tag[MAX_BUF]; if (!string_get_word(cmd, &pos, ' ', tag, sizeof(tag), 0) || string_isempty(cmd + pos)) { packet_free(packet); return 1; } packet_append_uint32(packet, atoi(tag)); packet_append_string_terminated(packet, cmd + pos); } socket_send_packet(packet); return 1; } else if (string_startswith(cmd, "/widget_toggle")) { size_t pos; char word[MAX_BUF], *cps[2]; int widget_id; pos = 14; while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) { if (string_split(word, cps, arraysize(cps), ':') < 1) { continue; } widget_id = widget_id_from_name(cps[0]); /* Invalid widget ID */ if (widget_id == -1) { continue; } /* Redraw all or a specific one identified by its UID */ if (cps[1] == NULL) { WIDGET_SHOW_TOGGLE_ALL(widget_id); } else { widgetdata *widget; widget = widget_find(NULL, widget_id, cps[1], NULL); if (widget) { WIDGET_SHOW_TOGGLE(widget); } } } return 1; } else if (string_startswith(cmd, "/widget_focus")) { size_t pos; char word[MAX_BUF], *cps[2]; int widget_id; pos = 14; while (string_get_word(cmd, &pos, ' ', word, sizeof(word), 0)) { if (string_split(word, cps, arraysize(cps), ':') < 1) { continue; } widget_id = widget_id_from_name(cps[0]); if (widget_id == -1) { /* Invalid widget ID */ continue; } widget_switch_focus(widget_id, cps[1]); } return 1; } else if (string_startswith(cmd, "/ping")) { keepalive_ping_stats(); return 1; } else if (string_startswith(cmd, "/region_map")) { region_map_open(); return 1; } return 0; }
void run_server_script( pp_script_t *pp_script, execute_on_t execute_on, char *config, disk_t *dp, int level) { pid_t scriptpid; int scriptin, scriptout, scripterr; char *cmd; char *command = NULL; GPtrArray *argv_ptr = g_ptr_array_new(); FILE *streamout; char *line; char *plugin; char level_number[NUM_STR_SIZE]; struct stat cmd_stat; int result; if ((pp_script_get_execute_on(pp_script) & execute_on) == 0) return; if (pp_script_get_execute_where(pp_script) != ES_SERVER) return; plugin = pp_script_get_plugin(pp_script); cmd = vstralloc(APPLICATION_DIR, "/", plugin, NULL); result = stat(cmd, &cmd_stat); if (result == -1) { dbprintf("Can't stat script '%s': %s\n", cmd, strerror(errno)); amfree(cmd); cmd = vstralloc(get_config_dir(), "/application/", plugin, NULL); result = stat(cmd, &cmd_stat); if (result == -1) { dbprintf("Can't stat script '%s': %s\n", cmd, strerror(errno)); amfree(cmd); cmd = vstralloc(CONFIG_DIR, "/application/", plugin, NULL); result = stat(cmd, &cmd_stat); if (result == -1) { dbprintf("Can't stat script '%s': %s\n", cmd, strerror(errno)); amfree(cmd); cmd = vstralloc(APPLICATION_DIR, "/", plugin, NULL); } } } g_ptr_array_add(argv_ptr, stralloc(plugin)); switch (execute_on) { case EXECUTE_ON_PRE_AMCHECK: command = "PRE-AMCHECK"; break; case EXECUTE_ON_PRE_DLE_AMCHECK: command = "PRE-DLE-AMCHECK"; break; case EXECUTE_ON_PRE_HOST_AMCHECK: command = "PRE-HOST-AMCHECK"; break; case EXECUTE_ON_POST_AMCHECK: command = "POST-AMCHECK"; break; case EXECUTE_ON_POST_DLE_AMCHECK: command = "POST-DLE-AMCHECK"; break; case EXECUTE_ON_POST_HOST_AMCHECK: command = "POST-HOST-AMCHECK"; break; case EXECUTE_ON_PRE_ESTIMATE: command = "PRE-ESTIMATE"; break; case EXECUTE_ON_PRE_DLE_ESTIMATE: command = "PRE-DLE-ESTIMATE"; break; case EXECUTE_ON_PRE_HOST_ESTIMATE: command = "PRE-HOST-ESTIMATE"; break; case EXECUTE_ON_POST_ESTIMATE: command = "POST-ESTIMATE"; break; case EXECUTE_ON_POST_DLE_ESTIMATE: command = "POST-DLE-ESTIMATE"; break; case EXECUTE_ON_POST_HOST_ESTIMATE: command = "POST-HOST-ESTIMATE"; break; case EXECUTE_ON_PRE_BACKUP: command = "PRE-BACKUP"; break; case EXECUTE_ON_PRE_DLE_BACKUP: command = "PRE-DLE-BACKUP"; break; case EXECUTE_ON_PRE_HOST_BACKUP: command = "PRE-HOST-BACKUP"; break; case EXECUTE_ON_POST_BACKUP: command = "POST-BACKUP"; break; case EXECUTE_ON_POST_DLE_BACKUP: command = "POST-DLE-BACKUP"; break; case EXECUTE_ON_POST_HOST_BACKUP: command = "POST-HOST-BACKUP"; break; case EXECUTE_ON_PRE_RECOVER: case EXECUTE_ON_POST_RECOVER: case EXECUTE_ON_PRE_LEVEL_RECOVER: case EXECUTE_ON_POST_LEVEL_RECOVER: case EXECUTE_ON_INTER_LEVEL_RECOVER: { // ERROR these script can't be executed on server. return; } } g_ptr_array_add(argv_ptr, stralloc(command)); g_ptr_array_add(argv_ptr, stralloc("--execute-where")); g_ptr_array_add(argv_ptr, stralloc("server")); if (config) { g_ptr_array_add(argv_ptr, stralloc("--config")); g_ptr_array_add(argv_ptr, stralloc(config)); } if (dp->host->hostname) { g_ptr_array_add(argv_ptr, stralloc("--host")); g_ptr_array_add(argv_ptr, stralloc(dp->host->hostname)); } if (dp->name) { g_ptr_array_add(argv_ptr, stralloc("--disk")); g_ptr_array_add(argv_ptr, stralloc(dp->name)); } if (dp->device) { g_ptr_array_add(argv_ptr, stralloc("--device")); g_ptr_array_add(argv_ptr, stralloc(dp->device)); } if (level >= 0) { g_snprintf(level_number, SIZEOF(level_number), "%d", level); g_ptr_array_add(argv_ptr, stralloc("--level")); g_ptr_array_add(argv_ptr, stralloc(level_number)); } property_add_to_argv(argv_ptr, pp_script_get_property(pp_script)); g_ptr_array_add(argv_ptr, NULL); scripterr = fileno(stderr); scriptpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE, 0, &scriptin, &scriptout, &scripterr, (char **)argv_ptr->pdata); close(scriptin); streamout = fdopen(scriptout, "r"); if (streamout) { while((line = agets(streamout)) != NULL) { dbprintf("script: %s\n", line); amfree(line); } } fclose(streamout); waitpid(scriptpid, NULL, 0); g_ptr_array_free_full(argv_ptr); amfree(cmd); }
bool FeSettings::build_romlist( const std::vector< FeImportTask > &task_list, const std::string &output_name, FeFilter &filter, bool full ) { FeRomInfoListType total_romlist; std::string best_name, list_name, path; for ( std::vector<FeImportTask>::const_iterator itr=task_list.begin(); itr < task_list.end(); ++itr ) { if ( (*itr).task_type == FeImportTask::BuildRomlist ) { // Build romlist task std::cout << "*** Generating Collection/Rom List" << std::endl; FeEmulatorInfo *emu = m_rl.get_emulator( (*itr).emulator_name ); if ( emu == NULL ) { std::cout << "Error: Invalid -build-rom-list target: " << (*itr).emulator_name << std::endl; } else { FeRomInfoListType romlist; best_name = emu->get_info( FeEmulatorInfo::Name ); FeImporterContext ctx( *emu, romlist ); build_basic_romlist( ctx ); apply_xml_import( ctx ); apply_import_extras( ctx ); apply_emulator_name( best_name, romlist ); total_romlist.splice( total_romlist.end(), romlist ); } } else if ( (*itr).task_type == FeImportTask::ImportRomlist ) { // import romlist from file task std::cout << "*** Importing Collection/Rom List" << std::endl; FeRomInfoListType romlist; std::string emu_name; if ( (*itr).emulator_name.empty() ) { // deduce the emulator name from the filename provided size_t my_start = (*itr).file_name.find_last_of( "\\/" ); if ( my_start == std::string::npos ) // if there is no / we start at the beginning my_start = 0; else my_start += 1; size_t my_end = (*itr).file_name.find_last_of( "." ); if ( my_end != std::string::npos ) emu_name = (*itr).file_name.substr( my_start, my_end - my_start ); } else emu_name = (*itr).emulator_name; best_name = emu_name; if ( tail_compare( (*itr).file_name, ".txt" ) ) { // Attract-Mode format list // FeRomList temp_list( m_config_path ); temp_list.load_from_file( (*itr).file_name, ";" ); FeRomInfoListType &entries = temp_list.get_list(); for ( FeRomInfoListType::iterator itr = entries.begin(); itr != entries.end(); ++itr ) romlist.push_back( *itr ); } else if ( tail_compare( (*itr).file_name, ".lst" ) ) { // Mamewah/Wahcade! format list // import_mamewah( (*itr).file_name, emu_name, romlist ); } else if ( tail_compare( (*itr).file_name, ".xml" ) ) { // HyperSpin format list // FeHyperSpinXMLParser my_parser( romlist ); if ( my_parser.parse( (*itr).file_name ) ) apply_emulator_name( emu_name, romlist ); } else { std::cerr << "Error: Unsupported --import-rom-list file: " << (*itr).file_name << std::endl; } std::cout << "[Import " << (*itr).file_name << "] - Imported " << romlist.size() << " entries." << std::endl; FeEmulatorInfo *emu = m_rl.get_emulator( emu_name ); if ( emu == NULL ) { std::cout << "Warning: The emulator specified with --import-rom-list was not found: " << emu_name << std::endl; } else { FeImporterContext ctx( *emu, romlist ); apply_import_extras( ctx ); } total_romlist.splice( total_romlist.end(), romlist ); } else // scrape artwork { FeEmulatorInfo *emu = m_rl.get_emulator( (*itr).emulator_name ); if ( emu == NULL ) return false; std::cout << "*** Scraping artwork for: " << (*itr).emulator_name << std::endl; FeRomInfoListType romlist; std::string fn = get_config_dir() + FE_ROMLIST_SUBDIR + (*itr).emulator_name + FE_ROMLIST_FILE_EXTENSION; FeImporterContext ctx( *emu, romlist ); if ( file_exists( fn ) ) { FeRomList loader( get_config_dir() ); loader.load_from_file( fn, ";" ); ctx.romlist.swap( loader.get_list() ); } else { build_basic_romlist( ctx ); apply_xml_import( ctx ); } ctx.scrape_art = true; confirm_directory( get_config_dir(), FE_SCRAPER_SUBDIR ); // do the mamedb scraper first (which only does anything for mame) followed // by the more general thegamesdb scraper. mamedb_scraper( ctx ); thegamesdb_scraper( ctx ); std::cout << "*** Scraping done." << std::endl; } } // return now if all we did was scrape artwork if ( total_romlist.empty() ) return true; total_romlist.sort( FeRomListSorter() ); // strip duplicate entries std::cout << " - Removing any duplicate entries..." << std::endl; total_romlist.unique(); // Apply the specified filter if ( filter.get_rule_count() > 0 ) { std::cout << " - Applying filter..." << std::endl; filter.init(); FeRomInfoListType::iterator last_it=total_romlist.begin(); for ( FeRomInfoListType::iterator it=total_romlist.begin(); it!=total_romlist.end(); ) { if ( filter.apply_filter( *it ) ) { if ( last_it != it ) it = total_romlist.erase( last_it, it ); else ++it; last_it = it; } else ++it; } if ( last_it != total_romlist.end() ) total_romlist.erase( last_it, total_romlist.end() ); } if ( task_list.size() > 1 ) best_name = "multi"; path = get_config_dir(); confirm_directory( path, FE_ROMLIST_SUBDIR ); path += FE_ROMLIST_SUBDIR; // if we weren't given a specific output name, then we come up with a name // that doesn't exist already // if ( output_name.empty() ) get_available_filename( path, best_name, FE_ROMLIST_FILE_EXTENSION, list_name ); else list_name = path + output_name + FE_ROMLIST_FILE_EXTENSION; write_romlist( list_name, total_romlist ); return true; }
bool FeSettings::thegamesdb_scraper( FeImporterContext &c ) { #ifndef NO_NET const char *HOSTNAME = "http://thegamesdb.net"; const char *PLATFORM_REQ = "api/GetPlatformsList.php"; const char *GAME_REQ = "api/GetGame.php?name=$1"; // // Get a list of valid platforms // FeNetQueue q; q.add_buffer_task( HOSTNAME, PLATFORM_REQ, 0 ); sf::Http::Response::Status status; q.do_next_task( status ); if ( status != sf::Http::Response::Ok ) { get_resource( "Error getting platform list from thegamesdb.net. Code: $1", as_str( status ), c.user_message ); std::cout << " * " << c.user_message << std::endl; return true; } int temp; std::string body; q.pop_completed_task( temp, body ); FeGameDBPlatformParser gdbpp; gdbpp.parse( body ); const std::vector<std::string> &sl_temp = c.emulator.get_systems(); std::vector<std::string> system_list; for ( std::vector<std::string>::const_iterator itr = sl_temp.begin(); itr!=sl_temp.end(); ++itr ) { if ( gdbpp.m_set.find( *itr ) != gdbpp.m_set.end() ) system_list.push_back( *itr ); else std::cout << " * System identifier '" << (*itr) << "' not recognized by " << HOSTNAME << std::endl; } if ( system_list.size() < 1 ) { // Correct if we can based on the configured info source, // otherwise we error out const std::string source = c.emulator.get_info( FeEmulatorInfo::Info_source ); if ( source.compare( "mame" ) == 0 ) system_list.push_back( "Arcade" ); else if ( source.compare( "steam" ) == 0 ) system_list.push_back( "PC" ); else { get_resource( "Error: None of the configured system identifier(s) are recognized by thegamesdb.net.", c.user_message ); std::cout << " * " << c.user_message << std::endl; return true; } } std::string emu_name = c.emulator.get_info( FeEmulatorInfo::Name ); // // Build a map for looking up parents // std::map < std::string, FeRomInfo * > parent_map; build_parent_map( parent_map, c.romlist ); // // Build a worklist of the roms where we need to lookup // std::vector<FeRomInfo *> worklist; worklist.reserve( c.romlist.size() ); for ( FeRomInfoListType::iterator itr=c.romlist.begin(); itr!=c.romlist.end(); ++itr ) { (*itr).set_info( FeRomInfo::Emulator, emu_name ); // Don't scrape for a clone if its parent has the same name // if ( has_same_name_as_parent( *itr, parent_map ) ) continue; if ( !c.scrape_art || m_scrape_fanart || ( m_scrape_flyers && (!has_artwork( *itr, "flyer" ) ) ) || ( m_scrape_wheels && (!has_artwork( *itr, "wheel" ) ) ) || ( m_scrape_snaps && (!has_artwork( *itr, "snap" ) ) ) || ( m_scrape_marquees && (!has_artwork( *itr, "marquee" ) ) ) ) worklist.push_back( &(*itr) ); } const int NUM_ARTS=5; // the number of scrape-able artwork types int done_count( 0 ); // // Set up our initial queue of network tasks // for ( unsigned int i=0; i<worklist.size(); i++ ) { std::string req_string = GAME_REQ; std::string game = url_escape( name_with_brackets_stripped( worklist[i]->get_info( FeRomInfo::Title ) ) ); perform_substitution( req_string, "$1", game ); // // If we don't need to scrape a wheel artwork, then add the specific platform to our request // If we are scraping a wheel, we want to be able to grab them where the game name (but // not the system) matches, so we don't limit ourselves by system... // if (( system_list.size() == 1 ) && ( !c.scrape_art || !m_scrape_wheels || has_artwork( *(worklist[i]), "wheel" ) )) { req_string += "&platform="; req_string += url_escape( system_list.front() ); } q.add_buffer_task( HOSTNAME, req_string, i ); } std::string base_path = get_config_dir() + FE_SCRAPER_SUBDIR; base_path += emu_name + "/"; // // Create worker threads to process the queue, adding new tasks to download // artwork files where appropriate // FeNetWorker worker1( q ), worker2( q ), worker3( q ), worker4( q ); // // Process the output queue from our worker threads // while ( !q.input_done() || !q.output_done() ) { int id; std::string result; if ( q.pop_completed_task( id, result ) ) { if ( id < 0 ) { if (( id == FeNetTask::FileTask ) || ( id == FeNetTask::SpecialFileTask )) { std::cout << " + Downloaded: " << result << std::endl; c.download_count++; } if ( id == FeNetTask::FileTask ) // we don't increment if id = FeNetTask::SpecialFileTask done_count++; } else { FeGameDBArt my_art; FeGameDBParser gdbp( system_list, *(worklist[id]), ( c.scrape_art ? &my_art : NULL ) ); gdbp.parse( result ); if ( c.scrape_art && !my_art.base.empty() ) { std::string hostn = HOSTNAME; std::string base_req = "banners/"; size_t pos=0; for ( int i=0; i<3 && ( pos != std::string::npos ); i++ ) pos = my_art.base.find_first_of( '/', pos+1 ); if (( pos != std::string::npos ) && ( pos < my_art.base.size()-1 ) ) { hostn = my_art.base.substr( 0, pos+1 ); base_req = my_art.base.substr( pos+1 ); } FeRomInfo &rom = *(worklist[id]); if ( m_scrape_flyers && ( !my_art.flyer.empty() ) && (!has_artwork( rom, "flyer" )) ) { const char *FLYER = "flyer/"; std::string fname = base_path + FLYER + rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, FLYER ); q.add_file_task( hostn, base_req + my_art.flyer, fname ); } else done_count++; if ( m_scrape_wheels && ( !my_art.wheel.empty() ) && (!has_artwork( rom, "wheel" )) ) { const char *WHEEL = "wheel/"; std::string fname = base_path + WHEEL + rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, WHEEL ); q.add_file_task( hostn, base_req + my_art.wheel, fname ); } else done_count++; if ( m_scrape_marquees && (!my_art.marquee.empty() ) && (!has_artwork( rom, "marquee" )) ) { const char *MARQUEE = "marquee/"; std::string fname = base_path + MARQUEE + rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, MARQUEE ); q.add_file_task( hostn, base_req + my_art.marquee, fname ); } else done_count++; if ( m_scrape_snaps && (!my_art.snap.empty() ) && (!has_artwork( rom, "snap" )) ) { const char *SNAP = "snap/"; std::string fname = base_path + SNAP + rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, SNAP ); q.add_file_task( hostn, base_req + my_art.snap, fname ); } else done_count++; if ( m_scrape_fanart && !my_art.fanart.empty() ) { const char *FANART = "fanart/"; std::string fname_base = base_path + FANART + rom.get_info( FeRomInfo::Romname ) + "/"; confirm_directory( base_path, "" ); confirm_directory( base_path + FANART, rom.get_info( FeRomInfo::Romname ) ); bool done_first=false; // we only count the first fanart against our percentage completed... for ( std::vector<std::string>::iterator itr = my_art.fanart.begin(); itr != my_art.fanart.end(); ++itr ) { size_t start_pos = (*itr).find_last_of( "/\\" ); size_t end_pos = (*itr).find_last_of( '.' ); if (( start_pos != std::string::npos ) && ( !file_exists( fname_base + (*itr).substr( start_pos+1 ) ) )) { if (( end_pos != std::string::npos ) && ( end_pos > start_pos )) { q.add_file_task( hostn, base_req + (*itr), fname_base + (*itr).substr( start_pos+1, end_pos-start_pos-1 ), done_first ); done_first=true; } } } } else done_count++; } else done_count+=NUM_ARTS; } if ( c.uiupdate ) { int p = c.progress_past + done_count * c.progress_range / ( NUM_ARTS * worklist.size() ); if ( c.uiupdate( c.uiupdatedata, p ) == false ) return false; } } else if ( q.output_done() ) { sf::Http::Response::Status status; q.do_next_task( status ); } else sf::sleep( sf::milliseconds( 10 ) ); } #endif return true; }
bool FeSettings::mamedb_scraper( FeImporterContext &c ) { #ifndef NO_NET if (( c.emulator.get_info( FeEmulatorInfo::Info_source ).compare( "mame" ) != 0 ) || ( !m_scrape_snaps && !m_scrape_marquees )) return true; // // Build a map for looking up parents // std::map < std::string, FeRomInfo * > parent_map; build_parent_map( parent_map, c.romlist ); const char *MAMEDB = "http://mamedb.com"; std::string emu_name = c.emulator.get_info( FeEmulatorInfo::Name ); std::string base_path = get_config_dir() + FE_SCRAPER_SUBDIR; base_path += emu_name + "/"; FeNetQueue q; int taskc( 0 ); int done( 0 ); for ( FeRomInfoListType::iterator itr=c.romlist.begin(); itr!=c.romlist.end(); ++itr ) { // ugh, this must be set for has_artwork() to correctly function (*itr).set_info( FeRomInfo::Emulator, emu_name ); // Don't scrape for a clone if its parent has the same name // if ( has_same_name_as_parent( *itr, parent_map ) ) continue; if ( m_scrape_marquees && !has_artwork( *itr, "marquee" ) ) { const char *MARQUEE = "marquee/"; std::string fname = base_path + MARQUEE + (*itr).get_info( FeRomInfo::Romname ); confirm_directory( base_path, MARQUEE ); q.add_file_task( MAMEDB, "marquees/" + (*itr).get_info( FeRomInfo::Romname ) +".png", fname ); taskc++; } if ( m_scrape_snaps && !has_artwork( *itr, "snap" ) ) { const char *SNAP = "snap/"; std::string fname = base_path + SNAP + (*itr).get_info( FeRomInfo::Romname ); confirm_directory( base_path, SNAP ); q.add_file_task( MAMEDB, SNAP + (*itr).get_info( FeRomInfo::Romname ) +".png", fname ); taskc++; } } // // Create worker threads to process the queue. // FeNetWorker worker1( q ), worker2( q ), worker3( q ), worker4( q ); // // Process the output queue from our worker threads // while ( !( q.input_done() && q.output_done() ) ) { int id; std::string result; if ( q.pop_completed_task( id, result ) ) { if ( id < 0 ) { if ( id == -1 ) { std::cout << " + Downloaded: " << result << std::endl; c.download_count++; } done++; } } if ( c.uiupdate ) { int p = c.progress_past + done * c.progress_range / taskc; if ( c.uiupdate( c.uiupdatedata, p ) == false ) return false; } } #endif return true; }
const char * S9xGetDirectory (enum s9x_getdirtype dirtype) { static char path[PATH_MAX + 1]; switch (dirtype) { case HOME_DIR: sstrncpy (path, get_config_dir ().c_str (), PATH_MAX + 1); break; case SNAPSHOT_DIR: sstrncpy (path, gui_config->savestate_directory.c_str (), PATH_MAX + 1); break; case PATCH_DIR: sstrncpy (path, gui_config->patch_directory.c_str (), PATH_MAX + 1); break; case CHEAT_DIR: sstrncpy (path, gui_config->cheat_directory.c_str (), PATH_MAX + 1); break; case SRAM_DIR: sstrncpy (path, gui_config->sram_directory.c_str (), PATH_MAX + 1); break; case SCREENSHOT_DIR: case SPC_DIR: sstrncpy (path, gui_config->export_directory.c_str (), PATH_MAX + 1); break; default: path[0] = '\0'; } /* Try and mkdir, whether it exists or not */ if (dirtype != HOME_DIR && path[0] != '\0') { mkdir (path, 0755); chmod (path, 0755); } /* Anything else, use ROM filename path */ if (path[0] == '\0') { char *loc; strcpy (path, Memory.ROMFilename); loc = strrchr (path, SLASH_CHAR); if (loc == NULL) { if (getcwd (path, PATH_MAX + 1) == NULL) { strcpy (path, getenv ("HOME")); } } else { path[loc - path] = '\0'; } } return path; }
void handle_event(struct inotify_event* event, int writefd) { char abort; char isglob; char foundslash; char *filename; char *path = NULL; char *handlerexec; char *name = NULL; char *newpathenv; char *configdir; char *scriptdir; char *temp; char *mimetypestr; const char *mimetype; magic_t magic; int i, j, sysret, attempts; int pathlen; struct keyval_node *child; struct keyval_node *handler; pcre *regex; char *regex_str; const char *pcre_err; int pcre_erroffset; int pcre_match; int delay_repeats; int delay_time; struct watchnode* node; /* find the node that corresponds to the event's descriptor */ for (node=g_watchnode->next; node; node = node->next) { if (node->wd == event->wd) break; } if (!node) return; /* combine the name inotify gives with the full path to the file */ filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1); sprintf(filename, "%s/%s", node->path, event->name); /* match the config's expression against a glob, regex, or mimetype */ abort = 0; for (child = node->section->children; child; child = child->next) { abort = 0; foundslash = 0; isglob = 1; if (!child->name) continue; for (i=0; child->name[i]; i++) { if (child->name[i] == '/') { isglob = 0; break; } } /* filename is '/path/foo', but we want to match against 'foo' for globbing and regexs */ name = strrchr(filename, '/') + 1; /* add one to change /foo -> foo */ pathlen = strlen(filename) - strlen(name); path = malloc(pathlen + 1); strncpy(path, filename, pathlen); /* remove the trailing / from path */ if (pathlen > 0) if (path[pathlen-1] == '/') path[pathlen-1] = '\0'; if (name == NULL) name = filename; if (isglob == 1) { if (fnmatch(child->name, name, 0) != 0) abort = 1; if (abort == 0) break; } /* regexs are in the format /regex/ */ if (isglob == 0 && child->name[0] == '/' && child->name[strlen(child->name)-1] == '/') { /* child->name is "/regex/", we want "regex" */ regex_str = strndup(child->name+1, strlen(child->name)-2); regex = pcre_compile(regex_str, 0, &pcre_err, &pcre_erroffset, NULL); pcre_match = pcre_exec(regex, NULL, name, strlen(name), 0, 0, NULL, 0); free(regex_str); if (pcre_match < 0) abort = 1; if (abort == 0) break; } /* parse the mimetype to see if it matches the one in the config . if we make it here, it means mimetype is the last possible thing, so here we init the magic file business and whatnot. */ if ( (magic = magic_open(MAGIC_MIME)) == NULL) { write_out(writefd, "Error: could not open libmagic (magic_open)"); /* can't set abort here becuase magic was never opened, so * magic_free below would fail hard. */ free(filename); EXIT_HANDLER(-1); } if (magic_load(magic, NULL) < 0) { write_out(writefd, "Error: magic_load failed."); magic_close(magic); abort = 1; break; } mimetype = magic_file(magic, filename); if (mimetype == NULL) { write_out(writefd, "Error: could not determine mime type (magic_file)"); magic_close(magic); abort = 1; break; } mimetypestr = strdup(mimetype); magic_close(magic); for (i=0, j=0; isglob == 0 && mimetypestr[i] && child->name[j] && abort == 0; i++, j++) { if (!mimetypestr[i]) { abort = 1; break; } else if (!child->name[j]) { abort = 1; break; } if (foundslash == 0 && child->name[j] == '/') foundslash = 1; if (mimetypestr[i] != child->name[j] && child->name[j] != '*') { abort = 1; break; } else if (child->name[j] == '*' && foundslash == 0) { while (mimetypestr[i] != '/') i++; while (child->name[j] != '/') j++; foundslash = 1; } else if (child->name[j] == '*' && foundslash == 1) break; } free(mimetypestr); if (abort == 0) { break; } /* if we make it here we need to free the path * (it's allocated every loop iteration) */ free(path); } if (abort == 1) { free(filename); EXIT_HANDLER(-1); } /* dup the fds */ dup2(writefd, fileno(stdout)); dup2(writefd, fileno(stderr)); /* find the handlers which correspond to the mimetype, and continue executing them until we've run them all or one returns 0 */ handler = child->children; /* delay attempts are limited! */ attempts = 0; /* modify PATH */ configdir = get_config_dir(); scriptdir = malloc(strlen(configdir) + strlen("/scripts") + 2 + 1); sprintf(scriptdir, ":%s/scripts:", configdir); free(configdir); newpathenv = malloc(strlen(getenv("PATH")) + strlen(scriptdir) + 1); strcpy(newpathenv, getenv("PATH")); strcat(newpathenv, scriptdir); setenv("PATH", newpathenv, 1); free(newpathenv); free(scriptdir); /* get delay info */ delay_repeats = get_delay_repeats(child); delay_time = get_delay_time(child); while (handler && (attempts < delay_repeats || delay_repeats == 0)) { /* if not a handler, skip it */ if (!handler->name || (strcmp(handler->name, "handler") != 0)) { handler = handler->next; continue; } /* create executable statement (subs %%) */ handlerexec = build_exec_line(handler->value, path, name); temp = malloc(11 + strlen(handlerexec) + 1 + 1); sprintf(temp, "Executing: %s\n", handlerexec); write_out(writefd, temp); free(temp); sysret = WEXITSTATUS(system(handlerexec)); /* ugh, i know. we have to make calls to write_out becuase we cannot log from this * function. if it's called from another process (aka, normal operation, opposed to syncmode) * you could get funny results. */ if (verbose) { temp = malloc(9 + strlen(handler->value) + 21 + 4 + 1 + 1); sprintf(temp, "Handler \"%s\" returned exit code %d\n", handler->value, sysret); write_out(writefd, temp); free(temp); } /* special message if system() didn't find the handler. control flow will pass down below * to calling the next handler */ if (sysret == 127) { temp = malloc(27 + strlen(handler->value) + 20 + 1); sprintf("Could not execute handler \"%s\", trying next one.\n", handler->value); write_out(writefd, temp); free(temp); } free(handlerexec); /* do somethng based on return code! */ if (sysret == 0) { /* the handler handled it! break out of the handler loop and exit this thread */ break; } else if (sysret == DELAY_RET_CODE) { /* go to sleep for a while */ attempts++; write_out(writefd, "Handler indicated delay, sleeping..."); sleep(delay_time); write_out(writefd, "Handler process resuming."); } else { /* some other return code, means try the next handler */ handler = handler->next; } } if (delay_repeats != 0 && attempts >= delay_repeats) write_out(writefd, "Handler gave up on retries."); free(filename); free(path); EXIT_HANDLER(0); }
bool FeSettings::thegamesdb_scraper( FeImporterContext &c ) { #ifndef NO_NET const char *HOSTNAME = "http://thegamesdb.net"; const char *PLATFORM_LIST_REQ = "api/GetPlatformsList.php"; const char *PLAT_REQ = "api/GetPlatform.php?id=$1"; const char *GAME_REQ = "api/GetGame.php?name=$1"; const char *FLYER = "flyer/"; const char *WHEEL = "wheel/"; const char *MARQUEE = "marquee/"; const char *SNAP = "snap/"; const char *FANART = "fanart/"; // // Get a list of valid platforms // FeNetQueue q; q.add_buffer_task( HOSTNAME, PLATFORM_LIST_REQ, 0 ); sf::Http::Response::Status status; std::string err_req; q.do_next_task( status, err_req ); if ( status != sf::Http::Response::Ok ) { get_resource( "Error getting platform list from thegamesdb.net. Code: $1", as_str( status ), c.user_message ); std::cerr << " ! " << c.user_message << " (" << err_req << ")" << std::endl; return true; } int temp; std::string body; q.pop_completed_task( temp, body ); FeGameDBPlatformListParser gdbplp; gdbplp.parse( body ); std::vector<std::string> system_list; std::vector<int> system_ids; const std::vector<std::string> &sl_temp = c.emulator.get_systems(); for ( std::vector<std::string>::const_iterator itr = sl_temp.begin(); itr != sl_temp.end(); ++itr ) { std::string comp_fuzz = get_fuzzy( *itr ); for ( size_t i=0; i<gdbplp.m_names.size(); i++ ) { ASSERT( gdbplp.m_names.size() == gdbplp.m_ids.size() ); std::string &n = gdbplp.m_names[i]; int id = ( i < gdbplp.m_ids.size() ) ? i : 0; if ( comp_fuzz.compare( get_fuzzy( n ) ) == 0 ) { system_list.push_back( n ); system_ids.push_back( id ); break; } else { size_t pos = n.find_first_of( "(" ); if (( pos != std::string::npos ) && (( comp_fuzz.compare( get_fuzzy( n.substr(0,pos-1))) == 0 ) || ( comp_fuzz.compare(get_fuzzy( n.substr(pos+1,n.size()-pos-1 ))) == 0 ))) { system_list.push_back( n ); system_ids.push_back( id ); break; } } } } if ( system_list.size() < 1 ) { // Correct if we can based on the configured info source, // otherwise we error out switch( c.emulator.get_info_source() ) { case FeEmulatorInfo::Listxml: system_list.push_back( "Arcade" ); break; case FeEmulatorInfo::Steam: system_list.push_back( "PC" ); break; default: get_resource( "Error: None of the configured system identifier(s) are recognized by thegamesdb.net.", c.user_message ); std::cerr << " ! " << c.user_message << std::endl; return true; } } std::string emu_name = c.emulator.get_info( FeEmulatorInfo::Name ); std::string base_path = get_config_dir() + FE_SCRAPER_SUBDIR; base_path += emu_name + "/"; if ( c.scrape_art ) { // // Get emulator-specific images // for ( std::vector<int>::iterator iti=system_ids.begin(); iti != system_ids.end(); ++iti ) { std::string plat_string = PLAT_REQ; perform_substitution( plat_string, "$1", as_str( *iti ) ); q.add_buffer_task( HOSTNAME, plat_string, 0 ); q.do_next_task( status, err_req ); if ( status != sf::Http::Response::Ok ) { std::cout << " * Unable to get platform information. Status code: " << status << " (" << err_req << ")" << std::endl; continue; } body.clear(); q.pop_completed_task( temp, body ); FeGameDBArt my_art; FeGameDBPlatformParser gdbpp( my_art ); gdbpp.parse( body ); std::string hostn = HOSTNAME; std::string base_req = "banners/"; get_url_components( my_art.base, hostn, base_req ); std::string path = base_path + FLYER; if ( m_scrape_flyers && ( !my_art.flyer.empty() ) && ( !art_exists( path, emu_name ) )) { confirm_directory( base_path, FLYER ); q.add_file_task( hostn, base_req + my_art.flyer, path + emu_name ); } path = base_path + WHEEL; if ( m_scrape_wheels && ( !my_art.wheel.empty() ) && ( !art_exists( path, emu_name ) )) { confirm_directory( base_path, WHEEL ); q.add_file_task( hostn, base_req + my_art.wheel, path + emu_name ); } path = base_path + MARQUEE; if ( m_scrape_marquees && ( !my_art.marquee.empty() ) && ( !art_exists( path, emu_name ) )) { confirm_directory( base_path, MARQUEE ); q.add_file_task( hostn, base_req + my_art.marquee, path + emu_name ); } if ( m_scrape_fanart && !my_art.fanart.empty() ) { std::string path_base = base_path + FANART + emu_name + "/"; confirm_directory( base_path, "" ); confirm_directory( base_path + FANART, emu_name ); for ( std::vector<std::string>::iterator itr = my_art.fanart.begin(); itr != my_art.fanart.end(); ++itr ) { size_t start_pos = (*itr).find_last_of( "/\\" ); size_t end_pos = (*itr).find_last_of( '.' ); if (( start_pos != std::string::npos ) && ( !file_exists( path_base + (*itr).substr( start_pos+1 ) ) )) { if (( end_pos != std::string::npos ) && ( end_pos > start_pos )) { q.add_file_task( hostn, base_req + (*itr), path_base + (*itr).substr( start_pos+1, end_pos-start_pos-1 ) ); } } } } } } bool prefer_alt_filename = c.emulator.is_mess(); // // Build a map for looking up parents // ParentMapType parent_map; build_parent_map( parent_map, c.romlist, prefer_alt_filename ); // // Build a worklist of the roms where we need to lookup // std::vector<FeRomInfo *> worklist; worklist.reserve( c.romlist.size() ); for ( FeRomInfoListType::iterator itr=c.romlist.begin(); itr!=c.romlist.end(); ++itr ) { (*itr).set_info( FeRomInfo::Emulator, emu_name ); // Don't scrape for a clone if its parent has the same name // if ( has_same_name_as_parent( *itr, parent_map ) ) continue; if ( !c.scrape_art || m_scrape_fanart || ( m_scrape_flyers && (!has_artwork( *itr, "flyer" ) ) ) || ( m_scrape_wheels && (!has_artwork( *itr, "wheel" ) ) ) || ( m_scrape_snaps && (!has_image_artwork( *itr, "snap" ) ) ) || ( m_scrape_marquees && (!has_artwork( *itr, "marquee" ) ) ) ) worklist.push_back( &(*itr) ); } const int NUM_ARTS=5; // the number of scrape-able artwork types int done_count( 0 ); // // Set up our initial queue of network tasks // for ( unsigned int i=0; i<worklist.size(); i++ ) { std::string req_string = GAME_REQ; std::string game = url_escape( name_with_brackets_stripped( worklist[i]->get_info( FeRomInfo::Title ) ) ); perform_substitution( req_string, "$1", game ); // // If we don't need to scrape a wheel artwork, then add the specific platform to our request // If we are scraping a wheel, we want to be able to grab them where the game name (but // not the system) matches, so we don't limit ourselves by system... // if (( system_list.size() == 1 ) && ( !c.scrape_art || !m_scrape_wheels || has_artwork( *(worklist[i]), "wheel" ) )) { req_string += "&platform="; req_string += url_escape( system_list.front() ); } q.add_buffer_task( HOSTNAME, req_string, i ); } // // Create worker threads to process the queue, adding new tasks to download // artwork files where appropriate // FeNetWorker worker1( q ), worker2( q ), worker3( q ), worker4( q ); std::string aux; // // Process the output queue from our worker threads // while ( !( q.input_done() && q.output_done() ) ) { int id; std::string result; if ( q.pop_completed_task( id, result ) ) { if ( id < 0 ) { if (( id == FeNetTask::FileTask ) || ( id == FeNetTask::SpecialFileTask )) { std::cout << " + Downloaded: " << result << std::endl; c.download_count++; // find second last forward slash in filename // we assume that there will always be at least two size_t pos = result.find_last_of( "\\/" ); if ( pos != std::string::npos ) { pos = result.find_last_of( "\\/", pos-1 ); if ( pos != std::string::npos ) aux = result.substr( pos ); } } if ( id == FeNetTask::FileTask ) // we don't increment if id = FeNetTask::SpecialFileTask done_count++; } else { FeGameDBArt my_art; FeGameDBParser gdbp( system_list, *(worklist[id]), ( c.scrape_art ? &my_art : NULL ) ); gdbp.parse( result ); if ( c.scrape_art && !my_art.base.empty() ) { std::string hostn = HOSTNAME; std::string base_req = "banners/"; get_url_components( my_art.base, hostn, base_req ); const FeRomInfo &rom = *(worklist[id]); if ( m_scrape_flyers && ( !my_art.flyer.empty() ) && (!has_artwork( rom, "flyer" )) ) { std::string fname = base_path + FLYER; const std::string &altname = rom.get_info( FeRomInfo::AltRomname ); if ( prefer_alt_filename && !altname.empty() ) fname += rom.get_info( FeRomInfo::AltRomname ); else fname += rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, FLYER ); q.add_file_task( hostn, base_req + my_art.flyer, fname ); } else done_count++; if ( m_scrape_wheels && ( !my_art.wheel.empty() ) && (!has_artwork( rom, "wheel" )) ) { std::string fname = base_path + WHEEL; const std::string &altname = rom.get_info( FeRomInfo::AltRomname ); if ( prefer_alt_filename && !altname.empty() ) fname += rom.get_info( FeRomInfo::AltRomname ); else fname += rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, WHEEL ); q.add_file_task( hostn, base_req + my_art.wheel, fname ); } else done_count++; if ( m_scrape_marquees && (!my_art.marquee.empty() ) && (!has_artwork( rom, "marquee" )) ) { std::string fname = base_path + MARQUEE; const std::string &altname = rom.get_info( FeRomInfo::AltRomname ); if ( prefer_alt_filename && !altname.empty() ) fname += rom.get_info( FeRomInfo::AltRomname ); else fname += rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, MARQUEE ); q.add_file_task( hostn, base_req + my_art.marquee, fname ); } else done_count++; if ( m_scrape_snaps && (!my_art.snap.empty() ) && (!has_image_artwork( rom, "snap" )) ) { std::string fname = base_path + SNAP; const std::string &altname = rom.get_info( FeRomInfo::AltRomname ); if ( prefer_alt_filename && !altname.empty() ) fname += rom.get_info( FeRomInfo::AltRomname ); else fname += rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path, SNAP ); q.add_file_task( hostn, base_req + my_art.snap, fname ); } else done_count++; if ( m_scrape_fanart && !my_art.fanart.empty() ) { std::string fname_base = base_path + FANART; confirm_directory( base_path, "" ); const std::string &altname = rom.get_info( FeRomInfo::AltRomname ); if ( prefer_alt_filename && !altname.empty() ) { fname_base += rom.get_info( FeRomInfo::AltRomname ); confirm_directory( base_path + FANART, rom.get_info( FeRomInfo::AltRomname ) ); } else { fname_base += rom.get_info( FeRomInfo::Romname ); confirm_directory( base_path + FANART, rom.get_info( FeRomInfo::Romname ) ); } fname_base += "/"; bool done_first=false; // we only count the first fanart against our percentage completed... for ( std::vector<std::string>::iterator itr = my_art.fanart.begin(); itr != my_art.fanart.end(); ++itr ) { size_t start_pos = (*itr).find_last_of( "/\\" ); size_t end_pos = (*itr).find_last_of( '.' ); if (( start_pos != std::string::npos ) && ( !file_exists( fname_base + (*itr).substr( start_pos+1 ) ) )) { if (( end_pos != std::string::npos ) && ( end_pos > start_pos )) { q.add_file_task( hostn, base_req + (*itr), fname_base + (*itr).substr( start_pos+1, end_pos-start_pos-1 ), done_first ); done_first=true; } } } } else done_count++; } else { aux = (worklist[id])->get_info( FeRomInfo::Title ); done_count+=NUM_ARTS; } } if (( c.uiupdate ) && !worklist.empty() ) { int p = c.progress_past + done_count * c.progress_range / ( NUM_ARTS * worklist.size() ); if ( c.uiupdate( c.uiupdatedata, p, aux ) == false ) return false; } } else if ( q.output_done() ) { sf::Http::Response::Status status; std::string err_req; q.do_next_task( status, err_req ); if ( status != sf::Http::Response::Ok ) { std::cout << " * Error processing request. Status code: " << status << " (" << err_req << ")" << std::endl; } } else sf::sleep( sf::milliseconds( 10 ) ); } #endif return true; }
int main(int argc, char** argv) { int ifd, len = 0, i = 0, selectret = 0, maxfd, retryselect, pid; char buf[BUF_LEN]; char *configdir; char *pidfilename; char *statusfilename; char *statusbin; char *error_str; char *version_str = PACKAGE_STRING; char *pbuf; char *filename; FILE *pidfile; FILE *statusfile; fd_set set; struct inotify_event *event; struct argument *argument = argument_new(); struct pipe_list *pipe_list_cur; struct stat file_stat; struct watchnode *node; /* alloc pipe list */ pipe_list_head = malloc(sizeof(struct pipe_list)); pipe_list_head->next = NULL; /* set up signals for exiting/reaping */ signal(SIGINT, &handle_quit_signal); signal(SIGTERM, &handle_quit_signal); signal(SIGCHLD, &handle_child_signal); signal(SIGHUP, &handle_hup_signal); /* add command line arguments */ argument_register(argument, "help", "Prints this help text.", 0); argument_register(argument, "version", "Prints version information.", 0); argument_register(argument, "daemon", "Run as a daemon.", 0); argument_register(argument, "verbose", "Turns on debug text.", 0); argument_register(argument, "sync", "Sync mode (for debugging).", 0); argument_register(argument, "log-to-stdout", "Deprecated, use \"--log-to=stdout\" instead", 0); argument_register(argument, "log-to", "Log messages with specified way. " #ifdef USE_SYSLOG "Can be: stdout, file, syslog. \"file\" by default.", 1); #else "Can be: stdout, file. \"file\" by default.", 1); #endif if ((error_str = argument_parse(argument, argc, argv))) { fprintf(stderr, "Error in arguments: %s", error_str); free(error_str); return -1; } if (argument_exists(argument, "help")) { char *help_txt = argument_get_help_text(argument); printf("%s", help_txt); free(help_txt); return 0; } if (argument_exists(argument, "version")) { printf("%s\n", version_str); return 0; } if (argument_exists(argument, "verbose")) { verbose = 1; } if (argument_exists(argument, "daemon") && fork()) return 0; if (argument_exists(argument, "sync")) syncmode = 1; if (argument_exists(argument, "log-to-stdout")) fprintf(stderr, "Warning, this option is deprecated, " \ "please use new syntax: \"--log-to=stdout\".\n"); logtype = LOG_FILE; if (argument_exists(argument, "log-to") && \ (log_arg = argument_get_value(argument, "log-to")) != NULL) { if (strcmp(log_arg, "stdout") == 0) logtype = LOG_STDOUT; #ifdef USE_SYSLOG else if (strcmp(log_arg, "syslog") == 0) logtype = LOG_SYS; #endif else /* logtype already set to 'file' above */ fprintf(stderr, "Warning, selected unknown logging type. " \ "Will use \"--log-to=file\" instead.\n"); } /* get config dir (must free this) */ configdir = get_config_dir(); /* if a config file has not been specified, use default */ if (argument_get_extra(argument)) { configfile = strdup(argument_get_extra(argument)); } else { configfile = malloc (strlen(configdir) + strlen ("/config") + 1); sprintf(configfile, "%s/config", configdir); } argument_free(argument); free(configdir); if (access(configfile, R_OK) != 0) { fprintf(stderr, "error: could not open config file: %s\n", configfile); return -1; } /* create a pid file */ pidfilename = get_pid_filename(); if (stat(pidfilename, &file_stat) == 0) /* pidfile exists */ { pidfile = fopen(pidfilename, "r"); if (fscanf(pidfile, "%d", &pid) == 1) /* pidfile has a pid inside */ { char *binaryname; char *scanformat; if ((binaryname = strrchr(argv[0], '/')) != NULL) { binaryname++; } else { binaryname = argv[0]; } scanformat = malloc(strlen("Name: %") + strlen(binaryname) + strlen("s") + 1); statusfilename = malloc(strlen("/proc/") + 6 + strlen("/status") + 1); sprintf(statusfilename, "/proc/%d/status", pid); if (stat(statusfilename, &file_stat) != 0) /* write pid file if the process no longer exists */ { write_pid_file(pidfilename); } else /* process exists, so check owner and binary name */ { statusfile = fopen(statusfilename, "r"); statusbin = malloc(strlen(binaryname) + 2); /* the binary name may start with "fsniper" but be longer */ sprintf(scanformat, "Name: %%%ds", strlen(binaryname) + 1); fscanf(statusfile, scanformat, statusbin); free(statusfilename); fclose(statusfile); fclose(pidfile); if (strcmp(binaryname, statusbin) == 0 && file_stat.st_uid == getuid()) /* exit if the process is fsniper and is owned by the current user */ { printf("%s: already running instance found with pid %d. exiting.\n", binaryname, pid); exit(1); } else /* the pid file contains an old pid, one that isn't fsniper, or one not owned by the current user */ { write_pid_file(pidfilename); } } } else /* pidfile is invalid */ { fclose(pidfile); write_pid_file(pidfilename); } } else /* the pidfile doesn't exist */ { write_pid_file(pidfilename); } free(pidfilename); /* start up log */ if (!log_open()) { fprintf(stderr, "Error: could not start log.\n"); return -1; } ifd = inotify_init(); if (ifd < 0) { perror("inotify_init"); return -1; } if (verbose) log_write("Parsing config file: %s\n", configfile); config = keyval_parse_file(configfile); if ((error_str = keyval_get_error())) { fprintf(stderr, "%s", error_str); free(error_str); exit(1); } validate_config(config); /* add nodes to the inotify descriptor */ g_watchnode = add_watches(ifd); /* wait for events and then handle them */ while (1) { /* set up fds and max */ FD_ZERO(&set); FD_SET(ifd, &set); maxfd = ifd; for (pipe_list_cur = pipe_list_head->next; pipe_list_cur; pipe_list_cur = pipe_list_cur->next) { FD_SET(pipe_list_cur->pfd[0], &set); if (pipe_list_cur->pfd[0] > maxfd) maxfd = pipe_list_cur->pfd[0]; } retryselect = 1; while (retryselect) { /* use select to get activity on any of the fds */ selectret = select(maxfd + 1, &set, NULL, NULL, NULL); if (selectret == -1) { if (errno == EINTR) retryselect = 1; else handle_quit_signal(-2); } else retryselect = 0; } /* handle any events on the inotify fd */ if (FD_ISSET(ifd, &set)) { len = read(ifd, buf, BUF_LEN); while (i < len) { event = (struct inotify_event *) &buf[i]; if (event->len && (event->mask & IN_CLOSE_WRITE || event->mask & IN_MOVED_TO)) { /* if sync mode, just call handle_exec */ if (syncmode == 1) { handle_event(event, fileno(_logfd)); } else { /* create new pipe_list entry */ for (pipe_list_cur = pipe_list_head; pipe_list_cur->next != NULL; pipe_list_cur = pipe_list_cur->next) {} pipe_list_cur->next = malloc(sizeof(struct pipe_list)); pipe_list_cur->next->next = NULL; /* create pipe */ pipe(pipe_list_cur->next->pfd); if (fork() == 0) { /* child, close 0 */ close(pipe_list_cur->next->pfd[0]); log_close(); signal(SIGINT, &handle_child_quit_signal); signal(SIGTERM, &handle_child_quit_signal); handle_event(event, pipe_list_cur->next->pfd[1]); } else { /* parent, close 1 */ close(pipe_list_cur->next->pfd[1]); } } } else if (event->len && (event->mask & IN_CREATE && event->mask & IN_ISDIR)) { for (node = g_watchnode->next; node; node = node->next) if (node->wd == event->wd) break; if (node) { /* combine the name inotify gives with the full path to the file */ filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1); sprintf(filename, "%s/%s", node->path, event->name); watch_dir(node, ifd, strdup(filename), node->section); free(filename); } } else if (event->len && (event->mask & IN_DELETE && event->mask & IN_ISDIR)) { for (node = g_watchnode->next; node; node = node->next) if (node->wd == event->wd) break; if (node) { /* combine the name inotify gives with the full path to the file */ filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1); sprintf(filename, "%s/%s", node->path, event->name); unwatch_dir(filename, ifd); free(filename); } } i += EVENT_SIZE + event->len; } i = 0; } /* now lets see if we have any pipe activity */ pipe_list_cur = pipe_list_head->next; while (pipe_list_cur) { if (FD_ISSET(pipe_list_cur->pfd[0], &set)) { len = read(pipe_list_cur->pfd[0], buf, BUF_LEN); if (len == 0) { close(pipe_list_cur->pfd[0]); /* remove this item from the list */ pipe_list_cur = pipe_list_remove(pipe_list_head, pipe_list_cur); } else { /* print it somewhere */ pbuf = malloc(len + 1); snprintf(pbuf, len, "%s", buf); log_write("%s\n", pbuf); free(pbuf); pipe_list_cur = pipe_list_cur->next; } } else { pipe_list_cur = pipe_list_cur->next; } } } }
//------------------------------------------------------------------------------ lua_State* initialise_lua() { static int once = 0; int i; int path_hash; char buffer[1024]; struct luaL_Reg clink_native_methods[] = { { "chdir", change_dir }, { "execute", lua_execute }, { "find_dirs", find_dirs }, { "find_files", find_files }, { "get_console_aliases", get_console_aliases }, { "get_cwd", get_cwd }, { "get_env", get_env }, { "get_env_var_names", get_env_var_names }, { "get_host_process", get_host_process }, { "get_rl_variable", get_rl_variable }, { "get_screen_info", get_screen_info }, { "get_setting_int", get_setting_int }, { "get_setting_str", get_setting_str }, { "is_dir", is_dir }, { "is_rl_variable_true", is_rl_variable_true }, { "lower", to_lowercase }, { "matches_are_files", matches_are_files }, { "slash_translation", slash_translation }, { "suppress_char_append", suppress_char_append }, { "suppress_quoting", suppress_quoting }, { NULL, NULL } }; if (g_lua != NULL) { return g_lua; } // Initialise Lua. g_lua = luaL_newstate(); luaL_openlibs(g_lua); // Add our API. lua_createtable(g_lua, 0, 0); lua_setglobal(g_lua, "clink"); lua_getglobal(g_lua, "clink"); luaL_setfuncs(g_lua, clink_native_methods, 0); lua_pop(g_lua, 1); // Load all the .lua files alongside the dll and in the script folder. if (g_inject_args.script_path[0] == '\0') { get_dll_dir(buffer, sizeof_array(buffer)); } else { buffer[0] = '\0'; str_cat(buffer, g_inject_args.script_path, sizeof_array(buffer)); } path_hash = hash_string(buffer); i = (int)strlen(buffer); str_cat(buffer, "/clink.lua", sizeof_array(buffer)); load_lua_script(buffer); buffer[i] = '\0'; load_lua_scripts(buffer); get_config_dir(buffer, sizeof(buffer)); if (hash_string(buffer) != path_hash) { load_lua_scripts(buffer); } if (!once) { rl_add_funmap_entry("reload-lua-state", reload_lua_state); once = 1; } return g_lua; }
//------------------------------------------------------------------------------ static void get_settings_file(char* buffer, int buffer_size) { get_config_dir(buffer, buffer_size); str_cat(buffer, "/settings", buffer_size); }
bool FeSettings::scrape_artwork( const std::string &emu_name, UiUpdate uiu, void *uid, std::string &msg ) { FeEmulatorInfo *emu = m_rl.get_emulator( emu_name ); if ( emu == NULL ) return false; // // Put up the "scraping artwork" message at 0 percent while we get going... // if ( uiu ) uiu( uid, 0 ); std::cout << "*** Scraping artwork for: " << emu_name << std::endl; FeRomInfoListType romlist; std::string fn = get_config_dir() + FE_ROMLIST_SUBDIR + emu_name + FE_ROMLIST_FILE_EXTENSION; FeImporterContext ctx( *emu, romlist ); ctx.uiupdate = uiu; ctx.uiupdatedata = uid; if ( file_exists( fn ) ) { FeRomList loader( get_config_dir() ); loader.load_from_file( fn, ";" ); ctx.romlist.swap( loader.get_list() ); } else { ctx.progress_range=33; build_basic_romlist( ctx ); apply_xml_import( ctx ); ctx.progress_past=33; } ctx.progress_range = ( 100-ctx.progress_past ) / 2; ctx.scrape_art = true; confirm_directory( get_config_dir(), FE_SCRAPER_SUBDIR ); // do the mamedb scraper first (which only does anything for mame) followed // by the more general thegamesdb scraper. these return false if the user // cancels... if ( mamedb_scraper( ctx ) ) { ctx.progress_past = ctx.progress_past + ctx.progress_range; thegamesdb_scraper( ctx ); } if ( uiu ) uiu( uid, 100 ); std::cout << "*** Scraping done." << std::endl; if ( ctx.user_message.empty() ) get_resource( "Scraped $1 artwork file(s)", as_str( ctx.download_count ), msg ); else msg = ctx.user_message; return true; }