diff --git a/README.md b/README.md index 749c74c16ddf988f593241e40b0727d61218055d..025f69a975befb820c4dc9e60fe07614adac4857 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ The manual way of installing and setting up lektor: ```sh sudo mkdir /home/kara && sudo chown USER:USER /home/kara -meson build && cd build -ninja && ninja install +meson build +ninja -C build && sudo ninja -C build install sudo chown USER:USER /home/kara/kara.db ``` diff --git a/doc/lektor.1 b/doc/lektor.1 index aa5f9cdaa5734ce3d24237493f3ad0d9cc7b2336..d10932c648eb3379ddb799c7e99cd0be201126dc 100644 --- a/doc/lektor.1 +++ b/doc/lektor.1 @@ -33,7 +33,20 @@ Lektord can be piloted over the network with \fBlkt\fP. \fBPlaylists and stickers\fP Reading and searching through the base can be facilitated by creating \fIplaylist\fP and using \fIstickers\fP (\fIMPD\fP version of tags). -.PP +.SH "INSTALLATION" +You may install lektor from source like this: +.sp +.RS 4 +.nf +\fB +% git clone https://git.iiens.net/martin2018/lektor && cd lektor +% sudo mkdir /home/kara && sudo chown USER:USER /home/kara +% meson build +% ninja -C build && sudo ninja -C build install +% sudo chown USER:USER /home/kara/kara.db +.fi \fR +.P +.RE .SH "SUPPORTED URIS" When searching the database, the following URIs are supported by lektor. Those URIs are hidden, you should not use them, but here is some documentation about diff --git a/doc/lektord.1 b/doc/lektord.1 index 5db48c628aee3f3345ca6d8521d5b17e4b89ae93..a49ff0118060fd5c1f0497eb8746bb80c085489e 100644 --- a/doc/lektord.1 +++ b/doc/lektord.1 @@ -17,20 +17,6 @@ You may be interested in other related programs like: Lektor allows one to interactivelly and remotly interact with the player. The lektor daemon is mpd compatible, even if some functionnalities may differ. You can almost use \fBmpc\fP with lektord. -.SH "INSTALLATION" -You may install lektor from source like this: -.sp -.RS 4 -.nf -\fB -% sudo mkdir /home/kara && sudo chown USER:USER /home/kara -% git clone https://git.iiens.net/martin2018/lektor && cd lektor -% mkdir build && meson build && cd build && ninja # Compilation -% sudo meson install --no-rebuild # Install -% sudo chown USER:USER /home/kara/kara.db # Or you will have some problems -.fi \fR -.P -.RE .SH "INVOCATION" To simply launch the daemon do not set any flag. The following flags are interpreted by the shell when invoked to determine where the shell will read diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h index a447ef3604501b192301410c5a365e592b11092e..c685230874d05f8d158d6faf8ae724ebbc32b643 100644 --- a/inc/lektor/commands.h +++ b/inc/lektor/commands.h @@ -60,10 +60,11 @@ bool command_noidle(struct lkt_state *srv, size_t c); /* Find commands */ enum lkt_find_action { - LKT_FND_ACT_NONE = 0, + LKT_FND_ACT_NONE = 0, LKT_FND_ACT_RESPOND = 1, - LKT_FND_ACT_PRINT = 2, + LKT_FND_ACT_PRINT = 2, LKT_FND_ACT_ENQUEUE = 3, + LKT_FND_ACT_ADD = 4, }; /* Find and send karas in the db that match the search expression */ diff --git a/inc/lektor/database.h b/inc/lektor/database.h index 1e7a7bfb66fa5207cc399d9158601e3f0c22373b..7494f9a21e70a520a8182a5e5fbafb017088cf79 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -58,14 +58,6 @@ bool database_queue_add_category(volatile sqlite3 *db, const char *author, int bool database_queue_add_type (volatile sqlite3 *db, const char *author, int priority); bool database_queue_add_plt (volatile sqlite3 *db, const char *plt_name, int priority); -bool database_queue_insert_query (volatile sqlite3 *db, const char *query, int pos); -bool database_queue_insert_id (volatile sqlite3 *db, int id); -bool database_queue_insert_author (volatile sqlite3 *db, const char *author); -bool database_queue_insert_language(volatile sqlite3 *db, const char *author); -bool database_queue_insert_category(volatile sqlite3 *db, const char *author); -bool database_queue_insert_type (volatile sqlite3 *db, const char *author); -bool database_queue_insert_plt (volatile sqlite3 *db, const char *plt_name); - bool database_queue_del_id (volatile sqlite3 *db, int id); bool database_queue_del_pos(volatile sqlite3 *db, int pos); bool database_queue_clear (volatile sqlite3 *db); diff --git a/scripts/getmanpath.sh b/scripts/getmanpath.sh old mode 100644 new mode 100755 diff --git a/scripts/init.sql b/scripts/init.sql index 21bffe9af33706a6d66816515760044f95c59789..040b0ff1005adb785082cc1a462f9e2436df7318 100644 --- a/scripts/init.sql +++ b/scripts/init.sql @@ -134,14 +134,3 @@ CREATE TABLE IF NOT EXISTS misc ); INSERT OR REPLACE INTO misc (id) VALUES (42); - - --- A simple view to select things in the queue, where the order matters and --- where we need to see all the priorities and position in a flatten manner. -CREATE VIEW IF NOT EXISTS queue_ AS - SELECT - ROW_NUMBER() OVER(ORDER BY priority DESC, position ASC) AS position, - kara_id, - priority, - queue.position AS old_position - FROM queue; diff --git a/src/commands.c b/src/commands.c index 7243a00bcadf8e4e81457d76ca7c37059a740b0a..8dbff5b2b389cda47de123abc6b39d5c263cf343 100644 --- a/src/commands.c +++ b/src/commands.c @@ -58,7 +58,7 @@ command_update(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX] } static inline void * -__rescan(void * arg) +__rescan(void *arg) { struct lkt_state *srv = arg; database_update(srv->db, srv->kara_prefix); @@ -465,7 +465,16 @@ static bool lkt_callback_insert_v1(struct lkt_state *srv, size_t c, int id, int id_len, const char *sql_row) { UNUSED(sql_row, id_len, c); - return database_queue_add_id(srv->db, id, 5); + return database_queue_add_id(srv->db, id, 5) && + lkt_callback_send_row_v2(srv, c, id, id_len, sql_row); +} + +static bool +lkt_callback_add_v2(struct lkt_state *srv, size_t c, int id, int id_len, const char *sql_row) +{ + UNUSED(sql_row, id_len, c); + return database_queue_add_id(srv->db, id, 1) && + lkt_callback_send_row_v2(srv, c, id, id_len, sql_row); } static bool @@ -498,6 +507,10 @@ __find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], lo search.call = (void(*)(void)) lkt_callback_insert_v1; srv->mpd_idle_events |= MPD_IDLE_PLAYLIST; break; + case LKT_FND_ACT_ADD: + search.call = (void(*)(void)) lkt_callback_add_v2; + srv->mpd_idle_events |= MPD_IDLE_PLAYLIST; + break; default: return false; } diff --git a/src/database/find.c b/src/database/find.c index 61205fe97ecf03b34acd92738de91f71d17cc970..9956610cdab7b533234b3cfa46a2280f3910ecf0 100644 --- a/src/database/find.c +++ b/src/database/find.c @@ -40,7 +40,7 @@ database_search_queue_init(volatile sqlite3 *db, char *col_name, char *rgx, stru static const char *SQL_STMT_TEMPLATE = "WITH content AS (" " SELECT kara_id AS id, string AS any_col, LENGTH(CAST(kara_id AS TEXT)) AS len" - " FROM queue_ " + " FROM queue" " JOIN kara " " ON kara_id = kara.id AND %s LIKE ?)" "SELECT id, any_col, (SELECT MAX(len) FROM content)" diff --git a/src/database/queue.c b/src/database/queue.c index 770796c60a8cc2b9aaddb0b8b5447c77fc0bd3b7..a8bf8a55a43b2bbc35a200e051b169aaaa37d76e 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -54,7 +54,7 @@ database_queue_current_kara(volatile sqlite3 *db, struct kara_metadata *res, int static const char *SQL_STMT = "SELECT song_name, source_name, category, language, author_name, song_type, song_number, kara_id" " FROM kara" - " JOIN queue_ ON kara_id = kara.id" + " JOIN queue ON kara_id = kara.id" " JOIN queue_state ON current = position"; sqlite3_stmt *stmt = 0; int ret = false; @@ -87,144 +87,141 @@ error: static bool queue_add_with_col_like_str(volatile sqlite3 *db, const char *col, const char *val, int priority) { - RETURN_IF(is_sql_str_invalid(col), "Column name is invalid", false); - - char SQL[LKT_MAX_SQLITE_STATEMENT]; +#define CURRENT_POS_OR_0 /* To move karas after the current */ \ + "(SELECT CASE WHEN (SELECT current FROM queue_state) IS NULL THEN 0" \ + " ELSE (SELECT current FROM queue_state) END AS val LIMIT 1)" static const char *SQL_STMT = + /* Add correspondig karas into the queue */ "INSERT INTO queue (kara_id, priority)" - " SELECT id, ?" - " FROM kara" - " WHERE %s LIKE ? AND available = 1" - " ORDER BY RANDOM();"; - bool status = false; + " SELECT id, ?" + " FROM kara" + " WHERE %s LIKE ? AND available = 1" + " ORDER BY RANDOM();"; + static const char *SQL_REORDER = + /* Create temporary tables */ + "CREATE TEMPORARY TABLE queue_tmp" + " ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)" + " , kara_id INTEGER" + " , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)" + " );" + /* Separate karas that are after the current one */ + "INSERT INTO queue_tmp (kara_id, priority)" + " SELECT kara_id, priority" + " FROM queue" + " WHERE position > " CURRENT_POS_OR_0 ";" + "DELETE FROM queue WHERE position > " CURRENT_POS_OR_0 ";" + /* Insert back */ + "INSERT INTO queue (position, kara_id, priority)" + " SELECT position + " CURRENT_POS_OR_0 ", kara_id, priority" + " FROM queue_tmp" + " ORDER BY priority, position;" + /* Drop temporary tables */ + "DROP TABLE queue_tmp;" + "DELETE FROM sqlite_sequence WHERE name = 'queue_tmp';"; +#undef CURRENT_POS_OR_0 + + RETURN_IF(is_sql_str_invalid(col), "Column name is invalid", false); + char SQL[LKT_MAX_SQLITE_STATEMENT]; sqlite3_stmt *stmt = NULL; + /* Begin, transactions are atomic so we won't be anoyed by multi-threading */ + SQLITE_EXEC(db, "BEGIN TRANSACTION;", error); + + /* Insert at the end of the queue */ snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT, col); SQL[LKT_MAX_SQLITE_STATEMENT - 1] = 0; SQLITE_PREPARE(db, stmt, SQL, error); SQLITE_BIND_INT(db, stmt, 1, priority, error); SQLITE_BIND_TEXT(db, stmt, 2, val, error); SQLITE_STEP_DONE(db, stmt, error); - status = true; -error: sqlite3_finalize(stmt); - return status; -} -static bool -queue_insert_with_col_like_str(volatile sqlite3 *db, const char *col, const char *val, int pos) -{ - RETURN_IF(is_sql_str_invalid(col), "Column name is invalid", false); + /* Reorder kara that are after the current one, do this shit only if priority > 1... */ + if (priority > 1) + SQLITE_EXEC(db, SQL_REORDER, error); - char SQL[LKT_MAX_SQLITE_STATEMENT]; - static const char *SQL_STMT = - "BEGIN TRANSACTION;" - "CREATE TEMPORARY TABLE queue_tmp" - " ( position_tmp INTEGER PRIMARY KEY AUTOINCREMENT" - " , kara_id_tmp INTEGER" - " , priority_tmp INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)" - " );" - "INERT INTO queue_tmp (kara_id_tmp, priority_tmp)" - " SELECT (kara_id, priority)" - " FROM queue" - " WHERE position >= ?" - " ORDER BY position ASC;" - "INSERT INTO queue (kara_id, priority)" - "SELECT id, priority" - " FROM kara" - " WHERE %s LIKE ? AND available = 1" - " ORDER BY RANDOM();" - "INSERT INTO queue (kara_id, priority)" - " SELECT kara_id_tmp, priority" - " FROM queue_tmp" - " ORDER BY position ASC;" - "DROP TABLE queue_tmp;" - "COMMIT TRANSACTION;"; - bool status = false; - sqlite3_stmt *stmt = NULL; + /* End */ + SQLITE_EXEC(db, "COMMIT;", error); + return true; - snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT, col); - SQL[LKT_MAX_SQLITE_STATEMENT - 1] = 0; - SQLITE_PREPARE(db, stmt, SQL, error); - SQLITE_BIND_INT(db, stmt, 1, pos, error); - SQLITE_BIND_TEXT(db, stmt, 2, val, error); - SQLITE_STEP_DONE(db, stmt, error); - status = true; error: sqlite3_finalize(stmt); - return status; -} - -bool -database_queue_insert_query(volatile sqlite3 *db, const char *query, int pos) -{ - bool status = queue_insert_with_col_like_str(db, LKT_DATABASE_KARA_ALL, query, pos); - LOG_INFO("%s '%s' at %d", status ? "Successfull add query" : "Failed add query", query, pos); - return status; + SQLITE_DO_ROLLBACK(db); + return false; } bool database_queue_add_plt(volatile sqlite3 *db, const char *plt_name, int priority) { +#define CURRENT_POS_OR_0 /* To move karas after the current */ \ + "(SELECT CASE WHEN (SELECT current FROM queue_state) IS NULL THEN 0" \ + " ELSE (SELECT current FROM queue_state) END AS val LIMIT 1)" static const char *SQL_STMT = + /* Insert the playlist */ "INSERT INTO queue (kara_id, priority) " "SELECT kara.id, ?" - " FROM kara" - " JOIN kara_playlist ON kara_id = kara.id AND kara.available = 1" - " JOIN playlist ON playlist_id = playlist.id AND playlist.name = ?" - " ORDER BY RANDOM();"; - bool status = false; + " FROM kara" + " JOIN kara_playlist ON kara_id = kara.id AND kara.available = 1" + " JOIN playlist ON playlist_id = playlist.id AND playlist.name = ?" + " ORDER BY RANDOM();"; + static const char *SQL_REORDER = + /* Create temporary tables */ + "CREATE TEMPORARY TABLE queue_tmp" + " ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)" + " , kara_id INTEGER" + " , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)" + " );" + /* Separate karas that are after the current one */ + "INSERT INTO queue_tmp (kara_id, priority) SELECT kara_id, priority FROM queue WHERE position > " CURRENT_POS_OR_0 ";" + "DELETE FROM queue WHERE position > " CURRENT_POS_OR_0 ";" + /* Insert back */ + "INSERT INTO queue (position, kara_id, priority)" + " SELECT position + " CURRENT_POS_OR_0 ", kara_id, priority" + " FROM queue_tmp" + " ORDER BY priority, position;" + /* Drop temporary tables */ + "DROP TABLE queue_tmp;" + "DELETE FROM sqlite_sequence WHERE name = 'queue_tmp';"; +#undef CURRENT_POS_OR_0 sqlite3_stmt *stmt = NULL; + /* Begin, transactions are atomic so we won't be anoyed by multi-threading */ + SQLITE_EXEC(db, "BEGIN TRANSACTION;", error); + SQLITE_PREPARE(db, stmt, SQL_STMT, error); SQLITE_BIND_INT(db, stmt, 1, priority, error); SQLITE_BIND_TEXT(db, stmt, 2, plt_name, error); SQLITE_STEP_DONE(db, stmt, error); - status = true; -error: sqlite3_finalize(stmt); - return status; -} -bool -database_queue_add_query(volatile sqlite3 *db, const char *query, int priority) -{ - bool status = queue_add_with_col_like_str(db, LKT_DATABASE_KARA_ALL, query, priority); - LOG_INFO("%s '%s' with prio %d", status ? "Successfull add query" : "Failed add query", query, priority); - return status; -} - -bool -database_queue_add_author(volatile sqlite3 *db, const char *author, int priority) -{ - bool status = queue_add_with_col_like_str(db, LKT_DATABASE_NAME_KAUTHOR, author, priority); - LOG_INFO("%s '%s'", status ? "Successfull add author" : "Failed add author", author); - return status; -} + /* Do the move shit only if the priority > 1 */ + if (priority > 1) + SQLITE_EXEC(db, SQL_REORDER, error); -bool -database_queue_add_language(volatile sqlite3 *db, const char *language, int priority) -{ - bool status = queue_add_with_col_like_str(db, LKT_DATABASE_NAME_KLANG, language, priority); - LOG_INFO("%s '%s'", status ? "Successfull add language" : "Failed add language", language); - return status; -} + SQLITE_EXEC(db, "COMMIT;", error); + return true; -bool -database_queue_add_category(volatile sqlite3 *db, const char *cat, int priority) -{ - bool status = queue_add_with_col_like_str(db, LKT_DATABASE_NAME_KCAT, cat, priority); - LOG_INFO("%s '%s'", status ? "Successfull add category" : "Failed add category", cat); - return status; +error: + SQLITE_DO_ROLLBACK(db); + sqlite3_finalize(stmt); + return false; } -bool -database_queue_add_type(volatile sqlite3 *db, const char *type, int priority) -{ - bool status = queue_add_with_col_like_str(db, LKT_DATABASE_NAME_KTYPE, type, priority); - LOG_INFO("%s '%s'", status ? "Successfull add type" : "Failed add type", type); - return status; -} +#define database_queue_add(suffix, column_name) \ + bool \ + database_queue_add_ ## suffix (volatile sqlite3 *db, const char *query, int priority) \ + { \ + bool status = queue_add_with_col_like_str(db, column_name, query, priority); \ + LOG_INFO("%s " #suffix " '%s' with priority of %d", \ + status ? "Successfully added" : "Failed to add", query, priority); \ + return status; \ + } +database_queue_add(query, LKT_DATABASE_KARA_ALL) +database_queue_add(author, LKT_DATABASE_NAME_KAUTHOR) +database_queue_add(language, LKT_DATABASE_NAME_KLANG) +database_queue_add(category, LKT_DATABASE_NAME_KCAT) +database_queue_add(type, LKT_DATABASE_NAME_KTYPE) +#undef database_queue_add bool database_queue_add_id(volatile sqlite3 *db, int id, int priority) @@ -247,11 +244,11 @@ database_queue_del_id(volatile sqlite3 *db, int id) { static const char *SQL_TEMPLATE = "BEGIN TRANSACTION;" - "WITH before(pos) AS (SELECT position FROM queue_ JOIN queue_state WHERE position < current ORDER BY position DESC LIMIT 1) " + "WITH before(pos) AS (SELECT position FROM queue JOIN queue_state WHERE position < current ORDER BY position DESC LIMIT 1) " "UPDATE queue_state SET current = CASE" " WHEN current IS NULL THEN NULL" " ELSE (SELECT pos FROM before) " - "END WHERE current > (SELECT position FROM queue_ WHERE kara_id = %d);" + "END WHERE current > (SELECT position FROM queue WHERE kara_id = %d);" "DELETE FROM queue WHERE kara_id = %d;" "COMMIT TRANSACTION;"; char SQL[LKT_MAX_SQLITE_STATEMENT]; @@ -268,15 +265,15 @@ database_queue_next(volatile sqlite3 *db, char filepath[PATH_MAX]) { static const char *SQL_STMT = "SELECT file_path, position, RANDOM()" - " FROM kara" - " JOIN queue_ ON kara.id = queue_.kara_id" - " JOIN queue_state" - " ON available = 1 AND current IS NULL OR" - " CASE WHEN (SELECT single FROM queue_state) = 1 THEN position = current" - " WHEN (SELECT random FROM queue_state) = 1 THEN position <> current" - " ELSE position > current END" - " ORDER BY CASE WHEN (SELECT random FROM queue_state) = 1 THEN RANDOM() ELSE 2 END" - " LIMIT 1"; + " FROM kara" + " JOIN queue ON kara.id = queue.kara_id" + " JOIN queue_state" + " ON current IS NULL" + " OR (CASE WHEN (SELECT single FROM queue_state LIMIT 1) = 1 THEN position = current" + " WHEN (SELECT random FROM queue_state LIMIT 1) = 1 THEN position <> current" + " ELSE position > current END)" + " ORDER BY CASE WHEN (SELECT random FROM queue_state LIMIT 1) = 1 THEN RANDOM() ELSE 2 END" + " LIMIT 1"; char SQL_UPDATE[LKT_MAX_SQLITE_STATEMENT]; bool status = false; int code = SQLITE_OK, id; @@ -332,10 +329,10 @@ database_queue_prev(volatile sqlite3 *db, char filepath[PATH_MAX]) static const char *SQL_STMT = "SELECT file_path, position " " FROM kara" - " JOIN queue_ ON kara.id = queue_.kara_id AND available = 1" + " JOIN queue ON kara.id = queue.kara_id AND available = 1" " JOIN queue_state ON CASE " " WHEN (SELECT single FROM queue_state LIMIT 1) = 1 THEN position = current" - " ELSE queue_.position < queue_state.current" + " ELSE queue.position < queue_state.current" " END" " ORDER BY position DESC LIMIT 1;"; char SQL_UPDATE[LKT_MAX_SQLITE_STATEMENT]; @@ -498,8 +495,8 @@ database_queue_get_current_file(volatile sqlite3 *db, char filepath[PATH_MAX]) static const char *SQL_STMT = "SELECT file_path" " FROM kara" - " JOIN queue_ ON kara.id = queue_.kara_id" - " JOIN queue_state ON queue_.position = queue_state.current"; + " JOIN queue ON kara.id = queue.kara_id" + " JOIN queue_state ON queue.position = queue_state.current"; bool status = false; int code = SQLITE_OK; sqlite3_stmt *stmt = NULL; @@ -539,27 +536,18 @@ database_queue_shuffle(volatile sqlite3 *db) { const char *SQL = "BEGIN TRANSACTION;" - /* Create temporary queue. */ + /* Create temporary queue */ "CREATE TEMPORARY TABLE queue_tmp" " ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)" " , kara_id INTEGER" " , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)" " );" - /* When current is NULL, that thing is also NULL, so no insertion is done. */ + /* When current is NULL, that thing is also NULL, so no insertion is done */ "INSERT INTO queue_tmp (kara_id, priority)" - " SELECT kara_id, priority" + " SELECT kara_id, 5" " FROM queue" " JOIN queue_state ON queue.position = queue_state.current;" - /* Insert Max priority in order. */ - "INSERT INTO queue_tmp (kara_id, priority)" - " SELECT kara_id, priority" - " FROM queue" - " JOIN queue_state ON" - " queue.position <> CASE" - " WHEN queue_state.current IS NOT NULL THEN queue_state.current" - " ELSE 0 END" - " AND queue.priority = 5;" - /* Insert the others karas, where the priority is < 5. */ + /* Insert the others karas */ "INSERT INTO queue_tmp (kara_id, priority)" " SELECT kara_id, priority" " FROM queue" @@ -567,9 +555,8 @@ database_queue_shuffle(volatile sqlite3 *db) " queue.position <> CASE" " WHEN queue_state.current IS NOT NULL THEN queue_state.current" " ELSE 0 END" - " AND queue.priority <> 5" " ORDER BY RANDOM();" - /* Do the insertion in the other way. */ + /* Do the insertion in the other way */ "DELETE FROM queue;" "DELETE FROM sqlite_sequence WHERE name = 'queue';" "INSERT INTO queue (position, kara_id, priority)" @@ -578,7 +565,7 @@ database_queue_shuffle(volatile sqlite3 *db) " ORDER BY priority, position;" "DROP TABLE queue_tmp;" "DELETE FROM sqlite_sequence WHERE name = 'queue_tmp';" - /* Set the current to the right kara when needed. */ + /* Set the current to the right kara when needed */ "UPDATE queue_state" " SET current = CASE" " WHEN current NOT NULL THEN 1" @@ -596,10 +583,10 @@ database_queue_list(volatile sqlite3 *db, size_t from, size_t to, struct lkt_cal const char *SQL_STMT = "WITH content AS (" " SELECT kara.id AS id, string, LENGTH(CAST(kara.id AS TEXT)) AS len" - " FROM queue_" + " FROM queue" " JOIN kara ON kara_id = kara.id" " WHERE position >= ? AND position <= ?" - " GROUP BY position ORDER BY position)" + " GROUP BY position ORDER BY position ASC, priority DESC)" "SELECT id, string, (SELECT MAX(len) FROM content) FROM content;"; int code, id, id_len; const char *row; @@ -642,7 +629,7 @@ error: bool database_queue_seekid(volatile sqlite3 *db, int id, int *out_pos) { - static const char *SQL_STMT = "SELECT position FROM queue_ WHERE kara_id = ? LIMIT 1"; + static const char *SQL_STMT = "SELECT position FROM queue WHERE kara_id = ? LIMIT 1"; int ret = 0; sqlite3_stmt *stmt; diff --git a/src/main/lkt.c b/src/main/lkt.c index 94114a9475e01a9b5a7c1da0275c6280a22b2a30..6b4dfd27a022a0190a057b65eb080f70bf7aa644 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -25,26 +25,28 @@ #include <stdarg.h> #include <limits.h> -#define LKT_KEY_VALUE_SEP ": \n\t\0" -#define STR_MATCH(str1, str2) (! strcasecmp(str1, str2)) -#define STR_NMATCH(str1, str2, n) (! strncasecmp(str1, str2, n)) +#define LKT_KEY_VALUE_SEP ": \n\t\0" +#define STR_MATCH(str1, str2) (! strcasecmp(str1, str2)) +#define STR_NMATCH(str1, str2, n) (! strncasecmp(str1, str2, n)) +#define fail_if(cond, msg) if (cond) { LOG_ERROR("%s", msg); exit(EXIT_FAILURE); } +#define fail(msg) { LOG_ERROR("%s", msg); exit(EXIT_FAILURE); } +#define lkt_send_and_exit(buffer, len) exit(write_socket(lkt_connect(), buffer, len)) +#define write_socket(sock, buff, len) (fwrite(buff, sizeof(char), len, sock) != len) -static noreturn inline void -fail(const char *message) -{ - LOG_ERROR("%s", message); - exit(EXIT_FAILURE); +#define exit_with_status(sock, buff) { \ + fail_if(read_socket(sock, buff, 2) == 0, "ACK"); \ + fail_if(buff[0] != 'O' && buff[1] != 'K', "ACK"); \ + exit(EXIT_SUCCESS); \ } /* Type definition. */ typedef struct { - const char *host; /* Serveur host, may be resolved. */ - const char *port; /* Serveur port. */ - const char *pwd; /* The password for the user. */ - const char **argv; /* Pointer to the argv from the main - function. */ - int argc; /* Argument count of the args. */ + const char *host; /* Serveur host, may be resolved. */ + const char *port; /* Serveur port. */ + const char *pwd; /* The password for the user. */ + const char **argv; /* Pointer to the argv from the main function. */ + int argc; /* Argument count of the args. */ } args_t; /* Global variables. */ @@ -61,7 +63,6 @@ lkt_valid_type(const char *type) { return (STR_MATCH(type, "all") || STR_MATCH(type, "any") || - STR_MATCH(type, "a") || STR_MATCH(type, "id") || STR_MATCH(type, "title") || STR_MATCH(type, "type") || @@ -78,31 +79,15 @@ static int read_socket(FILE *sock, char *buff, size_t max_len) { size_t i, len; - for (i = 0; i < max_len; ++i) { len = fread(buff + i, sizeof(char), 1, sock); if (buff[i] == '\n' || len != 1) - goto end; + return i; } - -end: return i; } -static inline int -write_socket(FILE *sock, const char *buff, size_t len) -{ - int ret = 1; - - if (fwrite(buff, sizeof(char), len, sock) != len) - goto end; - - ret = 0; -end: - return ret; -} - static int write_socket_format(FILE *sock, const char *format, ...) { @@ -169,12 +154,6 @@ lkt_connect(void) return sock; } -static noreturn inline void -lkt_send_and_exit(const char *buffer, size_t len) -{ - exit(write_socket(lkt_connect(), buffer, len)); -} - static char * lkt_skip_key(char *buffer) { @@ -186,42 +165,18 @@ lkt_skip_key(char *buffer) /* Functions implementing options. */ -noreturn void -queue_clear__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the clear command takes no arguments"); - static const char cmd__[] = "clear\nclose\n"; - lkt_send_and_exit(cmd__, sizeof(cmd__)); -} - -noreturn void -queue_crop__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the crop command takes no arguments"); - static const char cmd__[] = "crop\nclose\n"; - lkt_send_and_exit(cmd__, sizeof(cmd__)); -} - - -noreturn void -next__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the next command takes no arguments"); - static const char cmd__[] = "next\nclose\n"; - lkt_send_and_exit(cmd__, sizeof(cmd__)); /* In bytes. */ -} - -noreturn void -prev__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the previous command takes no arguments"); - static const char cmd__[] = "previous\nclose\n"; - lkt_send_and_exit(cmd__, sizeof(cmd__)); /* In bytes. */ -} +#define just_send(func, msg) /* Just send a simple string functions */ \ + noreturn void func (struct lkt_cmd_args *args) { \ + fail_if(args->argc, "This command takes no arguments"); \ + lkt_send_and_exit(msg, sizeof(msg)); \ + } +just_send(queue_clear__, "clear\nclose\n") +just_send(queue_crop__, "crop\nclose\n") +just_send(next__, "next\nclose\n") +just_send(prev__, "previous\nclose\n") +just_send(stop__, "stop\nclose\n") +just_send(shuffle__, "shuffle\nplay\nclose\n") +#undef just_send noreturn void simple_send_with_password__(const char *cmd) @@ -238,7 +193,7 @@ restart__(struct lkt_cmd_args *args) { if (args->argc != 0) fail("Invalid argument, the previous command takes no arguments"); - simple_send_with_password__("restart"); + simple_send_with_password__("__restart"); } noreturn void @@ -285,15 +240,6 @@ update__(struct lkt_cmd_args *args) rescan_or_update__(args, "update"); } -noreturn void -stop__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the stop command takes no arguments"); - static const char cmd__[] = "stop\nclose\n"; - lkt_send_and_exit(cmd__, sizeof(cmd__)); /* In bytes. */ -} - noreturn void play__(struct lkt_cmd_args *args) { @@ -314,7 +260,7 @@ play__(struct lkt_cmd_args *args) FILE *sock = lkt_connect(); if (write_socket(sock, status__, sizeof(status__))) /* In bytes. */ - goto error; + exit(EXIT_FAILURE); for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); @@ -336,12 +282,9 @@ play__(struct lkt_cmd_args *args) else lkt_send_and_exit(cmd_pause__, sizeof(cmd_pause__)); /* In bytes. */ - goto error; + exit(EXIT_FAILURE); } } - -error: - exit(EXIT_FAILURE); } noreturn void @@ -374,7 +317,7 @@ current__(struct lkt_cmd_args *args) FILE *sock = lkt_connect(); if (write_socket(sock, current_song__, sizeof(current_song__))) /* In bytes. */ - goto error; + exit(EXIT_FAILURE); assert(mem = calloc(6 * LKT_MESSAGE_MAX, sizeof(char))); assert(memset(mem, 0, 6 * LKT_MESSAGE_MAX * sizeof(char))); @@ -389,35 +332,35 @@ current__(struct lkt_cmd_args *args) for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); if (read_socket(sock, buff, LKT_MESSAGE_MAX - 1) <= 0) - goto error; + exit(EXIT_FAILURE); const size_t len = strcspn(buff, LKT_KEY_VALUE_SEP); char *value = lkt_skip_key(buff); const size_t value_size = strcspn(value, "\n\0") * sizeof(char); - if (! strncasecmp("title", buff, len)) + if (STR_NMATCH("title", buff, len)) assert(memcpy(title, value, value_size)); - if (! strncasecmp("author", buff, len)) + if (STR_NMATCH("author", buff, len)) assert(memcpy(author, value, value_size)); - if (! strncasecmp("source", buff, len)) + if (STR_NMATCH("source", buff, len)) assert(memcpy(source, value, value_size)); - if (!strncasecmp("type", buff, len)) + if (STR_NMATCH("type", buff, len)) assert(memcpy(type, value, value_size)); - if (!strncasecmp("language", buff, len)) + if (STR_NMATCH("language", buff, len)) assert(memcpy(language, value, value_size)); - if (!strncasecmp("category", buff, len)) + if (STR_NMATCH("category", buff, len)) assert(memcpy(category, value, value_size)); /* At this point every key has been parsed. */ - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) goto ok; - else if (! strncmp(buff, "ACK", 3)) - goto error; + else if (STR_NMATCH(buff, "ACK", 3)) + exit(EXIT_FAILURE); } ok: @@ -429,8 +372,6 @@ ok: category, source, type, title, author); exit(EXIT_SUCCESS); -error: - exit(EXIT_FAILURE); } noreturn void @@ -449,7 +390,6 @@ queue_pop__(struct lkt_cmd_args *args) goto error; #define assign_int(str, var) if (! strncmp(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; } - for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); if (read_socket(sock, buff, LKT_MESSAGE_MAX - 1) <= 0) @@ -459,11 +399,12 @@ queue_pop__(struct lkt_cmd_args *args) assign_int("songid", songid) /* At this point every key has been parsed. */ - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) break; - else if (! strncmp(buff, "ACK", 3)) + else if (STR_NMATCH(buff, "ACK", 3)) goto error; } +#undef assign_int fclose(sock); sock = lkt_connect(); @@ -498,9 +439,8 @@ status__(struct lkt_cmd_args *args) if (write_socket(sock, status_str__, strlen(status_str__))) goto error; -#define assign_flag(str, f) if (! strncmp(buff, str, len) && (atoi(lkt_skip_key(buff)) == 1)) { flags[it++] = f; continue; } -#define assign_int(str, var) if (! strncmp(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; } - +#define assign_flag(str, f) if (STR_NMATCH(buff, str, len) && (atoi(lkt_skip_key(buff)) == 1)) { flags[it++] = f; continue; } +#define assign_int(str, var) if (STR_NMATCH(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; } for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); if (read_socket(sock, buff, LKT_MESSAGE_MAX - 1) <= 0) @@ -508,7 +448,7 @@ status__(struct lkt_cmd_args *args) size_t len = strcspn(buff, LKT_KEY_VALUE_SEP); - if (! strncmp(buff, "state", len)) { + if (STR_NMATCH(buff, "state", len)) { char *it = lkt_skip_key(buff); play = ! strncmp(it, "play", 4); stopped = ! strncmp(it, "stop", 4); @@ -526,11 +466,13 @@ status__(struct lkt_cmd_args *args) assign_int("playlistlength", plt_len) /* At this point every key has been parsed. */ - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) goto print; - else if (! strncmp(buff, "ACK", 3)) + else if (STR_NMATCH(buff, "ACK", 3)) goto error; } +#undef assign_flag +#undef assign_int print: fclose(sock); @@ -551,16 +493,6 @@ error: exit(ret); } -noreturn void -shuffle__(struct lkt_cmd_args *args) -{ - if (args->argc != 0) - fail("Invalid argument, the shuffle command takes no arguments"); - - static const char *const shuffle_str__ = "shuffle\nplay\nclose\n"; - lkt_send_and_exit(shuffle_str__, strlen(shuffle_str__)); -} - noreturn void queue_delete__(struct lkt_cmd_args *args) { @@ -575,23 +507,16 @@ queue_delete__(struct lkt_cmd_args *args) sscanf(args->argv[0], "%d", &dumy); if (dumy != 0) { write_socket_format(sock, cmd_id__, dumy); - goto check; + exit_with_status(sock, buff); } fail("Invalid argument"); - -check: - assert(read_socket(sock, buff, 2) > 0); - if (buff[0] == 'O' && buff[1] == 'K') - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); } noreturn void queue_add__(struct lkt_cmd_args *args) { - char buff[LKT_MESSAGE_MAX]; + char buff[3]; int i; if (args->argc < 1) @@ -614,24 +539,13 @@ queue_add__(struct lkt_cmd_args *args) /* Here we have `i == argc - 1`. */ write_socket(sock, args->argv[i], strlen(args->argv[i])); write_socket(sock, "\n", sizeof(char)); - - for (;;) { - memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); - assert(read_socket(sock, buff, LKT_MESSAGE_MAX - 1) > 0); - - if (! strncmp(buff, "OK", 2)) - exit(EXIT_SUCCESS); - - else if (! strncmp(buff, "ACK", 3)) - exit(EXIT_FAILURE); - } + exit_with_status(sock, buff); } noreturn void queue_seek__(struct lkt_cmd_args *args) { - if (args->argc != 1) - fail("The seek command needs one argument: queue seek <id>"); + fail_if(args->argc != 1, "The seek command needs one argument: queue seek <id>"); char *endptr, buf[3]; long id = strtol(args->argv[0], &endptr, 0); @@ -646,8 +560,7 @@ queue_seek__(struct lkt_cmd_args *args) FILE *sock = lkt_connect(); write_socket_format(sock, "playid %ld\n", id); - read_socket(sock, buf, 2); - exit(!strncmp(buf, "OK", 2)); + exit_with_status(sock, buf); } noreturn void @@ -693,9 +606,9 @@ redo: } } - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) exit(EXIT_SUCCESS); - else if (! strncmp(buff, "ACK", 3)) + else if (STR_NMATCH(buff, "ACK", 3)) exit(EXIT_FAILURE); fprintf(stdout, "%s", buff); @@ -731,7 +644,6 @@ queue_list__(struct lkt_cmd_args *args) fail("Communication error"); #define assign_int(str, var) if (! strncmp(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; } - for (;;) { memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); if (read_socket(sock, buff, LKT_MESSAGE_MAX - 1) <= 0) @@ -741,11 +653,12 @@ queue_list__(struct lkt_cmd_args *args) assign_int("song", song_index); /* At this point every key has been parsed. */ - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) break; - else if (! strncmp(buff, "ACK", 3)) + else if (STR_NMATCH(buff, "ACK", 3)) exit(EXIT_FAILURE); } +#undef assign_int fclose(sock); /* Get the content of the queue. */ @@ -768,11 +681,8 @@ plt_add__(struct lkt_cmd_args *args) char buff[2]; FILE *sock = lkt_connect(); - if (args->argc < 3) - fail("Invalid argument, need at least three arguments: plt add <plt> <query>"); - - if (!lkt_valid_type(args->argv[1])) - fail("Invalid argument, type for the query is invalid"); + fail_if(args->argc < 3, "Invalid argument, need at least three arguments: plt add <plt> <query>"); + fail_if(!lkt_valid_type(args->argv[1]), "Invalid argument, type for the query is invalid"); write_socket(sock, "playlistadd ", strlen("playlistadd ")); write_socket(sock, args->argv[0], strlen(args->argv[0])); @@ -788,12 +698,7 @@ plt_add__(struct lkt_cmd_args *args) /* Here we have `i == argc - 1`. */ write_socket(sock, args->argv[i], strlen(args->argv[i])); write_socket(sock, "\n", sizeof(char)); - - assert(read_socket(sock, buff, 2) > 0); - if (buff[0] == 'O' && buff[1] == 'K') - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); + exit_with_status(sock, buff); } noreturn void @@ -803,8 +708,7 @@ plt_delete__(struct lkt_cmd_args *args) char buff[2]; int i; - if (args->argc < 1) - fail("Invalid argument, need at least two arguments: plt delete <plt> <id>"); + fail_if(args->argc < 1, "Invalid argument"); write_socket(sock, "playlistdelete ", strlen("playlistdelete ")); write_socket(sock, args->argv[0], strlen(args->argv[0])); @@ -818,19 +722,13 @@ plt_delete__(struct lkt_cmd_args *args) /* Here we have `i == argc - 1`. */ write_socket(sock, args->argv[i], strlen(args->argv[i])); write_socket(sock, "\n", sizeof(char)); - - assert(read_socket(sock, buff, 2) > 0); - if (buff[0] == 'O' && buff[1] == 'K') - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); + exit_with_status(sock, buff); } noreturn void plt_destroy__(struct lkt_cmd_args *args) { - if (args->argc != 1) - fail("Invalid argument, you may only specify the name of the playlist to delete: plt destroy <plt>"); + fail_if(args->argc != 1, "Invalid argument"); FILE *sock = lkt_connect(); char buff[2]; @@ -839,19 +737,13 @@ plt_destroy__(struct lkt_cmd_args *args) write_socket(sock, "rm ", 3 * sizeof(char)); write_socket(sock, name, strlen(name)); write_socket(sock, "\n", sizeof(char)); - - assert(read_socket(sock, buff, 2) > 0); - if (buff[0] == 'O' && buff[1] == 'K') - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); + exit_with_status(sock, buff); } noreturn void plt_create__(struct lkt_cmd_args *args) { - if (args->argc != 1) - fail("Invalid argument, you may only specify the name of the playlist to create: plt create <plt>"); + fail_if(args->argc != 1, "Invalid argument"); FILE *sock = lkt_connect(); char buff[2]; @@ -860,12 +752,7 @@ plt_create__(struct lkt_cmd_args *args) write_socket(sock, "playlistadd ", strlen("playlistadd ")); write_socket(sock, name, strlen(name)); write_socket(sock, "\n", sizeof(char)); - - assert(read_socket(sock, buff, 2) > 0); - if (buff[0] == 'O' && buff[1] == 'K') - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); + exit_with_status(sock, buff); } /* Search functions. */ @@ -873,11 +760,8 @@ plt_create__(struct lkt_cmd_args *args) noreturn void search_with_cmd__(struct lkt_cmd_args *args, const char *cmd) { - if (args->argc < 2) - fail("Invalid number of arguments, need at least a valid query: search <action> <plt when action == plt> <query>"); - - if (!lkt_valid_type(args->argv[0])) - fail("Invalid type for the query"); + fail_if(args->argc < 2, "Invalid number of arguments"); + fail_if(!lkt_valid_type(args->argv[0]), "Invalid type for the query"); char buff[LKT_MESSAGE_MAX]; int continuation = 0, i; @@ -894,57 +778,30 @@ redo: memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char)); assert(read_socket(sock, buff, LKT_MESSAGE_MAX - 1) > 0); - if (! strncmp(buff, "continue:", strlen("continue:"))) { + if (STR_NMATCH(buff, "continue:", strlen("continue:"))) { continuation = atoi(lkt_skip_key(buff)); fclose(sock); goto redo; } - if (! strncmp(buff, "OK", 2)) + if (STR_NMATCH(buff, "OK", 2)) exit(EXIT_SUCCESS); - else if (! strncmp(buff, "ACK", 3)) + else if (STR_NMATCH(buff, "ACK", 3)) exit(EXIT_FAILURE); fprintf(stdout, "%s", buff); } } -noreturn void -search_get__(struct lkt_cmd_args *args) -{ - search_with_cmd__(args, "search"); -} - -noreturn void -search_add__(struct lkt_cmd_args *args) -{ - search_with_cmd__(args, "searchadd"); -} - -noreturn void -search_insert__(struct lkt_cmd_args *args) -{ - UNUSED(args); - fail("Not implemented"); -} - -noreturn void -search_plt__(struct lkt_cmd_args *args) -{ - search_with_cmd__(args, "listplaylist"); -} - -noreturn void -search_count__(struct lkt_cmd_args *args) -{ - search_with_cmd__(args, "count"); -} - -noreturn void -search_queue__(struct lkt_cmd_args *args) -{ - search_with_cmd__(args, "playlistfind"); -} +#define search_with_cmd(func, cmd) /* I don't want to write always the same things */ \ + noreturn void func (struct lkt_cmd_args *args) { search_with_cmd__(args, #cmd); } +search_with_cmd(search_get__, search) +search_with_cmd(search_add__, searchadd) +search_with_cmd(search_insert__, __insert) +search_with_cmd(search_plt__, listplaylist) +search_with_cmd(search_count__, count) +search_with_cmd(search_queue__, playlistfind) +#undef search_with_cmd /* Parsing stuff. */ @@ -986,41 +843,23 @@ static struct lkt_cmd_opt options_admin[] = { LKT_OPT_NULL, }; -noreturn void -admin__(struct lkt_cmd_args *args) -{ - if (args->argc == 0) - fail("Invalid argument, you must specify a sub command for the admin command"); - - lkt_cmd_parse(options_admin, args->argc, args->argv); -} +#define sub_command(name) /* Create sub-commands here */ \ + noreturn void name ## __(struct lkt_cmd_args *args) { \ + fail_if(!args->argc, "Invalid command, specify a sub command for " #name); \ + lkt_cmd_parse(options_ ## name, args->argc, args->argv); \ + } +sub_command(search) +sub_command(plt) +sub_command(admin) noreturn void queue__(struct lkt_cmd_args *args) { if (args->argc == 0) queue_list__(args); - lkt_cmd_parse(options_queue, args->argc, args->argv); } - -noreturn void -search__(struct lkt_cmd_args *args) -{ - if (args->argc == 0) - fail("Invalid argument, you must specify a sub command for the search command"); - - lkt_cmd_parse(options_search, args->argc, args->argv); -} - -noreturn void -plt__(struct lkt_cmd_args *args) -{ - if (args->argc == 0) - fail("Invalid argument, you must specify a sub command for the playlist command"); - - lkt_cmd_parse(options_plt, args->argc, args->argv); -} +#undef sub_command static struct lkt_cmd_opt options_[] = { { .name = "current", .call = current__ }, diff --git a/src/net/listen.c b/src/net/listen.c index 4c73ff20c836f587d0e71dcf9997d8549c05bbe0..23d4fddf2cb64900788e5dbca88b132ba662518b 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -117,13 +117,13 @@ static void send_status(struct lkt_state *srv, size_t c, int status, const char *cmd_name) { if (!status) { - LOG_INFO_SCT("COMMAND", " Command: %s", cmd_name); + LOG_INFO_SCT("COMMAND", "Command '%s'", cmd_name); send_ok(srv, c); } else { if (status == 2) - LOG_INFO_SCT("COMMAND", " Unknown command: %s", cmd_name); + LOG_INFO_SCT("COMMAND", "Unknown command '%s'", cmd_name); else - LOG_INFO_SCT("COMMAND", " Command failed: %s", cmd_name); + LOG_INFO_SCT("COMMAND", "Command failed '%s'", cmd_name); send_ack(srv, c, cmd_name); } } @@ -255,10 +255,12 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) goto end_no_send_status; } else if (!strcmp(cmd.name, "searchadd") || !strcmp(cmd.name, "findadd")) - err = !command_find(srv, c, cmd.args, cmd.cont, LKT_FND_ACT_RESPOND); + err = ! command_find(srv, c, cmd.args, cmd.cont, LKT_FND_ACT_ADD); else if (!strcmp(cmd.name, "search") || !strcmp(cmd.name, "find")) - err = !command_find(srv, c, cmd.args, cmd.cont, LKT_FND_ACT_RESPOND); + err = ! command_find(srv, c, cmd.args, cmd.cont, LKT_FND_ACT_RESPOND); + else if (!strcmp(cmd.name, "__insert")) + err = ! command_find(srv, c, cmd.args, cmd.cont, LKT_FND_ACT_ENQUEUE); else err = 2; @@ -279,7 +281,7 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) continuation = lkt_get_continuation(srv, c); if (continuation > 0) { - LOG_INFO_SCT("NETWORK", "Client should continue from %d", continuation); + LOG_INFO_SCT("NETWORK", "Client should continue from '%d'", continuation); send_continue(srv, c, continuation); } send_status(srv, c, err, cmd.name); @@ -327,7 +329,7 @@ handle_command(struct lkt_state *srv, size_t i, struct lkt_command cmd) else err = handle_simple_command(srv, i, cmd); - LOG_INFO_SCT("COMMAND", "Command result: %s -> %d", cmd.name, err); + LOG_INFO_SCT("COMMAND", "Command result '%s' -> %d", cmd.name, err); return err; } @@ -504,7 +506,7 @@ accept_all(int listen_fd, struct pollfd *fds, size_t fds_max, size_t *fds_len) } if (*fds_len == fds_max) { - LOG_ERROR_SCT("NETWORK", "%s", "Maximum number of file descriptors reached"); + LOG_ERROR_SCT("NETWORK", "Maximum number '%ld' of file descriptors reached", fds_max); break; }