void debug_mprintf (mchar* fmt, ...) { int was_open = 1; va_list argptr; int rc; mchar mbuf[DEBUG_BUF_LEN]; char cbuf[DEBUG_BUF_LEN]; if (!debug_on) return; if (!debug_initialized) { m_debug_lock = threadlib_create_sem(); threadlib_signal_sem(&m_debug_lock); } threadlib_waitfor_sem (&m_debug_lock); va_start (argptr, fmt); if (!gcsfp) { was_open = 0; debug_open(); if (!gcsfp) return; } if (!debug_initialized) { debug_initialized = 1; fprintf (gcsfp, "=========================\n"); fprintf (gcsfp, "STREAMRIPPER " SRPLATFORM " " SRVERSION "\n"); } #if defined HAVE_WCHAR_SUPPORT rc = vswprintf (mbuf, DEBUG_BUF_LEN, fmt, argptr); debug_on = 0; /* Avoid recursive call which hangs on semaphore */ rc = string_from_mstring (cbuf, DEBUG_BUF_LEN, mbuf, CODESET_LOCALE); debug_on = 1; #else rc = vsnprintf (cbuf, DEBUG_BUF_LEN, fmt, argptr); #endif fwrite (cbuf, 1, rc, gcsfp); fflush (gcsfp); va_end (argptr); if (!was_open) { debug_close (); } threadlib_signal_sem (&m_debug_lock); }
void rip_manager_stop (RIP_MANAGER_INFO *rmi) { // Make sure this function isn't getting called twice if (!rmi->started) { debug_printf ("rip_manager_stop() called while not started\n"); return; } /* Write to pipe so ripping thread will exit select() */ #if __UNIX__ debug_printf ("Writing to abort_pipe.\n"); write (rmi->abort_pipe[1], "0", 1); #endif // Make sure the ripping started before we try to stop debug_printf ("Waiting for m_started_sem...\n"); threadlib_waitfor_sem(&rmi->started_sem); rmi->started = 0; // Causes the code running in the thread to bail debug_printf ("Closing stream_sock...\n"); socklib_close(&rmi->stream_sock); // Kill external process if (rmi->ep) { debug_printf ("Close external\n"); close_external (&rmi->ep); } // blocks until everything is ok and closed debug_printf ("Waiting for hthread_ripper to close...\n"); threadlib_waitforclose(&rmi->hthread_ripper); debug_printf ("Destroying subsystems...\n"); destroy_subsystems (rmi); debug_printf ("Destroying m_started_sem\n"); threadlib_destroy_sem(&rmi->started_sem); debug_printf ("Done with rip_manager_stop\n"); /* Close pipes */ #if __UNIX__ debug_printf ("Closing abort_pipe.\n"); close (rmi->abort_pipe[0]); close (rmi->abort_pipe[1]); #endif }
void thread_send (void* arg) { RELAY_LIST* prev; RELAY_LIST* ptr; RELAY_LIST* next; int sock; BOOL good; error_code err = SR_SUCCESS; RIP_MANAGER_INFO* rmi = (RIP_MANAGER_INFO*) arg; RELAYLIB_INFO* rli = &rmi->relaylib_info; while (rli->m_running) { threadlib_waitfor_sem (&rmi->relay_list_sem); ptr = rmi->relay_list; if (ptr != NULL) { prev = NULL; while (ptr != NULL) { sock = ptr->m_sock; next = ptr->m_next; if (swallow_receive(sock) != 0) { good = FALSE; } else { good = send_to_relay (rmi, ptr); } if (!good) { debug_printf ("Relay: Client %d disconnected (%s)\n", sock, strerror(errno)); relaylib_disconnect (rmi, prev, ptr); } else if (ptr != NULL) { prev = ptr; } ptr = next; } } else { err = SR_ERROR_HOST_NOT_CONNECTED; } threadlib_signal_sem (&rmi->relay_list_sem); Sleep (50); } rli->m_running_send = FALSE; }
debug_printf (char* fmt, ...) #endif { int was_open = 1; va_list argptr; if (!debug_on) { /* Uncomment to debug debug_mprintf() */ #if defined (commentout) va_start (argptr, fmt); vprintf (fmt, argptr); va_end (argptr); #endif return; } if (!debug_initialized) { m_debug_lock = threadlib_create_sem(); threadlib_signal_sem(&m_debug_lock); } threadlib_waitfor_sem (&m_debug_lock); va_start (argptr, fmt); if (!gcsfp) { was_open = 0; debug_open(); if (!gcsfp) return; } if (!debug_initialized) { debug_initialized = 1; fprintf (gcsfp, "=========================\n"); fprintf (gcsfp, "STREAMRIPPER " SRPLATFORM " " SRVERSION "\n"); } vfprintf (gcsfp, fmt, argptr); fflush (gcsfp); va_end (argptr); if (!was_open) { debug_close (); } threadlib_signal_sem (&m_debug_lock); }
static void destroy_all_hostsocks (RIP_MANAGER_INFO* rmi) { RELAY_LIST* ptr; threadlib_waitfor_sem (&rmi->relay_list_sem); while (rmi->relay_list != NULL) { ptr = rmi->relay_list; closesocket(ptr->m_sock); rmi->relay_list = ptr->m_next; if (ptr->m_buffer != NULL) { free (ptr->m_buffer); ptr->m_buffer = NULL; } free(ptr); } rmi->relay_list_len = 0; rmi->relay_list = NULL; threadlib_signal_sem (&rmi->relay_list_sem); }
void debug_printf(char *fmt, ...) { int was_open = 1; va_list argptr; if (!debug_on) { return; } if (!debug_initialized) { m_debug_lock = threadlib_create_sem(); threadlib_signal_sem(&m_debug_lock); } threadlib_waitfor_sem(&m_debug_lock); va_start(argptr, fmt); if (!gcsfp) { was_open = 0; debug_open(); if (!gcsfp) return; } if (!debug_initialized) { debug_initialized = 1; fprintf(gcsfp, "=========================\n"); fprintf(gcsfp, "STREAMRIPPER " SRPLATFORM " " SRVERSION "\n"); } vfprintf(gcsfp, fmt, argptr); fflush(gcsfp); va_end(argptr); if (!was_open) { debug_close(); } threadlib_signal_sem(&m_debug_lock); }
void thread_accept (void* arg) { int ret; int newsock; BOOL good; struct sockaddr_in client; socklen_t iAddrSize = sizeof(client); RELAY_LIST* newhostsock; int icy_metadata; char* client_http_header; RIP_MANAGER_INFO* rmi = (RIP_MANAGER_INFO*) arg; RELAYLIB_INFO* rli = &rmi->relaylib_info; STREAM_PREFS* prefs = rmi->prefs; int have_metadata; if (rmi->http_info.meta_interval == NO_META_INTERVAL) { have_metadata = 0; } else { have_metadata = 1; } debug_printf("thread_accept:start\n"); while (rli->m_running) { fd_set fds; struct timeval tv; // this event will keep use from accepting while we // have a connection active // when a connection gets dropped, or when streamripper shuts down // this event will get signaled debug_printf("thread_accept:waiting on m_sem_not_connected\n"); threadlib_waitfor_sem (&rli->m_sem_not_connected); if (!rli->m_running) { debug_printf("thread_accept:exit (no longer m_running)\n"); break; } // Poll once per second, instead of blocking forever in // accept(), so that we can regain control if relaylib_stop() // called FD_ZERO (&fds); while (rli->m_listensock != SOCKET_ERROR && rli->m_running) { FD_SET (rli->m_listensock, &fds); tv.tv_sec = 1; tv.tv_usec = 0; debug_printf("thread_accept:calling select()\n"); ret = select (rli->m_listensock + 1, &fds, NULL, NULL, &tv); debug_printf("thread_accept:select() returned %d\n", ret); if (ret == 1) { unsigned long num_connected; /* If connections are full, do nothing. Note that m_max_connections is 0 for infinite connections allowed. */ threadlib_waitfor_sem (&rmi->relay_list_sem); num_connected = rmi->relay_list_len; threadlib_signal_sem (&rmi->relay_list_sem); if (prefs->max_connections > 0 && num_connected >= (unsigned long) prefs->max_connections) { continue; } /* Check for connections */ debug_printf ("Calling accept()\n"); newsock = accept (rli->m_listensock, (struct sockaddr *)&client, &iAddrSize); if (newsock != SOCKET_ERROR) { // Got successful accept debug_printf ("Relay: Client %d new from %s:%hu\n", newsock, inet_ntoa(client.sin_addr), ntohs(client.sin_port)); // Socket is new and its buffer had better have // room to hold the entire HTTP header! good = FALSE; if (header_receive (newsock, &icy_metadata) == 0 && rmi->cbuf2.buf != NULL) { int header_len; make_nonblocking (newsock); client_http_header = client_relay_header_generate (rmi, icy_metadata); header_len = strlen (client_http_header); ret = send (newsock, client_http_header, strlen(client_http_header), 0); debug_printf ("Relay: Sent response header to client %d (%d)\n", ret, header_len); client_relay_header_release (client_http_header); if (ret == header_len) { newhostsock = malloc (sizeof(RELAY_LIST)); if (newhostsock != NULL) { // Add new client to list (headfirst) threadlib_waitfor_sem (&rmi->relay_list_sem); newhostsock->m_is_new = 1; newhostsock->m_sock = newsock; newhostsock->m_next = rmi->relay_list; if (have_metadata) { newhostsock->m_icy_metadata = icy_metadata; } else { newhostsock->m_icy_metadata = 0; } rmi->relay_list = newhostsock; rmi->relay_list_len++; threadlib_signal_sem (&rmi->relay_list_sem); good = TRUE; } } } if (!good) { closesocket (newsock); debug_printf ("Relay: Client %d disconnected (Unable to receive HTTP header) or cbuf2.buf is NULL\n", newsock); //if (rmi->cbuf2.buf == NULL) { // debug_printf ("In fact, cbuf2.buf is NULL\n"); //} } } } else if (ret == SOCKET_ERROR) { /* Something went wrong with select */ break; } } threadlib_signal_sem (&rli->m_sem_not_connected); /* loop back up to select */ } rli->m_running_accept = FALSE; rli->m_running = FALSE; }