From b3cffd491d13886da3ce1e74c7521f5ae93afab4 Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Sun, 5 Apr 2009 22:42:03 +0200 Subject: [PATCH] Add and use io_urlencode() to replace %U format spec for io_open() Stopgap to replace the %U modifier until something happens with the whole io_* stuff. --- src/conf.c | 32 +++++++++++++++++++++++++++---- src/configfile.c | 36 ++++++++++++++++++++++++++++++++-- src/err.c | 25 ++++++++++++++++++++++-- src/ff-plugins.c | 18 ++++++++++++++++- src/io.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/io.h | 2 ++ src/mp3-scanner.c | 15 ++++++++++++++- src/rxml.c | 10 +++++++++- src/scan-url.c | 16 ++++++++++++++-- src/scan-wma.c | 14 +++++++++++++- src/webserver.c | 22 ++++++++++++++++++++- 11 files changed, 224 insertions(+), 15 deletions(-) diff --git a/src/conf.c b/src/conf.c index 0b783572..1ac1b21b 100644 --- a/src/conf.c +++ b/src/conf.c @@ -597,6 +597,8 @@ int conf_read(char *file) { char *temp; IOHANDLE hconfig; uint32_t len; + char *urltemp; + int ret; char *replaced_section = NULL; /* config key/value updates */ char *replaced_key = NULL; /* config key/value updates */ @@ -614,7 +616,17 @@ int conf_read(char *file) { DPRINTF(E_FATAL,L_CONF,"Malloc eror in io_new()\n"); DPRINTF(E_DBG,L_CONF,"Loading config file %s\n",conf_file); - if(!io_open(hconfig,"file://%s?ascii=1",conf_file)) { + urltemp = io_urlencode(conf_file); + if (!urltemp) + { + DPRINTF(E_LOG,L_MISC,"Error opening config file: out of memory\n"); + io_dispose(hconfig); + return CONF_E_FOPEN; + } + + ret = io_open(hconfig, "file://%s?ascii=1", urltemp); + free(urltemp); + if(!ret) { DPRINTF(E_LOG,L_MISC,"Error opening config file: %s\n",io_errstr(hconfig)); io_dispose(hconfig); return CONF_E_FOPEN; @@ -1245,6 +1257,8 @@ int conf_iswritable(void) { int conf_write(void) { int retval = CONF_E_NOTWRITABLE; IOHANDLE outfile; + char *urltemp; + int ret; if(!conf_main_file) { DPRINTF(E_DBG,L_CONF,"Config file apparently not loaded\n"); @@ -1256,15 +1270,25 @@ int conf_write(void) { if(!outfile) DPRINTF(E_FATAL,L_CONF,"io_new failed in conf_write\n"); - if(io_open(outfile,"file://%s?mode=w&ascii=1",conf_main_file)) { + urltemp = io_urlencode(conf_main_file); + if (!urltemp) + { + DPRINTF(E_LOG,L_CONF,"Error opening config file for write: out of memory\n"); + io_dispose(outfile); + return retval; + } + + ret = io_open(outfile, "file://%s?mode=w&ascii=1", urltemp); + free(urltemp); + if (ret) { retval = _conf_write(outfile,conf_main,0,NULL); io_close(outfile); - io_dispose(outfile); } else { DPRINTF(E_LOG,L_CONF,"Error opening config file for write: %s\n", io_errstr(outfile)); - io_dispose(outfile); } + io_dispose(outfile); + util_mutex_unlock(l_conf); return retval; diff --git a/src/configfile.c b/src/configfile.c index 74c5f9e0..34d8eeb6 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -394,6 +394,8 @@ void config_handler(WS_CONNINFO *pwsc) { struct stat sb; char *pw; int size; + char *urltemp; + int ret; if(!ws_hostname(pwsc)) { ws_returnerror(pwsc,500,"Couldn't determine remote hostname"); @@ -482,7 +484,21 @@ void config_handler(WS_CONNINFO *pwsc) { } DPRINTF(E_DBG,L_CONF|L_WS,"Opening %s\n",resolved_path); - if(!io_open(hfile,"file://%s",resolved_path)) { + urltemp = io_urlencode(resolved_path); + if (!urltemp) + { + ws_set_err(pwsc,E_WS_NATIVE); + DPRINTF(E_WARN,L_CONF|L_WS,"Thread %d: Error opening %s: out of memory\n", + ws_threadno(pwsc),resolved_path); + ws_returnerror(pwsc,404,"Not found"); + config_set_status(pwsc,0,NULL); + io_dispose(hfile); + return; + } + + ret = io_open(hfile, "file://%s", urltemp); + free(urltemp); + if(!ret) { ws_set_err(pwsc,E_WS_NATIVE); DPRINTF(E_WARN,L_CONF|L_WS,"Thread %d: Error opening %s: %s\n", ws_threadno(pwsc),resolved_path,io_errstr(hfile)); @@ -937,6 +953,8 @@ void config_emit_include(WS_CONNINFO *pwsc, void *value, char *arg) { IOHANDLE hfile; struct stat sb; int size; + char *urltemp; + int ret; size = sizeof(web_root); if(conf_get_string("general","web_root",NULL,web_root, @@ -984,7 +1002,21 @@ void config_emit_include(WS_CONNINFO *pwsc, void *value, char *arg) { ws_threadno(pwsc)); return; } - if(!io_open(hfile,"file://%s",resolved_path)) { + + urltemp = io_urlencode(resolved_path); + if (!urltemp) + { + ws_set_err(pwsc,E_WS_NATIVE); + DPRINTF(E_LOG,L_CONF|L_WS,"Thread %d: Error opening %s: out of memory\n", + ws_threadno(pwsc),resolved_path); + ws_writefd(pwsc,"
error: cannot open %s: out of memory
",arg); + io_dispose(hfile); + return; + } + + ret = io_open(hfile, "file://%s", urltemp); + free(urltemp); + if (!ret) { ws_set_err(pwsc,E_WS_NATIVE); DPRINTF(E_LOG,L_CONF|L_WS,"Thread %d: Error opening %s: %s\n", ws_threadno(pwsc),resolved_path,io_errstr(pwsc)); diff --git a/src/err.c b/src/err.c index ab7420f3..feee38d5 100644 --- a/src/err.c +++ b/src/err.c @@ -169,11 +169,21 @@ uint32_t __err_get_threadid(void) { * would help for log rotation */ void err_reopen(void) { + char *urltemp; + int ret; + if(!(err_logdest & LOGDEST_LOGFILE)) return; + urltemp = io_urlencode(err_filename); + if (!urltemp) + return; + io_close(err_file); - if(!io_open("file://%s?mode=a&ascii=1",err_filename)) { + + ret = io_open(err_file, "file://%s?mode=a&ascii=1", urltemp); + free(urltemp); + if (!ret) { /* what to do when you lose your logging mechanism? Keep * going? */ @@ -335,6 +345,8 @@ int err_settruncate(int truncate) { int err_setlogfile(char *file) { char *mode; + char *urltemp; + int ret; int result=TRUE; /* @@ -359,7 +371,16 @@ int err_setlogfile(char *file) { strncpy(err_filename,file,sizeof(err_filename)-1); - if(!io_open(err_file,"file://%s?mode=%s&ascii=1",err_filename,mode)) { + urltemp = io_urlencode(err_filename); + if (!urltemp) + { + fprintf(stderr,"Error opening logfile: out of memory\n"); + return FALSE; + } + + ret = io_open(err_file, "file://%s?mode=%s&ascii=1", urltemp, mode); + free(urltemp); + if (!ret) { fprintf(stderr,"Error opening logfile: %s",io_errstr(err_file)); err_logdest &= ~LOGDEST_LOGFILE; diff --git a/src/ff-plugins.c b/src/ff-plugins.c index 31a51937..e8cc99b1 100644 --- a/src/ff-plugins.c +++ b/src/ff-plugins.c @@ -304,6 +304,8 @@ EXPORT void pi_stream(WS_CONNINFO *pwsc, char *id) { uint64_t file_len; uint64_t offset=0; int item; + char *urltemp; + int ret; /* stream out the song */ ws_should_close(pwsc,1); @@ -352,7 +354,21 @@ EXPORT void pi_stream(WS_CONNINFO *pwsc, char *id) { if(!hfile) DPRINTF(E_FATAL,L_WS,"Cannot allocate file handle\n"); - if(!io_open(hfile,"file://%s",pmp3->path)) { + urltemp = io_urlencode(pmp3->path); + if (!urltemp) + { + ws_set_err(pwsc,E_WS_NATIVE); + DPRINTF(E_WARN,L_WS,"Thread %d: Error opening %s: out of memory\n", + ws_threadno(pwsc),pmp3->path); + ws_returnerror(pwsc,404,"Not found"); + config_set_status(pwsc,session,NULL); + db_dispose_item(pmp3); + io_dispose(hfile); + } + + ret = io_open(hfile, "file://%s", urltemp); + free(urltemp); + if (!ret) { /* FIXME: ws_set_errstr */ ws_set_err(pwsc,E_WS_NATIVE); DPRINTF(E_WARN,L_WS,"Thread %d: Error opening %s: %s\n", diff --git a/src/io.c b/src/io.c index 1ae390e1..22af30d6 100644 --- a/src/io.c +++ b/src/io.c @@ -308,6 +308,55 @@ int io_init(void) { return TRUE; } +char *io_urlencode(char *str) +{ + char *ret; + unsigned char *in_cur; + unsigned char *out_cur; + int len; + + char *digits = "0123456789abcdef"; + char *safe = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789$-_.!*(),/@\\"; + + len = 0; + + in_cur = (unsigned char *) str; + for (len = 0; *in_cur; in_cur++) + { + if (strchr(safe, *in_cur)) + len++; + else + len += 3; + } + + ret = (char *)malloc(len + 1); + if (!ret) + return NULL; + + in_cur = (unsigned char *)str; + out_cur = (unsigned char *)ret; + for (; *in_cur; in_cur++, out_cur++) + { + if (strchr(safe,*in_cur)) + *out_cur = *in_cur; + else if (*in_cur == ' ') + *out_cur = '+'; + else + { + *out_cur = '%'; + out_cur++; + *out_cur = digits[(*in_cur >> 4) & 0xf]; + out_cur++; + *out_cur = digits[*in_cur & 0xf]; + } + } + *out_cur = '\0'; + + return ret; +} + /** * urldecode a string in-place * diff --git a/src/io.h b/src/io.h index 5fa17886..0933b4dd 100644 --- a/src/io.h +++ b/src/io.h @@ -101,4 +101,6 @@ extern int io_wait_dispose(IO_WAITHANDLE wh); # define FALSE 0 #endif +char *io_urlencode(char *str); + #endif /* _IO_H_ */ diff --git a/src/mp3-scanner.c b/src/mp3-scanner.c index 3c055be5..a08494e8 100644 --- a/src/mp3-scanner.c +++ b/src/mp3-scanner.c @@ -349,6 +349,8 @@ int scan_static_playlist(char *path) { char *perr; char *ptr; uint32_t len; + char *urltemp; + int ret; DPRINTF(E_WARN,L_SCAN|L_PL,"Processing static playlist: %s\n",path); if(os_stat(path,&sb)) { @@ -388,7 +390,18 @@ int scan_static_playlist(char *path) { return FALSE; } - if(io_open(hfile,"file://%s?ascii=1",path)) { + urltemp = io_urlencode(path); + if (!urltemp) + { + DPRINTF(E_LOG, L_SCAN, "Cannot open playlist: out of memory\n"); + io_dispose(hfile); + db_dispose_playlist(pm3u); + return FALSE; + } + + ret = io_open(hfile, "file://%s?ascii=1", urltemp); + free(urltemp); + if (ret) { if(db_add_playlist(&perr,base_path,PL_STATICFILE,NULL,path, 0,&playlistid) != DB_E_SUCCESS) { DPRINTF(E_LOG,L_SCAN,"Error adding m3u %s: %s\n",path,perr); diff --git a/src/rxml.c b/src/rxml.c index 8df402c3..36de4561 100644 --- a/src/rxml.c +++ b/src/rxml.c @@ -128,6 +128,8 @@ int rxml_decode_string(char *string) { int rxml_open(RXMLHANDLE *vp, char *file, RXML_EVTHANDLER handler, void *udata) { RXML *pnew; + char *urltemp; + int ret; pnew=(RXML*)malloc(sizeof(RXML)); if(!pnew) { @@ -145,7 +147,13 @@ int rxml_open(RXMLHANDLE *vp, char *file, if(!pnew->hfile) RXML_ERROR(pnew,E_RXML_MALLOC); - if(!io_open(pnew->hfile, "file://%s?ascii=1", file)) { + urltemp = io_urlencode(file); + if (!urltemp) + RXML_ERROR(pnew,E_RXML_MALLOC); + + ret = io_open(pnew->hfile, "file://%s?ascii=1", urltemp); + free(urltemp); + if (!ret) { io_dispose(pnew->hfile); pnew->hfile = NULL; RXML_ERROR(pnew,E_RXML_OPEN); diff --git a/src/scan-url.c b/src/scan-url.c index c59a1248..6f2439ac 100644 --- a/src/scan-url.c +++ b/src/scan-url.c @@ -46,6 +46,8 @@ int scan_get_urlinfo(char *filename, MP3FILE *pmp3) { char *head, *tail; char linebuffer[256]; uint32_t len; + char *urltemp; + int ret; DPRINTF(E_DBG,L_SCAN,"Getting URL file info\n"); @@ -53,8 +55,18 @@ int scan_get_urlinfo(char *filename, MP3FILE *pmp3) { DPRINTF(E_LOG,L_SCAN,"Can't create file handle\n"); return FALSE; } - - if(!io_open(hfile,"file://%s?ascii=1",filename)) { + + urltemp = io_urlencode(filename); + if (!urltemp) + { + DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading: out of memory\n",filename); + io_dispose(hfile); + return FALSE; + } + + ret = io_open(hfile,"file://%s?ascii=1",filename); + free(urltemp); + if (!ret) { DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading: %s\n",filename, io_errstr(hfile)); io_dispose(hfile); diff --git a/src/scan-wma.c b/src/scan-wma.c index 5c662996..78333041 100644 --- a/src/scan-wma.c +++ b/src/scan-wma.c @@ -978,13 +978,25 @@ int scan_get_wmainfo(char *filename, MP3FILE *pmp3) { int item; int res=TRUE; int encrypted = 0; + char *urltemp; + int ret; if(!(hfile = io_new())) { DPRINTF(E_LOG,L_SCAN,"Can't create new file handle\n"); return FALSE; } - if(!io_open(hfile,"file://%s",filename)) { + urltemp = io_urlencode(filename); + if (!urltemp) + { + DPRINTF(E_INF,L_SCAN,"Error opening WMA file (%s): out of memory\n", filename); + io_dispose(hfile); + return FALSE; + } + + ret = io_open(hfile, "file://%s", urltemp); + free(urltemp); + if (!ret) { DPRINTF(E_INF,L_SCAN,"Error opening WMA file (%s): %s\n",filename, io_errstr(hfile)); io_dispose(hfile); diff --git a/src/webserver.c b/src/webserver.c index d566e7d4..cdbe52b6 100644 --- a/src/webserver.c +++ b/src/webserver.c @@ -1309,6 +1309,8 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) { char resolved_path[PATH_MAX]; IOHANDLE hfile; uint64_t len; + char *urltemp; + int ret; WS_ENTER(); @@ -1347,7 +1349,25 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) { return; } - if(!io_open(hfile,"file://%s",resolved_path)) { /* default is O_RDONLY */ + urltemp = io_urlencode(resolved_path); + if (!urltemp) + { + ws_set_err(pwsc,E_WS_NATIVE); /* FIXME: ws_set_errstr */ + ws_dprintf(L_WS_LOG,"Error opening %s: out of memory",resolved_path); + ws_dprintf(L_WS_WARN,"Exiting ws_defaulthandler: Thread %d: " + "Error opening %s: out of memory\n", + pwsc->threadno,resolved_path); + ws_returnerror(pwsc,404,"Not found"); + ws_close(pwsc); + + io_dispose(hfile); + WS_EXIT(); + return; + } + + ret = io_open(hfile, "file://%s", urltemp); /* default is O_RDONLY */ + free(urltemp); + if(!ret) { ws_set_err(pwsc,E_WS_NATIVE); /* FIXME: ws_set_errstr */ ws_dprintf(L_WS_LOG,"Error opening %s: %s",resolved_path, io_errstr(hfile));