unsigned int cache_get_meta_playlist_revision(){ unsigned int revision; /* Build cache filename. */ snprintf(cache_filename, PATH_MAX, "%s/meta_playlist_revision", cache_directory); /* Try to open file for reading. */ FILE *file = fopen(cache_filename, "r"); if(!file){ DSFYDEBUG("Error opening file in read-mode.\n"); return 0; } /* Write data to file. */ if(fread(&revision, sizeof(unsigned int), 1, file) != 1){ DSFYDEBUG("Error reading meta playlist revision.\n"); return 0; } fclose(file); return revision; }
int read_server_auth_response (SESSION * session) { unsigned char buf[256]; unsigned char payload_len; int ret; ret = block_read(session->ap_sock, buf, 2); if (ret != 2) { DSFYDEBUG("Failed to read 'status' + length byte, got %d bytes\n", ret); return -1; } if (buf[0] != 0x00) { DSFYDEBUG("Authentication failed with error 0x%02x, bad password?\n", buf[1]); return -1; } /* Payload length + this byte must not be zero(?) */ assert (buf[1] > 0); payload_len = buf[1]; ret = block_read (session->ap_sock, buf, payload_len); if (ret != payload_len) { DSFYDEBUG("Failed to read 'payload', got %d of %u bytes\n", ret, payload_len); return -1; } #ifdef DEBUG_LOGIN hexdump8x32 ("read_server_auth_response, payload", buf, payload_len); #endif return 0; }
int handle_secret_block (SESSION * session, unsigned char *payload, int len) { unsigned int *t; if (len != 336) { DSFYDEBUG ("Got cmd=0x02 with len %d, expected 336!\n", len); return -1; } t = (unsigned int *) payload; DSFYDEBUG ("Initial time %u (%ld seconds from now)\n", ntohl (*t), time (NULL) - ntohl (*t)); t++; DSFYDEBUG ("Future time %u (%ld seconds in the future)\n", ntohl (*t), ntohl (*t) - time (NULL)); t++; DSFYDEBUG ("Next value is %u\n", ntohl (*t)); t++; DSFYDEBUG ("Next value is %u\n", ntohl (*t)); assert (memcmp (session->rsa_pub_exp, payload + 16, 128) == 0); /* At payload+16+128 is a 144 bytes (1536-bit) RSA signature */ /* * Actually the cache hash is sent before the server has sent any * packets. It's just put here out of convenience, because this is * one of the first packets ever by the server, and also not * repeated during a session. * */ return cmd_send_cache_hash (session); }
/* Initialize sound session, called once */ bool snd_init(struct despotify_session *ds) { DSFYDEBUG ("Initializing sound FIFO etc (happens once)\n"); DSFYDEBUG("Setting state to DL_FILLING\n"); ds->dlstate = DL_FILLING; /* This is the fifo that will hold fragments of compressed audio */ ds->fifo = calloc(1, sizeof(struct ds_snd_fifo)); if (!ds->fifo) return false; ds->fifo->maxbytes = 1024 * 1024; /* 1 MB default buffer size */ ds->fifo->watermark = 200 * 1024; /* 200 KB default watermark */ if (pthread_mutex_init (&ds->fifo->lock, NULL)) { DSFYfree (ds->fifo); return NULL; } if (pthread_cond_init (&ds->fifo->cs, NULL)) { DSFYfree (ds->fifo); pthread_mutex_destroy (&ds->fifo->lock); return NULL; } return true; }
static void snd_fill_fifo(struct despotify_session* ds) { if (ds->dlabort) { while (ds->dlstate == DL_FILLING_BUSY) { DSFYDEBUG("dlstate = %d. waiting...\n", ds->dlstate); shortsleep(); } ds->dlstate = DL_DRAINING; return; } switch (ds->dlstate) { case DL_DRAINING: if (ds->fifo->totbytes < ds->fifo->watermark ) { DSFYDEBUG("Low on data (%d / %d), fetching another channel\n", ds->fifo->totbytes, ds->fifo->maxbytes); DSFYDEBUG("dlstate = DL_FILLING_BUSY\n"); ds->dlstate = DL_FILLING_BUSY; despotify_snd_read_stream(ds); } break; case DL_FILLING: if (ds->fifo->totbytes < (ds->fifo->maxbytes - SUBSTREAM_SIZE)) { DSFYDEBUG("dlstate = DL_FILLING_BUSY\n"); ds->dlstate = DL_FILLING_BUSY; despotify_snd_read_stream(ds); } else { DSFYDEBUG("buffer filled. setting dlstate DL_DRAINING\n"); ds->dlstate = DL_DRAINING; } break; } }
/* Free a login context */ void login_release(struct login_ctx *l) { /* Only close the socket if an error occurred */ if(l->error != SP_LOGIN_ERROR_OK && l->sock != -1) { DSFYDEBUG("Closing open socket %d, login error was %d\n", l->sock, l->error); #ifdef _WIN32 closesocket(l->sock); #else close(l->sock); #endif } if(l->service_records) dns_free_list(l->service_records); if(l->server_ai != NULL) freeaddrinfo(l->server_ai); RSA_free(l->rsa); DH_free(l->dh); if(l->client_parameters) buf_free(l->client_parameters); if(l->server_parameters) buf_free(l->server_parameters); free(l); DSFYDEBUG("Done free'ing login context\n"); }
DWORD __stdcall openspotify_thread(LPVOID *arg) { MSG msg; WNDCLASS wcOpenspotify; ATOM wc; hwndLibraryParent = (HWND)arg; DSFYDEBUG("Ping from thread\n"); /* Create a window to communicate with the plugin, playlist view and Winamp */ memset(&wcOpenspotify, 0, sizeof(WNDCLASS)); wcOpenspotify.lpszClassName = L"ml_openspotify"; wcOpenspotify.lpfnWndProc = wndproc; wc = RegisterClass(&wcOpenspotify); m_hWnd = CreateWindow(szAppName, L"ml_openspotify message sink", 0, 0, 0, 0, 0, hwndLibraryParent, NULL, 0, 0); DSFYDEBUG("Created window at %p\n", m_hWnd); if(openspotify_init() < 0) { DSFYDEBUG("Failed to initialize libopenspotify\n"); PostQuitMessage(0); } DSFYDEBUG("Openspotify initialized, now dispatching messages\n"); while(GetMessage(&msg, 0, 0, 0) == TRUE) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
static void event_loop(sp_session *session) { int timeout = -1; #ifndef _WIN32 sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGIO); #endif while (g_exit_code < 0) { #ifndef _WIN32 pthread_sigmask(SIG_BLOCK, &sigset, NULL); #endif DSFYDEBUG("Calling sp_session_process_events()\n"); sp_session_process_events(session, &timeout); if(test_run() < 0) { DSFYDEBUG("Done running test, existing event loop\n"); break; } #ifdef _WIN32 WaitForSingleObject(g_notify_event, timeout); #else pthread_sigmask(SIG_UNBLOCK, &sigset, NULL); usleep(timeout * 1000); #endif } DSFYDEBUG("Exiting from loop()\n"); }
int send_client_auth (SESSION * session) { int ret; struct buf* buf = buf_new(); buf_append_data(buf, session->auth_hmac, 20); buf_append_u8(buf, 0); /* random data length */ buf_append_u8(buf, 0); /* unknown */ buf_append_u16(buf, 8); /* puzzle solution length */ buf_append_u32(buf, 0); /* <-- random data would go here */ buf_append_data (buf, session->puzzle_solution, 8); #ifdef DEBUG_LOGIN hexdump8x32 ("send_client_auth, second client packet", buf->ptr, buf->len); #endif ret = send(session->ap_sock, buf->ptr, buf->len, 0); if (ret <= 0) { DSFYDEBUG("send_client_auth(): connection lost\n"); buf_free(buf); return -1; } else if (ret != buf->len) { DSFYDEBUG("send_client_auth(): only wrote %d of %d bytes\n", ret, buf->len); buf_free(buf); return -1; } buf_free(buf); return 0; }
int send_client_initial_packet (SESSION * session) { int ret; unsigned int len_idx; struct buf* b = buf_new(); buf_append_u16 (b, 3); /* protocol version */ len_idx = b->len; buf_append_u16(b, 0); /* packet length - updated later */ buf_append_u32(b, 0x00000300); /* unknown */ buf_append_u32(b, 0x00030c00); /* unknown */ buf_append_u32(b, session->client_revision); buf_append_u32(b, 0); /* unknown */ buf_append_u32(b, 0x01000000); /* unknown */ buf_append_data(b, session->client_id, 4); buf_append_u32(b, 0); /* unknown */ buf_append_data (b, session->client_random_16, 16); buf_append_data (b, session->my_pub_key, 96); BN_bn2bin (session->rsa->n, session->rsa_pub_exp); buf_append_data (b, session->rsa_pub_exp, sizeof(session->rsa_pub_exp)); buf_append_u8 (b, 0); /* length of random data */ buf_append_u8 (b, session->username_len); buf_append_u16(b, 0x0100); /* unknown */ /* <-- random data would go here */ buf_append_data (b, (unsigned char *) session->username, session->username_len); buf_append_u8 (b, 0x40); /* unknown */ /* * Update length bytes * */ b->ptr[len_idx] = (b->len >> 8) & 0xff; b->ptr[len_idx+1] = b->len & 0xff; #ifdef DEBUG_LOGIN hexdump8x32 ("initial client packet", b->ptr, b->len); #endif ret = send (session->ap_sock, b->ptr, b->len, 0); if (ret <= 0) { DSFYDEBUG("connection lost\n"); buf_free(b); return -1; } else if (ret != b->len) { DSFYDEBUG("only wrote %d of %d bytes\n", ret, b->len); buf_free(b); return -1; } /* save initial server packet for auth hmac generation */ session->init_client_packet = b; return 0; }
static int osfy_artistbrowse_browse_callback(struct browse_callback_ctx *brctx) { sp_artistbrowse *arb; int i; struct buf *xml; ezxml_t root; for(i = 0; i < brctx->num_in_request; i++) { arb = brctx->data.artistbrowses[brctx->num_browsed + i]; /* Set defaults */ arb->is_loaded = 0; arb->error = SP_ERROR_OTHER_TRANSIENT; } /* Might happen because of a channel error */ if(brctx->buf == NULL) return 0; xml = despotify_inflate(brctx->buf->ptr, brctx->buf->len); #ifdef DEBUG { FILE *fd; DSFYDEBUG("Decompresed %d bytes data, xml=%p\n", brctx->buf->len, xml); fd = fopen("browse-artistbrowse.xml", "w"); if(fd) { fwrite(xml->ptr, xml->len, 1, fd); fclose(fd); } } #endif root = ezxml_parse_str((char *) xml->ptr, xml->len); if(root == NULL) { DSFYDEBUG("Failed to parse XML\n"); buf_free(xml); return -1; } for(i = 0; i < brctx->num_in_request; i++) { arb = brctx->data.artistbrowses[brctx->num_browsed + i]; osfy_artistbrowse_load_from_xml(brctx->session, arb, root); arb->is_loaded = 1; arb->error = SP_ERROR_OK; } ezxml_free(root); buf_free(xml); /* Release references made in sp_artistbrowse_create() */ for(i = 0; i < brctx->num_in_request; i++) sp_artistbrowse_release(brctx->data.artistbrowses[brctx->num_browsed + i]); return 0; }
int packet_read (SESSION * session, PHEADER * h, unsigned char **payload) { int ret; int packet_len; unsigned char nonce[4]; unsigned char *ptr; packet_len = 0; if ((ret = block_read (session->ap_sock, h, 3)) != 3) { DSFYDEBUG ("packet_read(): read short count %d, expected 3 (header)\n", ret); return -1; } *(unsigned int *) nonce = htonl (session->key_recv_IV); shn_nonce (&session->shn_recv, nonce, 4); shn_decrypt (&session->shn_recv, (unsigned char *) h, 3); #ifdef DEBUG_PACKETS DSFYDEBUG ("packet_read(): cmd=%d [0x%02x], len=%d [0x%04x]\n", h->cmd, h->cmd, ntohs (h->len), ntohs (h->len)); logdata ("recv-hdr", session->key_recv_IV, (unsigned char *) h, 3); #endif /* Length of payload */ h->len = ntohs (h->len); packet_len = h->len; /* Account for MAC */ packet_len += 4; ptr = (unsigned char *) malloc (packet_len); if ((*payload = ptr) == NULL) return -1; if ((ret = block_read (session->ap_sock, ptr, packet_len)) != packet_len) { DSFYDEBUG ("packet_read(cmd=0x%02x): read short count %d, expected %d\n", h->cmd, ret, packet_len); return -1; } shn_decrypt (&session->shn_recv, *payload, packet_len); #ifdef DEBUG_PACKETS logdata ("recv-dec", session->key_recv_IV, *payload, h->len); #endif /* Increment IV */ session->key_recv_IV++; return 0; }
int session_connect (SESSION * session) { struct sockaddr_in sin; char host[1025 + 1], *service_list, *service; int port; /* Lookup service hosts in DNS */ service_list = dns_srv_list ("_spotify-client._tcp.spotify.com"); if (!service_list) { DSFYDEBUG("service lookup failed. falling back to ap.spotify.com\n"); service_list = malloc(200); strcpy(service_list, "ap.spotify.com:4070\n"); } for (service = service_list; *service;) { if (sscanf (service, "%[^:]:%d\n", host, &port) != 2) return -1; service += strlen (host) + 7; DSFYDEBUG ("session_connect(): Connecting to %s:%d\n", host, port); memset (&sin, 0, sizeof (sin)); sin.sin_family = PF_INET; sin.sin_port = htons (port); sin.sin_addr.s_addr = dns_resolve_name (host); if (sin.sin_addr.s_addr == INADDR_NONE) continue; session->ap_sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (connect (session->ap_sock, (struct sockaddr *) &sin, sizeof (sin)) != -1) break; sock_close (session->ap_sock); session->ap_sock = -1; } free (service_list); if (sin.sin_addr.s_addr == INADDR_NONE) return -1; /* * Save for later use in ConnectionInfo message * (too lazy to do getpeername() later ;) */ DSFYstrncpy (session->server_host, host, sizeof session->server_host); session->server_port = port; DSFYstrncpy (session->user_info.server_host, host, sizeof session->user_info.server_host); session->user_info.server_port = port; return 0; }
int packet_write (SESSION * session, unsigned char cmd, unsigned char *payload, unsigned short len) { unsigned char nonce[4]; unsigned char *buf, *ptr; PHEADER *h; int ret; *(unsigned int *) nonce = htonl (session->key_send_IV); shn_nonce (&session->shn_send, nonce, 4); buf = (unsigned char *) malloc (3 + len + 4); h = (PHEADER *) buf; h->cmd = cmd; h->len = htons (len); ptr = buf + 3; if (payload != NULL) { memcpy (ptr, payload, len); } #ifdef DEBUG_PACKETS DSFYDEBUG ("packet_write(): Sending packet with command 0x%02x, length %d\n", h->cmd, ntohs (h->len)); logdata ("send-hdr", session->key_send_IV, (unsigned char *) h, 3); if (payload != NULL) logdata ("send-payload", session->key_send_IV, payload, len); #endif shn_encrypt (&session->shn_send, buf, 3 + len); ptr += len; shn_finish (&session->shn_send, ptr, 4); ret = block_write (session->ap_sock, buf, 3 + len + 4); free(buf); session->key_send_IV++; if(ret != 3 + len + 4) { #ifdef DEBUG_PACKETS DSFYDEBUG ("packet_write(): only wrote %d of %d bytes\n", ret, 3 + len + 4); #endif return -1; } return 0; }
static void SP_CALLCONV logged_in(sp_session *session, sp_error error) { DSFYDEBUG("SESSION CALLBACK\n"); if (SP_ERROR_OK != error) { fprintf(stderr, "failed to log in to Spotify: %s\n", sp_error_message(error)); g_exit_code = 4; return; } DSFYDEBUG("Running session_ready()\n"); session_ready(session); }
static LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static char *username, *password; switch(uMsg) { case WM_TIMER: DSFYDEBUG("uMsg=%u (%s), wParam=%u, lParam=%u\n", uMsg, WM2STR(uMsg), wParam, lParam); if(session) { int timeout; KillTimer(hwnd, TIMERID); sp_session_process_events(session, &timeout); SetTimer(hwnd, TIMERID, timeout, NULL); } break; case WM_USER: switch(LOWORD(wParam)) { case 1: // Set tree root ID m_TreeRootId = (UINT_PTR)lParam; break; case 2: // Set username username = (char *)lParam; DSFYDEBUG("Got username '%s'\n", username); break; case 3: // Set password password = (char *)lParam; DSFYDEBUG("Got password '%s'\n", password); break; case 4: // Login if not yet logged in if(sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) sp_session_login(session, username, password); break; case 5: // Get connection status if(!session) return -1; else if(sp_session_connectionstate(session) != SP_CONNECTION_STATE_LOGGED_IN) return -1; return 0; } break; } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
static void SP_CALLCONV pc_playlist_added(sp_playlistcontainer *pc, sp_playlist *playlist, int position, void *userdata) { static sp_playlist_callbacks *callbacks; MLTREEITEM item; if(callbacks == NULL) { callbacks = (sp_playlist_callbacks *)malloc(sizeof(sp_playlist_callbacks)); memset(callbacks, 0, sizeof(sp_playlist_callbacks)); callbacks->tracks_added = pl_tracks_added; callbacks->playlist_renamed = playlist_renamed; } /* Snoop on the playlist to know when it's named and tracks are added */ sp_playlist_add_callbacks(playlist, callbacks, NULL); /* Add playlist to our Media Library tree */ item.size = sizeof(MLTREEITEM); item.parentId = m_TreeRootId; item.hasChildren = 0; item.id = 0; item.imageIndex = 0; item.title = "(Loading...)"; /* Create a new entry in under our tree in the Media Library pane */ SendMessage(hwndLibraryParent, WM_ML_IPC, (WPARAM) &item, ML_IPC_TREEITEM_ADD); DSFYDEBUG("New id of entry '%s' is '%u'\n", item.title, item.id); /* Add mapping between tree ID and playlist position in playlist container */ tpAdd(item.id, position); }
void SP_CALLCONV playlist_renamed(sp_playlist *pl, void *userdata) { sp_playlistcontainer *pc = sp_session_playlistcontainer(session); int num = sp_playlistcontainer_num_playlists(pc); int pos; MLTREEITEMINFO treeItemInfo; UINT_PTR treeId, treeHandle; /* Find position of renamed playlist in the playlist container */ for(pos = 0; pos < num; pos++) if(sp_playlistcontainer_playlist(pc, pos) == pl) break; if(pos == num) { DSFYDEBUG("WTF, did not find playlist %p in container!\n", pl); return; } /* Get tree ID so we can get the handle */ treeId = tpGetTreeId(pos); treeHandle = SendMessage(hwndLibraryParent, WM_ML_IPC, (WPARAM)treeId, ML_IPC_TREEITEM_GETHANDLE); /* Create request to update the item */ memset(&treeItemInfo, 0, sizeof(MLTREEITEMINFO)); treeItemInfo.handle = treeHandle; treeItemInfo.mask = MLTI_TEXT; treeItemInfo.item.size = sizeof(MLTREEITEM); treeItemInfo.item.title = (char *)sp_playlist_name(pl); /* Submit request */ SendMessage(hwndLibraryParent, WM_ML_IPC, (WPARAM)&treeItemInfo, ML_IPC_TREEITEM_SETINFO); }
/* Reset for new song */ void snd_reset(struct despotify_session* ds) { DSFYDEBUG("Setting state to DL_DRAINING\n"); ds->fifo->totbytes = 0; ds->dlstate = DL_DRAINING; snd_reset_codec(ds); }
/* * Initialize the Spotify session object, called by openspotify_thread() * */ static int openspotify_init(void) { sp_session_config config; sp_error error; sp_session_callbacks callbacks = { &logged_in, &logged_out, &metadata_updated, &connection_error, NULL, ¬ify_main_thread, NULL, NULL, &log_message }; memset(&config, 0, sizeof(config)); config.api_version = SPOTIFY_API_VERSION; config.cache_location = "tmp"; config.settings_location = "tmp"; config.application_key = g_appkey; config.application_key_size = g_appkey_size; config.user_agent = "ml_openspotify"; config.callbacks = &callbacks; error = sp_session_init(&config, &session); if(error != SP_ERROR_OK) { DSFYDEBUG("sp_session_init() failed with error '%s'\n", sp_error_message(error)); return -1; } return 0; }
static int osfy_image_callback(CHANNEL *ch, unsigned char *payload, unsigned short len) { struct image_ctx *image_ctx = (struct image_ctx *)ch->private; switch(ch->state) { case CHANNEL_DATA: buf_append_data(image_ctx->image->data, payload, len); break; case CHANNEL_ERROR: DSFYDEBUG("Got a channel ERROR, retrying within %d seconds\n", IMAGE_RETRY_TIMEOUT); buf_free(image_ctx->image->data); image_ctx->image->data = NULL; /* Reset timeout so the request can be retried */ image_ctx->req->next_timeout = get_millisecs() + IMAGE_RETRY_TIMEOUT*1000; break; case CHANNEL_END: /* We simply assume we're always getting a JPEG image back */ image_ctx->image->format = SP_IMAGE_FORMAT_JPEG; image_ctx->image->is_loaded = 1; image_ctx->image->error = SP_ERROR_OK; request_set_result(image_ctx->session, image_ctx->req, SP_ERROR_OK, image_ctx->image); free(image_ctx); break; default: break; } return 0; }
SP_LIBEXPORT(sp_error) sp_session_logout (sp_session *session) { DSFYDEBUG("Posting REQ_TYPE_LOGOUT\n"); request_post(session, REQ_TYPE_LOGOUT, NULL); return SP_ERROR_OK; }
sp_image *osfy_image_create(sp_session *session, const byte image_id[20]) { sp_image *image; image = (sp_image *)hashtable_find(session->hashtable_images, image_id); if(image) { { char buf[41]; hex_bytes_to_ascii(image->id, buf, 20); DSFYDEBUG("Returning existing image '%s'\n", buf); } return image; } image = malloc(sizeof(sp_image)); memcpy(image->id, image_id, sizeof(image->id)); image->format = SP_IMAGE_FORMAT_UNKNOWN; image->data = NULL; image->error = SP_ERROR_RESOURCE_NOT_LOADED; image->callback = NULL; image->userdata = NULL; image->is_loaded = 0; image->ref_count = 0; image->hashtable = session->hashtable_images; hashtable_insert(image->hashtable, image->id, image); return image; }
/* Destroy a sound session */ void snd_destroy (snd_SESSION * session) { int ret = 0; oggBUFF *b; DSFYDEBUG ("Destroying sound FIFO etc\n"); /* This will stop any playing sound too */ if (session->actx) ret = audio_context_free (session->actx); /* Free the FIFO */ if (session->fifo) { pthread_mutex_lock(&session->fifo->lock); /*rKA*/ /* free oggBuffs */ while (session->fifo->start) { b = session->fifo->start; session->fifo->start = session->fifo->start->next; DSFYfree (b); } pthread_mutex_unlock(&session->fifo->lock); /*rKA*/ DSFYfree (session->fifo); pthread_cond_destroy (&session->fifo->cs); pthread_mutex_destroy (&session->fifo->lock); } pthread_mutex_destroy (&session->lock); DSFYfree (session); }
/* Reset for new song */ void snd_reset (snd_SESSION * session) { DSFYDEBUG ("snd_reset(): Setting state to DL_IDLE\n"); session->fifo->totbytes = 0; session->dlstate = DL_IDLE; session->buffer_threshold = BUFFER_THRESHOLD; }
int do_auth (SESSION * session) { /* * !! cr4zy 0pp3rtun1ty 2 s4v3 s0m3 pr3c10uz 3n3rgy !@)#&$!@# * * g00gl3 w4z b4d but th1z 1z w0rz3 - w4zt1ng CPU cycl3z f0r * th3 s4k3 0f w4zt1ng th3m & d3l4y1ng th3 l0g1n pr0c3zz, * * 3d1t0rz r3m4rk: * sk1pp1n' th1z l4m3 puzzl3 w0u1d b3 4n 4w3z0m3 * 1Ph0n3 b4tt3ry 0pt1m1z4t10n t3kn1qu3 !! * * b4ckgr0und th30ry * http://google.com/search?q=aura-nikander-leiwo-protocols00.pdf * http://google.com/search?q=005-candolin.pdf * */ puzzle_solve (session); /* * Compute HMAC over random data, public keys, * more random data and finally some username- * related parts * * Key is part of a digest computed in key_init() * */ auth_generate_auth_hmac (session, session->auth_hmac, sizeof (session->auth_hmac)); if (send_client_auth (session)) { DSFYDEBUG("do_auth(): send_client_auth() failed\n"); return -1; } if (read_server_auth_response (session)) { DSFYDEBUG("do_auth(): read_server_auth_response() failed\n"); return -1; } if (session->init_client_packet) buf_free(session->init_client_packet); if (session->init_server_packet) buf_free(session->init_server_packet); return 0; }
unsigned char *cache_load(unsigned char *id, unsigned int *size){ unsigned char *data; unsigned long fsize; /* Build cache filename. */ snprintf(cache_filename, PATH_MAX, "%s/%s", cache_directory, id); /* Try to open file for reading. */ FILE *file = fopen(cache_filename, "r"); if(!file){ DSFYDEBUG("Error opening file in read-mode.\n"); return NULL; } /* Determine file size. */ fseek(file, 0, SEEK_END); fsize = ftell(file); fseek(file, 0L, SEEK_SET); /* Allocate memory. */ data = (unsigned char *)malloc(fsize); if(!data){ DSFYDEBUG("Error allocating memory for cache data.\n"); return NULL; } /* Read data into memory. */ if(fread(data, 1, fsize, file) != fsize){ free(data); DSFYDEBUG("Error reading cache data.\n"); return NULL; } fclose(file); if(size){ *size = fsize; } return data; }
SP_LIBEXPORT(void) sp_artistbrowse_release(sp_artistbrowse *arb) { int i; assert(arb->ref_count > 0); arb->ref_count--; if(arb->ref_count) return; if(arb->artist) { DSFYDEBUG("Unreferencing artist at %p\n", arb->artist); sp_artist_release(arb->artist); } for(i = 0; i < arb->num_tracks; i++) sp_track_release(arb->tracks[i]); if(arb->num_tracks) free(arb->tracks); for(i = 0; i < arb->num_portraits; i++) free(arb->portraits[i]); if(arb->num_portraits) free(arb->portraits); for(i = 0; i < arb->num_similar_artists; i++) sp_artist_release(arb->similar_artists[i]); if(arb->num_similar_artists) free(arb->similar_artists); for(i = 0; i < arb->num_albums; i++) sp_album_release(arb->albums[i]); if(arb->num_albums) free(arb->albums); DSFYDEBUG("Deallocating artistbrowse at %p\n", arb); free(arb); }
/* Initialize sound session, called once */ snd_SESSION *snd_init (void) { snd_SESSION *session; DSFYDEBUG ("snd_init(): Entering..\n"); /* Init session struct */ session = (snd_SESSION *) malloc (sizeof (snd_SESSION)); if (!session) return NULL; session->vf = NULL; session->actx = NULL; session->dlstate = DL_IDLE; session->audio_request = NULL; session->audio_request_arg = NULL; session->buffer_threshold = BUFFER_THRESHOLD; session->audio_end = snd_stop; /* Default is to stop the snd thread */ session->time_tell = NULL; if (pthread_mutex_init (&session->lock, NULL)) { DSFYfree (session); return NULL; } /* This is the queue that will hold fragments of compressed audio */ session->fifo = (oggFIFO *) malloc (sizeof (oggFIFO)); if (!session->fifo) { pthread_mutex_destroy (&session->lock); DSFYfree (session); return NULL; } session->fifo->totbytes = 0; session->fifo->start = NULL; session->fifo->end = NULL; if (pthread_mutex_init (&session->fifo->lock, NULL)) { DSFYfree (session->fifo); pthread_mutex_destroy (&session->lock); DSFYfree (session); return NULL; } if (pthread_cond_init (&session->fifo->cs, NULL) != 0) { pthread_mutex_destroy (&session->fifo->lock); DSFYfree (session->fifo); pthread_mutex_destroy (&session->lock); DSFYfree (session); return NULL; } return session; }
static void SP_CALLCONV notify_main_thread(sp_session *session) { DSFYDEBUG("SESSION CALLBACK\n"); #ifdef _WIN32 PulseEvent(g_notify_event); #else pthread_kill(g_main_thread, SIGIO); #endif }