mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 14:13:18 -05:00
Remove old webserver
This commit is contained in:
parent
6aca074f82
commit
9ef8acfa28
@ -12,8 +12,8 @@ endif
|
||||
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@
|
||||
mt_daapd_LDFLAGS = -export-dynamic
|
||||
mt_daapd_SOURCES = main.c daapd.h webserver.c \
|
||||
webserver.h configfile.c configfile.h err.c err.h \
|
||||
mt_daapd_SOURCES = main.c daapd.h \
|
||||
err.c err.h \
|
||||
conffile.c conffile.h \
|
||||
filescanner.c filescanner.h \
|
||||
filescanner_ffmpeg.c filescanner_urlfile.c filescanner_m3u.c \
|
||||
@ -27,7 +27,7 @@ mt_daapd_SOURCES = main.c daapd.h webserver.c \
|
||||
misc.c misc.h \
|
||||
db-generic.c db-generic.h \
|
||||
scan-wma.c \
|
||||
smart-parser.c smart-parser.h xml-rpc.c xml-rpc.h \
|
||||
smart-parser.c smart-parser.h \
|
||||
util.c util.h \
|
||||
db-sql-updates.c \
|
||||
io.h io.c io-errors.h io-plugin.h \
|
||||
|
@ -54,10 +54,6 @@ extern void conf_dispose_array(char **argv);
|
||||
|
||||
extern char *conf_get_filename(void);
|
||||
|
||||
/* FIXME: get enum functions and move to xml-rpc */
|
||||
#include "webserver.h"
|
||||
extern int conf_xml_dump(WS_CONNINFO *pwsc);
|
||||
|
||||
/* FIXME: well used config reading stuff... */
|
||||
extern char *conf_get_servername(void);
|
||||
|
||||
|
@ -574,10 +574,3 @@ conf_get_filename(void)
|
||||
{
|
||||
return "NOT SUPPORTED";
|
||||
}
|
||||
|
||||
int
|
||||
conf_xml_dump(WS_CONNINFO *pwsc)
|
||||
{
|
||||
/* Not supported */
|
||||
return CONF_E_NOTSUPP;
|
||||
}
|
||||
|
1111
src/configfile.c
1111
src/configfile.c
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Functions for reading and writing the config file
|
||||
*
|
||||
* Copyright (C) 2003 Ron Pedde (ron@pedde.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _CONFIGFILE_H_
|
||||
#define _CONFIGFILE_H_
|
||||
|
||||
#include "daapd.h"
|
||||
#include "webserver.h"
|
||||
|
||||
extern int config_auth(WS_CONNINFO *pwsc, char *user, char *password);
|
||||
extern void config_handler(WS_CONNINFO *pwsc);
|
||||
extern void config_set_status(WS_CONNINFO *pwsc, int session, char *fmt, ...);
|
||||
extern int config_get_session_count(void);
|
||||
extern int config_matches_role(WS_CONNINFO *pwsc, char *username, char *password, char *role);
|
||||
|
||||
/** thread local storage */
|
||||
typedef struct tag_scan_status {
|
||||
int session;
|
||||
int thread;
|
||||
char *what;
|
||||
char *host;
|
||||
} SCAN_STATUS;
|
||||
|
||||
#endif /* _CONFIGFILE_H_ */
|
@ -56,7 +56,6 @@
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include "webserver.h"
|
||||
|
||||
/** Simple struct for holding stat info.
|
||||
*/
|
||||
@ -77,7 +76,6 @@ typedef struct tag_config {
|
||||
int full_reload; /**< Whether the reload should be a full one */
|
||||
|
||||
STATS stats; /**< Stats structure (see above) */
|
||||
WSHANDLE server; /**< webserver handle */
|
||||
} CONFIG;
|
||||
|
||||
extern CONFIG config;
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include "ff-dbstruct.h" /** for MP3FILE */
|
||||
#include "smart-parser.h" /** for PARSETREE */
|
||||
#include "webserver.h" /** for WS_CONNINFO */
|
||||
|
||||
typedef enum {
|
||||
queryTypeItems,
|
||||
@ -63,7 +62,6 @@ typedef struct tag_dbqueryinfo {
|
||||
char *uri_sections[10];
|
||||
PARSETREE pt;
|
||||
void *output_info;
|
||||
WS_CONNINFO *pwsc;
|
||||
} DBQUERYINFO;
|
||||
|
||||
extern int db_open(char **pe, char *type, char *parameters);
|
||||
|
@ -84,7 +84,6 @@
|
||||
|
||||
#include "conffile.h"
|
||||
#include "conf.h"
|
||||
#include "configfile.h"
|
||||
#include "err.h"
|
||||
#include "misc.h"
|
||||
#include "filescanner.h"
|
||||
|
2219
src/webserver.c
2219
src/webserver.c
File diff suppressed because it is too large
Load Diff
142
src/webserver.h
142
src/webserver.h
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Webserver library
|
||||
*
|
||||
* Copyright (C) 2003 Ron Pedde (ron@pedde.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _WEBSERVER_H_
|
||||
#define _WEBSERVER_H_
|
||||
|
||||
#include "io.h"
|
||||
|
||||
/*
|
||||
* Defines
|
||||
*/
|
||||
|
||||
#define RT_GET 0
|
||||
#define RT_POST 1
|
||||
|
||||
#define E_WS_SUCCESS 0
|
||||
#define E_WS_NATIVE 1 /**< A native platform error */
|
||||
#define E_WS_MEMORY 2 /**< Malloc error */
|
||||
#define E_WS_PTHREADS 3 /**< Pthreads error */
|
||||
#define E_WS_EXHAUSTED 4 /**< ports exhausted!? */
|
||||
#define E_WS_LISTEN 5 /**< can't listen */
|
||||
#define E_WS_CONTENTLEN 6 /**< Invalid content length in POST */
|
||||
#define E_WS_READ 7 /**< read error on socket */
|
||||
#define E_WS_GETVARS 8 /**< could not parse get vars */
|
||||
#define E_WS_TIMEOUT 9 /**< timeout listening on socket */
|
||||
#define E_WS_REQTYPE 10 /**< invalid request type (POST, GET, etc) */
|
||||
#define E_WS_BADPATH 11 /**< requested path out of root */
|
||||
|
||||
#define L_WS_SPAM 10 /**< Logorrhea! */
|
||||
#define L_WS_DBG 9 /**< Way too verbose */
|
||||
#define L_WS_INF 5 /**< Good info, not too much spam */
|
||||
#define L_WS_WARN 2 /**< Goes in text log, but not syslog */
|
||||
#define L_WS_LOG 1 /**< Something that should go in syslog */
|
||||
#define L_WS_FATAL 0 /**< Log and force an exit */
|
||||
|
||||
/*
|
||||
* Typedefs
|
||||
*/
|
||||
typedef void* WSHANDLE;
|
||||
typedef void* WSTHREADENUM;
|
||||
|
||||
typedef struct tag_wsconfig {
|
||||
char *web_root;
|
||||
char *id;
|
||||
unsigned short port;
|
||||
} WSCONFIG;
|
||||
|
||||
typedef struct tag_arglist {
|
||||
char *key;
|
||||
char *value;
|
||||
struct tag_arglist *next;
|
||||
} ARGLIST;
|
||||
|
||||
typedef struct tag_ws_conninfo {
|
||||
int err_code;
|
||||
int err_native;
|
||||
char *err_msg;
|
||||
WSHANDLE pwsp;
|
||||
int threadno;
|
||||
int error;
|
||||
IOHANDLE hclient;
|
||||
int request_type;
|
||||
char *uri;
|
||||
char *hostname;
|
||||
int close;
|
||||
int secure;
|
||||
void *secure_storage;
|
||||
void *local_storage;
|
||||
void (*storage_callback)(void*);
|
||||
ARGLIST request_headers;
|
||||
ARGLIST response_headers;
|
||||
ARGLIST request_vars;
|
||||
} WS_CONNINFO;
|
||||
|
||||
/*
|
||||
* Externs
|
||||
*/
|
||||
|
||||
#define WS_REQ_HANDLER void (*)(WS_CONNINFO *)
|
||||
#define WS_AUTH_HANDLER int (*)(WS_CONNINFO*, char *, char *)
|
||||
|
||||
/** Server functions */
|
||||
extern WSHANDLE ws_init(WSCONFIG *config);
|
||||
extern int ws_start(WSHANDLE ws);
|
||||
extern int ws_stop(WSHANDLE ws);
|
||||
extern int ws_registerhandler(WSHANDLE ws, char *stem,
|
||||
void(*handler)(WS_CONNINFO*),
|
||||
int(*auth)(WS_CONNINFO*, char *, char *),
|
||||
int flags,
|
||||
int addheaders);
|
||||
extern int ws_server_errcode(WSHANDLE ws);
|
||||
|
||||
|
||||
|
||||
/** Local storage functions */
|
||||
extern void ws_lock_local_storage(WS_CONNINFO *pwsc);
|
||||
extern void ws_unlock_local_storage(WS_CONNINFO *pwsc);
|
||||
extern void *ws_get_local_storage(WS_CONNINFO *pwsc);
|
||||
extern void ws_set_local_storage(WS_CONNINFO *pwsc, void *ptr, void (*callback)(void *));
|
||||
|
||||
extern WS_CONNINFO *ws_thread_enum_first(WSHANDLE, WSTHREADENUM *);
|
||||
extern WS_CONNINFO *ws_thread_enum_next(WSHANDLE, WSTHREADENUM *);
|
||||
|
||||
/* for handlers */
|
||||
extern void ws_close(WS_CONNINFO *pwsc);
|
||||
extern int ws_returnerror(WS_CONNINFO *pwsc, int error, char *description);
|
||||
extern int ws_addresponseheader(WS_CONNINFO *pwsc, char *header, char *fmt, ...);
|
||||
extern int ws_writefd(WS_CONNINFO *pwsc, char *fmt, ...);
|
||||
extern int ws_writebinary(WS_CONNINFO *pwsc, char *data, int len);
|
||||
extern char *ws_getvar(WS_CONNINFO *pwsc, char *var);
|
||||
extern char *ws_getrequestheader(WS_CONNINFO *pwsc, char *header);
|
||||
extern int ws_testrequestheader(WS_CONNINFO *pwsc, char *header, char *value);
|
||||
extern void ws_emitheaders(WS_CONNINFO *pwsc);
|
||||
extern char *ws_uri(WS_CONNINFO *pwsc);
|
||||
extern void *ws_enum_var(WS_CONNINFO *pwsc, char **key, char **value, void *last);
|
||||
extern int ws_copyfile(WS_CONNINFO *pwsc, IOHANDLE hfile, uint64_t *bytes_copied);
|
||||
extern void ws_should_close(WS_CONNINFO *pwsc, int should_close);
|
||||
extern int ws_threadno(WS_CONNINFO *pwsc);
|
||||
extern char *ws_hostname(WS_CONNINFO *pwsc);
|
||||
|
||||
extern void ws_set_errhandler(void(*err_handler)(int, char*));
|
||||
extern int ws_set_err(WS_CONNINFO *pwsc, int ws_error);
|
||||
extern int ws_get_err(WS_CONNINFO *pwsc, int *errcode, char **err_msg);
|
||||
|
||||
#endif /* _WEBSERVER_H_ */
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Abstract os interface for non-unix platforms
|
||||
*
|
||||
* Copyright (C) 2006 Ron Pedde (rpedde@users.sourceforge.net)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _WSPRIVATE_H_
|
||||
#define _WSPRIVATE_H_
|
||||
|
||||
extern int ws_socket_write(WS_CONNINFO *pwsc, unsigned char *buffer, int len);
|
||||
extern int ws_socket_read(WS_CONNINFO *pwsc, unsigned char *buffer, int len);
|
||||
extern void ws_socket_shutdown(WS_CONNINFO *pwsc);
|
||||
|
||||
#endif /* _WSPRIVATE_H_ */
|
657
src/xml-rpc.c
657
src/xml-rpc.c
@ -1,657 +0,0 @@
|
||||
/*
|
||||
* This really isn't xmlrpc. It's xmlrpc-ish. Emphasis on -ish.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "daapd.h"
|
||||
|
||||
#include "configfile.h"
|
||||
#include "conf.h"
|
||||
#include "db-generic.h"
|
||||
#include "err.h"
|
||||
#include "webserver.h"
|
||||
#include "xml-rpc.h"
|
||||
|
||||
/* typedefs */
|
||||
typedef struct tag_xmlstack {
|
||||
char *tag;
|
||||
struct tag_xmlstack *next;
|
||||
} XMLSTACK;
|
||||
|
||||
struct tag_xmlstruct {
|
||||
WS_CONNINFO *pwsc;
|
||||
int stack_level;
|
||||
XMLSTACK stack;
|
||||
};
|
||||
|
||||
/* Forwards */
|
||||
void xml_get_stats(WS_CONNINFO *pwsc);
|
||||
void xml_set_config(WS_CONNINFO *pwsc);
|
||||
void xml_browse_path(WS_CONNINFO *pwsc);
|
||||
void xml_rescan(WS_CONNINFO *pwsc);
|
||||
void xml_return_error(WS_CONNINFO *pwsc, int err, char *errstr);
|
||||
char *xml_entity_encode(char *original);
|
||||
|
||||
void xml_return_error(WS_CONNINFO *pwsc, int err, char *errstr) {
|
||||
XMLSTRUCT *pxml;
|
||||
|
||||
pxml=xml_init(pwsc,TRUE);
|
||||
xml_push(pxml,"results");
|
||||
|
||||
xml_output(pxml,"status","%d",err);
|
||||
xml_output(pxml,"statusstring","%s",errstr);
|
||||
|
||||
xml_pop(pxml); /* results */
|
||||
xml_deinit(pxml);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create an xml response structure, a helper struct for
|
||||
* building xml responses.
|
||||
*
|
||||
* @param pwsc the pwsc we are emitting to
|
||||
* @param emit_header whether or not to throw out html headers and xml header
|
||||
* @returns XMLSTRUCT on success, or NULL if failure
|
||||
*/
|
||||
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) {
|
||||
XMLSTRUCT *pxml;
|
||||
|
||||
pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT));
|
||||
if(!pxml) {
|
||||
DPRINTF(E_FATAL,L_XML,"Malloc error\n");
|
||||
}
|
||||
|
||||
memset(pxml,0,sizeof(XMLSTRUCT));
|
||||
|
||||
pxml->pwsc = pwsc;
|
||||
|
||||
/* the world would be a wonderful place without ie */
|
||||
ws_addresponseheader(pwsc,"Cache-Control","no-cache");
|
||||
ws_addresponseheader(pwsc,"Expires","-1");
|
||||
|
||||
if(emit_header) {
|
||||
ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
|
||||
ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
}
|
||||
|
||||
return pxml;
|
||||
}
|
||||
|
||||
/**
|
||||
* bulk set config
|
||||
*/
|
||||
void xml_update_config(WS_CONNINFO *pwsc) {
|
||||
char *arg, *value, *duparg;
|
||||
char *ptmp;
|
||||
char *badparms=NULL;
|
||||
void *handle;
|
||||
int has_error=0;
|
||||
int badparms_len=0;
|
||||
int err;
|
||||
|
||||
handle = NULL;
|
||||
|
||||
|
||||
while((handle=ws_enum_var(pwsc,&arg,&value,handle)) != NULL) {
|
||||
/* arg will be section:value */
|
||||
duparg = strdup(arg);
|
||||
ptmp = strchr(duparg,':');
|
||||
if(ptmp) {
|
||||
*ptmp++ = '\0';
|
||||
/* this is stupidly inefficient */
|
||||
|
||||
DPRINTF(E_DBG,L_XML,"Setting %s/%s to %s\n",duparg,ptmp,value);
|
||||
err = conf_set_string(duparg,ptmp,value,TRUE);
|
||||
if(err != CONF_E_SUCCESS) {
|
||||
DPRINTF(E_DBG,L_XML,"Error setting %s/%s\n",duparg,ptmp);
|
||||
has_error = TRUE;
|
||||
if(!badparms) {
|
||||
badparms_len = (int)strlen(arg) + 1;
|
||||
badparms = (char*)malloc(badparms_len);
|
||||
if(!badparms) {
|
||||
DPRINTF(E_FATAL,L_XML,"xml_update_config: malloc\n");
|
||||
}
|
||||
strcpy(badparms,arg);
|
||||
} else {
|
||||
badparms_len += (int)strlen(arg) + 1;
|
||||
badparms = (char*)realloc(badparms,badparms_len);
|
||||
if(!badparms) {
|
||||
DPRINTF(E_FATAL,L_XML,"xml_update_config: malloc\n");
|
||||
}
|
||||
strcat(badparms,",");
|
||||
strcat(badparms,arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(duparg);
|
||||
}
|
||||
|
||||
if(has_error) {
|
||||
DPRINTF(E_INF,L_XML,"Bad parms; %s\n",badparms);
|
||||
xml_return_error(pwsc,500,badparms);
|
||||
free(badparms);
|
||||
return;
|
||||
}
|
||||
|
||||
handle = NULL;
|
||||
|
||||
/* now set! */
|
||||
while((handle=ws_enum_var(pwsc,&arg,&value,handle)) != NULL) {
|
||||
/* arg will be section:value */
|
||||
duparg = strdup(arg);
|
||||
ptmp = strchr(duparg,':');
|
||||
if(ptmp) {
|
||||
*ptmp++ = '\0';
|
||||
/* this is stupidly inefficient */
|
||||
|
||||
DPRINTF(E_DBG,L_XML,"Setting %s/%s to %s\n",duparg,ptmp,value);
|
||||
err = conf_set_string(duparg,ptmp,value,FALSE);
|
||||
if(err != CONF_E_SUCCESS) {
|
||||
/* shouldn't happen */
|
||||
DPRINTF(E_DBG,L_XML,"Error setting %s/%s\n",duparg,ptmp);
|
||||
xml_return_error(pwsc,500,arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
free(duparg);
|
||||
}
|
||||
|
||||
xml_return_error(pwsc,200,"Success");
|
||||
}
|
||||
|
||||
/**
|
||||
* rescan the database
|
||||
*/
|
||||
void xml_rescan(WS_CONNINFO *pwsc) {
|
||||
if(ws_getvar(pwsc,"full")) {
|
||||
config.full_reload=1;
|
||||
}
|
||||
|
||||
config.reload=1;
|
||||
|
||||
xml_return_error(pwsc,200,"Success");
|
||||
}
|
||||
|
||||
/**
|
||||
* post settings back to the config file
|
||||
*
|
||||
* @param pwsc connection do dump results back to
|
||||
*/
|
||||
void xml_set_config(WS_CONNINFO *pwsc) {
|
||||
char *section;
|
||||
char *key;
|
||||
char *value;
|
||||
int verify_only;
|
||||
int err;
|
||||
|
||||
section = ws_getvar(pwsc,"section");
|
||||
key = ws_getvar(pwsc,"key");
|
||||
value = ws_getvar(pwsc,"value");
|
||||
|
||||
verify_only=0;
|
||||
if(ws_getvar(pwsc,"verify_only")) {
|
||||
verify_only = 1;
|
||||
}
|
||||
|
||||
if((!section) || (!key) || (!value)) {
|
||||
xml_return_error(pwsc,500,"Missing section, key, or value");
|
||||
return;
|
||||
}
|
||||
|
||||
if((err=conf_set_string(section,key,value,verify_only)!=CONF_E_SUCCESS)) {
|
||||
/* should return text error from conf_ */
|
||||
switch(err) {
|
||||
case CONF_E_BADELEMENT:
|
||||
xml_return_error(pwsc,500,"Unknown section/key pair");
|
||||
break;
|
||||
case CONF_E_PATHEXPECTED:
|
||||
xml_return_error(pwsc,500,"Expecting valid path");
|
||||
break;
|
||||
case CONF_E_INTEXPECTED:
|
||||
xml_return_error(pwsc,500,"Expecting integer value");
|
||||
break;
|
||||
case CONF_E_NOTWRITABLE:
|
||||
xml_return_error(pwsc,500,"Config file not writable");
|
||||
break;
|
||||
default:
|
||||
xml_return_error(pwsc,500,"conf_set_string: error");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
xml_return_error(pwsc,200,"Success");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* push a new term on the stack
|
||||
*
|
||||
* @param pxml xml struct obtained from xml_init
|
||||
* @param term next xlm section to start
|
||||
*/
|
||||
void xml_push(XMLSTRUCT *pxml, char *term) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK));
|
||||
pstack->next=pxml->stack.next;
|
||||
pstack->tag=strdup(term);
|
||||
pxml->stack.next=pstack;
|
||||
|
||||
pxml->stack_level++;
|
||||
|
||||
ws_writefd(pxml->pwsc,"<%s>",term);
|
||||
}
|
||||
|
||||
/**
|
||||
* end an xml section
|
||||
*
|
||||
* @param pxml xml struct we are working with
|
||||
*/
|
||||
void xml_pop(XMLSTRUCT *pxml) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
pstack=pxml->stack.next;
|
||||
if(!pstack) {
|
||||
DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pxml->stack.next = pstack->next;
|
||||
|
||||
ws_writefd(pxml->pwsc,"</%s>",pstack->tag);
|
||||
free(pstack->tag);
|
||||
free(pstack);
|
||||
|
||||
pxml->stack_level--;
|
||||
}
|
||||
|
||||
/* FIXME: Fixed at 256? And can't I get an expandable sprintf/cat? */
|
||||
|
||||
/**
|
||||
* output a string
|
||||
*/
|
||||
void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) {
|
||||
va_list ap;
|
||||
char buf[256];
|
||||
char *output;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
output = xml_entity_encode(buf);
|
||||
if(section) {
|
||||
xml_push(pxml,section);
|
||||
}
|
||||
ws_writefd(pxml->pwsc,"%s",output);
|
||||
free(output);
|
||||
if(section) {
|
||||
xml_pop(pxml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up an xml struct
|
||||
*
|
||||
* @param pxml xml struct to clean up
|
||||
*/
|
||||
void xml_deinit(XMLSTRUCT *pxml) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
if(pxml->stack.next) {
|
||||
DPRINTF(E_LOG,L_XML,"xml_deinit: entries still on stack (%s)\n",
|
||||
pxml->stack.next->tag);
|
||||
}
|
||||
|
||||
while((pstack=pxml->stack.next)) {
|
||||
pxml->stack.next=pstack->next;
|
||||
free(pstack->tag);
|
||||
free(pstack);
|
||||
}
|
||||
free(pxml);
|
||||
}
|
||||
|
||||
/**
|
||||
* main entrypoint for the xmlrpc functions.
|
||||
*
|
||||
* @arg pwsc Pointer to the web request structure
|
||||
*/
|
||||
void xml_handle(WS_CONNINFO *pwsc) {
|
||||
char *method;
|
||||
|
||||
if((method=ws_getvar(pwsc,"method")) == NULL) {
|
||||
ws_returnerror(pwsc,500,"no method specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(method,"stats") == 0) {
|
||||
xml_get_stats(pwsc);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(method,"config") == 0) {
|
||||
conf_xml_dump(pwsc);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(method,"setconfig") == 0) {
|
||||
xml_set_config(pwsc);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(method,"updateconfig") == 0) {
|
||||
xml_update_config(pwsc);
|
||||
return;
|
||||
}
|
||||
|
||||
#if(0) /* Turn this off until it's done in the web admin */
|
||||
if(strcasecmp(method,"browse_path") == 0) {
|
||||
xml_browse_path(pwsc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(strcasecmp(method,"rescan") == 0) {
|
||||
xml_rescan(pwsc);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcasecmp(method,"shutdown") == 0) {
|
||||
config.stop=1;
|
||||
xml_return_error(pwsc,200,"Success");
|
||||
return;
|
||||
}
|
||||
|
||||
xml_return_error(pwsc,500,"Invalid method");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a base directory, walk through the directory and enumerate
|
||||
* all folders underneath it.
|
||||
*
|
||||
* @param pwsc connection over which to dump the result
|
||||
*/
|
||||
void xml_browse_path(WS_CONNINFO *pwsc) {
|
||||
XMLSTRUCT *pxml;
|
||||
DIR *pd;
|
||||
char *base_path;
|
||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1];
|
||||
struct dirent *pde;
|
||||
int readable, writable;
|
||||
char full_path[PATH_MAX+1];
|
||||
char resolved_path[PATH_MAX];
|
||||
int err;
|
||||
int ignore_dotfiles=1;
|
||||
int ignore_files=1;
|
||||
struct stat sb;
|
||||
|
||||
base_path = ws_getvar(pwsc, "path");
|
||||
if(!base_path)
|
||||
base_path = PATHSEP_STR;
|
||||
|
||||
if(ws_getvar(pwsc,"show_dotfiles"))
|
||||
ignore_dotfiles = 0;
|
||||
|
||||
if(ws_getvar(pwsc,"show_files"))
|
||||
ignore_files = 0;
|
||||
|
||||
pd = opendir(base_path);
|
||||
if(!pd) {
|
||||
xml_return_error(pwsc,500,"Bad path");
|
||||
return;
|
||||
}
|
||||
|
||||
pxml=xml_init(pwsc,1);
|
||||
xml_push(pxml,"results");
|
||||
|
||||
/* get rid of trailing slash */
|
||||
while(1) {
|
||||
pde = (struct dirent *)&de;
|
||||
err = readdir_r(pd,(struct dirent *)de, &pde);
|
||||
|
||||
if(err == -1) {
|
||||
DPRINTF(E_LOG,L_SCAN,"Error in readdir_r: %s\n",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if(!pde)
|
||||
break;
|
||||
|
||||
if((!strcmp(pde->d_name,".")) || (!strcmp(pde->d_name,"..")))
|
||||
continue;
|
||||
|
||||
|
||||
snprintf(full_path,PATH_MAX,"%s%c%s",base_path,PATHSEP,pde->d_name);
|
||||
realpath(full_path,resolved_path);
|
||||
|
||||
if(stat(resolved_path, &sb)) {
|
||||
DPRINTF(E_INF,L_XML,"Error statting %s: %s\n",
|
||||
resolved_path,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if((sb.st_mode & S_IFREG) && (ignore_files))
|
||||
continue;
|
||||
|
||||
/* skip symlinks and devices and whatnot */
|
||||
if((!(sb.st_mode & S_IFDIR)) &&
|
||||
(!(sb.st_mode & S_IFREG)))
|
||||
continue;
|
||||
|
||||
if((ignore_dotfiles) && (pde->d_name) && (pde->d_name[0] == '.'))
|
||||
continue;
|
||||
|
||||
readable = !access(resolved_path,R_OK);
|
||||
writable = !access(resolved_path,W_OK);
|
||||
|
||||
if(sb.st_mode & S_IFDIR) {
|
||||
xml_push(pxml,"directory");
|
||||
} else if((sb.st_mode & S_IFLNK) == S_IFLNK) {
|
||||
xml_push(pxml,"symlink");
|
||||
} else {
|
||||
xml_push(pxml,"file");
|
||||
}
|
||||
xml_output(pxml,"name",pde->d_name);
|
||||
xml_output(pxml,"full_path",resolved_path);
|
||||
xml_output(pxml,"readable","%d",readable);
|
||||
xml_output(pxml,"writable","%d",writable);
|
||||
|
||||
xml_pop(pxml); /* directory */
|
||||
|
||||
}
|
||||
|
||||
|
||||
xml_pop(pxml);
|
||||
xml_deinit(pxml);
|
||||
|
||||
closedir(pd);
|
||||
}
|
||||
|
||||
/**
|
||||
* return xml file of all playlists
|
||||
*/
|
||||
void xml_get_stats(WS_CONNINFO *pwsc) {
|
||||
int r_secs, r_days, r_hours, r_mins;
|
||||
char buf[80];
|
||||
WS_CONNINFO *pci;
|
||||
SCAN_STATUS *pss;
|
||||
WSTHREADENUM wste;
|
||||
int count;
|
||||
XMLSTRUCT *pxml;
|
||||
|
||||
pxml=xml_init(pwsc,1);
|
||||
xml_push(pxml,"status");
|
||||
|
||||
xml_push(pxml,"service_status");
|
||||
|
||||
xml_push(pxml,"service");
|
||||
xml_output(pxml,"name","DAAP Server");
|
||||
xml_output(pxml,"status",config.stop ? "Stopping" : "Running");
|
||||
xml_pop(pxml); /* service */
|
||||
|
||||
xml_push(pxml,"service");
|
||||
xml_output(pxml,"name","File Scanner");
|
||||
xml_output(pxml,"status",config.reload ? "Running" : "Idle");
|
||||
xml_pop(pxml); /* service */
|
||||
|
||||
xml_pop(pxml); /* service_status */
|
||||
|
||||
xml_push(pxml,"thread_status");
|
||||
|
||||
pci = ws_thread_enum_first(config.server,&wste);
|
||||
while(pci) {
|
||||
pss = ws_get_local_storage(pci);
|
||||
if(pss) {
|
||||
xml_push(pxml,"thread");
|
||||
xml_output(pxml,"id","%d",pss->thread);
|
||||
xml_output(pxml,"sourceip","%s",pss->host);
|
||||
xml_output(pxml,"action","%s",pss->what);
|
||||
xml_pop(pxml); /* thread */
|
||||
}
|
||||
pci=ws_thread_enum_next(config.server,&wste);
|
||||
}
|
||||
|
||||
xml_pop(pxml); /* thread_status */
|
||||
|
||||
xml_push(pxml,"statistics");
|
||||
|
||||
r_secs=(int)(time(NULL)-config.stats.start_time);
|
||||
|
||||
r_days=r_secs/(3600 * 24);
|
||||
r_secs -= ((3600 * 24) * r_days);
|
||||
|
||||
r_hours=r_secs/3600;
|
||||
r_secs -= (3600 * r_hours);
|
||||
|
||||
r_mins=r_secs/60;
|
||||
r_secs -= 60 * r_mins;
|
||||
|
||||
memset(buf,0x0,sizeof(buf));
|
||||
if(r_days)
|
||||
sprintf((char*)&buf[strlen(buf)],"%d day%s, ", r_days,
|
||||
r_days == 1 ? "" : "s");
|
||||
|
||||
if(r_days || r_hours)
|
||||
sprintf((char*)&buf[strlen(buf)],"%d hour%s, ", r_hours,
|
||||
r_hours == 1 ? "" : "s");
|
||||
|
||||
if(r_days || r_hours || r_mins)
|
||||
sprintf((char*)&buf[strlen(buf)],"%d minute%s, ", r_mins,
|
||||
r_mins == 1 ? "" : "s");
|
||||
|
||||
sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs,
|
||||
r_secs == 1 ? "" : "s");
|
||||
|
||||
xml_push(pxml,"stat");
|
||||
xml_output(pxml,"name","Uptime");
|
||||
xml_output(pxml,"value","%s",buf);
|
||||
xml_pop(pxml); /* stat */
|
||||
|
||||
xml_push(pxml,"stat");
|
||||
xml_output(pxml,"name","Songs");
|
||||
db_get_song_count(NULL,&count);
|
||||
xml_output(pxml,"value","%d",count);
|
||||
xml_pop(pxml); /* stat */
|
||||
|
||||
xml_push(pxml,"stat");
|
||||
xml_output(pxml,"name","Songs Served");
|
||||
xml_output(pxml,"value","%d",config.stats.songs_served);
|
||||
xml_pop(pxml); /* stat */
|
||||
|
||||
xml_pop(pxml); /* statistics */
|
||||
|
||||
|
||||
xml_push(pxml,"misc");
|
||||
xml_output(pxml,"writable_config","%d",conf_iswritable());
|
||||
xml_output(pxml,"config_path","%s",conf_get_filename());
|
||||
xml_output(pxml,"version","%s",VERSION);
|
||||
xml_pop(pxml); /* misc */
|
||||
|
||||
xml_pop(pxml); /* status */
|
||||
|
||||
xml_deinit(pxml);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* xml entity encoding, stupid style
|
||||
*/
|
||||
char *xml_entity_encode(char *original) {
|
||||
char *new;
|
||||
char *s, *d;
|
||||
int destsize;
|
||||
|
||||
destsize = 6*(int)strlen(original)+1;
|
||||
new=(char *)malloc(destsize);
|
||||
if(!new) return NULL;
|
||||
|
||||
memset(new,0x00,destsize);
|
||||
|
||||
s=original;
|
||||
d=new;
|
||||
|
||||
while(*s) {
|
||||
switch(*s) {
|
||||
case '>':
|
||||
strcat(d,">");
|
||||
d += 4;
|
||||
s++;
|
||||
break;
|
||||
case '<':
|
||||
strcat(d,"<");
|
||||
d += 4;
|
||||
s++;
|
||||
break;
|
||||
case '"':
|
||||
strcat(d,""");
|
||||
d += 6;
|
||||
s++;
|
||||
break;
|
||||
case '\'':
|
||||
strcat(d,"'");
|
||||
d += 6;
|
||||
s++;
|
||||
break;
|
||||
case '&':
|
||||
strcat(d,"&");
|
||||
d += 5;
|
||||
s++;
|
||||
break;
|
||||
default:
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
|
||||
#ifndef _XMLRPC_H_
|
||||
#define _XMLRPC_H_
|
||||
|
||||
#include "webserver.h"
|
||||
|
||||
extern void xml_handle(WS_CONNINFO *pwsc);
|
||||
|
||||
struct tag_xmlstruct;
|
||||
typedef struct tag_xmlstruct XMLSTRUCT;
|
||||
|
||||
extern XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header);
|
||||
extern void xml_push(XMLSTRUCT *pxml, char *term);
|
||||
extern void xml_pop(XMLSTRUCT *pxml);
|
||||
extern void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...);
|
||||
extern void xml_deinit(XMLSTRUCT *pxml);
|
||||
|
||||
|
||||
#endif /* _XMLRPC_H_ */
|
Loading…
x
Reference in New Issue
Block a user