unsigned geoip_num_countries() { if ((void*)xqf_geoip_country_code == (void*)-1) return 0; if (!xqf_geoip_country_code) { unsigned i; xqf_geoip_country_name = lookup_symbol("GeoIP_country_name"); xqf_geoip_country_code = lookup_symbol("GeoIP_country_code"); if (!xqf_geoip_country_name || !xqf_geoip_country_code) { /* nasty hack to determine the number of countries at run time */ MaxCountries = LAN_GeoIPid = 0; xqf_geoip_country_name = (void*)-1; xqf_geoip_country_code = (void*)-1; return 0; } for (i = 0; xqf_geoip_country_code[i*3] && i < 333 /* arbitrary limit */; ++i) /* nothing */; if (i >= 333) { xqf_geoip_country_name = (void*)-1; xqf_geoip_country_code = (void*)-1; xqf_error("failed to determine number of supported countries"); return 0; } MaxCountries = LAN_GeoIPid = i; } debug(1, "MaxCountries %u", MaxCountries); return MaxCountries; }
void script_set_env(void* data) { char buf[256]; GSList* l; struct script_env_callback_data* d = data; server_set_env(d->s); for (l = g_slist_next(d->script->options); l; l = g_slist_next(l)) { ScriptOption* opt = l->data; debug(4, "%s %s", opt->section, opt->defval); snprintf(buf, sizeof(buf), "XQF_SCRIPT_OPTION_%s", opt->section+7); switch(opt->type) { case SCRIPT_OPTION_TYPE_STRING: case SCRIPT_OPTION_TYPE_INT: case SCRIPT_OPTION_TYPE_LIST: if (opt->defval) { setenv(buf, opt->defval, 1); } break; case SCRIPT_OPTION_TYPE_BOOL: setenv(buf, opt->enable?"true":"false", 1); break; case SCRIPT_OPTION_TYPE_INVALID: xqf_error("unreachable code"); break; } } }
static void* lookup_symbol(const char* name) { void* p; char* error; dlerror(); p = dlsym(NULL, name); if ((error = dlerror()) != NULL) { xqf_error("failed to lookup %s: %s", name, error); return NULL; } return p; }
void geoip_init(void) { const char* geoipdat = getenv("xqf_GEOIPDAT"); if (gi) return; // already initialized if (geoipdat) gi = GeoIP_open(geoipdat, GEOIP_STANDARD); if (!gi) gi = GeoIP_new(GEOIP_STANDARD); if (gi && geoip_num_countries()) flags = g_malloc0((MaxCountries+1) *sizeof(struct pixmap)); /*+1-> flag for LAN server*/ else { geoip_done(); xqf_error("GeoIP initialization failed"); } }
void save_script_prefs() { GList* s; char path[PATH_MAX]; for (s = scripts; s; s = g_list_next(s)) { Script* script; GSList* optlist; script = g_datalist_get_data(&scriptdata, s->data); if (!script) { xqf_error("no data for script %s", s->data); continue; } snprintf(path, sizeof(path), "/" CONFIG_FILE "/scripts/%s", (char*)s->data); config_push_prefix(path); for (optlist = script->options; optlist; optlist = g_slist_next(optlist)) { ScriptOption* opt = optlist->data; const char* val = NULL; int enable = 0; switch(opt->type) { case SCRIPT_OPTION_TYPE_STRING: case SCRIPT_OPTION_TYPE_INT: case SCRIPT_OPTION_TYPE_LIST: val = gtk_entry_get_text(GTK_ENTRY(opt->widget)); if (!strlen(val)) { val = NULL; } if ((!val && opt->defval) || (val && !opt->defval) || (val && opt->defval && strcmp(opt->defval, val))) { g_free(opt->defval); debug(4, "set %s/%s=%s (before: %s)", s->data, opt->section, val, opt->defval); if (opt->type == SCRIPT_OPTION_TYPE_INT) { int tmp = val?atoi(val):0; config_set_int(opt->section, tmp); opt->defval = g_strdup_printf("%d", tmp); } else { config_set_string(opt->section, val?val:""); opt->defval = val?strdup(val):NULL; } } break; case SCRIPT_OPTION_TYPE_BOOL: enable = GTK_TOGGLE_BUTTON(opt->widget)->active; if (enable != opt->enable) { config_set_bool(opt->section, enable); debug(4, "set %s/%s=%d", s->data, opt->section, enable); opt->enable = enable; } break; case SCRIPT_OPTION_TYPE_INVALID: break; } } config_pop_prefix(); } }
static GtkWidget* create_script_option_widget(Script* script, ScriptOption* opt) { GtkWidget* ret = NULL; opt->widget = NULL; switch(opt->type) { case SCRIPT_OPTION_TYPE_STRING: case SCRIPT_OPTION_TYPE_INT: { GtkWidget* hbox = ret = gtk_hbox_new(FALSE, 0); GtkWidget* label = gtk_label_new(opt->name); GtkWidget* entry = opt->widget = gtk_entry_new(); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 4); gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 4); if (opt->defval) { gtk_entry_set_text(GTK_ENTRY(entry), opt->defval); } gtk_widget_show(hbox); gtk_widget_show(label); gtk_widget_show(entry); } break; case SCRIPT_OPTION_TYPE_BOOL: { GtkWidget* button = ret = opt->widget = gtk_check_button_new_with_label(opt->name); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), opt->enable); gtk_widget_show(button); } break; case SCRIPT_OPTION_TYPE_LIST: { GtkWidget* hbox = ret = gtk_hbox_new(FALSE, 0); GtkWidget* label = gtk_label_new(opt->name); GtkWidget* combo = gtk_combo_new (); GList* list = NULL; unsigned i; for (i = 0; i < opt->list->len; ++i) { list = g_list_append(list, g_ptr_array_index(opt->list, i)); } gtk_combo_set_popdown_strings(GTK_COMBO (combo), list); g_list_free(list); gtk_combo_set_use_arrows_always (GTK_COMBO (combo), TRUE); gtk_list_set_selection_mode (GTK_LIST (GTK_COMBO (combo)->list), GTK_SELECTION_BROWSE); if (opt->defval) { gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), opt->defval); } opt->widget = GTK_COMBO(combo)->entry; gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 4); gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 4); gtk_widget_show(combo); gtk_widget_show(label); gtk_widget_show(hbox); } break; case SCRIPT_OPTION_TYPE_INVALID: xqf_error("unreachable code"); break; } gtk_widget_ref(opt->widget); return ret; }
void scripts_load() { GSList* dir; GList* s; unsigned i; char path[PATH_MAX]; if (!scriptdata) { g_datalist_init(&scriptdata); } /* g_datalist_get_data(&scriptdata, "foo"); g_datalist_set_data_full(&scriptdata,"foo",value,g_free); */ for (dir = scriptdirs; dir; dir = g_slist_next(dir)) { GList* s = dir_to_list(dir->data, script_filter); scripts = merge_sorted_string_lists(scripts, s); } for (s = scripts; s; s = g_list_next(s)) { unsigned version; config_section_iterator* sit; Script* script; const char* filename = s->data; char* errtitle = _("Script error"); // already known? if (g_datalist_get_data(&scriptdata, filename)) { continue; } script = script_new(); snprintf(path, sizeof(path), "/scripts/%s/General", filename); config_push_prefix(path); version = config_get_int("xqf version"); script->summary = config_get_string("summary"); script->author = config_get_string("author"); script->license = config_get_string("license"); config_pop_prefix(); if (version > MAX_SCRIPT_VERSION) { dialog_ok(errtitle, _("Script %s has version %d, xqf only supports version %d."), filename, version, MAX_SCRIPT_VERSION); script_free(script); continue; } if (!script->summary) { dialog_ok(errtitle, _("Script %s missing summary."), filename); script_free(script); continue; } if (!script->author) { dialog_ok(errtitle, _("Script %s missing author."), filename); script_free(script); continue; } if (!script->license) { dialog_ok(errtitle, _("Script %s missing license."), filename); script_free(script); continue; } script->name = g_strdup(filename); snprintf(path, sizeof(path), "/scripts/%s/Action", filename); config_push_prefix(path); for (i = 0; i < NUM_ACTIONS; ++i) { gboolean on = config_get_bool(action_key[i]); if (on) { action[i] = g_slist_prepend(action[i], script); } } config_pop_prefix(); // treat script property 'enabled' as option as it has a widget // so it's easier to handle later { ScriptOption* opt; snprintf(path, sizeof(path), "/" CONFIG_FILE "/scripts/%s/enabled=false", filename); opt = scriptoption_new("bool"); opt->enable = config_get_bool(path); // Translator: whether this plugin script is enabled opt->name = _("Enabled"); opt->section = g_strdup("enabled"); script->options = g_slist_prepend(script->options, opt); } snprintf(path, sizeof(path), "/scripts/%s", filename); sit = config_init_section_iterator(path); while (sit) { char* sname = NULL; sit = config_section_iterator_next(sit, &sname); if (strlen(sname) > 7 && !strncmp(sname, "option ", 7)) { char* typestr; char* name; ScriptOption* opt; char settings_path[PATH_MAX]; snprintf(settings_path, sizeof(settings_path), "/" CONFIG_FILE "/scripts/%s/%s", filename, sname); snprintf(path, sizeof(path), "/scripts/%s/%s", filename, sname); config_push_prefix(path); typestr = config_get_string("type"); name = config_get_string("name"); opt = scriptoption_new(typestr); g_free(typestr); if (!opt || !name) { xqf_warning("script %s: invalid option %s", filename, sname+7); goto next; } opt->name = name; opt->section = sname; switch(opt->type) { case SCRIPT_OPTION_TYPE_LIST: { config_key_iterator* it; it = config_init_iterator(path); if (!opt->list) { opt->list = g_ptr_array_new(); } while (it) { char* key = NULL; char* val = NULL; it = config_iterator_next(it, &key, &val); if (!strncmp(key, "value",5)) { g_ptr_array_add(opt->list, val); } else { g_free(val); } g_free(key); } } // fall through case SCRIPT_OPTION_TYPE_STRING: case SCRIPT_OPTION_TYPE_INT: { char* defval = NULL; char* curval = NULL; defval = config_get_string("default"); curval = config_get_string(settings_path); if (curval) { opt->defval = g_strdup(curval); } else if (defval) { opt->defval = g_strdup(defval); } g_free(defval); g_free(curval); } break; case SCRIPT_OPTION_TYPE_BOOL: { gboolean defval; gboolean curval; int is_deflt = 0; defval = config_get_bool("default=false"); curval = config_get_bool_with_default(settings_path, &is_deflt); if (is_deflt) { opt->enable = defval; } else { opt->enable = curval; } } break; case SCRIPT_OPTION_TYPE_INVALID: xqf_error("unreachable code"); break; } script->options = g_slist_prepend(script->options, opt); next: config_pop_prefix(); } } script->options = g_slist_reverse(script->options); g_datalist_set_data_full(&scriptdata, filename, script, (GDestroyNotify)script_free); snprintf(path, sizeof(path), "/scripts/%s", filename); config_drop_file(path); } }