static int dbops_fixup_func(void** param, int init_act) { struct dbops_action **p, *a; char *c; int res; /* check if is it a declare_no that references to declare_xxxx */ c = *param; eat_spaces(c); *param = c; eat_alphanum(c); if (*c == 0) { a = find_action_by_name(*param, -1); if (!a) { ERR(MODULE_NAME": fixup_func: query (%s) not declared\n", (char*) *param); return -1; } *param = (void*) a; return 0; } for (p = &dbops_actions; *p; p=&(*p)->next); /* add at the end of list */ res = parse_ops(*param, p, init_act == 0 /* declare query has name */); if (res < 0) return res; /* pkg_free(*param); do not free it!*/ *param = (void*) *p; if (init_act) return init_action(*p); /* fixup is acquired after init_mod() therefore initialize new action */ else return 0; }
static int sel_do_select(str* result, str *query_name, int row_no, int field_no, struct sip_msg* msg) { struct dbops_action *a; int cur_row_no, res; a = find_action_by_name(query_name->s, query_name->len); if (!a) { ERR(MODULE_NAME": select: query: %.*s not declared using declare_query param\n", query_name->len, query_name->s); return -1; } if (a->operation != OPEN_QUERY_OPS) { ERR(MODULE_NAME": select: query: %.*s is not select\n", query_name->len, query_name->s); return -1; } if (row_no < 0) { ERR(MODULE_NAME": select: Row number must not be negative: %d\n", row_no); return -1; } res = dbops_func(msg, a); if (res < 0) return res; cur_row_no = -1; if (field_no >= 0) { if (do_seek(a->result, &cur_row_no, row_no) < 0) return -1; } res = sel_get_field(result, &cur_row_no, field_no, a->result); db_res_free(a->result); return res; }
static int sel_timer(str* res, select_t* s, struct sip_msg* msg) { struct timer_action* a; if (!msg) { /* select fixup */ a = find_action_by_name(timer_actions /* called after mod_init */, s->params[2].v.s.s, s->params[2].v.s.len); if (!a) { ERR(MODULE_NAME": timer_enable_fixup: timer '%.*s' not declared\n", s->params[2].v.s.len, s->params[2].v.s.s); return E_CFG; } s->params[2].v.p = a; } return 0; }
static int hotkeys_load (void) { GtkWidget *hotkeys = lookup_widget (prefwin, "hotkeys_list"); GtkListStore *hkstore = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (hotkeys))); gtk_list_store_clear (hkstore); int n_items = 0; DB_conf_item_t *item = deadbeef->conf_find ("hotkey.", NULL); while (item) { char token[MAX_TOKEN]; char keycombo[MAX_TOKEN]; int ctx; int isglobal; DB_plugin_action_t *action; const char *script = item->value; if ((script = gettoken (script, keycombo)) == 0) { goto out; } if ((script = gettoken (script, token)) == 0) { goto out; } ctx = atoi (token); if (ctx < 0 || ctx >= DDB_ACTION_CTX_COUNT) { goto out; } if ((script = gettoken (script, token)) == 0) { goto out; } isglobal = atoi (token); if ((script = gettoken (script, token)) == 0) { goto out; } action = find_action_by_name (token); if (!action) { goto out; } GtkTreeIter iter; gtk_list_store_append (hkstore, &iter); const char *t = get_display_action_title (action->title); char title[100]; unescape_forward_slash (t, title, sizeof (title)); gtk_list_store_set (hkstore, &iter, 0, keycombo, 1, title, 2, ctx_names[ctx], 3, isglobal, 4, action->name, 5, ctx, -1); n_items++; out: item = deadbeef->conf_find ("hotkey.", item); } return n_items; }
static int timer_enable_fixup(void** param, int param_no) { struct timer_action* a; int /*res, */n; switch (param_no) { case 1: a = find_action_by_name(timer_actions /* called after mod_init*/, (char*) *param, -1); if (!a) { ERR(MODULE_NAME": timer_enable_fixup: timer '%s' not declared\n", (char*) *param); return E_CFG; } *param = a; break; case 2: /* res = fixup_int_12(param, param_no); if (res < 0) return res; */ n=atoi((char *)*param); *param = (void*)(long)(/*(int) *param*/n != 0); break; default: ; } return 0; }
static int read_config (Display *disp) { int ks_per_kk; int first_kk, last_kk; Atom* syms; XDisplayKeycodes (disp, &first_kk, &last_kk); syms = XGetKeyboardMapping (disp, first_kk, last_kk - first_kk, &ks_per_kk); #else #define ShiftMask (1<<0) #define LockMask (1<<1) #define ControlMask (1<<2) #define Mod1Mask (1<<3) #define Mod2Mask (1<<4) #define Mod3Mask (1<<5) #define Mod4Mask (1<<6) #define Mod5Mask (1<<7) int ks_per_kk = -1; int first_kk = -1, last_kk = -1; int* syms = NULL; static int read_config (void) { #endif DB_conf_item_t *item = deadbeef->conf_find ("hotkey.", NULL); while (item) { if (command_count == MAX_COMMAND_COUNT) { fprintf (stderr, "hotkeys: maximum number (%d) of commands exceeded\n", MAX_COMMAND_COUNT); break; } command_t *cmd_entry = &commands[ command_count ]; memset (cmd_entry, 0, sizeof (command_t)); char token[MAX_TOKEN]; char keycombo[MAX_TOKEN]; const char *script = item->value; if ((script = gettoken (script, keycombo)) == 0) { trace ("hotkeys: unexpected eol (keycombo)\n"); goto out; } if ((script = gettoken (script, token)) == 0) { trace ("hotkeys: unexpected eol (ctx)\n"); goto out; } cmd_entry->ctx = atoi (token); if (cmd_entry->ctx < 0 || cmd_entry->ctx >= DDB_ACTION_CTX_COUNT) { trace ("hotkeys: invalid ctx %d\n", cmd_entry->ctx); goto out; } if ((script = gettoken (script, token)) == 0) { trace ("hotkeys: unexpected eol (isglobal)\n"); goto out; } cmd_entry->isglobal = atoi (token); if ((script = gettoken (script, token)) == 0) { trace ("hotkeys: unexpected eol (action)\n"); goto out; } cmd_entry->action = find_action_by_name (token); if (!cmd_entry->action) { trace ("hotkeys: action not found %s\n", token); goto out; } // parse key combo int done = 0; char* p; char* space = keycombo; do { p = space; space = strchr (p, ' '); if (space) { *space = 0; space++; } else done = 1; if (0 == strcasecmp (p, "Ctrl")) cmd_entry->modifier |= ControlMask; else if (0 == strcasecmp (p, "Alt")) cmd_entry->modifier |= Mod1Mask; else if (0 == strcasecmp (p, "Shift")) cmd_entry->modifier |= ShiftMask; else if (0 == strcasecmp (p, "Super")) { cmd_entry->modifier |= Mod4Mask; } else { if (p[0] == '0' && p[1] == 'x') { // parse hex keycode int r = sscanf (p, "0x%x", &cmd_entry->keycode); if (!r) { cmd_entry->keycode = 0; } } else { // lookup name table cmd_entry->keycode = get_keycode (p); #ifndef NO_XLIB_H cmd_entry->x11_keycode = get_x11_keycode (p, syms, first_kk, last_kk, ks_per_kk); trace ("%s: kc=%d, xkc=%d\n", p, cmd_entry->keycode, cmd_entry->x11_keycode); #endif } if (!cmd_entry->keycode) { trace ("hotkeys: got 0 from get_keycode while adding hotkey: %s %s\n", item->key, item->value); break; } } } while (!done); if (done) { if (cmd_entry->keycode == 0) { trace ("hotkeys: Key not found while parsing %s %s\n", item->key, item->value); } else { command_count++; } } out: item = deadbeef->conf_find ("hotkey.", item); } #ifndef NO_XLIB_H XFree (syms); int i; // need to grab it here to prevent gdk_x_error from being called while we're // doing it on other thread for (i = 0; i < command_count; i++) { if (!commands[i].isglobal) { continue; } for (int f = 0; f < 16; f++) { uint32_t flags = 0; if (f & 1) { flags |= LockMask; } if (f & 2) { flags |= Mod2Mask; } if (f & 4) { flags |= Mod3Mask; } if (f & 8) { flags |= Mod5Mask; } trace ("XGrabKey %d %x\n", commands[i].keycode, commands[i].modifier | flags); XGrabKey (disp, commands[i].x11_keycode, commands[i].modifier | flags, DefaultRootWindow (disp), False, GrabModeAsync, GrabModeAsync); } } #endif return 0; }
static int parse_ops(char* act_s, struct dbops_action** action, int has_name) { int res = 0, i; char *c, *s, *part; static int query_no = 0; s = act_s; *action = pkg_malloc(sizeof(**action)); if (!*action) return E_OUT_OF_MEM; memset(*action, 0, sizeof(**action)); (*action)->query_no = query_no++; eat_spaces(s); c = s; eat_alphanum(c); if (has_name) { char *c2; c2 = c; eat_spaces(c2); if (c != s && *c2 == '=') { *c = '\0'; if (find_action_by_name(s, -1) != NULL) { ERR(MODULE_NAME": parse_ops: duplicate query name: %s\n", s); return E_CFG; } (*action)->query_name = s; s = c2+1; eat_spaces(s); c = s; eat_alphanum(c); } else { ERR(MODULE_NAME": parse_ops: query_no: %d, valid query name not found in '%s'\n%s\n%s\n", (*action)->query_no, s, c, c2); return E_CFG; } } if (c[0] == ':' && c[1] == '/' && c[2] == '/') { /* database part is optional */ for (c=s; *c!=':'; c++) { *c = tolower(*c); /* _type_://user:host/database_name/ */ } (*action)->db_url = s; s = c+1; while (*s == '/') s++; res = get_next_part(&s, &part, PART_DELIM, 1); /* type://_user:host_/database_name/ */ if (res < 0) return res; res = get_next_part(&s, &part, PART_DELIM, 0); /* type://user:host/_database_name_/ */ if (res < 0) return res; } res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; for (c = part; *c && *c != PART_DELIM; c++) { if (*c == ' ') { (*action)->is_raw_query = 1; *c = '\0'; break; } } if (strcasecmp(part, "select") == 0) (*action)->operation = OPEN_QUERY_OPS; else if (strcasecmp(part, "insert") == 0) (*action)->operation = INSERT_OPS; else if (strcasecmp(part, "update") == 0) (*action)->operation = UPDATE_OPS; else if (strcasecmp(part, "replace") == 0) (*action)->operation = REPLACE_OPS; else if (strcasecmp(part, "delete") == 0) (*action)->operation = DELETE_OPS; else { if ((*action)->is_raw_query) *c = ' '; ERR(MODULE_NAME": parse_ops: query: %s(%d), unknown type of query '%s'\n", (*action)->query_name, (*action)->query_no, part); return E_CFG; } if ((*action)->is_raw_query) { *c = ' '; (*action)->raw.s = part; (*action)->table.s = part; } res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; if (!(*action)->is_raw_query) { if (!*part) { ERR(MODULE_NAME": parse_ops: query: %s(%d), table not specified near '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s); return E_CFG; } trim_apostr(&part); (*action)->table.s = part; res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; switch ((*action)->operation) { case OPEN_QUERY_OPS: case UPDATE_OPS: case REPLACE_OPS: case INSERT_OPS: res = split_fields(part, &(*action)->field_count, &(*action)->fields); if (res < 0) return res; if ((*action)->field_count == 0) { ERR(MODULE_NAME": parse_ops: query: %s(%d), no field specified near '%s' ?n '%s'\n", (*action)->query_name, (*action)->query_no, part, act_s); return E_CFG; } break; case DELETE_OPS: res = split_fields(part, &(*action)->where_count, &(*action)->wheres); if (res < 0) return res; res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; res = split_fields(part, &(*action)->op_count, &(*action)->ops); if (res < 0) return res; break; default:; } res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; switch ((*action)->operation) { case OPEN_QUERY_OPS: case UPDATE_OPS: res = split_fields(part, &(*action)->where_count, &(*action)->wheres); if (res < 0) return res; res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; res = split_fields(part, &(*action)->op_count, &(*action)->ops); if (res < 0) return res; res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; switch ((*action)->operation) { case OPEN_QUERY_OPS: if (*part) { (*action)->order.s = part; } res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; break; default:; } break; default: ; } } /* values */ res = split_fields(part, &(*action)->value_count, &(*action)->values); if (res < 0) return res; if ((*action)->value_count) { (*action)->value_types = (int*)pkg_malloc(sizeof(int) * (*action)->value_count); if ((*action)->value_types == NULL) { ERR(MODULE_NAME": No memory left\n"); return -1; } for (i=0; i<(*action)->value_count; i++) { (*action)->value_types[i] = DB_CSTR; // DB_NONE; /* let decide db driver itself, FIXME: until jjanak changes then default type is string */ res = get_type(&(*action)->values[i].s, &(*action)->value_types[i]); if (res < 0) return res; } } /* extra options */ res = get_next_part(&s, &part, PART_DELIM, 0); if (res < 0) return res; (*action)->extra_ops_count = 0; c = part; while (*c) { char *fld; res = get_next_part(&c, &fld, FLD_DELIM, 1); if (res < 0) return res; (*action)->extra_ops_count++; } if ((*action)->extra_ops_count > 0) { (*action)->extra_ops = pkg_malloc( (*action)->extra_ops_count*sizeof(*(*action)->extra_ops)); if (!(*action)->extra_ops) { ERR(MODULE_NAME": parse_ops: not enough pkg memory\n"); return E_OUT_OF_MEM; } memset((*action)->extra_ops, 0, (*action)->extra_ops_count*sizeof(*(*action)->extra_ops)); i = 0; c = part; while (*c) { char *fld; res = get_next_part(&c, &fld, FLD_DELIM, 0); if (res < 0) return res; /* name=[i|s]:value */ (*action)->extra_ops[i].name = fld; eat_alphanum(fld); if (*fld != '=') { ERR(MODULE_NAME": parse_ops: query: %s(%d), bad extra parameter format in '%s'\n", (*action)->query_name, (*action)->query_no, (*action)->extra_ops[i].name); return E_CFG; } *fld = '\0'; fld++; while (*fld==' ' || *fld=='\t') fld++; (*action)->extra_ops[i].type = DB_NONE; res = get_type(&fld, &(*action)->extra_ops[i].type); if (res < 0) return res; trim_apostr(&fld); (*action)->extra_ops[i].value = fld; DEBUG(MODULE_NAME": extra_ops #%d, name='%s', type=%d, val='%s'\n", i, (*action)->extra_ops[i].name, (*action)->extra_ops[i].type, (*action)->extra_ops[i].value); i++; } } if (*s) { ERR(MODULE_NAME": parse_ops: query: %s(%d), too many parameters/parts, remaining '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s); return E_CFG; } if ((*action)->is_raw_query) { DEBUG(MODULE_NAME": query: %s(%d) oper:%d database:'%s' query:'%s' value#:%d extra_ops#:%d\n", (*action)->query_name, (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->raw.s, (*action)->value_count, (*action)->extra_ops_count); } else { /* check num of fields */ if ((((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count)+(*action)->where_count != (*action)->value_count) { ERR(MODULE_NAME": parse_ops: query: %s(%d), number of values does not correspond to number of fields (%d+%d!=%d) in '%s'\n", (*action)->query_name, (*action)->query_no, ((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count, (*action)->where_count, (*action)->value_count, act_s); return E_CFG; } DEBUG(MODULE_NAME": query_no:%d oper:%d database:'%s' table:'%s' 'field#:'%d' where#:'%d' order:'%s' value#:%d extra_ops#:%d\n", (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->table.s, (*action)->field_count, (*action)->where_count, (*action)->order.s, (*action)->value_count, (*action)->extra_ops_count); } return 0; }
/* timer_id=route_no,interval_ms[,"slow"|"fast"[,"enable"]] */ static int declare_timer(modparam_t type, char* param) { int n; unsigned int route_no, interval, enabled, flags; struct timer_action *pa; char *p, *save_p, c, *timer_name; str s; timer_name = 0; save_p = p = param; eat_alphanum(p); if (*p != '=' || p == save_p) goto err; *p = '\0'; timer_name = save_p; p++; if (find_action_by_name(pkg_timer_actions, timer_name, -1) != NULL) { ERR(MODULE_NAME": declare_timer: timer '%s' already exists\n", timer_name); return E_CFG; } save_p = p; if (!get_next_part(&p, &s, ',')) goto err; c = s.s[s.len]; s.s[s.len] = '\0'; n = route_get(&main_rt, s.s); s.s[s.len] = c; if (n == -1) goto err; route_no = n; save_p = p; if (!get_next_part(&p, &s, ',')) goto err; if (str2int(&s, &interval) < 0) goto err; save_p = p; flags = 0; if (get_next_part(&p, &s, ',')) { if (s.len == 4 && strncasecmp(s.s, "FAST", 4)==0) flags = F_TIMER_FAST; else if (s.len == 4 && strncasecmp(s.s, "SLOW", 4)==0) ; else goto err; } save_p = p; enabled = 0; if (get_next_part(&p, &s, ',')) { if (s.len == 6 && strncasecmp(s.s, "ENABLE", 6)==0) enabled = 1; else goto err; } pa = pkg_malloc(sizeof(*pa)); /* cannot use shmmem here! */ if (!pa) { ERR(MODULE_NAME": cannot allocate timer data\n"); return E_OUT_OF_MEM; } memset(pa, 0, sizeof(*pa)); pa->timer_name = timer_name; pa->route_no = route_no; pa->interval = interval; pa->enable_on_start = enabled; pa->flags = flags; pa->next = pkg_timer_actions; pkg_timer_actions = pa; return 0; err: ERR(MODULE_NAME": declare_timer: timer_name: '%s', error near '%s'\n", timer_name, save_p); return E_CFG; }