예제 #1
0
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);
}
예제 #2
0
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
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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);
}
예제 #7
0
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;
}