diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h index 83bb70c999b210d044808683ecfbaeb49b9c7951..53067fe5f6c6752625b7d1d1e0bc08dae8444828 100644 --- a/inc/lektor/commands.h +++ b/inc/lektor/commands.h @@ -28,7 +28,8 @@ bool command_stop (volatile sqlite3 *db, struct lkt_win *win, bool command_set_pos(volatile sqlite3 *db, struct lkt_win *win, mpd_idle_flag *watch_mask_ptr, int index); /* The queue */ -bool command_add (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr, int priority); +bool command_add (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr, + int priority); bool command_addid (volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr); bool command_del (volatile sqlite3 *db, struct lkt_win *win, char *pos_range, mpd_idle_flag *watch_mask_ptr); bool command_delid (volatile sqlite3 *db, struct lkt_win *win, char *id, mpd_idle_flag *watch_mask_ptr); diff --git a/inc/lektor/database.h b/inc/lektor/database.h index d50fa1d2b4e8bacf49a538201bf5872b8739fc9d..2923dc854a8616e850d06b0eca577cbec253440f 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -96,8 +96,8 @@ struct lkt_search { const char *name; /* Stickers and playlists */ int st_value; /* The value of a sticker */ int st_uri; /* URI of a sticker */ - - char *ka_col_name; /* Column name for karas */ + char st_op; /* Comparaison operator for stickers */ + char *st_type; /* Type of sticker */ char *ka_rgx; /* Regex for the content of the selected column */ }; @@ -108,7 +108,7 @@ typedef bool (*lkt_search_sticker_func) (struct lkt_state *srv, size_t c, const bool database_search_database_init(volatile sqlite3 *db, struct lkt_search *ret); bool database_search_queue_init (volatile sqlite3 *db, struct lkt_search *ret); -bool database_search_sticker_init (volatile sqlite3 *db, char *type, char *name, int uri, char op, int value, struct lkt_search *ret); +bool database_search_sticker_init (volatile sqlite3 *db, struct lkt_search *ret); bool database_search_iter(struct lkt_search *item); /* Next and prev operation on the queue. */ diff --git a/src/commands.c b/src/commands.c index 4db7b1d58eacf67704d2c5d0a472f821229ce1b4..b205df41cace9d5564608a9a22a0d0bf766247d2 100644 --- a/src/commands.c +++ b/src/commands.c @@ -415,19 +415,25 @@ command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MA /* Select the right column */ mpd_tag = cmd_args[0]; if (!strcasecmp("any", mpd_tag) || !strcasecmp("all", mpd_tag) || !strcasecmp("query", mpd_tag) || - !strcasecmp("source", mpd_tag) || !strcasecmp("title", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_KARA_COLUMNT_ANY; - } else if (!strcasecmp("author", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_NAME_KAUTHOR; - } else if (!strcasecmp("category", mpd_tag) || !strcasecmp("cat", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_NAME_KCAT; - } else if (!strcasecmp("type", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_NAME_KTYPE; - } else if (!strcasecmp("language", mpd_tag) || !strcasecmp("lang", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_NAME_KLANG; - } else if (!strcasecmp("id", mpd_tag)) { - search.ka_col_name = LKT_DATABASE_NAME_KID; - } else + !strcasecmp("source", mpd_tag) || !strcasecmp("title", mpd_tag)) + search.name = LKT_DATABASE_KARA_COLUMNT_ANY; + + else if (!strcasecmp("author", mpd_tag)) + search.name = LKT_DATABASE_NAME_KAUTHOR; + + else if (!strcasecmp("category", mpd_tag) || !strcasecmp("cat", mpd_tag)) + search.name = LKT_DATABASE_NAME_KCAT; + + else if (!strcasecmp("type", mpd_tag)) + search.name = LKT_DATABASE_NAME_KTYPE; + + else if (!strcasecmp("language", mpd_tag) || !strcasecmp("lang", mpd_tag)) + search.name = LKT_DATABASE_NAME_KLANG; + + else if (!strcasecmp("id", mpd_tag)) + search.name = LKT_DATABASE_NAME_KID; + + else return false; /* Get the regex */ @@ -726,17 +732,21 @@ bool command_sticker_get(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX]) { RETURN_UNLESS(argv[0] && argv[1] && argv[2] && !argv[3], "Invalid argument", false); - int uri, err; - char *endptr; + long uri; + char *endptr, err; STRTOL(uri, argv[1], endptr, err); RETURN_IF(err, "STRTOL failed", false); struct lkt_search cb = { + .call = (void(*)(void)) sticker_send, .srv = srv, .c = c, + .name = argv[2], + .st_type = argv[0], + .st_uri = (int) uri, }; - if (!database_search_sticker_init(srv->db, argv[0], argv[2], uri, 0, 0, &cb)) + if (!database_search_sticker_init(srv->db, &cb)) return false; - while(database_search_iter(&cb)) + while (database_search_iter(&cb)) continue; return true; } @@ -763,50 +773,46 @@ command_sticker_list(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARG .srv = srv, .c = c, .call = (void(*)(void)) sticker_send, + .st_type = argv[0], }; /* Simple list {type} {uri} command */ - if (argv[0] != NULL && argv[1] != NULL && argv[2] == NULL) - goto simple_list_command; + if (argv[0] != NULL && argv[1] != NULL && argv[2] == NULL) { + callback.st_uri = atoi(argv[1]); + if (database_search_sticker_init(srv->db, &callback)) + goto iter; + } /* list {type} {uri} {name} command */ else if (argv[0] != NULL && argv[1] != NULL && - argv[2] != NULL && argv[3] == NULL) - goto list_stickers_in_uri; + argv[2] != NULL && argv[3] == NULL) { + callback.name = argv[2]; + callback.st_uri = atoi(argv[1]); + if (database_search_sticker_init(srv->db, &callback)) + goto iter; + } /* list {type} {uri} {name} `op` {value} command */ else if (argv[0] != NULL && argv[1] != NULL && argv[2] != NULL && argv[3] != NULL && - argv[4] != NULL && argv[5] == NULL) - goto list_stickers_check_value; + argv[4] != NULL && argv[5] == NULL) { + callback.name = argv[2]; + callback.st_uri = atoi(argv[1]); + callback.st_op = argv[3][0]; + callback.st_value = atoi(argv[4]); + if (database_search_sticker_init(srv->db, &callback)) + goto iter; + } /* Just list all stickers */ - else if ( (argv[0] != NULL && argv[1] == NULL) || argv[0] == NULL ) - goto just_list_all; + else if ( (argv[0] != NULL && argv[1] == NULL) || argv[0] == NULL ) { + if (database_search_sticker_init(srv->db, &callback)) + goto iter; + } else goto unknown; -just_list_all: - if (!database_search_sticker_init(srv->db, argv[0], NULL, 0, 0, 0, &callback)) - return false; - goto iter; - -simple_list_command: - if (!database_search_sticker_init(srv->db, argv[0], NULL, atoi(argv[1]), 0, 0, &callback)) - return false; - goto iter; - -list_stickers_in_uri: - if (!database_search_sticker_init(srv->db, argv[0], argv[2], atoi(argv[1]), 0, 0, &callback)) - return false; - goto iter; - -list_stickers_check_value: - if (!database_search_sticker_init(srv->db, argv[0], argv[2], atoi(argv[1]), argv[3][0], atoi(argv[4]), &callback)) - return false; - goto iter; - iter: while (database_search_iter(&callback)) continue; diff --git a/src/database/find.c b/src/database/find.c index 73e566369984c7dc9d02fafc71fe9abe62f57a5c..c31a1ab690e07d45ff1e46760336fc03f01b53ae 100644 --- a/src/database/find.c +++ b/src/database/find.c @@ -22,7 +22,7 @@ database_search_database_init(volatile sqlite3 *db, struct lkt_search *ret) ret->type = lkt_search_database; /* Search part */ - snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, ret->ka_col_name, + snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, ret->name, ret->msg_count, ret->continuation); SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0; SQLITE_PREPARE(db, ret->stmt, SQL_STMT, error); @@ -35,7 +35,7 @@ error: } bool -database_search_sticker_init(volatile sqlite3 *db, char *type, char *name, int uri, char op, int value, struct lkt_search *ret) +database_search_sticker_init(volatile sqlite3 *db, struct lkt_search *ret) { /* No bound checks in strcats, should be fine. Possible SQL injection, depend on the `type`. */ static const char *SQL_all_types = @@ -52,19 +52,21 @@ database_search_sticker_init(volatile sqlite3 *db, char *type, char *name, int u "ON 'stickers'.id = sts.sticker"; char SQL[LKT_MAX_SQLITE_STATEMENT]; - if (type == NULL) + if (ret->st_type == NULL) memcpy(SQL, SQL_all_types, strlen(SQL_all_types) + 1); else - sprintf(SQL, SQL_one_type, type, type); - if (uri != 0) - sprintf(SQL, " AND sts.id = %d", uri); - if (op != 0) - sprintf(SQL, " AND sts.value %s %d", op == '>' ? ">=" : op == '<' ? "<=" : "=", value); - strcat(SQL, name ? " AND name = ?;": ";"); + sprintf(SQL, SQL_one_type, ret->st_type, ret->st_type); + if (ret->st_uri != 0) + sprintf(SQL, " AND sts.id = %d", ret->st_uri); + if (ret->st_op != 0) + sprintf(SQL, " AND sts.value %s %d", + ret->st_op == '>' ? ">=" : ret->st_op == '<' ? "<=" : "=", + ret->st_value); + strcat(SQL, ret->name ? " AND name = ?;" : ";"); SQLITE_PREPARE(db, ret->stmt, SQL, error); - if (name) - SQLITE_BIND_TEXT(db, ret->stmt, 1, name, error) + if (ret->name) + SQLITE_BIND_TEXT(db, ret->stmt, 1, ret->name, error) return true; error: sqlite3_finalize(ret->stmt); @@ -87,7 +89,7 @@ database_search_queue_init(volatile sqlite3 *db, struct lkt_search *ret) ret->type = lkt_search_queue; /* Search part */ - snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, ret->ka_col_name, + snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, ret->name, ret->msg_count, ret->continuation); SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0; SQLITE_PREPARE(db, ret->stmt, SQL_STMT, error);