mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-29 00:23:23 -05:00
Merge pull request #1398 from owntone/coverity_issues
Fixes for misc minor issues reported by Coverity
This commit is contained in:
commit
119eb46daa
@ -851,7 +851,13 @@ parent_dir_image_find(char *out_path, size_t len, const char *dir)
|
|||||||
DPRINTF(E_LOG, L_ART, "Could not find parent dir name (%s)\n", path);
|
DPRINTF(E_LOG, L_ART, "Could not find parent dir name (%s)\n", path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
strcpy(parentdir, ptr + 1);
|
|
||||||
|
ret = snprintf(parentdir, sizeof(parentdir), "%s", ptr + 1);
|
||||||
|
if ((ret < 0) || (ret >= sizeof(parentdir)))
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_ART, "Impossible error occured in parent_dir_image_find(), cause was: %s\n", ptr + 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
path_len = strlen(path);
|
path_len = strlen(path);
|
||||||
nextensions = ARRAY_SIZE(cover_extension);
|
nextensions = ARRAY_SIZE(cover_extension);
|
||||||
|
@ -88,22 +88,21 @@ command_cb_sync(struct commands_base *cmdbase, struct command *cmd)
|
|||||||
// Command execution is waiting for pending events before returning to the caller
|
// Command execution is waiting for pending events before returning to the caller
|
||||||
cmdbase->current_cmd = cmd;
|
cmdbase->current_cmd = cmd;
|
||||||
cmd->pending = cmd->ret;
|
cmd->pending = cmd->ret;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Command execution finished, execute the bottom half function
|
|
||||||
if (cmd->ret == 0 && cmd->func_bh)
|
|
||||||
cmd->func_bh(cmd->arg, &cmd->ret);
|
|
||||||
|
|
||||||
event_add(cmdbase->command_event, NULL);
|
// Command execution finished, execute the bottom half function
|
||||||
|
if (cmd->ret == 0 && cmd->func_bh)
|
||||||
|
cmd->func_bh(cmd->arg, &cmd->ret);
|
||||||
|
|
||||||
// Signal the calling thread that the command execution finished
|
event_add(cmdbase->command_event, NULL);
|
||||||
CHECK_ERR(L_MAIN, pthread_cond_signal(&cmd->cond));
|
|
||||||
CHECK_ERR(L_MAIN, pthread_mutex_unlock(&cmd->lck));
|
|
||||||
|
|
||||||
// Note if cmd->func was cmdloop_exit then cmdbase may be invalid now,
|
// Signal the calling thread that the command execution finished
|
||||||
// because commands_base_destroy() may have freed it
|
CHECK_ERR(L_MAIN, pthread_cond_signal(&cmd->cond));
|
||||||
}
|
CHECK_ERR(L_MAIN, pthread_mutex_unlock(&cmd->lck));
|
||||||
|
|
||||||
|
// Note if cmd->func was cmdloop_exit then cmdbase may be invalid now,
|
||||||
|
// because commands_base_destroy() may have freed it
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -357,7 +356,7 @@ commands_exec_async(struct commands_base *cmdbase, command_function func, void *
|
|||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cmd = calloc(1, sizeof(struct command));
|
CHECK_NULL(L_MAIN, cmd = calloc(1, sizeof(struct command)));
|
||||||
cmd->func = func;
|
cmd->func = func;
|
||||||
cmd->func_bh = NULL;
|
cmd->func_bh = NULL;
|
||||||
cmd->arg = arg;
|
cmd->arg = arg;
|
||||||
|
95
src/db.c
95
src/db.c
@ -775,6 +775,20 @@ free_di(struct directory_info *di, int content_only)
|
|||||||
memset(di, 0, sizeof(struct directory_info));
|
memset(di, 0, sizeof(struct directory_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_wi(struct watch_info *wi, int content_only)
|
||||||
|
{
|
||||||
|
if (!wi)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(wi->path);
|
||||||
|
|
||||||
|
if (!content_only)
|
||||||
|
free(wi);
|
||||||
|
else
|
||||||
|
memset(wi, 0, sizeof(struct watch_info));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
free_query_params(struct query_params *qp, int content_only)
|
free_query_params(struct query_params *qp, int content_only)
|
||||||
{
|
{
|
||||||
@ -2682,8 +2696,8 @@ db_query_fetch_string_sort(char **string, char **sortstring, struct query_params
|
|||||||
int
|
int
|
||||||
db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
||||||
{
|
{
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt = NULL;
|
||||||
char *query;
|
char *query = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!filter && !nstreams)
|
if (!filter && !nstreams)
|
||||||
@ -2698,17 +2712,16 @@ db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
|||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query);
|
||||||
|
|
||||||
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
|
ret = db_blocking_prepare_v2(query, -1, &stmt, NULL);
|
||||||
sqlite3_free(query);
|
|
||||||
if (ret != SQLITE_OK)
|
if (ret != SQLITE_OK)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = db_blocking_step(stmt);
|
ret = db_blocking_step(stmt);
|
||||||
@ -2719,8 +2732,7 @@ db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
|||||||
else
|
else
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s (%s)\n", sqlite3_errmsg(hdl), query);
|
DPRINTF(E_LOG, L_DB, "Could not step: %s (%s)\n", sqlite3_errmsg(hdl), query);
|
||||||
|
|
||||||
sqlite3_finalize(stmt);
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nitems)
|
if (nitems)
|
||||||
@ -2733,9 +2745,16 @@ db_files_get_count(uint32_t *nitems, uint32_t *nstreams, const char *filter)
|
|||||||
; /* EMPTY */
|
; /* EMPTY */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
sqlite3_free(query);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (query)
|
||||||
|
sqlite3_free(query);
|
||||||
|
if (stmt)
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -6059,10 +6078,10 @@ queue_reshuffle(uint32_t item_id, int queue_version)
|
|||||||
int pos;
|
int pos;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
struct db_queue_item queue_item;
|
struct db_queue_item queue_item;
|
||||||
int *shuffle_pos;
|
int *shuffle_pos = NULL;
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
struct query_params qp;
|
struct query_params qp = { 0 };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Reshuffle queue after item with item-id: %d\n", item_id);
|
DPRINTF(E_DBG, L_DB, "Reshuffle queue after item with item-id: %d\n", item_id);
|
||||||
@ -6071,43 +6090,39 @@ queue_reshuffle(uint32_t item_id, int queue_version)
|
|||||||
query = sqlite3_mprintf("UPDATE queue SET shuffle_pos = pos, queue_version = %d;", queue_version);
|
query = sqlite3_mprintf("UPDATE queue SET shuffle_pos = pos, queue_version = %d;", queue_version);
|
||||||
ret = db_query_run(query, 1, 0);
|
ret = db_query_run(query, 1, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
if (item_id > 0)
|
if (item_id > 0)
|
||||||
{
|
{
|
||||||
pos = db_queue_get_pos(item_id, 0);
|
pos = db_queue_get_pos(item_id, 0);
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
pos++; // Do not reshuffle the base item
|
pos++; // Do not reshuffle the base item
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = db_queue_get_count(&count);
|
ret = db_queue_get_count(&count);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
len = count - pos;
|
len = count - pos;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DB, "Reshuffle %d items off %" PRIu32 " total items, starting from pos %d\n", len, count, pos);
|
DPRINTF(E_DBG, L_DB, "Reshuffle %d items off %" PRIu32 " total items, starting from pos %d\n", len, count, pos);
|
||||||
|
|
||||||
shuffle_pos = malloc(len * sizeof(int));
|
CHECK_NULL(L_DB, shuffle_pos = malloc(len * sizeof(int)));
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
shuffle_pos[i] = i + pos;
|
shuffle_pos[i] = i + pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
shuffle_int(&shuffle_rng, shuffle_pos, len);
|
rng_shuffle_int(&shuffle_rng, shuffle_pos, len);
|
||||||
|
|
||||||
memset(&qp, 0, sizeof(struct query_params));
|
|
||||||
qp.filter = sqlite3_mprintf("pos >= %d", pos);
|
qp.filter = sqlite3_mprintf("pos >= %d", pos);
|
||||||
|
|
||||||
ret = queue_enum_start(&qp);
|
ret = queue_enum_start(&qp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
goto error;
|
||||||
sqlite3_free(qp.filter);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((ret = queue_enum_fetch(&qp, &queue_item, 0)) == 0 && (queue_item.id > 0) && (i < len))
|
while ((ret = queue_enum_fetch(&qp, &queue_item, 0)) == 0 && (queue_item.id > 0) && (i < len))
|
||||||
@ -6124,12 +6139,18 @@ queue_reshuffle(uint32_t item_id, int queue_version)
|
|||||||
}
|
}
|
||||||
|
|
||||||
db_query_end(&qp);
|
db_query_end(&qp);
|
||||||
sqlite3_free(qp.filter);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
goto error;
|
||||||
|
|
||||||
|
sqlite3_free(qp.filter);
|
||||||
|
free(shuffle_pos);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
sqlite3_free(qp.filter);
|
||||||
|
free(shuffle_pos);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6216,7 +6237,7 @@ db_watch_delete_bywd(uint32_t wd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_delete_bypath(char *path)
|
db_watch_delete_bypath(const char *path)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "DELETE FROM inotify WHERE path = '%q';"
|
#define Q_TMPL "DELETE FROM inotify WHERE path = '%q';"
|
||||||
char *query;
|
char *query;
|
||||||
@ -6228,7 +6249,7 @@ db_watch_delete_bypath(char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_delete_bymatch(char *path)
|
db_watch_delete_bymatch(const char *path)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "DELETE FROM inotify WHERE path LIKE '%q/%%';"
|
#define Q_TMPL "DELETE FROM inotify WHERE path LIKE '%q/%%';"
|
||||||
char *query;
|
char *query;
|
||||||
@ -6316,12 +6337,12 @@ db_watch_get_byquery(struct watch_info *wi, char *query)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_get_bywd(struct watch_info *wi)
|
db_watch_get_bywd(struct watch_info *wi, int wd)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "SELECT * FROM inotify WHERE wd = %d;"
|
#define Q_TMPL "SELECT * FROM inotify WHERE wd = %d;"
|
||||||
char *query;
|
char *query;
|
||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, wi->wd);
|
query = sqlite3_mprintf(Q_TMPL, wd);
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
@ -6333,12 +6354,12 @@ db_watch_get_bywd(struct watch_info *wi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_get_bypath(struct watch_info *wi)
|
db_watch_get_bypath(struct watch_info *wi, const char *path)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "SELECT * FROM inotify WHERE path = '%q';"
|
#define Q_TMPL "SELECT * FROM inotify WHERE path = '%q';"
|
||||||
char *query;
|
char *query;
|
||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, wi->path);
|
query = sqlite3_mprintf(Q_TMPL, path);
|
||||||
if (!query)
|
if (!query)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
|
||||||
@ -6350,7 +6371,7 @@ db_watch_get_bypath(struct watch_info *wi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_mark_bypath(char *path, enum strip_type strip, uint32_t cookie)
|
db_watch_mark_bypath(const char *path, enum strip_type strip, uint32_t cookie)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path = '%q';"
|
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path = '%q';"
|
||||||
char *query;
|
char *query;
|
||||||
@ -6368,7 +6389,7 @@ db_watch_mark_bypath(char *path, enum strip_type strip, uint32_t cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_mark_bymatch(char *path, enum strip_type strip, uint32_t cookie)
|
db_watch_mark_bymatch(const char *path, enum strip_type strip, uint32_t cookie)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path LIKE '%q/%%';"
|
#define Q_TMPL "UPDATE inotify SET path = substr(path, %d), cookie = %" PRIi64 " WHERE path LIKE '%q/%%';"
|
||||||
char *query;
|
char *query;
|
||||||
@ -6386,7 +6407,7 @@ db_watch_mark_bymatch(char *path, enum strip_type strip, uint32_t cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_move_bycookie(uint32_t cookie, char *path)
|
db_watch_move_bycookie(uint32_t cookie, const char *path)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "UPDATE inotify SET path = '%q' || path, cookie = 0 WHERE cookie = %" PRIi64 ";"
|
#define Q_TMPL "UPDATE inotify SET path = '%q' || path, cookie = 0 WHERE cookie = %" PRIi64 ";"
|
||||||
char *query;
|
char *query;
|
||||||
@ -6611,8 +6632,6 @@ db_pragma_get_cache_size()
|
|||||||
if (ret != SQLITE_OK)
|
if (ret != SQLITE_OK)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
||||||
|
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6620,13 +6639,11 @@ db_pragma_get_cache_size()
|
|||||||
if (ret == SQLITE_DONE)
|
if (ret == SQLITE_DONE)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (ret != SQLITE_ROW)
|
else if (ret != SQLITE_ROW)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
||||||
sqlite3_free(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6717,8 +6734,6 @@ db_pragma_get_synchronous()
|
|||||||
if (ret != SQLITE_OK)
|
if (ret != SQLITE_OK)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
||||||
|
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6726,13 +6741,11 @@ db_pragma_get_synchronous()
|
|||||||
if (ret == SQLITE_DONE)
|
if (ret == SQLITE_DONE)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (ret != SQLITE_ROW)
|
else if (ret != SQLITE_ROW)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
||||||
sqlite3_free(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6781,8 +6794,6 @@ db_pragma_get_mmap_size()
|
|||||||
if (ret != SQLITE_OK)
|
if (ret != SQLITE_OK)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not prepare statement: %s\n", sqlite3_errmsg(hdl));
|
||||||
|
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6790,13 +6801,11 @@ db_pragma_get_mmap_size()
|
|||||||
if (ret == SQLITE_DONE)
|
if (ret == SQLITE_DONE)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
DPRINTF(E_DBG, L_DB, "End of query results\n");
|
||||||
sqlite3_free(query);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (ret != SQLITE_ROW)
|
else if (ret != SQLITE_ROW)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
|
||||||
sqlite3_free(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
src/db.h
17
src/db.h
@ -573,6 +573,9 @@ free_pli(struct playlist_info *pli, int content_only);
|
|||||||
void
|
void
|
||||||
free_di(struct directory_info *di, int content_only);
|
free_di(struct directory_info *di, int content_only);
|
||||||
|
|
||||||
|
void
|
||||||
|
free_wi(struct watch_info *wi, int content_only);
|
||||||
|
|
||||||
void
|
void
|
||||||
free_query_params(struct query_params *qp, int content_only);
|
free_query_params(struct query_params *qp, int content_only);
|
||||||
|
|
||||||
@ -960,28 +963,28 @@ int
|
|||||||
db_watch_delete_bywd(uint32_t wd);
|
db_watch_delete_bywd(uint32_t wd);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_delete_bypath(char *path);
|
db_watch_delete_bypath(const char *path);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_delete_bymatch(char *path);
|
db_watch_delete_bymatch(const char *path);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_delete_bycookie(uint32_t cookie);
|
db_watch_delete_bycookie(uint32_t cookie);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_get_bywd(struct watch_info *wi);
|
db_watch_get_bywd(struct watch_info *wi, int wd);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_get_bypath(struct watch_info *wi);
|
db_watch_get_bypath(struct watch_info *wi, const char *path);
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_mark_bypath(char *path, enum strip_type strip, uint32_t cookie);
|
db_watch_mark_bypath(const char *path, enum strip_type strip, uint32_t cookie);
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_mark_bymatch(char *path, enum strip_type strip, uint32_t cookie);
|
db_watch_mark_bymatch(const char *path, enum strip_type strip, uint32_t cookie);
|
||||||
|
|
||||||
void
|
void
|
||||||
db_watch_move_bycookie(uint32_t cookie, char *path);
|
db_watch_move_bycookie(uint32_t cookie, const char *path);
|
||||||
|
|
||||||
int
|
int
|
||||||
db_watch_cookie_known(uint32_t cookie);
|
db_watch_cookie_known(uint32_t cookie);
|
||||||
|
@ -1702,13 +1702,23 @@ bind_socket_ai(int family, struct addrinfo *ai, int reuse)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (family == AF_INET6)
|
if (family == AF_INET6) {
|
||||||
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
r = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
|
||||||
|
if (r == -1) {
|
||||||
|
event_warn("IPV6_V6ONLY");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
|
||||||
|
if (r == -1) {
|
||||||
|
event_warn("SO_KEEPALIVE");
|
||||||
|
}
|
||||||
|
|
||||||
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
|
|
||||||
if (reuse) {
|
if (reuse) {
|
||||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
|
||||||
(void *)&on, sizeof(on));
|
if (r == -1) {
|
||||||
|
event_warn("SO_REUSEADDR");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ai != NULL) {
|
if (ai != NULL) {
|
||||||
|
11
src/httpd.c
11
src/httpd.c
@ -1310,9 +1310,10 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
|||||||
if (!transcode)
|
if (!transcode)
|
||||||
{
|
{
|
||||||
/* Hint the OS */
|
/* Hint the OS */
|
||||||
posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_WILLNEED);
|
if ( (ret = posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_WILLNEED)) != 0 ||
|
||||||
posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_SEQUENTIAL);
|
(ret = posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_SEQUENTIAL)) != 0 ||
|
||||||
posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_NOREUSE);
|
(ret = posix_fadvise(st->fd, st->start_offset, st->stream_size, POSIX_FADV_NOREUSE)) != 0 )
|
||||||
|
DPRINTF(E_DBG, L_HTTPD, "posix_fadvise() failed with error %d\n", ret);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1353,6 +1354,10 @@ httpd_gzip_deflate(struct evbuffer *in)
|
|||||||
strm.zfree = Z_NULL;
|
strm.zfree = Z_NULL;
|
||||||
strm.opaque = Z_NULL;
|
strm.opaque = Z_NULL;
|
||||||
|
|
||||||
|
// Just to keep Coverity from complaining about uninitialized values
|
||||||
|
strm.total_in = 0;
|
||||||
|
strm.total_out = 0;
|
||||||
|
|
||||||
// Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default)
|
// Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default)
|
||||||
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
|
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
|
@ -136,9 +136,6 @@ static struct timeval daap_update_refresh_tv = { DAAP_UPDATE_REFRESH, 0 };
|
|||||||
static void
|
static void
|
||||||
daap_session_free(struct daap_session *s)
|
daap_session_free(struct daap_session *s)
|
||||||
{
|
{
|
||||||
if (!s)
|
|
||||||
return;
|
|
||||||
|
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +634,7 @@ parse_meta(const struct dmap_field ***out_meta, const char *param)
|
|||||||
CHECK_NULL(L_DAAP, meta = calloc(nmeta, sizeof(const struct dmap_field *)));
|
CHECK_NULL(L_DAAP, meta = calloc(nmeta, sizeof(const struct dmap_field *)));
|
||||||
|
|
||||||
field = strtok_r(metastr, ",", &ptr);
|
field = strtok_r(metastr, ",", &ptr);
|
||||||
for (i = 0; i < nmeta; i++)
|
for (i = 0; field != NULL && i < nmeta; i++)
|
||||||
{
|
{
|
||||||
for (n = 0; (n < i) && (strcmp(field, meta[n]->desc) != 0); n++);
|
for (n = 0; (n < i) && (strcmp(field, meta[n]->desc) != 0); n++);
|
||||||
|
|
||||||
@ -662,8 +659,6 @@ parse_meta(const struct dmap_field ***out_meta, const char *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
field = strtok_r(NULL, ",", &ptr);
|
field = strtok_r(NULL, ",", &ptr);
|
||||||
if (!field)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(metastr);
|
free(metastr);
|
||||||
@ -1185,14 +1180,14 @@ daap_reply_songlist_generic(struct httpd_request *hreq, int playlist)
|
|||||||
struct evbuffer *songlist;
|
struct evbuffer *songlist;
|
||||||
struct evkeyvalq *headers;
|
struct evkeyvalq *headers;
|
||||||
struct daap_session *s;
|
struct daap_session *s;
|
||||||
const struct dmap_field **meta;
|
const struct dmap_field **meta = NULL;
|
||||||
struct sort_ctx *sctx;
|
struct sort_ctx *sctx;
|
||||||
const char *param;
|
const char *param;
|
||||||
const char *client_codecs;
|
const char *client_codecs;
|
||||||
const char *tag;
|
const char *tag;
|
||||||
char *last_codectype;
|
char *last_codectype;
|
||||||
size_t len;
|
size_t len;
|
||||||
int nmeta;
|
int nmeta = 0;
|
||||||
int sort_headers;
|
int sort_headers;
|
||||||
int nsongs;
|
int nsongs;
|
||||||
int transcode;
|
int transcode;
|
||||||
@ -1246,18 +1241,12 @@ daap_reply_songlist_generic(struct httpd_request *hreq, int playlist)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
meta = NULL;
|
|
||||||
nmeta = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = db_query_start(&qp);
|
ret = db_query_start(&qp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||||
|
|
||||||
free(meta);
|
|
||||||
dmap_error_make(hreq->reply, tag, "Could not start query");
|
dmap_error_make(hreq->reply, tag, "Could not start query");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1320,7 +1309,6 @@ daap_reply_songlist_generic(struct httpd_request *hreq, int playlist)
|
|||||||
DPRINTF(E_DBG, L_DAAP, "Done with song list, %d songs\n", nsongs);
|
DPRINTF(E_DBG, L_DAAP, "Done with song list, %d songs\n", nsongs);
|
||||||
|
|
||||||
free(last_codectype);
|
free(last_codectype);
|
||||||
free(meta);
|
|
||||||
db_query_end(&qp);
|
db_query_end(&qp);
|
||||||
|
|
||||||
if (ret == -100)
|
if (ret == -100)
|
||||||
@ -1361,6 +1349,7 @@ daap_reply_songlist_generic(struct httpd_request *hreq, int playlist)
|
|||||||
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, sctx->headerlist));
|
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, sctx->headerlist));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(meta);
|
||||||
daap_sort_context_free(sctx);
|
daap_sort_context_free(sctx);
|
||||||
evbuffer_free(song);
|
evbuffer_free(song);
|
||||||
evbuffer_free(songlist);
|
evbuffer_free(songlist);
|
||||||
@ -1369,6 +1358,7 @@ daap_reply_songlist_generic(struct httpd_request *hreq, int playlist)
|
|||||||
return DAAP_REPLY_OK;
|
return DAAP_REPLY_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(meta);
|
||||||
daap_sort_context_free(sctx);
|
daap_sort_context_free(sctx);
|
||||||
evbuffer_free(song);
|
evbuffer_free(song);
|
||||||
evbuffer_free(songlist);
|
evbuffer_free(songlist);
|
||||||
@ -1417,7 +1407,7 @@ daap_reply_playlists(struct httpd_request *hreq)
|
|||||||
struct evbuffer *playlist;
|
struct evbuffer *playlist;
|
||||||
const struct dmap_field_map *dfm;
|
const struct dmap_field_map *dfm;
|
||||||
const struct dmap_field *df;
|
const struct dmap_field *df;
|
||||||
const struct dmap_field **meta;
|
const struct dmap_field **meta = NULL;
|
||||||
const char *param;
|
const char *param;
|
||||||
char **strval;
|
char **strval;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -1473,7 +1463,6 @@ daap_reply_playlists(struct httpd_request *hreq)
|
|||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||||
|
|
||||||
free(meta);
|
|
||||||
dmap_error_make(hreq->reply, "aply", "Could not start query");
|
dmap_error_make(hreq->reply, "aply", "Could not start query");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1585,7 +1574,6 @@ daap_reply_playlists(struct httpd_request *hreq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
db_query_end(&qp);
|
db_query_end(&qp);
|
||||||
free(meta);
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DAAP, "Done with playlist list, %d playlists\n", npls);
|
DPRINTF(E_DBG, L_DAAP, "Done with playlist list, %d playlists\n", npls);
|
||||||
|
|
||||||
@ -1612,6 +1600,7 @@ daap_reply_playlists(struct httpd_request *hreq)
|
|||||||
|
|
||||||
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, playlistlist));
|
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, playlistlist));
|
||||||
|
|
||||||
|
free(meta);
|
||||||
evbuffer_free(playlist);
|
evbuffer_free(playlist);
|
||||||
evbuffer_free(playlistlist);
|
evbuffer_free(playlistlist);
|
||||||
free_query_params(&qp, 1);
|
free_query_params(&qp, 1);
|
||||||
@ -1619,6 +1608,7 @@ daap_reply_playlists(struct httpd_request *hreq)
|
|||||||
return DAAP_REPLY_OK;
|
return DAAP_REPLY_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(meta);
|
||||||
evbuffer_free(playlist);
|
evbuffer_free(playlist);
|
||||||
evbuffer_free(playlistlist);
|
evbuffer_free(playlistlist);
|
||||||
free_query_params(&qp, 1);
|
free_query_params(&qp, 1);
|
||||||
@ -1635,7 +1625,7 @@ daap_reply_groups(struct httpd_request *hreq)
|
|||||||
struct evbuffer *grouplist;
|
struct evbuffer *grouplist;
|
||||||
const struct dmap_field_map *dfm;
|
const struct dmap_field_map *dfm;
|
||||||
const struct dmap_field *df;
|
const struct dmap_field *df;
|
||||||
const struct dmap_field **meta;
|
const struct dmap_field **meta = NULL;
|
||||||
struct sort_ctx *sctx;
|
struct sort_ctx *sctx;
|
||||||
cfg_t *lib;
|
cfg_t *lib;
|
||||||
const char *param;
|
const char *param;
|
||||||
@ -1699,7 +1689,6 @@ daap_reply_groups(struct httpd_request *hreq)
|
|||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||||
|
|
||||||
free(meta);
|
|
||||||
dmap_error_make(hreq->reply, tag, "Could not start query");
|
dmap_error_make(hreq->reply, tag, "Could not start query");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -1787,7 +1776,6 @@ daap_reply_groups(struct httpd_request *hreq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
db_query_end(&qp);
|
db_query_end(&qp);
|
||||||
free(meta);
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_DAAP, "Done with group list, %d groups\n", ngrp);
|
DPRINTF(E_DBG, L_DAAP, "Done with group list, %d groups\n", ngrp);
|
||||||
|
|
||||||
@ -1829,6 +1817,7 @@ daap_reply_groups(struct httpd_request *hreq)
|
|||||||
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, sctx->headerlist));
|
CHECK_ERR(L_DAAP, evbuffer_add_buffer(hreq->reply, sctx->headerlist));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(meta);
|
||||||
daap_sort_context_free(sctx);
|
daap_sort_context_free(sctx);
|
||||||
evbuffer_free(group);
|
evbuffer_free(group);
|
||||||
evbuffer_free(grouplist);
|
evbuffer_free(grouplist);
|
||||||
@ -1837,6 +1826,7 @@ daap_reply_groups(struct httpd_request *hreq)
|
|||||||
return DAAP_REPLY_OK;
|
return DAAP_REPLY_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(meta);
|
||||||
daap_sort_context_free(sctx);
|
daap_sort_context_free(sctx);
|
||||||
evbuffer_free(group);
|
evbuffer_free(group);
|
||||||
evbuffer_free(grouplist);
|
evbuffer_free(grouplist);
|
||||||
|
@ -1410,7 +1410,12 @@ dacp_reply_play(struct httpd_request *hreq)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
player_playback_start();
|
ret = player_playback_start();
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
httpd_send_error(hreq->req, 500, "Internal Server Error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 204 No Content is the canonical reply */
|
/* 204 No Content is the canonical reply */
|
||||||
httpd_send_reply(hreq->req, HTTP_NOCONTENT, "No Content", hreq->reply, HTTPD_SEND_NO_GZIP);
|
httpd_send_reply(hreq->req, HTTP_NOCONTENT, "No Content", hreq->reply, HTTPD_SEND_NO_GZIP);
|
||||||
@ -2731,10 +2736,12 @@ dacp_reply_mutetoggle(struct httpd_request *hreq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We don't actually mute, because the player doesn't currently support unmuting
|
// We don't actually mute, because the player doesn't currently support unmuting
|
||||||
if (speaker_info.selected)
|
ret = speaker_info.selected ? player_speaker_disable(speaker_info.id) : player_speaker_enable(speaker_info.id);
|
||||||
player_speaker_disable(speaker_info.id);
|
if (ret < 0)
|
||||||
else
|
{
|
||||||
player_speaker_enable(speaker_info.id);
|
httpd_send_error(hreq->req, 500, "Internal Server Error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 204 No Content is the canonical reply */
|
/* 204 No Content is the canonical reply */
|
||||||
httpd_send_reply(hreq->req, HTTP_NOCONTENT, "No Content", hreq->reply, HTTPD_SEND_NO_GZIP);
|
httpd_send_reply(hreq->req, HTTP_NOCONTENT, "No Content", hreq->reply, HTTPD_SEND_NO_GZIP);
|
||||||
|
@ -1829,7 +1829,7 @@ jsonapi_reply_outputs_set(struct httpd_request *hreq)
|
|||||||
{
|
{
|
||||||
nspk = json_object_array_length(outputs);
|
nspk = json_object_array_length(outputs);
|
||||||
|
|
||||||
ids = calloc((nspk + 1), sizeof(uint64_t));
|
CHECK_NULL(L_WEB, ids = calloc((nspk + 1), sizeof(uint64_t)));
|
||||||
ids[0] = nspk;
|
ids[0] = nspk;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -2502,8 +2502,8 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
const char *param_uris;
|
const char *param_uris;
|
||||||
const char *param_expression;
|
const char *param_expression;
|
||||||
const char *param;
|
const char *param;
|
||||||
int pos = -1;
|
int pos;
|
||||||
int limit = -1;
|
int limit;
|
||||||
bool shuffle;
|
bool shuffle;
|
||||||
int total_count = 0;
|
int total_count = 0;
|
||||||
json_object *reply;
|
json_object *reply;
|
||||||
@ -2522,6 +2522,8 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
|
|
||||||
DPRINTF(E_DBG, L_WEB, "Add tracks starting at position '%d\n", pos);
|
DPRINTF(E_DBG, L_WEB, "Add tracks starting at position '%d\n", pos);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
pos = -1;
|
||||||
|
|
||||||
param_uris = evhttp_find_header(hreq->query, "uris");
|
param_uris = evhttp_find_header(hreq->query, "uris");
|
||||||
param_expression = evhttp_find_header(hreq->query, "expression");
|
param_expression = evhttp_find_header(hreq->query, "expression");
|
||||||
@ -2557,9 +2559,10 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
{
|
{
|
||||||
// This overrides the value specified in query
|
// This overrides the value specified in query
|
||||||
param = evhttp_find_header(hreq->query, "limit");
|
param = evhttp_find_header(hreq->query, "limit");
|
||||||
if (param)
|
if (param && safe_atoi32(param, &limit) == 0)
|
||||||
safe_atoi32(param, &limit);
|
ret = queue_tracks_add_byexpression(param_expression, pos, limit, &total_count);
|
||||||
ret = queue_tracks_add_byexpression(param_expression, pos, limit, &total_count);
|
else
|
||||||
|
ret = queue_tracks_add_byexpression(param_expression, pos, -1, &total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@ -2579,9 +2582,12 @@ jsonapi_reply_queue_tracks_add(struct httpd_request *hreq)
|
|||||||
if (param && strcmp(param, "start") == 0)
|
if (param && strcmp(param, "start") == 0)
|
||||||
{
|
{
|
||||||
if ((param = evhttp_find_header(hreq->query, "playback_from_position")))
|
if ((param = evhttp_find_header(hreq->query, "playback_from_position")))
|
||||||
play_item_at_position(param);
|
ret = (play_item_at_position(param) == HTTP_NOCONTENT) ? 0 : -1;
|
||||||
else
|
else
|
||||||
player_playback_start();
|
ret = player_playback_start();
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return HTTP_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTTP_OK;
|
return HTTP_OK;
|
||||||
@ -2610,10 +2616,11 @@ update_pos(uint32_t item_id, const char *new, char shuffle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
update_str(char **str, const char *new)
|
update_str(bool *is_changed, char **str, const char *new)
|
||||||
{
|
{
|
||||||
free(*str);
|
free(*str);
|
||||||
*str = strdup(new);
|
*str = strdup(new);
|
||||||
|
*is_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2629,11 +2636,19 @@ jsonapi_reply_queue_tracks_update(struct httpd_request *hreq)
|
|||||||
player_get_status(&status);
|
player_get_status(&status);
|
||||||
|
|
||||||
if (strcmp(hreq->uri_parsed->path_parts[3], "now_playing") != 0)
|
if (strcmp(hreq->uri_parsed->path_parts[3], "now_playing") != 0)
|
||||||
safe_atou32(hreq->uri_parsed->path_parts[3], &item_id);
|
{
|
||||||
|
ret = safe_atou32(hreq->uri_parsed->path_parts[3], &item_id);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "No valid item id given: '%s'\n", hreq->uri_parsed->path);
|
||||||
|
return HTTP_BADREQUEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
item_id = status.item_id;
|
item_id = status.item_id;
|
||||||
|
|
||||||
if (!item_id || !(queue_item = db_queue_fetch_byitemid(item_id)))
|
queue_item = db_queue_fetch_byitemid(item_id);
|
||||||
|
if (!queue_item)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "No valid item id given, or now_playing given but not playing: '%s'\n", hreq->uri_parsed->path);
|
DPRINTF(E_LOG, L_WEB, "No valid item id given, or now_playing given but not playing: '%s'\n", hreq->uri_parsed->path);
|
||||||
return HTTP_BADREQUEST;
|
return HTTP_BADREQUEST;
|
||||||
@ -2643,20 +2658,20 @@ jsonapi_reply_queue_tracks_update(struct httpd_request *hreq)
|
|||||||
is_changed = false;
|
is_changed = false;
|
||||||
if ((param = evhttp_find_header(hreq->query, "new_position")))
|
if ((param = evhttp_find_header(hreq->query, "new_position")))
|
||||||
ret = update_pos(item_id, param, status.shuffle);
|
ret = update_pos(item_id, param, status.shuffle);
|
||||||
if ((param = evhttp_find_header(hreq->query, "title")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "title")))
|
||||||
update_str(&queue_item->title, param);
|
update_str(&is_changed, &queue_item->title, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "album")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "album")))
|
||||||
update_str(&queue_item->album, param);
|
update_str(&is_changed, &queue_item->album, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "artist")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "artist")))
|
||||||
update_str(&queue_item->artist, param);
|
update_str(&is_changed, &queue_item->artist, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "album_artist")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "album_artist")))
|
||||||
update_str(&queue_item->album_artist, param);
|
update_str(&is_changed, &queue_item->album_artist, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "composer")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "composer")))
|
||||||
update_str(&queue_item->composer, param);
|
update_str(&is_changed, &queue_item->composer, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "genre")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "genre")))
|
||||||
update_str(&queue_item->genre, param);
|
update_str(&is_changed, &queue_item->genre, param);
|
||||||
if ((param = evhttp_find_header(hreq->query, "artwork_url")) && (is_changed = true))
|
if ((param = evhttp_find_header(hreq->query, "artwork_url")))
|
||||||
update_str(&queue_item->artwork_url, param);
|
update_str(&is_changed, &queue_item->artwork_url, param);
|
||||||
|
|
||||||
if (ret != HTTP_OK)
|
if (ret != HTTP_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -645,6 +645,7 @@ streaming_init(void)
|
|||||||
default:
|
default:
|
||||||
DPRINTF(E_LOG, L_STREAMING, "Unsuppported streaming bit_rate=%d, supports: 64/96/128/192/320, defaulting\n", val);
|
DPRINTF(E_LOG, L_STREAMING, "Unsuppported streaming bit_rate=%d, supports: 64/96/128/192/320, defaulting\n", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_STREAMING, "Streaming quality: %d/%d/%d @ %dkbps\n", streaming_quality_out.sample_rate, streaming_quality_out.bits_per_sample, streaming_quality_out.channels, streaming_quality_out.bit_rate/1000);
|
DPRINTF(E_INFO, L_STREAMING, "Streaming quality: %d/%d/%d @ %dkbps\n", streaming_quality_out.sample_rate, streaming_quality_out.bits_per_sample, streaming_quality_out.channels, streaming_quality_out.bit_rate/1000);
|
||||||
|
|
||||||
val = cfg_getint(cfgsec, "icy_metaint");
|
val = cfg_getint(cfgsec, "icy_metaint");
|
||||||
@ -654,7 +655,12 @@ streaming_init(void)
|
|||||||
else
|
else
|
||||||
DPRINTF(E_INFO, L_STREAMING, "Unsupported icy_metaint=%d, supported range: 4096..131072, defaulting to %d\n", val, streaming_icy_metaint);
|
DPRINTF(E_INFO, L_STREAMING, "Unsupported icy_metaint=%d, supported range: 4096..131072, defaulting to %d\n", val, streaming_icy_metaint);
|
||||||
|
|
||||||
pthread_mutex_init(&streaming_sessions_lck, NULL);
|
ret = mutex_init(&streaming_sessions_lck);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_FATAL, L_STREAMING, "Could not initialize mutex (%d): %s\n", ret, strerror(ret));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
// Non-blocking because otherwise httpd and player thread may deadlock
|
// Non-blocking because otherwise httpd and player thread may deadlock
|
||||||
#ifdef HAVE_PIPE2
|
#ifdef HAVE_PIPE2
|
||||||
|
@ -217,7 +217,7 @@ metadata_get(struct input_source *source)
|
|||||||
if (!inputs[source->type]->metadata_get)
|
if (!inputs[source->type]->metadata_get)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
metadata = calloc(1, sizeof(struct input_metadata));
|
CHECK_NULL(L_PLAYER, metadata = calloc(1, sizeof(struct input_metadata)));
|
||||||
|
|
||||||
ret = inputs[source->type]->metadata_get(metadata, source);
|
ret = inputs[source->type]->metadata_get(metadata, source);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -890,8 +890,8 @@ input_init(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Prepare input buffer
|
// Prepare input buffer
|
||||||
pthread_mutex_init(&input_buffer.mutex, NULL);
|
CHECK_ERR(L_PLAYER, mutex_init(&input_buffer.mutex));
|
||||||
pthread_cond_init(&input_buffer.cond, NULL);
|
CHECK_ERR(L_PLAYER, pthread_cond_init(&input_buffer.cond, NULL));
|
||||||
|
|
||||||
CHECK_NULL(L_PLAYER, evbase_input = event_base_new());
|
CHECK_NULL(L_PLAYER, evbase_input = event_base_new());
|
||||||
CHECK_NULL(L_PLAYER, input_buffer.evbuf = evbuffer_new());
|
CHECK_NULL(L_PLAYER, input_buffer.evbuf = evbuffer_new());
|
||||||
|
@ -51,7 +51,7 @@ path_to_media_id_and_type(struct sp_file *file)
|
|||||||
struct sp_channel *
|
struct sp_channel *
|
||||||
channel_get(uint32_t channel_id, struct sp_session *session)
|
channel_get(uint32_t channel_id, struct sp_session *session)
|
||||||
{
|
{
|
||||||
if (channel_id > sizeof(session->channels)/sizeof(session->channels)[0])
|
if (channel_id >= sizeof(session->channels)/sizeof(session->channels)[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (session->channels[channel_id].state == SP_CHANNEL_STATE_UNALLOCATED)
|
if (session->channels[channel_id].state == SP_CHANNEL_STATE_UNALLOCATED)
|
||||||
@ -148,6 +148,7 @@ channel_flush(struct sp_channel *channel)
|
|||||||
int fd = channel->audio_fd[0];
|
int fd = channel->audio_fd[0];
|
||||||
int flags;
|
int flags;
|
||||||
int got;
|
int got;
|
||||||
|
int ret;
|
||||||
|
|
||||||
evbuffer_drain(channel->audio_buf, -1);
|
evbuffer_drain(channel->audio_buf, -1);
|
||||||
|
|
||||||
@ -157,13 +158,18 @@ channel_flush(struct sp_channel *channel)
|
|||||||
if (flags == -1)
|
if (flags == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
do
|
do
|
||||||
got = read(fd, buf, sizeof(buf));
|
got = read(fd, buf, sizeof(buf));
|
||||||
while (got > 0);
|
while (got > 0);
|
||||||
|
|
||||||
fcntl(fd, F_SETFL, flags);
|
ret = fcntl(fd, F_SETFL, flags);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +207,10 @@ commands_base_new(struct event_base *evbase, command_exit_cb exit_cb)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cmdbase = calloc(1, sizeof(struct commands_base));
|
cmdbase = calloc(1, sizeof(struct commands_base));
|
||||||
|
if (!cmdbase)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PIPE2
|
#ifdef HAVE_PIPE2
|
||||||
ret = pipe2(cmdbase->command_pipe, O_CLOEXEC);
|
ret = pipe2(cmdbase->command_pipe, O_CLOEXEC);
|
||||||
@ -370,6 +374,9 @@ commands_exec_async(struct commands_base *cmdbase, command_function func, void *
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cmd = calloc(1, sizeof(struct command));
|
cmd = calloc(1, sizeof(struct command));
|
||||||
|
if (!cmd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
cmd->func = func;
|
cmd->func = func;
|
||||||
cmd->func_bh = NULL;
|
cmd->func_bh = NULL;
|
||||||
cmd->arg = arg;
|
cmd->arg = arg;
|
||||||
|
@ -620,7 +620,7 @@ response_aplogin_failed(uint8_t *payload, size_t payload_len, struct sp_session
|
|||||||
}
|
}
|
||||||
|
|
||||||
sp_errmsg = "(unknown login error)";
|
sp_errmsg = "(unknown login error)";
|
||||||
for (int i = 0; i < sizeof(sp_login_errors); i++)
|
for (int i = 0; i < sizeof(sp_login_errors)/sizeof(sp_login_errors[0]); i++)
|
||||||
{
|
{
|
||||||
if (sp_login_errors[i].errorcode != aplogin_failed->error_code)
|
if (sp_login_errors[i].errorcode != aplogin_failed->error_code)
|
||||||
continue;
|
continue;
|
||||||
|
@ -48,6 +48,7 @@ events for proceeding are activated directly.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "librespot-c-internal.h"
|
#include "librespot-c-internal.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
@ -833,6 +834,8 @@ librespotc_write(int fd, sp_progress_cb progress_cb, void *cb_arg)
|
|||||||
|
|
||||||
cmdargs = calloc(1, sizeof(struct sp_cmdargs));
|
cmdargs = calloc(1, sizeof(struct sp_cmdargs));
|
||||||
|
|
||||||
|
assert(cmdargs);
|
||||||
|
|
||||||
cmdargs->fd_read = fd;
|
cmdargs->fd_read = fd;
|
||||||
cmdargs->progress_cb = progress_cb;
|
cmdargs->progress_cb = progress_cb;
|
||||||
cmdargs->cb_arg = cb_arg;
|
cmdargs->cb_arg = cb_arg;
|
||||||
|
@ -180,7 +180,7 @@ pipe_create(const char *path, int id, enum pipetype type, event_callback_fn cb)
|
|||||||
{
|
{
|
||||||
struct pipe *pipe;
|
struct pipe *pipe;
|
||||||
|
|
||||||
pipe = calloc(1, sizeof(struct pipe));
|
CHECK_NULL(L_PLAYER, pipe = calloc(1, sizeof(struct pipe)));
|
||||||
pipe->path = strdup(path);
|
pipe->path = strdup(path);
|
||||||
pipe->id = id;
|
pipe->id = id;
|
||||||
pipe->fd = -1;
|
pipe->fd = -1;
|
||||||
@ -916,9 +916,6 @@ pipe_metadata_watch_add(void *arg)
|
|||||||
pipe_metadata_watch_del(NULL); // Just in case we somehow already have a metadata pipe open
|
pipe_metadata_watch_del(NULL); // Just in case we somehow already have a metadata pipe open
|
||||||
|
|
||||||
pipe_metadata.pipe = pipe_create(path, 0, PIPE_METADATA, pipe_metadata_read_cb);
|
pipe_metadata.pipe = pipe_create(path, 0, PIPE_METADATA, pipe_metadata_read_cb);
|
||||||
if (!pipe_metadata.pipe)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pipe_metadata.evbuf = evbuffer_new();
|
pipe_metadata.evbuf = evbuffer_new();
|
||||||
|
|
||||||
ret = watch_add(pipe_metadata.pipe);
|
ret = watch_add(pipe_metadata.pipe);
|
||||||
@ -948,13 +945,18 @@ pipe_thread_start(void)
|
|||||||
static void
|
static void
|
||||||
pipe_thread_stop(void)
|
pipe_thread_stop(void)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!tid_pipe)
|
if (!tid_pipe)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
commands_exec_sync(cmdbase, pipe_watch_update, NULL, NULL);
|
commands_exec_sync(cmdbase, pipe_watch_update, NULL, NULL);
|
||||||
|
|
||||||
commands_base_destroy(cmdbase);
|
commands_base_destroy(cmdbase);
|
||||||
pthread_join(tid_pipe, NULL);
|
|
||||||
|
ret = pthread_join(tid_pipe, NULL);
|
||||||
|
if (ret != 0)
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Could not join pipe thread: %s\n", strerror(errno));
|
||||||
|
|
||||||
event_base_free(evbase_pipe);
|
event_base_free(evbase_pipe);
|
||||||
tid_pipe = 0;
|
tid_pipe = 0;
|
||||||
}
|
}
|
||||||
@ -1037,9 +1039,10 @@ setup(struct input_source *source)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
CHECK_NULL(L_PLAYER, pipe = pipe_create(source->path, source->id, PIPE_PCM, NULL));
|
|
||||||
CHECK_NULL(L_PLAYER, source->evbuf = evbuffer_new());
|
CHECK_NULL(L_PLAYER, source->evbuf = evbuffer_new());
|
||||||
|
|
||||||
|
pipe = pipe_create(source->path, source->id, PIPE_PCM, NULL);
|
||||||
|
|
||||||
pipe->fd = fd;
|
pipe->fd = fd;
|
||||||
pipe->is_autostarted = (source->id == pipe_autostart_id);
|
pipe->is_autostarted = (source->id == pipe_autostart_id);
|
||||||
|
|
||||||
|
@ -170,10 +170,10 @@ virtual_path_make(char *virtual_path, int virtual_path_len, const char *path)
|
|||||||
|
|
||||||
ret = snprintf(virtual_path, virtual_path_len, "/file:%s", path);
|
ret = snprintf(virtual_path, virtual_path_len, "/file:%s", path);
|
||||||
if ((ret < 0) || (ret >= virtual_path_len))
|
if ((ret < 0) || (ret >= virtual_path_len))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Virtual path '/file:%s', virtual_path_len exceeded (%d/%d)\n", path, ret, virtual_path_len);
|
DPRINTF(E_LOG, L_SCAN, "Virtual path '/file:%s', virtual_path_len exceeded (%d/%d)\n", path, ret, virtual_path_len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -816,7 +816,6 @@ process_directory(char *path, int parent_id, int flags)
|
|||||||
if (!dirp)
|
if (!dirp)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Could not open directory %s: %s\n", path, strerror(errno));
|
DPRINTF(E_LOG, L_SCAN, "Could not open directory %s: %s\n", path, strerror(errno));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,7 +823,10 @@ process_directory(char *path, int parent_id, int flags)
|
|||||||
|
|
||||||
ret = virtual_path_make(virtual_path, sizeof(virtual_path), path);
|
ret = virtual_path_make(virtual_path, sizeof(virtual_path), path);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
{
|
||||||
|
closedir(dirp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dir_id = db_directory_addorupdate(virtual_path, path, 0, parent_id);
|
dir_id = db_directory_addorupdate(virtual_path, path, 0, parent_id);
|
||||||
if (dir_id <= 0)
|
if (dir_id <= 0)
|
||||||
@ -853,7 +855,6 @@ process_directory(char *path, int parent_id, int flags)
|
|||||||
if (errno)
|
if (errno)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "readdir error in %s: %s\n", path, strerror(errno));
|
DPRINTF(E_LOG, L_SCAN, "readdir error in %s: %s\n", path, strerror(errno));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +880,6 @@ process_directory(char *path, int parent_id, int flags)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Skipping %s, read_attributes() failed\n", entry);
|
DPRINTF(E_LOG, L_SCAN, "Skipping %s, read_attributes() failed\n", entry);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +916,6 @@ process_directory(char *path, int parent_id, int flags)
|
|||||||
if (wi.wd < 0)
|
if (wi.wd < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_SCAN, "Could not create inotify watch for %s: %s\n", path, strerror(errno));
|
DPRINTF(E_WARN, L_SCAN, "Could not create inotify watch for %s: %s\n", path, strerror(errno));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,8 +1111,8 @@ static void
|
|||||||
process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
|
process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
|
||||||
{
|
{
|
||||||
struct watch_enum we;
|
struct watch_enum we;
|
||||||
|
struct watch_info dummy_wi;
|
||||||
uint32_t rm_wd;
|
uint32_t rm_wd;
|
||||||
char *s;
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int ret;
|
int ret;
|
||||||
int parent_id;
|
int parent_id;
|
||||||
@ -1204,12 +1203,9 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
|
|||||||
DPRINTF(E_DBG, L_SCAN, "Directory permissions changed (%s): %s\n", wi->path, path);
|
DPRINTF(E_DBG, L_SCAN, "Directory permissions changed (%s): %s\n", wi->path, path);
|
||||||
|
|
||||||
// Find out if we are already watching the dir (ret will be 0)
|
// Find out if we are already watching the dir (ret will be 0)
|
||||||
s = wi->path;
|
ret = db_watch_get_bypath(&dummy_wi, path);
|
||||||
wi->path = path;
|
|
||||||
ret = db_watch_get_bypath(wi);
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
free(wi->path);
|
free_wi(&dummy_wi, 1);
|
||||||
wi->path = s;
|
|
||||||
|
|
||||||
// We don't use access() or euidaccess() because they don't work with ACL's
|
// We don't use access() or euidaccess() because they don't work with ACL's
|
||||||
// - this also means we can't check for executable permission, which stat()
|
// - this also means we can't check for executable permission, which stat()
|
||||||
@ -1237,7 +1233,7 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie)
|
|||||||
DPRINTF(E_INFO, L_SCAN, "Directory event, but '%s' already being watched\n", path);
|
DPRINTF(E_INFO, L_SCAN, "Directory event, but '%s' already being watched\n", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd > 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1321,7 +1317,7 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
|
|||||||
ie->mask |= IN_CLOSE_WRITE;
|
ie->mask |= IN_CLOSE_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd > 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,7 +1332,7 @@ process_inotify_file(struct watch_info *wi, char *path, struct inotify_event *ie
|
|||||||
ret = virtual_path_make(dir_vpath, sizeof(dir_vpath), path);
|
ret = virtual_path_make(dir_vpath, sizeof(dir_vpath), path);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
ptr = strrchr(dir_vpath, '/');
|
CHECK_NULL(L_SCAN, ptr = strrchr(dir_vpath, '/'));
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
|
|
||||||
dir_id = db_directory_id_byvirtualpath(dir_vpath);
|
dir_id = db_directory_id_byvirtualpath(dir_vpath);
|
||||||
@ -1539,8 +1535,7 @@ inotify_cb(int fd, short event, void *arg)
|
|||||||
* the memory space for ie[1+] contains the name of the file
|
* the memory space for ie[1+] contains the name of the file
|
||||||
* see the inotify documentation
|
* see the inotify documentation
|
||||||
*/
|
*/
|
||||||
wi.wd = ie->wd;
|
ret = db_watch_get_bywd(&wi, ie->wd);
|
||||||
ret = db_watch_get_bywd(&wi);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
if (!(ie->mask & IN_IGNORED))
|
if (!(ie->mask & IN_IGNORED))
|
||||||
@ -1554,30 +1549,30 @@ inotify_cb(int fd, short event, void *arg)
|
|||||||
DPRINTF(E_DBG, L_SCAN, "%s deleted or backing filesystem unmounted!\n", wi.path);
|
DPRINTF(E_DBG, L_SCAN, "%s deleted or backing filesystem unmounted!\n", wi.path);
|
||||||
|
|
||||||
db_watch_delete_bywd(ie->wd);
|
db_watch_delete_bywd(ie->wd);
|
||||||
free(wi.path);
|
free_wi(&wi, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
path[0] = '\0';
|
path[0] = '\0';
|
||||||
|
|
||||||
ret = snprintf(path, PATH_MAX, "%s", wi.path);
|
ret = snprintf(path, sizeof(path), "%s", wi.path);
|
||||||
if ((ret < 0) || (ret >= PATH_MAX))
|
if ((ret < 0) || (ret >= sizeof(path)))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Skipping event under %s, PATH_MAX exceeded\n", wi.path);
|
DPRINTF(E_LOG, L_SCAN, "Skipping event under %s, PATH_MAX exceeded\n", wi.path);
|
||||||
|
|
||||||
free(wi.path);
|
free_wi(&wi, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ie->len > 0)
|
if (ie->len > 0)
|
||||||
{
|
{
|
||||||
namelen = PATH_MAX - ret;
|
namelen = sizeof(path) - ret;
|
||||||
ret = snprintf(path + ret, namelen, "/%s", ie->name);
|
ret = snprintf(path + ret, namelen, "/%s", ie->name);
|
||||||
if ((ret < 0) || (ret >= namelen))
|
if ((ret < 0) || (ret >= namelen))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SCAN, "Skipping %s/%s, PATH_MAX exceeded\n", wi.path, ie->name);
|
DPRINTF(E_LOG, L_SCAN, "Skipping %s/%s, PATH_MAX exceeded\n", wi.path, ie->name);
|
||||||
|
|
||||||
free(wi.path);
|
free_wi(&wi, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1595,7 +1590,7 @@ inotify_cb(int fd, short event, void *arg)
|
|||||||
#else
|
#else
|
||||||
process_inotify_file_defer(&wi, path, ie);
|
process_inotify_file_defer(&wi, path, ie);
|
||||||
#endif
|
#endif
|
||||||
free(wi.path);
|
free_wi(&wi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -749,40 +749,40 @@ process_pl_items(plist_t items, int pl_id, const char *name, struct itml_to_db_m
|
|||||||
db_transaction_end();
|
db_transaction_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool
|
||||||
ignore_pl(plist_t pl, const char *name)
|
ignore_pl(plist_t pl, const char *name)
|
||||||
{
|
{
|
||||||
uint64_t kind;
|
uint64_t kind;
|
||||||
int smart;
|
|
||||||
uint8_t master;
|
uint8_t master;
|
||||||
uint8_t party;
|
uint8_t party;
|
||||||
|
|
||||||
kind = 0;
|
if (get_dictval_int_from_key(pl, "Distinguished Kind", &kind) == 0 && kind > 0)
|
||||||
smart = 0;
|
{
|
||||||
master = 0;
|
DPRINTF(E_INFO, L_SCAN, "Ignoring iTunes builtin playlist '%s' (k %" PRIu64 ")\n", name, kind);
|
||||||
party = 0;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Special (builtin) playlists */
|
if (get_dictval_bool_from_key(pl, "Master", &master) == 0 && master)
|
||||||
get_dictval_int_from_key(pl, "Distinguished Kind", &kind);
|
{
|
||||||
|
DPRINTF(E_INFO, L_SCAN, "Ignoring iTunes Master playlist '%s'\n", name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_dictval_bool_from_key(pl, "Party Shuffle", &party) == 0 && party)
|
||||||
|
{
|
||||||
|
DPRINTF(E_INFO, L_SCAN, "Ignoring iTunes Party Shuffle playlist '%s'\n", name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Import smart playlists (optional) */
|
/* Import smart playlists (optional) */
|
||||||
if (!cfg_getbool(cfg_getsec(cfg, "library"), "itunes_smartpl")
|
if (!cfg_getbool(cfg_getsec(cfg, "library"), "itunes_smartpl")
|
||||||
&& (plist_dict_get_item(pl, "Smart Info") || plist_dict_get_item(pl, "Smart Criteria")))
|
&& (plist_dict_get_item(pl, "Smart Info") || plist_dict_get_item(pl, "Smart Criteria")))
|
||||||
smart = 1;
|
|
||||||
|
|
||||||
/* Not interested in the Master playlist */
|
|
||||||
get_dictval_bool_from_key(pl, "Master", &master);
|
|
||||||
/* Not interested in Party Shuffle playlists */
|
|
||||||
get_dictval_bool_from_key(pl, "Party Shuffle", &party);
|
|
||||||
|
|
||||||
if ((kind > 0) || smart || party || master)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_INFO, L_SCAN, "Ignoring playlist '%s' (k %" PRIu64 " s%d p%d m%d)\n", name, kind, smart, party, master);
|
DPRINTF(E_INFO, L_SCAN, "Ignoring iTunes smart playlist as set in config '%s'\n", name);
|
||||||
|
return true;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -351,9 +351,10 @@ request_endpoint(const char *uri)
|
|||||||
json_object *json_response = NULL;
|
json_object *json_response = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(struct http_client_ctx));
|
CHECK_NULL(L_SPOTIFY, ctx = calloc(1, sizeof(struct http_client_ctx)));
|
||||||
ctx->output_headers = calloc(1, sizeof(struct keyval));
|
CHECK_NULL(L_SPOTIFY, ctx->output_headers = calloc(1, sizeof(struct keyval)));
|
||||||
ctx->input_body = evbuffer_new();
|
CHECK_NULL(L_SPOTIFY, ctx->input_body = evbuffer_new());
|
||||||
|
|
||||||
ctx->url = uri;
|
ctx->url = uri;
|
||||||
|
|
||||||
snprintf(bearer_token, sizeof(bearer_token), "Bearer %s", spotify_credentials.access_token);
|
snprintf(bearer_token, sizeof(bearer_token), "Bearer %s", spotify_credentials.access_token);
|
||||||
@ -1091,7 +1092,9 @@ spotifywebapi_oauth_uri_get(const char *redirect_uri)
|
|||||||
if (param)
|
if (param)
|
||||||
{
|
{
|
||||||
uri_len = strlen(spotify_auth_uri) + strlen(param) + 3;
|
uri_len = strlen(spotify_auth_uri) + strlen(param) + 3;
|
||||||
uri = calloc(uri_len, sizeof(char));
|
|
||||||
|
CHECK_NULL(L_SPOTIFY, uri = calloc(uri_len, sizeof(char)));
|
||||||
|
|
||||||
snprintf(uri, uri_len, "%s/?%s", spotify_auth_uri, param);
|
snprintf(uri, uri_len, "%s/?%s", spotify_auth_uri, param);
|
||||||
|
|
||||||
free(param);
|
free(param);
|
||||||
|
@ -364,7 +364,7 @@ signal_signalfd_cb(int fd, short event, void *arg)
|
|||||||
struct signalfd_siginfo info;
|
struct signalfd_siginfo info;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
while (read(fd, &info, sizeof(struct signalfd_siginfo)) > 0)
|
while (read(fd, &info, sizeof(struct signalfd_siginfo)) == sizeof(struct signalfd_siginfo))
|
||||||
{
|
{
|
||||||
switch (info.ssi_signo)
|
switch (info.ssi_signo)
|
||||||
{
|
{
|
||||||
|
@ -258,7 +258,7 @@ net_bind(short unsigned *port, int type, const char *log_service_name)
|
|||||||
char strport[8];
|
char strport[8];
|
||||||
int yes = 1;
|
int yes = 1;
|
||||||
int no = 0;
|
int no = 0;
|
||||||
int fd;
|
int fd = -1;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cfgaddr = cfg_getstr(cfg_getsec(cfg, "general"), "bind_address");
|
cfgaddr = cfg_getstr(cfg_getsec(cfg, "general"), "bind_address");
|
||||||
@ -275,7 +275,7 @@ net_bind(short unsigned *port, int type, const char *log_service_name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ptr = servinfo, fd = -1; ptr != NULL; ptr = ptr->ai_next)
|
for (ptr = servinfo; ptr != NULL; ptr = ptr->ai_next)
|
||||||
{
|
{
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -338,7 +338,8 @@ net_bind(short unsigned *port, int type, const char *log_service_name)
|
|||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
close(fd);
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,7 +811,8 @@ parse_group_params(int argc, char **argv, bool group_in_listcommand, struct quer
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*groupsize = (argc - first_group) / 2;
|
*groupsize = (argc - first_group) / 2;
|
||||||
*group = calloc(*groupsize, sizeof(struct mpd_tagtype *));
|
|
||||||
|
CHECK_NULL(L_MPD, *group = calloc(*groupsize, sizeof(struct mpd_tagtype *)));
|
||||||
|
|
||||||
// Now process all group/field arguments
|
// Now process all group/field arguments
|
||||||
for (j = 0; j < (*groupsize); j++)
|
for (j = 0; j < (*groupsize); j++)
|
||||||
@ -3557,7 +3558,7 @@ output_get_cb(struct player_speaker_info *spk, void *arg)
|
|||||||
if (!param->output
|
if (!param->output
|
||||||
&& param->shortid == (unsigned short) spk->id)
|
&& param->shortid == (unsigned short) spk->id)
|
||||||
{
|
{
|
||||||
param->output = calloc(1, sizeof(struct output));
|
CHECK_NULL(L_MPD, param->output = calloc(1, sizeof(struct output)));
|
||||||
|
|
||||||
param->output->id = spk->id;
|
param->output->id = spk->id;
|
||||||
param->output->shortid = (unsigned short) spk->id;
|
param->output->shortid = (unsigned short) spk->id;
|
||||||
|
@ -559,7 +559,8 @@ device_id_colon_parse(uint64_t *id, const char *id_str)
|
|||||||
char *ptr;
|
char *ptr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
s = calloc(1, strlen(id_str) + 1);
|
CHECK_NULL(L_AIRPLAY, s = calloc(1, strlen(id_str) + 1));
|
||||||
|
|
||||||
for (ptr = s; *id_str != '\0'; id_str++)
|
for (ptr = s; *id_str != '\0'; id_str++)
|
||||||
{
|
{
|
||||||
if (*id_str == ':')
|
if (*id_str == ':')
|
||||||
|
@ -948,6 +948,7 @@ sync_correct(struct alsa_playback_session *pb, double drift, double latency, str
|
|||||||
{
|
{
|
||||||
int step;
|
int step;
|
||||||
int sign;
|
int sign;
|
||||||
|
int ret;
|
||||||
|
|
||||||
// We change the sample_rate in steps that are a multiple of 50. So we might
|
// We change the sample_rate in steps that are a multiple of 50. So we might
|
||||||
// step 44100 -> 44000 -> 40900 -> 44000 -> 44100. If we used percentages to
|
// step 44100 -> 44000 -> 40900 -> 44000 -> 44100. If we used percentages to
|
||||||
@ -975,7 +976,14 @@ sync_correct(struct alsa_playback_session *pb, double drift, double latency, str
|
|||||||
pb->quality.sample_rate += sign * step;
|
pb->quality.sample_rate += sign * step;
|
||||||
|
|
||||||
if (pb->sync_resample_step != 0)
|
if (pb->sync_resample_step != 0)
|
||||||
outputs_quality_subscribe(&pb->quality);
|
{
|
||||||
|
ret = outputs_quality_subscribe(&pb->quality);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_LAUDIO, "Error adjusting sample rate to %d to maintain sync\n", pb->quality.sample_rate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reset position so next sync_correct latency correction is only based on
|
// Reset position so next sync_correct latency correction is only based on
|
||||||
// what has elapsed since our correction
|
// what has elapsed since our correction
|
||||||
|
@ -931,7 +931,7 @@ static int
|
|||||||
raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
||||||
{
|
{
|
||||||
const char *param;
|
const char *param;
|
||||||
char *auth;
|
char *auth = NULL;
|
||||||
char *token;
|
char *token;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
@ -951,8 +951,7 @@ raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
|||||||
if (!param)
|
if (!param)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "WWW-Authenticate header not found\n");
|
DPRINTF(E_LOG, L_RAOP, "WWW-Authenticate header not found\n");
|
||||||
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_RAOP, "WWW-Authenticate: %s\n", param);
|
DPRINTF(E_DBG, L_RAOP, "WWW-Authenticate: %s\n", param);
|
||||||
@ -960,19 +959,23 @@ raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
|||||||
if (strncmp(param, "Digest ", strlen("Digest ")) != 0)
|
if (strncmp(param, "Digest ", strlen("Digest ")) != 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "Unsupported authentication method: %s\n", param);
|
DPRINTF(E_LOG, L_RAOP, "Unsupported authentication method: %s\n", param);
|
||||||
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auth = strdup(param);
|
auth = strdup(param);
|
||||||
if (!auth)
|
if (!auth)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "Out of memory for WWW-Authenticate header copy\n");
|
DPRINTF(E_LOG, L_RAOP, "Out of memory for WWW-Authenticate header copy\n");
|
||||||
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token = strchr(auth, ' ');
|
token = strchr(auth, ' ');
|
||||||
|
if (!token)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_RAOP, "Unexpected WWW-Authenticate auth\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
token++;
|
token++;
|
||||||
|
|
||||||
token = strtok_r(token, " =", &ptr);
|
token = strtok_r(token, " =", &ptr);
|
||||||
@ -998,8 +1001,6 @@ raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
|||||||
token = strtok_r(NULL, " =", &ptr);
|
token = strtok_r(NULL, " =", &ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(auth);
|
|
||||||
|
|
||||||
if (!rs->realm || !rs->nonce)
|
if (!rs->realm || !rs->nonce)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "Could not find realm/nonce in WWW-Authenticate header\n");
|
DPRINTF(E_LOG, L_RAOP, "Could not find realm/nonce in WWW-Authenticate header\n");
|
||||||
@ -1016,12 +1017,17 @@ raop_parse_auth(struct raop_session *rs, struct evrtsp_request *req)
|
|||||||
rs->nonce = NULL;
|
rs->nonce = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_RAOP, "Found realm: [%s], nonce: [%s]\n", rs->realm, rs->nonce);
|
DPRINTF(E_DBG, L_RAOP, "Found realm: [%s], nonce: [%s]\n", rs->realm, rs->nonce);
|
||||||
|
|
||||||
|
free(auth);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(auth);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -3363,6 +3369,14 @@ raop_cb_startup_setup(struct evrtsp_request *req, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
token = strchr(transport, ';');
|
token = strchr(transport, ';');
|
||||||
|
if (!token)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_RAOP, "Missing semicolon in Transport header: %s\n", transport);
|
||||||
|
|
||||||
|
free(transport);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
token++;
|
token++;
|
||||||
|
|
||||||
token = strtok_r(token, ";=", &ptr);
|
token = strtok_r(token, ";=", &ptr);
|
||||||
|
@ -70,6 +70,9 @@ pair_tlv_new() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
pair_tlv_free(pair_tlv_values_t *values) {
|
pair_tlv_free(pair_tlv_values_t *values) {
|
||||||
|
if (!values)
|
||||||
|
return;
|
||||||
|
|
||||||
pair_tlv_t *t = values->head;
|
pair_tlv_t *t = values->head;
|
||||||
while (t) {
|
while (t) {
|
||||||
pair_tlv_t *t2 = t;
|
pair_tlv_t *t2 = t;
|
||||||
|
@ -347,7 +347,7 @@ srp_user_process_challenge(struct SRPUser *usr, const unsigned char *bytes_s, in
|
|||||||
bnum u, x;
|
bnum u, x;
|
||||||
|
|
||||||
*len_M = 0;
|
*len_M = 0;
|
||||||
*bytes_M = 0;
|
*bytes_M = NULL;
|
||||||
|
|
||||||
bnum_bin2bn(s, bytes_s, len_s);
|
bnum_bin2bn(s, bytes_s, len_s);
|
||||||
bnum_bin2bn(B, bytes_B, len_B);
|
bnum_bin2bn(B, bytes_B, len_B);
|
||||||
@ -384,14 +384,7 @@ srp_user_process_challenge(struct SRPUser *usr, const unsigned char *bytes_s, in
|
|||||||
calculate_H_AMK(usr->alg, usr->H_AMK, usr->A, usr->M, usr->session_key, usr->session_key_len);
|
calculate_H_AMK(usr->alg, usr->H_AMK, usr->A, usr->M, usr->session_key, usr->session_key_len);
|
||||||
|
|
||||||
*bytes_M = usr->M;
|
*bytes_M = usr->M;
|
||||||
if (len_M)
|
*len_M = hash_length(usr->alg);
|
||||||
*len_M = hash_length(usr->alg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*bytes_M = NULL;
|
|
||||||
if (len_M)
|
|
||||||
*len_M = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup2:
|
cleanup2:
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
#define REQUEST_BUFSIZE 4096
|
#define REQUEST_BUFSIZE 4096
|
||||||
#define ENCRYPTED_LEN_MAX 0x400
|
#define ENCRYPTED_LEN_MAX 0x400
|
||||||
|
|
||||||
|
// #define DEBUG_SHORT_A 1
|
||||||
|
|
||||||
enum pair_keys
|
enum pair_keys
|
||||||
{
|
{
|
||||||
PAIR_SETUP_MSG01 = 0,
|
PAIR_SETUP_MSG01 = 0,
|
||||||
@ -418,6 +420,14 @@ srp_user_get_session_key(struct SRPUser *usr, int *key_length)
|
|||||||
return usr->session_key;
|
return usr->session_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SHORT_A
|
||||||
|
// This value of "a" will yield a 383 byte A
|
||||||
|
static uint8_t short_a[] = {
|
||||||
|
0xef, 0xb5, 0x93, 0xf5, 0x03, 0x97, 0x69, 0x8e, 0x15, 0xed, 0xee, 0x5b, 0xf2, 0xf9, 0x23, 0x6c,
|
||||||
|
0xf0, 0x59, 0x6c, 0xe2, 0x77, 0xf2, 0x14, 0x16, 0xac, 0x99, 0xfa, 0x31, 0xae, 0x2b, 0xd3, 0x41,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Output: username, bytes_A, len_A */
|
/* Output: username, bytes_A, len_A */
|
||||||
static void
|
static void
|
||||||
srp_user_start_authentication(struct SRPUser *usr, const char **username,
|
srp_user_start_authentication(struct SRPUser *usr, const char **username,
|
||||||
@ -425,6 +435,9 @@ srp_user_start_authentication(struct SRPUser *usr, const char **username,
|
|||||||
{
|
{
|
||||||
// BN_hex2bn(&(usr->a), "D929DFB605687233C9E9030C2280156D03BDB9FDCF3CCE3BC27D9CCFCB5FF6A1");
|
// BN_hex2bn(&(usr->a), "D929DFB605687233C9E9030C2280156D03BDB9FDCF3CCE3BC27D9CCFCB5FF6A1");
|
||||||
bnum_random(usr->a, 256);
|
bnum_random(usr->a, 256);
|
||||||
|
#ifdef DEBUG_SHORT_A
|
||||||
|
bnum_bin2bn(usr->a, short_a, sizeof(short_a));
|
||||||
|
#endif
|
||||||
#ifdef DEBUG_PAIR
|
#ifdef DEBUG_PAIR
|
||||||
bnum_dump("Random value of usr->a:\n", usr->a);
|
bnum_dump("Random value of usr->a:\n", usr->a);
|
||||||
#endif
|
#endif
|
||||||
@ -459,7 +472,7 @@ srp_user_process_challenge(struct SRPUser *usr, const unsigned char *bytes_s, in
|
|||||||
bnum u, x;
|
bnum u, x;
|
||||||
|
|
||||||
*len_M = 0;
|
*len_M = 0;
|
||||||
*bytes_M = 0;
|
*bytes_M = NULL;
|
||||||
|
|
||||||
bnum_bin2bn(s, bytes_s, len_s);
|
bnum_bin2bn(s, bytes_s, len_s);
|
||||||
bnum_bin2bn(B, bytes_B, len_B);
|
bnum_bin2bn(B, bytes_B, len_B);
|
||||||
@ -499,14 +512,7 @@ srp_user_process_challenge(struct SRPUser *usr, const unsigned char *bytes_s, in
|
|||||||
calculate_H_AMK(usr->alg, usr->H_AMK, usr->A, usr->M, usr->session_key, usr->session_key_len);
|
calculate_H_AMK(usr->alg, usr->H_AMK, usr->A, usr->M, usr->session_key, usr->session_key_len);
|
||||||
|
|
||||||
*bytes_M = usr->M;
|
*bytes_M = usr->M;
|
||||||
if (len_M)
|
*len_M = hash_length(usr->alg);
|
||||||
*len_M = hash_length(usr->alg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*bytes_M = NULL;
|
|
||||||
if (len_M)
|
|
||||||
*len_M = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup2:
|
cleanup2:
|
||||||
@ -1936,6 +1942,7 @@ client_verify_response2(struct pair_verify_context *handle, const uint8_t *data,
|
|||||||
|
|
||||||
handle->status = PAIR_STATUS_COMPLETED;
|
handle->status = PAIR_STATUS_COMPLETED;
|
||||||
|
|
||||||
|
pair_tlv_free(response);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +764,7 @@ remote_pairing_pair(const char *pin)
|
|||||||
return REMOTE_INVALID_PIN;
|
return REMOTE_INVALID_PIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(cmdarg, pin, sizeof(cmdarg));
|
snprintf(cmdarg, sizeof(cmdarg), "%s", pin);
|
||||||
|
|
||||||
return commands_exec_sync(cmdbase, pairing_pair, NULL, &cmdarg);
|
return commands_exec_sync(cmdbase, pairing_pair, NULL, &cmdarg);
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ rng_rand_range(struct rng_ctx *ctx, int32_t min, int32_t max)
|
|||||||
* Durstenfeld in-place shuffling variant
|
* Durstenfeld in-place shuffling variant
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
shuffle_int(struct rng_ctx *ctx, int *values, int len)
|
rng_shuffle_int(struct rng_ctx *ctx, int *values, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int32_t j;
|
int32_t j;
|
||||||
|
@ -19,7 +19,7 @@ int32_t
|
|||||||
rng_rand_range(struct rng_ctx *ctx, int32_t min, int32_t max);
|
rng_rand_range(struct rng_ctx *ctx, int32_t min, int32_t max);
|
||||||
|
|
||||||
void
|
void
|
||||||
shuffle_int(struct rng_ctx *ctx, int *values, int len);
|
rng_shuffle_int(struct rng_ctx *ctx, int *values, int len);
|
||||||
|
|
||||||
#endif /* !__RNG_H__ */
|
#endif /* !__RNG_H__ */
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include <json.h>
|
#include <json.h>
|
||||||
#include <libwebsockets.h>
|
#include <libwebsockets.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -511,13 +510,19 @@ websocket_init(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_init(&websocket_write_event_lock, NULL);
|
ret = mutex_init(&websocket_write_event_lock);
|
||||||
websocket_write_events = 0;
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Failed to initialize mutex: %s\n", strerror(ret));
|
||||||
|
lws_context_destroy(context);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = pthread_create(&tid_websocket, NULL, websocket, NULL);
|
ret = pthread_create(&tid_websocket, NULL, websocket, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_WEB, "Could not spawn websocket thread: %s\n", strerror(errno));
|
DPRINTF(E_LOG, L_WEB, "Could not spawn websocket thread (%d): %s\n", ret, strerror(ret));
|
||||||
|
pthread_mutex_destroy(&websocket_write_event_lock);
|
||||||
lws_context_destroy(context);
|
lws_context_destroy(context);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -530,10 +535,15 @@ websocket_init(void)
|
|||||||
void
|
void
|
||||||
websocket_deinit(void)
|
websocket_deinit(void)
|
||||||
{
|
{
|
||||||
if (websocket_port > 0)
|
int ret;
|
||||||
{
|
|
||||||
websocket_exit = true;
|
if (websocket_port <= 0)
|
||||||
pthread_join(tid_websocket, NULL);
|
return;
|
||||||
pthread_mutex_destroy(&websocket_write_event_lock);
|
|
||||||
}
|
websocket_exit = true;
|
||||||
|
ret = pthread_join(tid_websocket, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_WEB, "Error joining websocket thread (%d): %s\n", ret, strerror(ret));
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&websocket_write_event_lock);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user