mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-12 15:33:23 -05:00
Switch to the new database code
This commit is contained in:
parent
f2c677462b
commit
a200703393
@ -31,9 +31,7 @@ options {
|
||||
#include <errno.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db-sql.h"
|
||||
#include "db.h"
|
||||
#include "daap_query.h"
|
||||
}
|
||||
|
||||
@ -217,7 +215,7 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||
goto STR_result_valid_0; /* ABORT */
|
||||
}
|
||||
|
||||
escaped = (pANTLR3_UINT8)db_sql_escape_dup("\%q", val);
|
||||
escaped = (pANTLR3_UINT8)db_escape_string((char *)val);
|
||||
if (!escaped)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not escape value\n");
|
||||
|
@ -24,6 +24,7 @@ ANTLR_PRODUCTS =
|
||||
mt_daapd_CPPFLAGS = -D_GNU_SOURCE @AVAHI_CFLAGS@ @SQLITE3_CFLAGS@ @FFMPEG_CFLAGS@ @CONFUSE_CFLAGS@ @TAGLIB_CFLAGS@ @MINIXML_CFLAGS@
|
||||
mt_daapd_LDADD = @AVAHI_LIBS@ @SQLITE3_LIBS@ @FFMPEG_LIBS@ @CONFUSE_LIBS@ @FLAC_LIBS@ @TAGLIB_LIBS@ @LIBEVENT_LIBS@ @LIBAVL_LIBS@ @MINIXML_LIBS@ @ANTLR3C_LIBS@
|
||||
mt_daapd_SOURCES = main.c \
|
||||
db.c db.h \
|
||||
logger.c logger.h \
|
||||
conffile.c conffile.h \
|
||||
filescanner.c filescanner.h \
|
||||
@ -38,10 +39,7 @@ mt_daapd_SOURCES = main.c \
|
||||
misc.c misc.h \
|
||||
rsp_query.c rsp_query.h \
|
||||
daap_query.c daap_query.h \
|
||||
db-generic.c db-generic.h \
|
||||
scan-wma.c \
|
||||
db-sql-updates.c \
|
||||
db-sql.c db-sql.h db-sql-sqlite3.c db-sql-sqlite3.h\
|
||||
$(FLACSRC) $(MUSEPACKSRC)
|
||||
|
||||
nodist_mt_daapd_SOURCES = \
|
||||
@ -50,9 +48,7 @@ nodist_mt_daapd_SOURCES = \
|
||||
EXTRA_DIST = \
|
||||
$(ANTLR_GRAMMARS) \
|
||||
scan-mpc.c \
|
||||
scan-flac.c \
|
||||
ff-dbstruct.h
|
||||
|
||||
scan-flac.c
|
||||
|
||||
# Let's help the dependencies a little.
|
||||
rsp_query.c: RSPLexer.h RSPParser.h RSP2SQL.h
|
||||
|
@ -32,9 +32,7 @@ options {
|
||||
#include <time.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db-sql.h"
|
||||
#include "db.h"
|
||||
#include "misc.h"
|
||||
#include "rsp_query.h"
|
||||
}
|
||||
@ -181,7 +179,7 @@ strcrit returns [ pANTLR3_STRING result, int valid ]
|
||||
goto strcrit_valid_0; /* ABORT */
|
||||
}
|
||||
|
||||
escaped = db_sql_escape_dup("\%q", $s->getText($s)->chars);
|
||||
escaped = db_escape_string((char *)$s->getText($s)->chars);
|
||||
if (!escaped)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Could not escape value\n");
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include <avl.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "db-generic.h"
|
||||
#include "db.h"
|
||||
#include "filescanner.h"
|
||||
#include "conffile.h"
|
||||
|
||||
@ -144,55 +144,6 @@ pop_dir(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
free_mfi(struct media_file_info *mfi)
|
||||
{
|
||||
if (mfi->path)
|
||||
free(mfi->path);
|
||||
|
||||
if (mfi->fname)
|
||||
free(mfi->fname);
|
||||
|
||||
if (mfi->title)
|
||||
free(mfi->title);
|
||||
|
||||
if (mfi->artist)
|
||||
free(mfi->artist);
|
||||
|
||||
if (mfi->album)
|
||||
free(mfi->album);
|
||||
|
||||
if (mfi->genre)
|
||||
free(mfi->genre);
|
||||
|
||||
if (mfi->comment)
|
||||
free(mfi->comment);
|
||||
|
||||
if (mfi->type)
|
||||
free(mfi->type);
|
||||
|
||||
if (mfi->composer)
|
||||
free(mfi->composer);
|
||||
|
||||
if (mfi->orchestra)
|
||||
free(mfi->orchestra);
|
||||
|
||||
if (mfi->conductor)
|
||||
free(mfi->conductor);
|
||||
|
||||
if (mfi->grouping)
|
||||
free(mfi->grouping);
|
||||
|
||||
if (mfi->description)
|
||||
free(mfi->description);
|
||||
|
||||
if (mfi->codectype)
|
||||
free(mfi->codectype);
|
||||
|
||||
if (mfi->album_artist)
|
||||
free(mfi->album_artist);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fixup_tags(struct media_file_info *mfi)
|
||||
@ -256,32 +207,42 @@ fixup_tags(struct media_file_info *mfi)
|
||||
static void
|
||||
process_media_file(char *file, time_t mtime, off_t size, int compilation)
|
||||
{
|
||||
struct media_file_info *db_mfi;
|
||||
struct media_file_info *mfi;
|
||||
char *filename;
|
||||
char *ext;
|
||||
int need_update;
|
||||
int ret;
|
||||
|
||||
db_mfi = db_fetch_path(NULL, file, 0);
|
||||
mfi = db_file_fetch_bypath(file);
|
||||
|
||||
need_update = (!db_mfi || (db_mfi->db_timestamp < mtime) || db_mfi->force_update);
|
||||
|
||||
db_dispose_item(db_mfi);
|
||||
need_update = (!mfi || (mfi->db_timestamp < mtime) || mfi->force_update);
|
||||
|
||||
if (!need_update)
|
||||
return;
|
||||
|
||||
mfi = (struct media_file_info *)malloc(sizeof(struct media_file_info));
|
||||
if (!mfi)
|
||||
{
|
||||
DPRINTF(E_WARN, L_SCAN, "Out of memory for media_file_info\n");
|
||||
db_file_ping(mfi->id);
|
||||
|
||||
db_dispose_item(db_mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mfi)
|
||||
{
|
||||
ret = mfi->id;
|
||||
free_mfi(mfi, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
mfi = (struct media_file_info *)malloc(sizeof(struct media_file_info));
|
||||
if (!mfi)
|
||||
{
|
||||
DPRINTF(E_WARN, L_SCAN, "Out of memory for media_file_info\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset(mfi, 0, sizeof(struct media_file_info));
|
||||
mfi->id = ret;
|
||||
|
||||
filename = strrchr(file, '/');
|
||||
if (!filename)
|
||||
@ -340,8 +301,7 @@ process_media_file(char *file, time_t mtime, off_t size, int compilation)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Could not extract metadata for %s\n");
|
||||
|
||||
free_mfi(mfi);
|
||||
free(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -350,10 +310,12 @@ process_media_file(char *file, time_t mtime, off_t size, int compilation)
|
||||
|
||||
fixup_tags(mfi);
|
||||
|
||||
db_add(NULL, mfi, NULL);
|
||||
if (mfi->id == 0)
|
||||
db_file_add(mfi);
|
||||
else
|
||||
db_file_update(mfi);
|
||||
|
||||
free_mfi(mfi);
|
||||
free(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -669,6 +631,8 @@ bulk_scan(void)
|
||||
}
|
||||
}
|
||||
|
||||
db_pl_update_all();
|
||||
|
||||
if (playlists)
|
||||
process_deferred_playlists();
|
||||
|
||||
@ -681,10 +645,22 @@ bulk_scan(void)
|
||||
static void *
|
||||
filescanner(void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = db_perthread_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Error: DB init failed\n");
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
bulk_scan();
|
||||
|
||||
if (!scan_exit)
|
||||
{
|
||||
db_pl_update_all();
|
||||
|
||||
/* Enable inotify */
|
||||
event_add(&inoev, NULL);
|
||||
|
||||
@ -694,6 +670,8 @@ filescanner(void *arg)
|
||||
if (!scan_exit)
|
||||
DPRINTF(E_FATAL, L_SCAN, "Scan event loop terminated ahead of time!\n");
|
||||
|
||||
db_perthread_deinit();
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#ifndef __FILESCANNER_H__
|
||||
#define __FILESCANNER_H__
|
||||
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
|
||||
int
|
||||
filescanner_init(void);
|
||||
|
@ -41,12 +41,12 @@
|
||||
|
||||
|
||||
/* Legacy format-specific scanners */
|
||||
extern int scan_get_wmainfo(char *filename, MP3FILE *pmp3);
|
||||
extern int scan_get_wmainfo(char *filename, struct media_file_info *pmp3);
|
||||
#ifdef FLAC
|
||||
extern int scan_get_flacinfo(char *filename, MP3FILE *pmp3);
|
||||
extern int scan_get_flacinfo(char *filename, struct media_file_info *pmp3);
|
||||
#endif
|
||||
#ifdef MUSEPACK
|
||||
extern int scan_get_mpcinfo(char *filename, MP3FILE *pmp3);
|
||||
extern int scan_get_mpcinfo(char *filename, struct media_file_info *pmp3);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -34,8 +34,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db.h"
|
||||
#include "filescanner.h"
|
||||
|
||||
|
||||
@ -44,7 +43,6 @@ scan_m3u_playlist(char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
struct playlist_info *pli;
|
||||
struct media_file_info *mfi;
|
||||
struct stat sb;
|
||||
char buf[PATH_MAX];
|
||||
char rel_entry[PATH_MAX];
|
||||
@ -52,9 +50,9 @@ scan_m3u_playlist(char *file)
|
||||
char *entry;
|
||||
char *filename;
|
||||
char *ptr;
|
||||
char *db_errmsg;
|
||||
size_t len;
|
||||
int pl_id;
|
||||
int mf_id;
|
||||
int ret;
|
||||
|
||||
DPRINTF(E_INFO, L_SCAN, "Processing static playlist: %s\n", file);
|
||||
@ -73,7 +71,7 @@ scan_m3u_playlist(char *file)
|
||||
else
|
||||
filename++;
|
||||
|
||||
pli = db_fetch_playlist(NULL, file, 0);
|
||||
pli = db_pl_fetch_bypath(file);
|
||||
|
||||
if (pli)
|
||||
{
|
||||
@ -81,15 +79,17 @@ scan_m3u_playlist(char *file)
|
||||
{
|
||||
DPRINTF(E_DBG, L_SCAN, "Playlist up-to-date\n");
|
||||
|
||||
db_dispose_playlist(pli);
|
||||
db_pl_ping(pli->id);
|
||||
|
||||
free_pli(pli, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_DBG, L_SCAN, "Playlist needs update\n");
|
||||
|
||||
db_delete_playlist(NULL, pli->id);
|
||||
db_dispose_playlist(pli);
|
||||
db_pl_delete(pli->id);
|
||||
free_pli(pli, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,13 +113,11 @@ scan_m3u_playlist(char *file)
|
||||
if (ptr)
|
||||
*ptr = '.';
|
||||
|
||||
ret = db_add_playlist(&db_errmsg, buf, PL_STATICFILE, NULL, file, 0, &pl_id);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_pl_add(buf, file, &pl_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_SCAN, "Error adding m3u playlist '%s': %s\n", file, db_errmsg);
|
||||
DPRINTF(E_LOG, L_SCAN, "Error adding m3u playlist '%s'\n", file);
|
||||
|
||||
free(db_errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -197,19 +195,19 @@ scan_m3u_playlist(char *file)
|
||||
|
||||
DPRINTF(E_DBG, L_SCAN, "Checking %s\n", filename);
|
||||
|
||||
mfi = db_fetch_path(&db_errmsg, filename, 0);
|
||||
if (!mfi)
|
||||
ret = db_file_id_bypath(filename, &mf_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_SCAN, "Playlist entry '%s' not found: %s\n", entry, db_errmsg);
|
||||
DPRINTF(E_WARN, L_SCAN, "Playlist entry '%s' not found\n", entry);
|
||||
|
||||
free(db_errmsg);
|
||||
free(filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_SCAN, "Resolved %s to %d\n", filename, mfi->id);
|
||||
db_add_playlist_item(NULL, pl_id, mfi->id);
|
||||
db_dispose_item(mfi);
|
||||
DPRINTF(E_DBG, L_SCAN, "Resolved %s to %d\n", filename, mf_id);
|
||||
ret = db_pl_add_item(pl_id, mf_id);
|
||||
if (ret < 0)
|
||||
DPRINTF(E_WARN, L_SCAN, "Could not add %s to playlist\n", filename);
|
||||
}
|
||||
|
||||
if (!feof(fp))
|
||||
@ -222,5 +220,7 @@ scan_m3u_playlist(char *file)
|
||||
|
||||
fclose(fp);
|
||||
|
||||
db_pl_update(pl_id);
|
||||
|
||||
DPRINTF(E_INFO, L_SCAN, "Done processing playlist\n");
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
#include "filescanner.h"
|
||||
|
||||
|
||||
|
41
src/httpd.c
41
src/httpd.c
@ -35,8 +35,7 @@
|
||||
#include "evhttp/evhttp.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db.h"
|
||||
#include "conffile.h"
|
||||
#include "misc.h"
|
||||
#include "httpd.h"
|
||||
@ -199,7 +198,7 @@ stream_chunk_xcode_cb(int fd, short event, void *arg)
|
||||
if (!st->marked && (st->offset > ((st->size * 80) / 100)))
|
||||
{
|
||||
st->marked = 1;
|
||||
db_playcount_increment(NULL, st->id);
|
||||
db_file_inc_playcount(st->id);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -245,7 +244,7 @@ stream_chunk_raw_cb(int fd, short event, void *arg)
|
||||
if (!st->marked && (st->offset > ((st->size * 80) / 100)))
|
||||
{
|
||||
st->marked = 1;
|
||||
db_playcount_increment(NULL, st->id);
|
||||
db_file_inc_playcount(st->id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,7 +301,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
}
|
||||
}
|
||||
|
||||
mfi = db_fetch_item(NULL, id);
|
||||
mfi = db_file_fetch_byid(id);
|
||||
if (!mfi)
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Item %d not found\n", id);
|
||||
@ -315,7 +314,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
{
|
||||
evhttp_send_error(req, 500, "Cannot stream radio station");
|
||||
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -326,7 +325,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
|
||||
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
memset(st, 0, sizeof(struct stream_ctx));
|
||||
@ -348,7 +347,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
|
||||
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -370,7 +369,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
|
||||
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -383,7 +382,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
|
||||
close(st->fd);
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
st->size = sb.st_size;
|
||||
@ -397,7 +396,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
|
||||
close(st->fd);
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
st->offset = offset;
|
||||
@ -425,7 +424,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
else
|
||||
close(st->fd);
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -443,7 +442,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
close(st->fd);
|
||||
evbuffer_free(st->evbuf);
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -464,7 +463,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
close(st->fd);
|
||||
evbuffer_free(st->evbuf);
|
||||
free(st);
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -494,7 +493,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||
|
||||
DPRINTF(E_INFO, L_HTTPD, "Kicking off streaming for %s\n", mfi->path);
|
||||
|
||||
db_dispose_item(mfi);
|
||||
free_mfi(mfi, 0);
|
||||
}
|
||||
|
||||
/* Thread: httpd */
|
||||
@ -745,11 +744,23 @@ httpd_gen_cb(struct evhttp_request *req, void *arg)
|
||||
static void *
|
||||
httpd(void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = db_perthread_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Error: DB init failed\n");
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
event_base_dispatch(evbase_httpd);
|
||||
|
||||
if (!httpd_exit)
|
||||
DPRINTF(E_FATAL, L_HTTPD, "HTTPd event loop terminated ahead of time!\n");
|
||||
|
||||
db_perthread_deinit();
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
264
src/httpd_daap.c
264
src/httpd_daap.c
@ -26,6 +26,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/types.h>
|
||||
@ -39,8 +40,7 @@
|
||||
#include <avl.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db.h"
|
||||
#include "conffile.h"
|
||||
#include "misc.h"
|
||||
#include "httpd.h"
|
||||
@ -569,16 +569,18 @@ dmap_find_field(uint32_t hash)
|
||||
return (struct dmap_field_map *)node->item;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_query_params(struct evkeyvalq *query, DBQUERYINFO *qi)
|
||||
get_query_params(struct evkeyvalq *query, struct query_params *qp)
|
||||
{
|
||||
const char *param;
|
||||
char *ptr;
|
||||
int val;
|
||||
int low;
|
||||
int high;
|
||||
int ret;
|
||||
|
||||
qi->index_low = 0;
|
||||
qi->index_high = 9999999; /* Arbitrarily high number */
|
||||
low = 0;
|
||||
high = -1; /* No limit */
|
||||
|
||||
param = evhttp_find_header(query, "index");
|
||||
if (param)
|
||||
@ -587,38 +589,40 @@ get_query_params(struct evkeyvalq *query, DBQUERYINFO *qi)
|
||||
DPRINTF(E_LOG, L_DAAP, "Unsupported index range: %s\n", param);
|
||||
else
|
||||
{
|
||||
ret = safe_atoi(param, &val);
|
||||
ret = safe_atoi(param, &low);
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not parse index range: %s\n", param);
|
||||
else
|
||||
{
|
||||
qi->index_low = val;
|
||||
|
||||
ptr = strchr(param, '-');
|
||||
if (!ptr) /* single item */
|
||||
qi->index_high = qi->index_low;
|
||||
high = low;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
if (*ptr != '\0') /* low-high */
|
||||
{
|
||||
ret = safe_atoi(ptr, &val);
|
||||
ret = safe_atoi(ptr, &high);
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not parse high index in range: %s\n", param);
|
||||
else
|
||||
qi->index_high = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTF(E_DBG, L_DAAP, "Index range %s: low %d, high %d\n", param, qi->index_low, qi->index_high);
|
||||
DPRINTF(E_DBG, L_DAAP, "Index range %s: low %d, high %d (offset %d, limit %d)\n", param, low, high, qp->offset, qp->limit);
|
||||
}
|
||||
|
||||
if (qi->index_high < qi->index_low)
|
||||
qi->index_high = 9999999; /* Arbitrarily high number */
|
||||
if (high < low)
|
||||
high = -1; /* No limit */
|
||||
|
||||
qi->index_type = indexTypeSub;
|
||||
qp->offset = low;
|
||||
if (high < 0)
|
||||
qp->limit = -1; /* No limit */
|
||||
else
|
||||
qp->limit = (high - low) + 1;
|
||||
|
||||
qp->idx_type = I_SUB;
|
||||
|
||||
param = evhttp_find_header(query, "query");
|
||||
if (!param)
|
||||
@ -628,13 +632,10 @@ get_query_params(struct evkeyvalq *query, DBQUERYINFO *qi)
|
||||
{
|
||||
DPRINTF(E_DBG, L_DAAP, "DAAP browse query filter: %s\n", param);
|
||||
|
||||
qi->filter = daap_query_parse_sql(param);
|
||||
if (!qi->filter)
|
||||
qp->filter = daap_query_parse_sql(param);
|
||||
if (!qp->filter)
|
||||
DPRINTF(E_LOG, L_DAAP, "Ignoring improper DAAP query\n");
|
||||
}
|
||||
|
||||
qi->want_count = 1;
|
||||
qi->correct_order = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -879,7 +880,7 @@ daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Just send back the current db revision.
|
||||
/* Just send back the current time.
|
||||
*
|
||||
* This probably doesn't cut it, but then again we don't claim to support
|
||||
* updates, so... that support should be added eventually.
|
||||
@ -895,8 +896,8 @@ daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
}
|
||||
|
||||
dmap_add_container(evbuf, "mupd", 24);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_int(evbuf, "musr", db_revision()); /* 12 */
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_int(evbuf, "musr", (int)time(NULL)); /* 12 */
|
||||
|
||||
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||
}
|
||||
@ -904,12 +905,10 @@ daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
static void
|
||||
daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
int count;
|
||||
|
||||
cfg_t *lib;
|
||||
char *db_errmsg;
|
||||
char *name;
|
||||
int namelen;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
lib = cfg_getnsec(cfg, "library", 0);
|
||||
@ -936,23 +935,21 @@ daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
dmap_add_long(evbuf, "mper", 1); /* 16 */
|
||||
dmap_add_string(evbuf, "minm", name); /* 8 + namelen */
|
||||
|
||||
ret = db_get_song_count(&db_errmsg, &count);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_files_get_count(&count);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not get song count: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not get song count\n");
|
||||
|
||||
count = 0;
|
||||
free(db_errmsg);
|
||||
}
|
||||
dmap_add_int(evbuf, "mimc", count); /* 12 */
|
||||
|
||||
ret = db_get_playlist_count(&db_errmsg, &count);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_pl_get_count(&count);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not get playlist count: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not get playlist count\n");
|
||||
|
||||
count = 0;
|
||||
free(db_errmsg);
|
||||
}
|
||||
dmap_add_int(evbuf, "mctc", count); /* 12 */
|
||||
|
||||
@ -962,12 +959,11 @@ daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
static void
|
||||
daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf, int playlist, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct db_media_file_info *dbmfi;
|
||||
struct query_params qp;
|
||||
struct db_media_file_info dbmfi;
|
||||
struct evbuffer *song;
|
||||
struct evbuffer *songlist;
|
||||
struct dmap_field_map *dfm;
|
||||
char *db_errmsg;
|
||||
const char *param;
|
||||
char *tag;
|
||||
char **strval;
|
||||
@ -1071,26 +1067,29 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
nmeta = 0;
|
||||
}
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
get_query_params(query, &qi);
|
||||
qi.query_type = queryTypePlaylistItems;
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
get_query_params(query, &qp);
|
||||
|
||||
if (playlist != -1)
|
||||
qi.playlist_id = playlist;
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (playlist < 2)
|
||||
qp.type = Q_ITEMS;
|
||||
else
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not fetch song list: %s\n", db_errmsg);
|
||||
qp.type = Q_PLITEMS;
|
||||
qp.pl_id = playlist;
|
||||
}
|
||||
|
||||
daap_send_error(req, tag, db_errmsg);
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||
|
||||
daap_send_error(req, tag, "Could not stat query");
|
||||
|
||||
free(db_errmsg);
|
||||
free(meta);
|
||||
evbuffer_free(song);
|
||||
evbuffer_free(songlist);
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1098,11 +1097,11 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
want_asdk = 0;
|
||||
oom = 0;
|
||||
nsongs = 0;
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, &dbmfi, &qi)) == DB_E_SUCCESS) && (dbmfi))
|
||||
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
|
||||
{
|
||||
nsongs++;
|
||||
|
||||
transcode = transcode_needed(req->input_headers, dbmfi->codectype);
|
||||
transcode = transcode_needed(req->input_headers, dbmfi.codectype);
|
||||
|
||||
i = -1;
|
||||
while (1)
|
||||
@ -1151,7 +1150,7 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
|
||||
DPRINTF(E_DBG, L_DAAP, "Investigating %s\n", dfm->desc);
|
||||
|
||||
strval = (char **) ((char *)dbmfi + dfm->mfi_offset);
|
||||
strval = (char **) ((char *)&dbmfi + dfm->mfi_offset);
|
||||
|
||||
if (!(*strval) || (**strval == '\0'))
|
||||
continue;
|
||||
@ -1174,7 +1173,7 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
|
||||
case dbmfi_offsetof(bitrate):
|
||||
val = 0;
|
||||
ret = safe_atoi(dbmfi->samplerate, &val);
|
||||
ret = safe_atoi(dbmfi.samplerate, &val);
|
||||
if ((ret < 0) || (val == 0))
|
||||
val = 1411;
|
||||
else
|
||||
@ -1220,14 +1219,14 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
if (want_mikd)
|
||||
{
|
||||
/* dmap.itemkind must come first */
|
||||
ret = safe_atoi(dbmfi->item_kind, &val);
|
||||
ret = safe_atoi(dbmfi.item_kind, &val);
|
||||
if (ret < 0)
|
||||
val = 2; /* music by default */
|
||||
dmap_add_char(songlist, "mikd", val);
|
||||
}
|
||||
if (want_asdk)
|
||||
{
|
||||
ret = safe_atoi(dbmfi->data_kind, &val);
|
||||
ret = safe_atoi(dbmfi.data_kind, &val);
|
||||
if (ret < 0)
|
||||
val = 0;
|
||||
dmap_add_char(songlist, "asdk", val);
|
||||
@ -1248,34 +1247,25 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
|
||||
evbuffer_free(song);
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results\n");
|
||||
|
||||
daap_send_error(req, tag, db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
daap_send_error(req, tag, "Error fetching query results");
|
||||
db_query_end(&qp);
|
||||
evbuffer_free(songlist);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
if (oom)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not add song to song list for DAAP song list reply\n");
|
||||
|
||||
daap_send_error(req, tag, "Out of memory");
|
||||
|
||||
db_query_end(&qp);
|
||||
evbuffer_free(songlist);
|
||||
return;
|
||||
}
|
||||
@ -1284,10 +1274,12 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
|
||||
dmap_add_container(evbuf, tag, EVBUFFER_LENGTH(songlist) + 53);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_char(evbuf, "muty", 0); /* 9 */
|
||||
dmap_add_int(evbuf, "mtco", qi.specifiedtotalcount); /* 12 */
|
||||
dmap_add_int(evbuf, "mtco", qp.results); /* 12 */
|
||||
dmap_add_int(evbuf, "mrco", nsongs); /* 12 */
|
||||
dmap_add_container(evbuf, "mlcl", EVBUFFER_LENGTH(songlist));
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
ret = evbuffer_add_buffer(evbuf, songlist);
|
||||
evbuffer_free(songlist);
|
||||
if (ret < 0)
|
||||
@ -1327,13 +1319,12 @@ daap_reply_plsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char *
|
||||
static void
|
||||
daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct query_params qp;
|
||||
struct db_playlist_info dbpli;
|
||||
struct evbuffer *playlistlist;
|
||||
struct evbuffer *playlist;
|
||||
struct db_playlist_info *dbpli;
|
||||
struct dmap_field_map *dfm;
|
||||
const char *param;
|
||||
char *db_errmsg;
|
||||
char **strval;
|
||||
uint32_t *meta;
|
||||
int nmeta;
|
||||
@ -1415,29 +1406,28 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
get_query_params(query, &qi);
|
||||
qi.query_type = queryTypePlaylists;
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
get_query_params(query, &qp);
|
||||
qp.type = Q_PL;
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not fetch playlist list: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||
|
||||
daap_send_error(req, "aply", db_errmsg);
|
||||
daap_send_error(req, "aply", "Could not start query");
|
||||
|
||||
free(db_errmsg);
|
||||
free(meta);
|
||||
evbuffer_free(playlist);
|
||||
evbuffer_free(playlistlist);
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
return;
|
||||
}
|
||||
|
||||
npls = 0;
|
||||
oom = 0;
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, (struct db_media_file_info **)&dbpli, &qi)) == DB_E_SUCCESS) && (dbpli))
|
||||
while (((ret = db_query_fetch_pl(&qp, &dbpli)) == 0) && (dbpli.id))
|
||||
{
|
||||
npls++;
|
||||
|
||||
@ -1451,11 +1441,11 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
if (meta[i] == 0x670fc55e)
|
||||
{
|
||||
val = 0;
|
||||
ret = safe_atoi(dbpli->type, &val);
|
||||
ret = safe_atoi(dbpli.type, &val);
|
||||
if ((ret == 0) && (val == 1))
|
||||
{
|
||||
val = 1;
|
||||
ret = safe_atoi(dbpli->id, &val);
|
||||
ret = safe_atoi(dbpli.id, &val);
|
||||
if ((ret == 0) && (val != 1))
|
||||
dmap_add_char(playlist, "aeSP", 1);
|
||||
}
|
||||
@ -1474,7 +1464,7 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
if (dfm->pli_offset < 0)
|
||||
continue;
|
||||
|
||||
strval = (char **) ((char *)dbpli + dfm->pli_offset);
|
||||
strval = (char **) ((char *)&dbpli + dfm->pli_offset);
|
||||
|
||||
if (!(*strval) || (**strval == '\0'))
|
||||
continue;
|
||||
@ -1486,13 +1476,13 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
|
||||
/* Item count (mimc) */
|
||||
val = 0;
|
||||
ret = safe_atoi(dbpli->items, &val);
|
||||
ret = safe_atoi(dbpli.items, &val);
|
||||
if ((ret == 0) && (val > 0))
|
||||
dmap_add_int(playlist, "mimc", val);
|
||||
|
||||
/* Base playlist (abpl), id = 1 */
|
||||
val = 0;
|
||||
ret = safe_atoi(dbpli->id, &val);
|
||||
ret = safe_atoi(dbpli.id, &val);
|
||||
if ((ret == 0) && (val == 1))
|
||||
dmap_add_char(playlist, "abpl", 1);
|
||||
|
||||
@ -1512,34 +1502,25 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
free(meta);
|
||||
evbuffer_free(playlist);
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results\n");
|
||||
|
||||
daap_send_error(req, "aply", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
daap_send_error(req, "aply", "Error fetching query results");
|
||||
db_query_end(&qp);
|
||||
evbuffer_free(playlistlist);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
if (oom)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not add playlist to playlist list for DAAP playlists reply\n");
|
||||
|
||||
daap_send_error(req, "aply", "Out of memory");
|
||||
|
||||
db_query_end(&qp);
|
||||
evbuffer_free(playlistlist);
|
||||
return;
|
||||
}
|
||||
@ -1548,10 +1529,12 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
dmap_add_container(evbuf, "aply", EVBUFFER_LENGTH(playlistlist) + 53);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_char(evbuf, "muty", 0); /* 9 */
|
||||
dmap_add_int(evbuf, "mtco", qi.specifiedtotalcount); /* 12 */
|
||||
dmap_add_int(evbuf, "mtco", qp.results); /* 12 */
|
||||
dmap_add_int(evbuf,"mrco", npls); /* 12 */
|
||||
dmap_add_container(evbuf, "mlcl", EVBUFFER_LENGTH(playlistlist));
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
ret = evbuffer_add_buffer(evbuf, playlistlist);
|
||||
evbuffer_free(playlistlist);
|
||||
if (ret < 0)
|
||||
@ -1568,35 +1551,34 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
|
||||
static void
|
||||
daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct query_params qp;
|
||||
struct evbuffer *itemlist;
|
||||
char **item;
|
||||
char *browse_item;
|
||||
char *tag;
|
||||
char *db_errmsg;
|
||||
int nitems;
|
||||
int ret;
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
if (strcmp(uri[3], "artists") == 0)
|
||||
{
|
||||
tag = "abar";
|
||||
qi.query_type = queryTypeBrowseArtists;
|
||||
qp.type = Q_BROWSE_ARTISTS;
|
||||
}
|
||||
else if (strcmp(uri[3], "genres") == 0)
|
||||
{
|
||||
tag = "abgn";
|
||||
qi.query_type = queryTypeBrowseGenres;
|
||||
qp.type = Q_BROWSE_GENRES;
|
||||
}
|
||||
else if (strcmp(uri[3], "albums") == 0)
|
||||
{
|
||||
tag = "abal";
|
||||
qi.query_type = queryTypeBrowseAlbums;
|
||||
qp.type = Q_BROWSE_ALBUMS;
|
||||
}
|
||||
else if (strcmp(uri[3], "composers") == 0)
|
||||
{
|
||||
tag = "abcp";
|
||||
qi.query_type = queryTypeBrowseComposers;
|
||||
qp.type = Q_BROWSE_COMPOSERS;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1636,58 +1618,50 @@ daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
|
||||
return;
|
||||
}
|
||||
|
||||
get_query_params(query, &qi);
|
||||
get_query_params(query, &qp);
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not fetch browse item list: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Could not start query\n");
|
||||
|
||||
daap_send_error(req, "abro", db_errmsg);
|
||||
daap_send_error(req, "abro", "Could not start query");
|
||||
|
||||
free(db_errmsg);
|
||||
evbuffer_free(itemlist);
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
return;
|
||||
}
|
||||
|
||||
nitems = 0;
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, (struct db_media_file_info **)&item, &qi)) == DB_E_SUCCESS) && (item))
|
||||
while (((ret = db_query_fetch_string(&qp, &browse_item)) == 0) && (browse_item))
|
||||
{
|
||||
nitems++;
|
||||
|
||||
dmap_add_string(itemlist, "mlit", *item);
|
||||
dmap_add_string(itemlist, "mlit", browse_item);
|
||||
}
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_DAAP, "Error fetching results\n");
|
||||
|
||||
daap_send_error(req, "abro", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
daap_send_error(req, "abro", "Error fetching query results");
|
||||
db_query_end(&qp);
|
||||
evbuffer_free(itemlist);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
dmap_add_container(evbuf, "abro", EVBUFFER_LENGTH(itemlist) + 44);
|
||||
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||
dmap_add_int(evbuf, "mtco", qi.specifiedtotalcount); /* 12 */
|
||||
dmap_add_int(evbuf, "mtco", qp.results); /* 12 */
|
||||
dmap_add_int(evbuf, "mrco", nitems); /* 12 */
|
||||
dmap_add_container(evbuf, tag, EVBUFFER_LENGTH(itemlist));
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
ret = evbuffer_add_buffer(evbuf, itemlist);
|
||||
evbuffer_free(itemlist);
|
||||
if (ret < 0)
|
||||
|
246
src/httpd_rsp.c
246
src/httpd_rsp.c
@ -38,8 +38,7 @@
|
||||
#include <mxml.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db-generic.h"
|
||||
#include "db.h"
|
||||
#include "conffile.h"
|
||||
#include "misc.h"
|
||||
#include "httpd.h"
|
||||
@ -176,16 +175,16 @@ static void
|
||||
rsp_send_error(struct evhttp_request *req, char *errmsg);
|
||||
|
||||
static int
|
||||
get_query_params(struct evhttp_request *req, struct evkeyvalq *query, DBQUERYINFO *qi, int *offset, int *limit)
|
||||
get_query_params(struct evhttp_request *req, struct evkeyvalq *query, struct query_params *qp)
|
||||
{
|
||||
const char *param;
|
||||
int ret;
|
||||
|
||||
*offset = 0;
|
||||
qp->offset = 0;
|
||||
param = evhttp_find_header(query, "offset");
|
||||
if (param)
|
||||
{
|
||||
ret = safe_atoi(param, offset);
|
||||
ret = safe_atoi(param, &qp->offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
rsp_send_error(req, "Invalid offset");
|
||||
@ -193,11 +192,11 @@ get_query_params(struct evhttp_request *req, struct evkeyvalq *query, DBQUERYINF
|
||||
}
|
||||
}
|
||||
|
||||
*limit = 0;
|
||||
qp->limit = 0;
|
||||
param = evhttp_find_header(query, "limit");
|
||||
if (param)
|
||||
{
|
||||
ret = safe_atoi(param, limit);
|
||||
ret = safe_atoi(param, &qp->limit);
|
||||
if (ret < 0)
|
||||
{
|
||||
rsp_send_error(req, "Invalid limit");
|
||||
@ -205,29 +204,18 @@ get_query_params(struct evhttp_request *req, struct evkeyvalq *query, DBQUERYINF
|
||||
}
|
||||
}
|
||||
|
||||
if (*offset || *limit)
|
||||
{
|
||||
qi->index_low = *offset;
|
||||
qi->index_high = *offset + *limit - 1;
|
||||
|
||||
if (qi->index_high < qi->index_low)
|
||||
qi->index_high = 9999999; /* Arbitrarily high number */
|
||||
|
||||
qi->index_type = indexTypeSub;
|
||||
}
|
||||
if (qp->offset || qp->limit)
|
||||
qp->idx_type = I_SUB;
|
||||
else
|
||||
qi->index_type = indexTypeNone;
|
||||
|
||||
qi->want_count = 1;
|
||||
qi->correct_order = 1;
|
||||
qp->idx_type = I_NONE;
|
||||
|
||||
param = evhttp_find_header(query, "query");
|
||||
if (param)
|
||||
{
|
||||
DPRINTF(E_DBG, L_RSP, "RSP browse query filter: %s\n", param);
|
||||
|
||||
qi->filter = rsp_query_parse_sql(param);
|
||||
if (!qi->filter)
|
||||
qp->filter = rsp_query_parse_sql(param);
|
||||
if (!qp->filter)
|
||||
DPRINTF(E_LOG, L_RSP, "Ignoring improper RSP query\n");
|
||||
}
|
||||
|
||||
@ -291,18 +279,15 @@ rsp_reply_info(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
mxml_node_t *node;
|
||||
cfg_t *lib;
|
||||
char *library;
|
||||
char *db_errmsg;
|
||||
int songcount;
|
||||
int ret;
|
||||
|
||||
ret = db_get_song_count(&db_errmsg, &songcount);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_files_get_count(&songcount);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Could not get song count: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Could not get song count\n");
|
||||
|
||||
songcount = 0;
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
lib = cfg_getnsec(cfg, "library", 0);
|
||||
@ -363,10 +348,9 @@ rsp_reply_info(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
static void
|
||||
rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct db_playlist_info *dbpli;
|
||||
struct query_params qp;
|
||||
struct db_playlist_info dbpli;
|
||||
struct evbuffer *evbuf;
|
||||
char *db_errmsg;
|
||||
char **strval;
|
||||
mxml_node_t *reply;
|
||||
mxml_node_t *status;
|
||||
@ -376,20 +360,17 @@ rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
memset(&qp, 0, sizeof(struct db_playlist_info));
|
||||
|
||||
qi.query_type = queryTypePlaylists;
|
||||
qi.index_type = indexTypeNone;
|
||||
qi.want_count = 1;
|
||||
qp.type = Q_PL;
|
||||
qp.idx_type = I_NONE;
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Could not fetch playlists: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Could not start query\n");
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
rsp_send_error(req, "Could not start query");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -410,13 +391,13 @@ rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
mxmlNewText(node, 0, "");
|
||||
|
||||
node = mxmlNewElement(status, "records");
|
||||
mxmlNewTextf(node, 0, "%d", qi.specifiedtotalcount);
|
||||
mxmlNewTextf(node, 0, "%d", qp.results);
|
||||
|
||||
node = mxmlNewElement(status, "totalrecords");
|
||||
mxmlNewTextf(node, 0, "%d", qi.specifiedtotalcount);
|
||||
mxmlNewTextf(node, 0, "%d", qp.results);
|
||||
|
||||
/* Playlists block (all playlists) */
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, (struct db_media_file_info **)&dbpli, &qi)) == DB_E_SUCCESS) && (dbpli))
|
||||
while (((ret = db_query_fetch_pl(&qp, &dbpli)) == 0) && (dbpli.id))
|
||||
{
|
||||
/* Playlist block (one playlist) */
|
||||
pl = mxmlNewElement(pls, "playlist");
|
||||
@ -425,7 +406,7 @@ rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
if (pl_fields[i].flags & F_FULL)
|
||||
{
|
||||
strval = (char **) ((char *)dbpli + pl_fields[i].offset);
|
||||
strval = (char **) ((char *)&dbpli + pl_fields[i].offset);
|
||||
|
||||
node = mxmlNewElement(pl, pl_fields[i].field);
|
||||
mxmlNewText(node, 0, *strval);
|
||||
@ -433,34 +414,26 @@ rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results\n");
|
||||
|
||||
mxmlDelete(reply);
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
db_query_end(&qp);
|
||||
rsp_send_error(req, "Error fetching query results");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
/* HACK
|
||||
* Add a dummy empty string to the playlists element if there is no data
|
||||
* to return - this prevents mxml from sending out an empty <playlists/>
|
||||
* tag that the SoundBridge does not handle. It's hackish, but it works.
|
||||
*/
|
||||
if (qi.specifiedtotalcount == 0)
|
||||
if (qp.results == 0)
|
||||
mxmlNewText(pls, 0, "");
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
evbuf = mxml_to_evbuf(reply);
|
||||
mxmlDelete(reply);
|
||||
|
||||
@ -481,10 +454,9 @@ rsp_reply_db(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
static void
|
||||
rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct db_media_file_info *dbmfi;
|
||||
struct query_params qp;
|
||||
struct db_media_file_info dbmfi;
|
||||
struct evbuffer *evbuf;
|
||||
char *db_errmsg;
|
||||
const char *param;
|
||||
char **strval;
|
||||
mxml_node_t *reply;
|
||||
@ -493,25 +465,26 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
mxml_node_t *item;
|
||||
mxml_node_t *node;
|
||||
int mode;
|
||||
int limit;
|
||||
int offset;
|
||||
int records;
|
||||
int transcode;
|
||||
int bitrate;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
qi.query_type = queryTypePlaylistItems;
|
||||
|
||||
ret = safe_atoi(uri[2], &qi.playlist_id);
|
||||
ret = safe_atoi(uri[2], &qp.pl_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
rsp_send_error(req, "Invalid playlist ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (qp.pl_id == 0)
|
||||
qp.type = Q_ITEMS;
|
||||
else
|
||||
qp.type = Q_PLITEMS;
|
||||
|
||||
mode = F_FULL;
|
||||
param = evhttp_find_header(query, "type");
|
||||
if (param)
|
||||
@ -528,29 +501,28 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
DPRINTF(E_LOG, L_RSP, "Unknown browse mode %s\n", param);
|
||||
}
|
||||
|
||||
ret = get_query_params(req, query, &qi, &offset, &limit);
|
||||
ret = get_query_params(req, query, &qp);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Could not fetch data: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Could not start query\n");
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
rsp_send_error(req, "Could not start query");
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
free(db_errmsg);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset > qi.specifiedtotalcount)
|
||||
if (qp.offset > qp.results)
|
||||
records = 0;
|
||||
else if (limit > (qi.specifiedtotalcount - offset))
|
||||
records = qi.specifiedtotalcount - offset;
|
||||
else if (qp.limit > (qp.results - qp.offset))
|
||||
records = qp.results - qp.offset;
|
||||
else
|
||||
records = limit;
|
||||
records = qp.limit;
|
||||
|
||||
/* We'd use mxmlNewXML(), but then we can't put any attributes
|
||||
* on the root node and we need some.
|
||||
@ -572,12 +544,12 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
mxmlNewTextf(node, 0, "%d", records);
|
||||
|
||||
node = mxmlNewElement(status, "totalrecords");
|
||||
mxmlNewTextf(node, 0, "%d", qi.specifiedtotalcount);
|
||||
mxmlNewTextf(node, 0, "%d", qp.results);
|
||||
|
||||
/* Items block (all items) */
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, &dbmfi, &qi)) == DB_E_SUCCESS) && (dbmfi))
|
||||
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
|
||||
{
|
||||
transcode = transcode_needed(req->input_headers, dbmfi->codectype);
|
||||
transcode = transcode_needed(req->input_headers, dbmfi.codectype);
|
||||
|
||||
/* Item block (one item) */
|
||||
item = mxmlNewElement(items, "item");
|
||||
@ -587,7 +559,7 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
if (!(rsp_fields[i].flags & mode))
|
||||
continue;
|
||||
|
||||
strval = (char **) ((char *)dbmfi + rsp_fields[i].offset);
|
||||
strval = (char **) ((char *)&dbmfi + rsp_fields[i].offset);
|
||||
|
||||
if (!(*strval) || (strlen(*strval) == 0))
|
||||
continue;
|
||||
@ -606,7 +578,7 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
|
||||
case dbmfi_offsetof(bitrate):
|
||||
bitrate = 0;
|
||||
ret = safe_atoi(dbmfi->samplerate, &bitrate);
|
||||
ret = safe_atoi(dbmfi.samplerate, &bitrate);
|
||||
if ((ret < 0) || (bitrate == 0))
|
||||
bitrate = 1411;
|
||||
else
|
||||
@ -634,37 +606,29 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
}
|
||||
}
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results\n");
|
||||
|
||||
mxmlDelete(reply);
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
db_query_end(&qp);
|
||||
rsp_send_error(req, "Error fetching query results");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
/* HACK
|
||||
* Add a dummy empty string to the items element if there is no data
|
||||
* to return - this prevents mxml from sending out an empty <items/>
|
||||
* tag that the SoundBridge does not handle. It's hackish, but it works.
|
||||
*/
|
||||
if (qi.specifiedtotalcount == 0)
|
||||
if (qp.results == 0)
|
||||
mxmlNewText(items, 0, "");
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
evbuf = mxml_to_evbuf(reply);
|
||||
mxmlDelete(reply);
|
||||
|
||||
@ -685,29 +649,26 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
|
||||
static void
|
||||
rsp_reply_browse(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
|
||||
{
|
||||
DBQUERYINFO qi;
|
||||
struct db_media_file_info *dbmfi;
|
||||
struct query_params qp;
|
||||
struct evbuffer *evbuf;
|
||||
char *db_errmsg;
|
||||
char *browse_item;
|
||||
mxml_node_t *reply;
|
||||
mxml_node_t *status;
|
||||
mxml_node_t *items;
|
||||
mxml_node_t *node;
|
||||
int limit;
|
||||
int offset;
|
||||
int records;
|
||||
int ret;
|
||||
|
||||
memset(&qi, 0, sizeof(DBQUERYINFO));
|
||||
memset(&qp, 0, sizeof(struct query_params));
|
||||
|
||||
if (strcmp(uri[3], "artist") == 0)
|
||||
qi.query_type = queryTypeBrowseArtists;
|
||||
qp.type = Q_BROWSE_ARTISTS;
|
||||
else if (strcmp(uri[3], "genre") == 0)
|
||||
qi.query_type = queryTypeBrowseGenres;
|
||||
qp.type = Q_BROWSE_GENRES;
|
||||
else if (strcmp(uri[3], "album") == 0)
|
||||
qi.query_type = queryTypeBrowseAlbums;
|
||||
qp.type = Q_BROWSE_ALBUMS;
|
||||
else if (strcmp(uri[3], "composer") == 0)
|
||||
qi.query_type = queryTypeBrowseComposers;
|
||||
qp.type = Q_BROWSE_COMPOSERS;
|
||||
else
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Unsupported browse type '%s'\n", uri[3]);
|
||||
@ -716,36 +677,35 @@ rsp_reply_browse(struct evhttp_request *req, char **uri, struct evkeyvalq *query
|
||||
return;
|
||||
}
|
||||
|
||||
ret = safe_atoi(uri[2], &qi.playlist_id);
|
||||
ret = safe_atoi(uri[2], &qp.pl_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
rsp_send_error(req, "Invalid playlist ID");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = get_query_params(req, query, &qi, &offset, &limit);
|
||||
ret = get_query_params(req, query, &qp);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
ret = db_enum_start(&db_errmsg, &qi);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
ret = db_query_start(&qp);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Could not fetch data: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Could not start query\n");
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
rsp_send_error(req, "Could not start query");
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
free(db_errmsg);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset > qi.specifiedtotalcount)
|
||||
if (qp.offset > qp.results)
|
||||
records = 0;
|
||||
else if (limit > (qi.specifiedtotalcount - offset))
|
||||
records = qi.specifiedtotalcount - offset;
|
||||
else if (qp.limit > (qp.results - qp.offset))
|
||||
records = qp.results - qp.offset;
|
||||
else
|
||||
records = limit;
|
||||
records = qp.limit;
|
||||
|
||||
/* We'd use mxmlNewXML(), but then we can't put any attributes
|
||||
* on the root node and we need some.
|
||||
@ -767,46 +727,38 @@ rsp_reply_browse(struct evhttp_request *req, char **uri, struct evkeyvalq *query
|
||||
mxmlNewTextf(node, 0, "%d", records);
|
||||
|
||||
node = mxmlNewElement(status, "totalrecords");
|
||||
mxmlNewTextf(node, 0, "%d", qi.specifiedtotalcount);
|
||||
mxmlNewTextf(node, 0, "%d", qp.results);
|
||||
|
||||
/* Items block (all items) */
|
||||
while (((ret = db_enum_fetch_row(&db_errmsg, &dbmfi, &qi)) == DB_E_SUCCESS) && (dbmfi))
|
||||
while (((ret = db_query_fetch_string(&qp, &browse_item)) == 0) && (browse_item))
|
||||
{
|
||||
node = mxmlNewElement(items, "item");
|
||||
mxmlNewText(node, 0, dbmfi->id);
|
||||
mxmlNewText(node, 0, browse_item);
|
||||
}
|
||||
|
||||
if (qi.filter)
|
||||
free(qi.filter);
|
||||
if (qp.filter)
|
||||
free(qp.filter);
|
||||
|
||||
if (ret != DB_E_SUCCESS)
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results: %s\n", db_errmsg);
|
||||
DPRINTF(E_LOG, L_RSP, "Error fetching results\n");
|
||||
|
||||
mxmlDelete(reply);
|
||||
|
||||
rsp_send_error(req, db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
db_query_end(&qp);
|
||||
rsp_send_error(req, "Error fetching query results");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = db_enum_end(&db_errmsg);
|
||||
if (ret != DB_E_SUCCESS)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RSP, "Error cleaning up DB enum: %s\n", db_errmsg);
|
||||
|
||||
free(db_errmsg);
|
||||
}
|
||||
|
||||
/* HACK
|
||||
* Add a dummy empty string to the items element if there is no data
|
||||
* to return - this prevents mxml from sending out an empty <items/>
|
||||
* tag that the SoundBridge does not handle. It's hackish, but it works.
|
||||
*/
|
||||
if (qi.specifiedtotalcount == 0)
|
||||
if (qp.results == 0);
|
||||
mxmlNewText(items, 0, "");
|
||||
|
||||
db_query_end(&qp);
|
||||
|
||||
evbuf = mxml_to_evbuf(reply);
|
||||
mxmlDelete(reply);
|
||||
|
||||
|
22
src/main.c
22
src/main.c
@ -47,11 +47,11 @@
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#include "conffile.h"
|
||||
#include "db.h"
|
||||
#include "logger.h"
|
||||
#include "misc.h"
|
||||
#include "filescanner.h"
|
||||
#include "httpd.h"
|
||||
#include "db-generic.h"
|
||||
#include "mdns_avahi.h"
|
||||
|
||||
|
||||
@ -334,7 +334,6 @@ main(int argc, char **argv)
|
||||
char *logdomains;
|
||||
char *logfile;
|
||||
char *ffid;
|
||||
char *perr;
|
||||
char *pidfile;
|
||||
sigset_t sigs;
|
||||
int sigfd;
|
||||
@ -500,23 +499,17 @@ main(int argc, char **argv)
|
||||
goto mdns_fail;
|
||||
}
|
||||
|
||||
/* this will require that the db be readable by the runas user */
|
||||
ret = db_open(&perr, "sqlite3", "/var/cache/mt-daapd"); /* FIXME */
|
||||
if (ret != 0)
|
||||
/* Initialize the database before starting */
|
||||
DPRINTF(E_INFO, L_MAIN, "Initializing database\n");
|
||||
ret = db_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_MAIN, "Error opening db: %s\n", perr);
|
||||
DPRINTF(E_FATAL, L_MAIN, "Database init failed\n");
|
||||
|
||||
ret = EXIT_FAILURE;
|
||||
goto db_fail;
|
||||
}
|
||||
|
||||
/* Initialize the database before starting */
|
||||
DPRINTF(E_INFO, L_MAIN, "Initializing database\n");
|
||||
if (db_init(0))
|
||||
{
|
||||
DPRINTF(E_FATAL, L_MAIN, "Error in db_init: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
/* Spawn file scanner thread */
|
||||
ret = filescanner_init();
|
||||
if (ret != 0)
|
||||
@ -582,9 +575,6 @@ main(int argc, char **argv)
|
||||
filescanner_deinit();
|
||||
|
||||
filescanner_fail:
|
||||
DPRINTF(E_LOG, L_MAIN, "Closing database\n");
|
||||
db_deinit();
|
||||
|
||||
db_fail:
|
||||
if (ret == EXIT_FAILURE)
|
||||
{
|
||||
|
@ -40,13 +40,15 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
|
||||
#include <FLAC/metadata.h>
|
||||
|
||||
#define TRUE ((1 == 1))
|
||||
#define FALSE (!TRUE)
|
||||
|
||||
typedef struct media_file_info MP3FILE;
|
||||
|
||||
#define GET_VORBIS_COMMENT(comment, name, len) (char*) \
|
||||
(((strncasecmp(name, (char*)(comment).entry, strlen(name)) == 0) && \
|
||||
((comment).entry[strlen(name)] == '=')) ? \
|
||||
|
@ -31,11 +31,12 @@
|
||||
#include <taglib/tag_c.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
|
||||
#define TRUE ((1 == 1))
|
||||
#define FALSE (!TRUE)
|
||||
|
||||
typedef struct media_file_info MP3FILE;
|
||||
|
||||
/**
|
||||
* scan a musepack file for metainfo.
|
||||
|
@ -34,11 +34,13 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
|
||||
#define TRUE ((1 == 1))
|
||||
#define FALSE (!TRUE)
|
||||
|
||||
typedef struct media_file_info MP3FILE;
|
||||
|
||||
typedef struct tag_wma_guidlist {
|
||||
char *name;
|
||||
char *guid;
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "logger.h"
|
||||
#include "conffile.h"
|
||||
#include "ff-dbstruct.h"
|
||||
#include "db.h"
|
||||
#include "transcode.h"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user