Only in xmms-scrobbler-0.3.8.1-proxy: .deps diff -urp xmms-scrobbler-0.3.8.1/gtkstuff.c xmms-scrobbler-0.3.8.1-proxy/gtkstuff.c --- xmms-scrobbler-0.3.8.1/gtkstuff.c 2005-02-20 10:26:08.000000000 +0600 +++ xmms-scrobbler-0.3.8.1-proxy/gtkstuff.c 2006-07-06 18:15:12.000000000 +0700 @@ -15,9 +15,12 @@ #include #include "config.h" #include "md5.h" +#include "tags/include/unicode.h" static GtkWidget *eduname, - *edpwd; + *edpwd, + *edenc, + *edprx; static int errorbox_done; void about_show(void) { @@ -115,6 +118,11 @@ static void saveconfig(GtkWidget *wid, g const char *pwd = gtk_entry_get_text(GTK_ENTRY(edpwd)); const char *uid = gtk_entry_get_text(GTK_ENTRY(eduname)); + const char *enc = gtk_entry_get_text(GTK_ENTRY(edenc)); + const char *prx = gtk_entry_get_text(GTK_ENTRY(edprx)); + + g_free(tags_encoding); + tags_encoding = g_strdup(enc); if ((cfgfile = xmms_cfg_open_default_file())) { @@ -130,6 +138,11 @@ static void saveconfig(GtkWidget *wid, g xmms_cfg_write_string(cfgfile, "audioscrobbler", "password", (char *)hexify(md5pword, sizeof(md5pword))); } + + xmms_cfg_write_string(cfgfile, "audioscrobbler", "encoding", (char *)enc); + if (strcmp(prx, "")) + xmms_cfg_write_string(cfgfile, "audioscrobbler", "proxy", (char *)prx); + #ifdef MAKE_XMMS xmms_cfg_write_default_file(cfgfile); #endif @@ -147,8 +160,12 @@ void configure_dialog(void) *hbox, *unhbox, *pwhbox, + *enhbox, + *prhbox, *lblun, *lblpw, + *lblen, + *lblpr, *frame; ConfigFile *cfgfile; @@ -184,10 +201,25 @@ void configure_dialog(void) gtk_entry_set_visibility(GTK_ENTRY(edpwd), FALSE); gtk_box_pack_start(GTK_BOX(pwhbox), lblpw, FALSE, FALSE, 3); gtk_box_pack_start(GTK_BOX(pwhbox), edpwd, FALSE, FALSE, 3); - + + enhbox = gtk_hbox_new(FALSE, 0); + edenc = gtk_entry_new(); + lblen = gtk_label_new("Tags encoding"); + gtk_box_pack_start(GTK_BOX(enhbox), lblen, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(enhbox), edenc, FALSE, FALSE, 3); + + prhbox = gtk_hbox_new(FALSE, 0); + edprx = gtk_entry_new(); + lblpr = gtk_label_new("Proxy server"); + gtk_box_pack_start(GTK_BOX(prhbox), lblpr, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(prhbox), edprx, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(vbox), unhbox, FALSE, FALSE, 3); gtk_box_pack_start(GTK_BOX(vbox), pwhbox, FALSE, FALSE, 3); - + gtk_box_pack_start(GTK_BOX(vbox), enhbox, FALSE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(vbox), prhbox, FALSE, FALSE, 3); + + hbox = gtk_hbox_new(FALSE, 0); btnok = gtk_button_new_with_label("OK"); @@ -202,17 +234,33 @@ void configure_dialog(void) gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); - frame = gtk_frame_new(" The plugin will have to be restarted for changes to take effect! "); + frame = gtk_frame_new(" The plugin will have to be restarted for username/password and proxy changes to take effect! "); gtk_container_add(GTK_CONTAINER(frame), vbox); gtk_container_add(GTK_CONTAINER(cnfdlg), frame); if ((cfgfile = xmms_cfg_open_default_file())) { - gchar *username = NULL; - xmms_cfg_read_string(cfgfile, "audioscrobbler", "username", - &username); - if (username) { - gtk_entry_set_text(GTK_ENTRY(eduname), username); - g_free(username); + gchar *entry; + + entry = NULL; + xmms_cfg_read_string(cfgfile, "audioscrobbler", "username", &entry); + if (entry) { + gtk_entry_set_text(GTK_ENTRY(eduname), entry); + g_free(entry); + } + + entry = NULL; + xmms_cfg_read_string(cfgfile, "audioscrobbler", "encoding", &entry); + if (entry) { + gtk_entry_set_text(GTK_ENTRY(edenc), entry); + g_free(entry); } + + entry = NULL; + xmms_cfg_read_string(cfgfile, "audioscrobbler", "proxy", &entry); + if (entry) { + gtk_entry_set_text(GTK_ENTRY(edprx), entry); + g_free(entry); + } + xmms_cfg_free(cfgfile); } diff -urp xmms-scrobbler-0.3.8.1/scrobbler.c xmms-scrobbler-0.3.8.1-proxy/scrobbler.c --- xmms-scrobbler-0.3.8.1/scrobbler.c 2005-02-21 06:45:05.000000000 +0600 +++ xmms-scrobbler-0.3.8.1-proxy/scrobbler.c 2006-07-06 17:57:31.000000000 +0700 @@ -42,6 +42,8 @@ static char *sc_submit_url, sc_curl_errbuf[CURL_ERROR_SIZE], *sc_major_error; +char* proxy_server = NULL; + static void dump_queue(); /* Error functions */ @@ -227,6 +229,80 @@ static void hexify(char *pass, int len) static int sc_handshake(void) { + pdebug("Handshaking directly", DEBUG); + int status; + char buf[4096]; + CURL *curl; + + snprintf(buf, sizeof(buf), "%s/?hs=true&p=%s&c=%s&v=%s&u=%s", + SCROBBLER_HS_URL, SCROBBLER_VERSION, + SCROBBLER_CLI_ID, VERSION, sc_username); + + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_URL, buf); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + sc_store_res); + memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf)); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + status = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + sc_hs_timeout = time(NULL) + SCROBBLER_HS_WAIT; + + if (status) { + pdebug(sc_curl_errbuf, DEBUG); + sc_hs_errors++; + sc_free_res(); + return -1; + } + + if (sc_parse_hs_res()) { + sc_hs_errors++; + sc_free_res(); + return -1; + } + + if (sc_challenge_hash != NULL) { + md5_state_t md5state; + unsigned char md5pword[16]; + + md5_init(&md5state); + /*pdebug(fmt_vastr("Pass Hash: %s", sc_password), DEBUG);*/ + md5_append(&md5state, (unsigned const char *)sc_password, + strlen(sc_password)); + /*pdebug(fmt_vastr("Challenge Hash: %s", sc_challenge_hash), DEBUG);*/ + md5_append(&md5state, (unsigned const char *)sc_challenge_hash, + strlen(sc_challenge_hash)); + md5_finish(&md5state, md5pword); + hexify(md5pword, sizeof(md5pword)); + /*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/ + } + + sc_hs_errors = 0; + sc_hs_status = 1; + + sc_free_res(); + + pdebug(fmt_vastr("submiturl: %s - interval: %d", + sc_submit_url, sc_submit_interval), DEBUG); + + return 0; +} + +static int sc_handshake_proxy(void) +{ + pdebug("Handshaking through proxy", DEBUG); + if (!proxy_server) + { + pdebug("No proxy specified", DEBUG); + sc_hs_errors++; + sc_free_res(); + return -1; + } + pdebug(proxy_server, DEBUG); + int status; char buf[4096]; CURL *curl; @@ -240,6 +316,8 @@ static int sc_handshake(void) curl_easy_setopt(curl, CURLOPT_URL, buf); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, sc_store_res); + curl_easy_setopt(curl, CURLOPT_PROXY, proxy_server); + memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf)); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); @@ -399,7 +477,7 @@ static int sc_generateentry(GString *sub i = 0; #ifdef ALLOW_MULTIPLE q_peekall(1); - while ((item = q_peekall(0)) && i < 10) { + while ((item = q_peekall(0)) /* && i < 10 */ ) { #else item = q_peek(); #endif @@ -427,6 +505,76 @@ static int sc_generateentry(GString *sub static int sc_submitentry(gchar *entry) { + pdebug("Submitting directly", DEBUG); + CURL *curl; + /* struct HttpPost *post = NULL , *last = NULL; */ + int status; + GString *submission; + + curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_URL, sc_submit_url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, + sc_store_res); + curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + /*cfa(&post, &last, "debug", "failed");*/ + + /*pdebug(fmt_vastr("Username: %s", sc_username), DEBUG);*/ + submission = g_string_new("u="); + g_string_append(submission,(gchar *)sc_username); + + /*pdebug(fmt_vastr("Response Hash: %s", sc_response_hash), DEBUG);*/ + g_string_append(submission,"&s="); + g_string_append(submission,(gchar *)sc_response_hash); + + g_string_append(submission, entry); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *)submission->str); + memset(sc_curl_errbuf, 0, sizeof(sc_curl_errbuf)); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sc_curl_errbuf); + + /* + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, SCROBBLER_SB_WAIT); + */ + + status = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + g_string_free(submission,TRUE); + + if (status) { + pdebug(sc_curl_errbuf, DEBUG); + sc_sb_errors++; + sc_free_res(); + return -1; + } + + if (sc_parse_sb_res()) { + sc_sb_errors++; + sc_free_res(); + pdebug(fmt_vastr("Retrying in %d secs, %d elements in queue", + sc_submit_interval, q_len()), DEBUG); + return -1; + } + sc_free_res(); + return 0; +} + +static int sc_submitentry_proxy(gchar *entry) +{ + pdebug("Submitting through proxy", DEBUG); + if (!proxy_server) + { + pdebug("No proxy specified", DEBUG); + sc_sb_errors++; + sc_free_res(); + return -1; + } + pdebug(proxy_server, DEBUG); + CURL *curl; /* struct HttpPost *post = NULL , *last = NULL; */ int status; @@ -439,6 +587,7 @@ static int sc_submitentry(gchar *entry) sc_store_res); curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + curl_easy_setopt(curl, CURLOPT_PROXY, proxy_server); /*cfa(&post, &last, "debug", "failed");*/ /*pdebug(fmt_vastr("Username: %s", sc_username), DEBUG);*/ @@ -527,6 +676,30 @@ static void sc_handlequeue(pthread_mutex sc_sb_errors = 0; } + else + { + if(!sc_submitentry_proxy(submitentry->str)) + { + pthread_mutex_lock(&mutex); + +#ifdef ALLOW_MULTIPLE + q_free(); +#else + q_get(); +#endif + /* + * This should make sure that the queue doesn't + * get submitted multiple times on a nasty + * segfault... + */ + dump_queue(); + + pthread_mutex_unlock(&mutex); + + sc_sb_errors = 0; + } + + } if(sc_sb_errors) { if(sc_sb_errors < 5) @@ -707,7 +880,9 @@ static void sc_checkhandshake(void) return; if (sc_hs_timeout < time(NULL)) { - sc_handshake(); + if (sc_handshake()) + sc_handshake_proxy(); + if(sc_hs_errors) { diff -urp xmms-scrobbler-0.3.8.1/scrobbler.h xmms-scrobbler-0.3.8.1-proxy/scrobbler.h --- xmms-scrobbler-0.3.8.1/scrobbler.h 2004-09-11 10:27:03.000000000 +0700 +++ xmms-scrobbler-0.3.8.1-proxy/scrobbler.h 2006-07-06 17:31:42.000000000 +0700 @@ -7,4 +7,6 @@ void sc_cleaner(void); int sc_catch_error(void); char *sc_fetch_error(void); void sc_clear_error(void); + +extern char* proxy_server; #endif diff -urp xmms-scrobbler-0.3.8.1/tags/include/unicode.h xmms-scrobbler-0.3.8.1-proxy/tags/include/unicode.h --- xmms-scrobbler-0.3.8.1/tags/include/unicode.h 2004-03-29 00:34:56.000000000 +0700 +++ xmms-scrobbler-0.3.8.1-proxy/tags/include/unicode.h 2006-07-06 17:14:05.000000000 +0700 @@ -26,4 +26,6 @@ void iso88591_to_utf8(unsigned char *, s void utf16bom_to_utf8(unsigned char *, size_t, unsigned char **); void utf16be_to_utf8(unsigned char *, size_t, unsigned char **); void utf16le_to_utf8(unsigned char *, size_t, unsigned char **); + +extern char *tags_encoding; #endif diff -urp xmms-scrobbler-0.3.8.1/tags/unicode.c xmms-scrobbler-0.3.8.1-proxy/tags/unicode.c --- xmms-scrobbler-0.3.8.1/tags/unicode.c 2004-03-29 01:15:37.000000000 +0700 +++ xmms-scrobbler-0.3.8.1-proxy/tags/unicode.c 2006-07-06 17:14:05.000000000 +0700 @@ -21,9 +21,84 @@ #include #include #include +#include +#include +#include #include "include/endian.h" #include "include/unicode.h" +char *tags_encoding = NULL; + +/* + * generic iconv function + * taken from gentoo libxmms - looks nice and works + * + * Tue Dec 13 22:15:06 CET 2005 - Kosma Moczek + */ +static char* generic_iconv(const unsigned char *string, size_t insize, char *from, char *to) +{ + size_t outleft, outsize; + iconv_t cd; + char *out, *outptr; + char *input = (char *) string; + + if (!string) return NULL; + +// g_message("converting %s from %s to %s (%u)", string, from, to, insize); + + /* check if the conversion is needed */ + if (!strcmp(from,to)) return g_strdup(string); + + if ((cd = iconv_open(to, from)) == (iconv_t)-1) + { + g_warning("convert_string(): Conversion not supported. " + "Charsets: %s -> %s", from, to); + return g_strdup(string); + } + + /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */ + /* + 1 for nul in case len == 1 */ + outsize = ((insize + 3) & ~3) + 1; + out = g_malloc(outsize); + outleft = outsize - 1; + outptr = out; + + retry: + if (iconv(cd, &input, &insize, &outptr, &outleft) == -1) + { + int used; + switch (errno) + { + case E2BIG: + used = outptr - out; + outsize = (outsize - 1) * 2 + 1; + out = g_realloc(out, outsize); + outptr = out + used; + outleft = outsize - 1 - used; + goto retry; + case EINVAL: + /* incomplete multibyte sequence (at the end of string) + * - just quit, nothing to do here */ + break; + case EILSEQ: + /* Invalid sequence, try to get the + rest of the string */ + input++; + insize--; + goto retry; + default: + g_warning("convert_string(): Conversion failed. " + "Inputstring: %s; Error: %s", + string, strerror(errno)); + break; + } + } + *outptr = '\0'; + + iconv_close(cd); + return out; +} + wchar_t *utf8_to_wchar(unsigned char *utf, size_t memsize) { int i, j = 0; @@ -141,6 +216,12 @@ unsigned char *wchar_to_utf8(wchar_t *wc void iso88591_to_utf8(unsigned char *iso, size_t memsize, unsigned char **utf) { + /* don't run recoder of setting is incomplete */ + if (tags_encoding && *tags_encoding) { + *utf = generic_iconv(iso, memsize, tags_encoding, "UTF-8"); + return; + } + int i; wchar_t *wchar; diff -urp xmms-scrobbler-0.3.8.1/xmms_scrobbler.c xmms-scrobbler-0.3.8.1-proxy/xmms_scrobbler.c --- xmms-scrobbler-0.3.8.1/xmms_scrobbler.c 2005-02-21 07:25:47.000000000 +0600 +++ xmms-scrobbler-0.3.8.1-proxy/xmms_scrobbler.c 2006-07-06 18:17:07.000000000 +0700 @@ -59,7 +59,7 @@ static GeneralPlugin xmms_scrobbler = static void init(void) { - char *username = NULL, *password = NULL; + char *username = NULL, *password = NULL, *encoding = NULL, *proxy = NULL; ConfigFile *cfgfile; going = 1; @@ -68,6 +68,10 @@ static void init(void) &username); xmms_cfg_read_string(cfgfile, "audioscrobbler", "password", &password); + xmms_cfg_read_string(cfgfile, "audioscrobbler", "encoding", + &encoding); + xmms_cfg_read_string(cfgfile, "audioscrobbler", "proxy", + &proxy); xmms_cfg_free(cfgfile); } if ((!username || !password) || (!*username || !*password)) { @@ -76,6 +80,26 @@ static void init(void) going = 0; return; } + if (encoding) { + tags_encoding = g_strdup(encoding); + g_free(encoding); + } + if (proxy) { + proxy_server = g_strdup(proxy); + g_free(proxy); + pdebug(fmt_vastr("Got proxy %s from cfg", proxy_server), DEBUG); + } + else + { + proxy_server = getenv("HTTP_PROXY"); + if (proxy_server) { + pdebug(fmt_vastr("Got proxy %s from getenv(\"HTTP_PROXY\")", + proxy_server), DEBUG); + } else { + pdebug("No proxy specified", DEBUG); + } + } + sc_init(username, password); g_free(username); g_free(password);