Пример #1
0
bool repeaterClient::connect ()
{
    int status;

    if ( ! makeSocket ( PORT_ANY, false, & this->sock ) ) {
        char sockErrBuf[64];
        epicsSocketConvertErrnoToString ( 
            sockErrBuf, sizeof ( sockErrBuf ) );
        fprintf ( stderr, "%s: no client sock because \"%s\"\n",
                __FILE__, sockErrBuf );
        return false;
    }

    status = ::connect ( this->sock, &this->from.sa, sizeof ( this->from.sa ) );
    if ( status < 0 ) {
        char sockErrBuf[64];
        epicsSocketConvertErrnoToString ( 
            sockErrBuf, sizeof ( sockErrBuf ) );
        fprintf ( stderr, "%s: unable to connect client sock because \"%s\"\n",
            __FILE__, sockErrBuf );
        return false;
    }

    return true;
}
Пример #2
0
void serverServe(Server *server)
{
#ifdef _WIN32
    WSADATA wsaData;
    WSAStartup(2 , &wsaData);
#endif

    int sock = makeSocket(server->port);
    int newSock;

    socklen_t size;

    fd_set activeFDs;
    fd_set readFDs;

    struct sockaddr_in addr;

    FD_ZERO(&activeFDs);
    FD_SET(sock, &activeFDs);

    fprintf(stdout, "Listening on port %d.\n\n", server->port);

    for (;;) {
        readFDs = activeFDs;

        if (select(FD_SETSIZE, &readFDs, NULL, NULL, NULL) < 0) {
            fprintf(stderr, "error: failed to select\n");
            exit(1);
        }

        for (int fd = 0; fd < FD_SETSIZE; ++fd) {
            if (FD_ISSET(fd, &readFDs)) {
                if (fd == sock) {
                    size    = sizeof(addr);
                    newSock = accept(sock, (struct sockaddr *) &addr, &size);

                    if (newSock < 0) {
                        fprintf(stderr, "error: failed to accept connection\n");
                        exit(1);
                    }

                    FD_SET(newSock, &activeFDs);
                } else {
                    handle(server, fd, &activeFDs, &addr);
                }
            }
        }
    }
}
Пример #3
0
void DebuggerServer::accept() {
  TRACE(2, "DebuggerServer::accept\n");
  // Setup server-side usage logging before accepting any connections.
  Debugger::InitUsageLogging();
  // server loop
  unsigned int count = m_socks.size();
  struct pollfd fds[count];

  for (unsigned int i = 0; i < count; i++) {
    fds[i].fd = nthSocket(i)->fd();
    fds[i].events = POLLIN|POLLERR|POLLHUP;
  }

  while (!m_stopped) {
    int ret = poll(fds, count, POLLING_SECONDS * 1000);
    for (unsigned int i = 0; ret > 0 && i < count; i++) {
      bool in = (fds[i].revents & POLLIN);
      if (in) {
        struct sockaddr sa;
        socklen_t salen = sizeof(sa);
        try {
          auto sock = nthSocket(i);
          auto new_sock = makeSocket(
            ::accept(sock->fd(), &sa, &salen), sock->getType());
          if (new_sock->valid()) {
            Debugger::CreateProxy(new_sock, false);
          } else {
            Logger::Error("unable to accept incoming debugger request");
          }
        } catch (Exception &e) {
          Logger::Error("%s", e.getMessage().c_str());
        } catch (std::exception &e) {
          Logger::Error("%s", e.what());
        } catch (...) {
          Logger::Error("(unknown exception was thrown)");
        }
      }

      fds[i].revents = 0; // reset the POLLIN flag
    } // else timed out, then we have a chance to check m_stopped bit

    // A chance for some housekeeping...
    Debugger::CleanupRetiredProxies();
  }

  for(auto &m_sock : m_socks) {
    m_sock.reset();
  }
}
Пример #4
0
 PothosPacketSocketEndpointInterfaceUdt(const Poco::Net::SocketAddress &addr, const bool server):
     server(server),
     connected(false),
     sess(getUDTSession())
 {
     if (server)
     {
         this->serverSock = makeSocket();
         if (UDT::ERROR == UDT::bind(this->serverSock, addr.addr(), addr.length()))
         {
             throw Pothos::RuntimeException("UDT::bind("+addr.toString()+")", UDT::getlasterror().getErrorMessage());
         }
         UDT::listen(this->serverSock, 1/*only one client expected*/);
     }
     else
     {
         this->clientSock = makeSocket();
         if (UDT::ERROR == UDT::connect(this->clientSock, addr.addr(), addr.length()))
         {
             throw Pothos::RuntimeException("UDT::connect("+addr.toString()+")", UDT::getlasterror().getErrorMessage());
         }
         this->connected = true;
     }
 }
Пример #5
0
bool repeaterClient::verify ()  // X aCC 361
{
    SOCKET tmpSock;
    bool success = makeSocket ( this->port (), false, & tmpSock );
    if ( success ) {
        epicsSocketDestroy ( tmpSock );
    }
    else {
        if ( SOCKERRNO != SOCK_EADDRINUSE ) {
            char sockErrBuf[64];
            epicsSocketConvertErrnoToString ( 
                sockErrBuf, sizeof ( sockErrBuf ) );
            fprintf ( stderr, "CA Repeater: bind test err was \"%s\"\n", 
                sockErrBuf );
        }
    }
    return ! success;
}
Пример #6
0
bool Ts2Rtp::addChannels( QPtrList<ChannelDesc> *channels )
{
	int i, j, k, pmtpid=8191;
	ChannelDesc *desc, *d;
	QValueList<int> pids;

	if ( !rtpSocket && !makeSocket() )
		return false;

	sendList = "";
	for ( i=0; i<(int)channels->count(); i++ ) {
		desc = channels->at( i );
		sendList = sendList+desc->name+"|"+QString().setNum(desc->vpid)+"|"+QString().setNum(desc->apid[0].pid)+"|";
		if ( desc->apid[0].ac3 ) sendList+= "y|";
		else sendList+= "n|";
		sendList+= QString().setNum(desc->subpid[0].pid);
		sendList+= "|";
		sendList+= QString().setNum(desc->subpid[0].page);
		sendList+= "|";
		sendList+= QString().setNum(desc->subpid[0].id);
		sendList+= "|";
		sendList+= QString().setNum(desc->subpid[0].type);
		sendList+= "|";
		sendList+= desc->subpid[0].lang+"|";
		for ( j=i; j<(int)channels->count(); j++ ) {
			pids.clear();
			d = channels->at( j );
			if ( d->vpid )
				pids.append( d->vpid );
			for ( k=0; k<d->napid && k<MAX_AUDIO; k++ )
				pids.append( d->apid[k].pid );
			for ( k=0; k<d->nsubpid && k<MAX_DVBSUB; k++ )
				pids.append( d->subpid[k].pid );
			while ( pmtpid==17 || pids.contains( pmtpid ) )
				--pmtpid;
		}
		desc->pmtpid = pmtpid--;
	}
	sendList+="\n";
	psiTables( channels );
	writePsi = true;
	psiTimer.start( 500 );
	return true;
}
Пример #7
0
void Handler::listenner(void *)
{
	SOCKET connection, sock = makeSocket();
	if (INVALID_SOCKET == sock)
		return;

	const int buffLen = 512;
	char *buffer = new char[buffLen];
	int datalen = 0;
	while ((connection = accept(sock, 0, 0)) != INVALID_SOCKET) {
		int len = 0;
		while ((len = recv(connection, &buffer[datalen], buffLen-datalen, 0)) > 0) {
			datalen += len;
			Sleep(1);
		}
		buffer[datalen] = 0;
		if (instance()->m_callback)
			instance()->m_callback(buffer);
		datalen = 0;
	}
	delete[] buffer;
}
Пример #8
0
/*
 * register_new_client()
 */
static void register_new_client ( osiSockAddr & from, 
            tsFreeList < repeaterClient, 0x20 > & freeList )
{
    bool newClient = false;
    int status;

    if ( from.sa.sa_family != AF_INET ) {
        return;
    }

    /*
     * the repeater and its clients must be on the same host
     */
    if ( INADDR_LOOPBACK != ntohl ( from.ia.sin_addr.s_addr ) ) {
        static SOCKET testSock = INVALID_SOCKET;
        static bool init = false;

        if ( ! init ) {
            SOCKET sock;
            if ( ! makeSocket ( PORT_ANY, true, & sock ) ) {
                char sockErrBuf[64];
                epicsSocketConvertErrnoToString ( 
                    sockErrBuf, sizeof ( sockErrBuf ) );
                fprintf ( stderr, "%s: Unable to create repeater bind test socket because \"%s\"\n",
                    __FILE__, sockErrBuf );
            }
            else {
                testSock = sock;
            }
            init = true;
        }

        /*
         * Unfortunately on 3.13 beta 11 and before the
         * repeater would not always allow the loopback address
         * as a local client address so current clients alternate
         * between the address of the first non-loopback interface
         * found and the loopback addresss when subscribing with 
         * the CA repeater until all CA repeaters have been updated
         * to current code.
         */
        if ( testSock != INVALID_SOCKET ) {
            osiSockAddr addr;

            addr = from;
            addr.ia.sin_port = PORT_ANY;

            /* we can only bind to a local address */
            status = bind ( testSock, &addr.sa, sizeof ( addr ) );
            if ( status ) {
                return;
            }
        }
        else {
            return;
        }
    }

    tsDLIter < repeaterClient > pclient = client_list.firstIter ();
    while ( pclient.valid () ) {
        if ( pclient->identicalPort ( from ) ) {
            break;
        }
        pclient++;
    }      
    
    repeaterClient *pNewClient;
    if ( pclient.valid () ) {
        pNewClient = pclient.pointer ();
    }
    else {
        pNewClient = new ( freeList ) repeaterClient ( from );
        if ( ! pNewClient ) {
            fprintf ( stderr, "%s: no memory for new client\n", __FILE__ );
            return;
        }
        if ( ! pNewClient->connect () ) {
            pNewClient->~repeaterClient ();
            freeList.release ( pNewClient );
            return;
        }
        client_list.add ( *pNewClient ); 
        newClient = true;
    }

    if ( ! pNewClient->sendConfirm () ) {
        client_list.remove ( *pNewClient );
        pNewClient->~repeaterClient ();
        freeList.release ( pNewClient );
#       ifdef DEBUG
            epicsUInt16 port = ntohs ( from.ia.sin_port );
            debugPrintf ( ( "Deleted repeater client=%u (error while sending ack)\n",
                        port ) );
#       endif
    }

    /*
     * send a noop message to all other clients so that we dont 
     * accumulate sockets when there are no beacons
     */
    caHdr noop;
    memset ( (char *) &noop, '\0', sizeof ( noop ) );
    AlignedWireRef < epicsUInt16 > ( noop.m_cmmd ) = CA_PROTO_VERSION;
    fanOut ( from, &noop, sizeof ( noop ), freeList );

    if ( newClient ) {
        /*
         * For HPUX and Solaris we need to verify that the clients
         * have not gone away - because an ICMP error return does not
         * get through to send(), which returns no error code.
         *
         * This is done each time that a new client is created.
         * See also the note in the file header.
         *
         * This is done here in order to avoid deleting a client
         * prior to sending its confirm message.
         */
        verifyClients ( freeList );
    }
}
Пример #9
0
/*
 *  ca_repeater ()
 */
void ca_repeater () 
{
    tsFreeList < repeaterClient, 0x20 > freeList;
    int size;
    SOCKET sock;
    osiSockAddr from;
    unsigned short port;
    char * pBuf; 

    pBuf = new char [MAX_UDP_RECV];

    {
        bool success = osiSockAttach();
        assert ( success );
    }

    port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT,
                                       static_cast <unsigned short> (CA_REPEATER_PORT) );
    if ( ! makeSocket ( port, true, & sock ) ) {
        /*
         * test for server was already started
         */
        if ( SOCKERRNO == SOCK_EADDRINUSE ) {
            osiSockRelease ();
            debugPrintf ( ( "CA Repeater: exiting because a repeater is already running\n" ) );
            return;
        }
        char sockErrBuf[64];
        epicsSocketConvertErrnoToString ( 
            sockErrBuf, sizeof ( sockErrBuf ) );
        fprintf ( stderr, "%s: Unable to create repeater socket because \"%s\" - fatal\n",
            __FILE__, sockErrBuf );
        osiSockRelease ();
        delete [] pBuf;
        return;
    }

    debugPrintf ( ( "CA Repeater: Attached and initialized\n" ) );

    while ( true ) {
        osiSocklen_t from_size = sizeof ( from );
        size = recvfrom ( sock, pBuf, MAX_UDP_RECV, 0,
                    &from.sa, &from_size );
        if ( size < 0 ) {
            int errnoCpy = SOCKERRNO;
            // Avoid spurious ECONNREFUSED bug in linux
            if ( errnoCpy == SOCK_ECONNREFUSED ) {
                continue;
            }
            // Avoid ECONNRESET from connected socket in windows
            if ( errnoCpy == SOCK_ECONNRESET ) {
                continue;
            }
            char sockErrBuf[64];
            epicsSocketConvertErrnoToString ( 
                sockErrBuf, sizeof ( sockErrBuf ) );
            fprintf ( stderr, "CA Repeater: unexpected UDP recv err: %s\n",
                sockErrBuf );
            continue;
        }

        caHdr * pMsg = ( caHdr * ) pBuf;

        /*
         * both zero length message and a registration message
         * will register a new client
         */
        if ( ( (size_t) size) >= sizeof (*pMsg) ) {
            if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == REPEATER_REGISTER ) {
                register_new_client ( from, freeList );

                /*
                 * strip register client message
                 */
                pMsg++;
                size -= sizeof ( *pMsg );
                if ( size==0 ) {
                    continue;
                }
            }
            else if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == CA_PROTO_RSRV_IS_UP ) {
                if ( pMsg->m_available == 0u ) {
                    pMsg->m_available = from.ia.sin_addr.s_addr;
                }
            }
        }
        else if ( size == 0 ) {
            register_new_client ( from, freeList );
            continue;
        }

        fanOut ( from, pMsg, size, freeList ); 
    }
}
Пример #10
0
extern "C" JNIEXPORT jint JNICALL
    Java_java_nio_channels_DatagramChannel_makeSocket(JNIEnv* e, jclass)
{
  return makeSocket(e, SOCK_DGRAM, IPPROTO_UDP);
}
Пример #11
0
extern "C" JNIEXPORT jint JNICALL
    Java_java_nio_channels_SocketChannel_makeSocket(JNIEnv* e, jclass)
{
  return makeSocket(e);
}
Пример #12
0
	/* 
	 * Actually downloads the page, registering a hit (donation)
	 *	If the fileBuf passed in is NULL, the url is downloaded and then
	 *	freed; otherwise the necessary space is allocated for fileBuf.
	 *	Returns size of download on success, -1 on error is set, 
	 */
int http_fetch(const char *url_tmp, char **fileBuf)
	{
	fd_set rfds;
	struct timeval tv;
	char headerBuf[HEADER_BUF_SIZE];
	char *tmp, *url, *pageBuf, *requestBuf = NULL, *host, *charIndex;
	int sock, bytesRead = 0, contentLength = -1, bufsize = REQUEST_BUF_SIZE;
	int i,
		ret = -1,
		tempSize,
		selectRet,
		found = 0,	/* For redirects */
		redirectsFollowed = 0;


	if(url_tmp == NULL)
		{
		errorSource = FETCHER_ERROR;
		http_errno = HF_NULLURL;
		return -1;
		}

	/* Copy the url passed in into a buffer we can work with, change, etc. */
	url = malloc(strlen(url_tmp)+1);
	if(url == NULL)
		{
		errorSource = ERRNO;
		return -1;
		}
	strncpy(url, url_tmp, strlen(url_tmp) + 1);
	
	/* This loop allows us to follow redirects if need be.  An afterthought,
	 * added to provide this basic functionality.  Will hopefully be designed
	 * better in 2.x.x ;) */
/*	while(!found &&
		  (followRedirects < 0 || redirectsFollowed < followRedirects) )
  */  do
		{
		/* Seek to the file path portion of the url */
		charIndex = strstr(url, "://");
		if(charIndex != NULL)
			{
			/* url contains a protocol field */
			charIndex += strlen("://");
			host = charIndex;
			charIndex = strchr(charIndex, '/');
			}
		else
			{
			host = (char *)url;
			charIndex = strchr(url, '/');
			}

		/* Compose a request string */
		requestBuf = malloc(bufsize);
		if(requestBuf == NULL)
			{
			free(url);
			errorSource = ERRNO;
			return -1;
			}
		requestBuf[0] = 0;

		if(charIndex == NULL)
			{
			/* The url has no '/' in it, assume the user is making a root-level
			 *	request */ 
			tempSize = strlen("GET /") + strlen(HTTP_VERSION) + 2;
			if(_checkBufSize(&requestBuf, &bufsize, tempSize) ||
				snprintf(requestBuf, bufsize, "GET / %s\r\n", HTTP_VERSION) < 0)
				{
				free(url);
				free(requestBuf);
				errorSource = ERRNO;
				return -1;
				}
			}
		else
			{
			tempSize = strlen("GET ") + strlen(charIndex) +
  	          strlen(HTTP_VERSION) + 4;
		 	/* + 4 is for ' ', '\r', '\n', and NULL */
                                    
			if(_checkBufSize(&requestBuf, &bufsize, tempSize) ||
					snprintf(requestBuf, bufsize, "GET %s %s\r\n",
					charIndex, HTTP_VERSION) < 0)
				{
				free(url);
				free(requestBuf);
				errorSource = ERRNO;
				return -1;
				}
			}

		/* Null out the end of the hostname if need be */
		if(charIndex != NULL)
			*charIndex = 0;

		/* Use Host: even though 1.0 doesn't specify it.  Some servers
		 *	won't play nice if we don't send Host, and it shouldn't
		 *	hurt anything */
		ret = bufsize - strlen(requestBuf); /* Space left in buffer */
		tempSize = (int)strlen("Host: ") + (int)strlen(host) + 3;
        /* +3 for "\r\n\0" */
		if(_checkBufSize(&requestBuf, &bufsize, tempSize + 128))
			{
			free(url);
			free(requestBuf);
			errorSource = ERRNO;
			return -1;
			}
		strcat(requestBuf, "Host: ");
		strcat(requestBuf, host);
		strcat(requestBuf, "\r\n");

		if(!hideReferer && referer != NULL)	/* NO default referer */
			{
			tempSize = (int)strlen("Referer: ") + (int)strlen(referer) + 3;
   	        /* + 3 is for '\r', '\n', and NULL */
			if(_checkBufSize(&requestBuf, &bufsize, tempSize))
				{
				free(url);
				free(requestBuf);
				errorSource = ERRNO;
				return -1;
				}
			strcat(requestBuf, "Referer: ");
			strcat(requestBuf, referer);
			strcat(requestBuf, "\r\n");
			}

		if(!hideUserAgent && userAgent == NULL)
			{
			tempSize = (int)strlen("User-Agent: ") +
				(int)strlen(DEFAULT_USER_AGENT) + (int)strlen(VERSION) + 4;
   	        /* + 4 is for '\', '\r', '\n', and NULL */
			if(_checkBufSize(&requestBuf, &bufsize, tempSize))
				{
				free(url);
				free(requestBuf);
				errorSource = ERRNO;
				return -1;
				}
			strcat(requestBuf, "User-Agent: ");
			strcat(requestBuf, DEFAULT_USER_AGENT);
			strcat(requestBuf, "/");
			strcat(requestBuf, VERSION);
			strcat(requestBuf, "\r\n");
			}
		else if(!hideUserAgent)
			{
			tempSize = (int)strlen("User-Agent: ") + (int)strlen(userAgent) + 3;
   	        /* + 3 is for '\r', '\n', and NULL */
			if(_checkBufSize(&requestBuf, &bufsize, tempSize))
				{
				free(url);
				free(requestBuf);
				errorSource = ERRNO;
				return -1;
				}
			strcat(requestBuf, "User-Agent: ");
			strcat(requestBuf, userAgent);
			strcat(requestBuf, "\r\n");
			}

		tempSize = (int)strlen("Connection: Close\r\n\r\n");
		if(_checkBufSize(&requestBuf, &bufsize, tempSize))
			{
			free(url);
			free(requestBuf);
			errorSource = ERRNO;
			return -1;
			}
		strcat(requestBuf, "Connection: Close\r\n\r\n");

		/* Now free any excess memory allocated to the buffer */
		tmp = realloc(requestBuf, strlen(requestBuf) + 1);
		if(tmp == NULL)
			{
			free(url);
			free(requestBuf);
			errorSource = ERRNO;
			return -1;
			}
		requestBuf = tmp;

		sock = makeSocket(host);		/* errorSource set within makeSocket */
		if(sock == -1) { free(url); free(requestBuf); return -1;}

		free(url);
        url = NULL;

		if(write(sock, requestBuf, strlen(requestBuf)) == -1)
			{
			close(sock);
			free(requestBuf);
			errorSource = ERRNO;
			return -1;
			}

		free(requestBuf);
        requestBuf = NULL;

		/* Grab enough of the response to get the metadata */
		ret = _http_read_header(sock, headerBuf);	/* errorSource set within */
		if(ret < 0) { close(sock); return -1; }

		/* Get the return code */
		charIndex = strstr(headerBuf, "HTTP/");
		if(charIndex == NULL)
			{
			close(sock);
			errorSource = FETCHER_ERROR;
			http_errno = HF_FRETURNCODE;
			return -1;
			}
		while(*charIndex != ' ')
			charIndex++;
		charIndex++;

		ret = sscanf(charIndex, "%d", &i);
		if(ret != 1)
			{
			close(sock);
			errorSource = FETCHER_ERROR;
			http_errno = HF_CRETURNCODE;
			return -1;
			}
		if(i<200 || i>307)
			{
			close(sock);
			errorInt = i;	/* Status code, to be inserted in error string */
			errorSource = FETCHER_ERROR;
			http_errno = HF_STATUSCODE;
			return -1;
			}

		/* If a redirect, repeat operation until final URL is found or we
		 *  redirect followRedirects times.  Note the case sensitive "Location",
		 *  should probably be made more robust in the future (without relying
		 *  on the non-standard strcasecmp()).
		 * This bit mostly by Dean Wilder, tweaked by me */
		if(i >= 300)
			{
		    redirectsFollowed++;

			/* Pick up redirect URL, allocate new url, and repeat process */
			charIndex = strstr(headerBuf, "Location:");
			if(!charIndex)
				{
				close(sock);
				errorInt = i; /* Status code, to be inserted in error string */
				errorSource = FETCHER_ERROR;
				http_errno = HF_CANTREDIRECT;
				return -1;
				}
			charIndex += strlen("Location:");
            /* Skip any whitespace... */
            while(*charIndex != '\0' && isspace((int)*charIndex))
                charIndex++;
            if(*charIndex == '\0')
                {
				close(sock);
				errorInt = i; /* Status code, to be inserted in error string */
				errorSource = FETCHER_ERROR;
				http_errno = HF_CANTREDIRECT;
				return -1;
                }

			i = strcspn(charIndex, " \r\n");
			if(i > 0)
				{
				url = (char *)malloc(i + 1);
				strncpy(url, charIndex, i);
				url[i] = '\0';
				}
			else
                /* Found 'Location:' but contains no URL!  We'll handle it as
                 * 'found', hopefully the resulting document will give the user
                 * a hint as to what happened. */
                found = 1;
            }
		else
			found = 1;
	    } while(!found &&
                (followRedirects < 0 || redirectsFollowed <= followRedirects) );

    if(url) /* Redirection code may malloc this, then exceed followRedirects */
        {
        free(url);
        url = NULL;
        }
    
    if(redirectsFollowed >= followRedirects && !found)
        {
        close(sock);
    	errorInt = followRedirects; /* To be inserted in error string */
    	errorSource = FETCHER_ERROR;
    	http_errno = HF_MAXREDIRECTS;
	    return -1;
        }
	
	/*
	 * Parse out about how big the data segment is.
	 *	Note that under current HTTP standards (1.1 and prior), the
	 *	Content-Length field is not guaranteed to be accurate or even present. 
	 *	I just use it here so I can allocate a ballpark amount of memory.
	 *
	 * Note that some servers use different capitalization
	 */
	charIndex = strstr(headerBuf, "Content-Length:");
	if(charIndex == NULL)
		charIndex = strstr(headerBuf, "Content-length:");

	if(charIndex != NULL)
		{
		ret = sscanf(charIndex + strlen("content-length: "), "%d",
			&contentLength);
		if(ret < 1)
			{
			close(sock);
			errorSource = FETCHER_ERROR;
			http_errno = HF_CONTENTLEN;
			return -1;
			}
		}
	
	/* Allocate enough memory to hold the page */
	if(contentLength == -1)
		contentLength = DEFAULT_PAGE_BUF_SIZE;

	pageBuf = (char *)malloc(contentLength);
	if(pageBuf == NULL)
		{
		close(sock);
		errorSource = ERRNO;
		return -1;
		}

	/* Begin reading the body of the file */
	while(ret > 0)
		{
		FD_ZERO(&rfds);
		FD_SET(sock, &rfds);
		tv.tv_sec = timeout; 
		tv.tv_usec = 0;

		if(timeout >= 0)
			selectRet = select(sock+1, &rfds, NULL, NULL, &tv);
		else		/* No timeout, can block indefinately */
			selectRet = select(sock+1, &rfds, NULL, NULL, NULL);

		if(selectRet == 0)
			{
			errorSource = FETCHER_ERROR;
			http_errno = HF_DATATIMEOUT;
			errorInt = timeout;
			close(sock);
			free(pageBuf);
			return -1;
			}
		else if(selectRet == -1)
			{
			setoserror(neterror());
			close(sock);
			free(pageBuf);
			errorSource = ERRNO;
			return -1;
			}

		ret = recv(sock, pageBuf + bytesRead, contentLength, 0);
		if(ret == -1)
			{
			setoserror(neterror());
			close(sock);
			free(pageBuf);
			errorSource = ERRNO;
			return -1;
			}

		bytesRead += ret;

		if(ret > 0)
			{
			/* To be tolerant of inaccurate Content-Length fields, we'll
			 *	allocate another read-sized chunk to make sure we have
			 *	enough room.
			 */
			tmp = (char *)realloc(pageBuf, bytesRead + contentLength);
			if(tmp == NULL)
				{
				close(sock);
				free(pageBuf);
				errorSource = ERRNO;
				return -1;
				}
            pageBuf = tmp;
			}
		}
	
	/*
	 * The download buffer is too large.  Trim off the safety padding.
     * Note that we add one NULL byte to the end of the data, as it may not
     *  already be NULL terminated and we can't be sure what type of data it
     *  is or what the caller will do with it.
	 */
	tmp = (char *)realloc(pageBuf, bytesRead + 1);
		/* tmp shouldn't be null, since we're _shrinking_ the buffer,
		 *	and if it DID fail, we could go on with the too-large buffer,
		 *	but something would DEFINATELY be wrong, so we'll just give
		 *	an error message */
	if(tmp == NULL)
		{
		close(sock);
		free(pageBuf);
		errorSource = ERRNO;
		return -1;
		}
    pageBuf = tmp;
    pageBuf[bytesRead] = '\0';  /* NULL terminate the data */

	if(fileBuf == NULL)	/* They just wanted us to "hit" the url */
		free(pageBuf);
	else
		*fileBuf = pageBuf;

	close(sock);
	return bytesRead;
	}
Пример #13
0
int main(int argc, char *argv[]) {
	fd_set rset;
	struct timeval timeout;
	char * IP; //IP address of socket
	char * PTY; //Pseudo Terminal Name
	
	unsigned char cBuff[BUFFER];
	//char c[BUFFER];
	
	int csize;
	int pty = -1; //Pseudo Terminal File Descriptor
	int sockfd1, sockfd2 = -1;
	int x;
	int args = 0;
	int tmp;
	
	char argSerial[] = "-serial";
	char argHelp[]   = "-help";
	char argPort[]   = "-port";
	char argPTY[]    = "-pty";
	char argStrip[]  = "-strip";
	char argBaud[]   = "-baud";
	char argDebug[]  = "-debug";
	
	int SOCKET_PORT, BAUD, STRIP, DEBUG = 0;
	char SERIAL[100];


	for (x = 0; x < argc; x++){//Cycle through the command line arguments
		if (!strcmp(argSerial,argv[x])) {//Look for the -serial option
			strcpy(SERIAL,argv[x+1]); //Copies the port to SERIAL
			if(BAUD>0){ //If the baud option has been passed
				sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor
				if (sockfd2 < 0) {
					close(sockfd2);
					if(sockfd1>=0)
						close(sockfd1);
					if(pty>=0)
						close(pty);
					return -1;
				}else{
					args+=3;
				}
			}else{ 
				args+=3;
			}
		}
		else if (!strcmp(argPort,argv[x])) {  //Look for -port  option
			SOCKET_PORT = atoi(argv[x+1]); //Convert string address into int
			sockfd1 = makeSocket(SOCKET_PORT);  //Make the socket and return the file descriptor
			if (sockfd1 < 0) {
				close(sockfd1);
				if(sockfd2>=0)
					close(sockfd2);
				if(pty>=0)
					close(pty);
				return -1;
			}else{
				args+=5;
			}
		}
		else if (!strcmp(argPTY,argv[x])) {  //Look for -pty  option
			pty = pseudoTY(&PTY);
			if(pty<0){
				close(pty);
				if(sockfd2>=0)
					close(sockfd2);
				if(sockfd1>=0)
					close(sockfd1);
				return -1;
			}else{
				args+=7;
			}
		}
		else if (!strcmp(argBaud,argv[x])) { //Look for -baud option
			tmp = atoi(argv[x+1]); //Convert string baud rate to int
			switch (tmp) { //Make sure the value is supported
				case 115200:
					BAUD = B115200;
					break;
				case 38400:
					BAUD = B38400;
					break;
				case 19200:
					BAUD = B19200;
					break;
				case 9600:
					BAUD = B9600;
					break;
				default:
					printf("ERROR!: Unknown baud rate.\n");
					return -1;
					break;
			}
			
			if(strlen(SERIAL) != 0) //If we got the tag for a serial port, create the serial port
				sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor
			args+=1;
		}
		else if ( (args != 9 &&  args != 11 && args !=16 && x == argc-1) || (!strcmp(argHelp,argv[x]))) { 
                        //If not enough arguments, output usage directions and exit
			// Serial <=> Socket  w/ baud  = 9
			// Serial <=> PTY  w/ baud = 11
			// Serial <=> Socket, Serial <=> PTY w/ baud = 16
			printf("--------------------------------------\n");
			printf("------------ SerialDaemon ------------\n");
			printf("--------------------------------------\n");
			printf("Usage:");
			printf("\t./serialdaemon [options] [arguments]\n");
			printf("\t-serial [Use to indicate which serial port to connect to. E.G. /dev/ttyS1]\n");
			printf("\t-port   [Use to indicate which TCP/IP port of the local host to connect to. E.G. 5000]\n");
			printf("\t-pty    [Create a pseudo terminal for the serial port to connect to.]\n");
			printf("\t-baud   [Serial port baudrate.]\n");
			printf("\t\t115200\n");
			printf("\t\t38400\n");
			printf("\t\t19200\n");
			printf("\t\t9600\n");
			printf("\t-strip  [Strip the endline character and replace with a space.]\n");
			printf("\t-debug  [Set the verbose debug mode for help.]\n");
			printf("\t-help   [For this help screen.]\n\n");
			printf("Example Usage:\t./serialdaemon -serial /dev/ttyS1 -baud 115200 -pty -port 5000\n");
			printf("This will link ttyS1 to localhost:5000 and ttyS1 to a pseudo terminal.  The connection to ttyS1 will have a baudrate of 115200.\n");
			return -1;
		}
		else if (!strcmp(argStrip,argv[x])){STRIP = 1;}  //Look for the -strip option
		else if (!strcmp(argDebug,argv[x])){DEBUG = 1; printf ("DEBUG: debug mode on!\n");}  //Look for the -debug option
		
	}
	
	signal(SIGINT, controlC);	// catch ^C so we can close sockets & exit cleanly

	IP = getIP(); //Get the local IP address

	if(args == 9)//Serial to Socket
		printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n",SERIAL,IP,SOCKET_PORT); 
	else if(args == 11)//Serial to PTY
		printf("Connections made: \n\t\t\t%s < = > %s\n",SERIAL,PTY); 
	else if(args == 16)//Serial to PTY  &  Serial to Socket
		printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n\t\t\t%s < = > %s\n",SERIAL,IP,SOCKET_PORT,SERIAL,PTY); 

	sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket

	while(1){
		/* Select on sockets */
		if(sd1 > 0){ //If There is a connection to the socket then potentially set up these connections:  tty < = > socket and tty < = > pty
			if (DEBUG)
				printf("DEBUG: New client socket opened.\n");
			if (sd1 < 0) { //Error in creating connection
				close(sd1); 
				return -1;
			}
			sd2 = sockfd2; //File descriptor of the serial port
			if (sd2 < 0) { //If an error
				close(sd1);
				close(sd2); 
				return -1;
			}
			FD_ZERO(&rset); //Clear file descriptors in the rset set
			while(1) {
				FD_SET(sd1,&rset);//Set sd1 in rset
				FD_SET(sd2,&rset);//Set sd2 in rset
				if(pty!=-1) {//If a virtual port is requested
					FD_SET(pty,&rset);
					select(max(max(sd1,sd2),pty)+1,&rset,NULL,NULL,NULL); 
                                       //Select specifies which of the file descriptors is ready for reading or writing
				}else {
					select(max(sd1,sd2)+1,&rset,NULL,NULL,NULL); 
					//Select tests file descriptors in the range of 0 to nfds-1 or in this case 0 to max(sd1,sd2).
				}
				//----------------Check The Socket For Data ------------------
				if (FD_ISSET(sd1,&rset)) {  //Is there stuff to read from the socket
					/* There's stuff to read */
					if ((csize= read(sd1, &cBuff, BUFFER)) >= 1) { //If there's something worth reading
						if (STRIP==1) { //Remove endline characters and replace with space
							for(x = 0 ; x < csize; x++) {
								if (cBuff[x] == '\n' ) {
									cBuff[x] = ' ';
									if (DEBUG)
										printf ("DEBUG: **STRIPPED**\n");
								}
							}
						}
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
						write(sd2, &cBuff, csize);//Write data from sd1 to sd2
					}else{break;}// Failed  -- port closed
				}
				
				//----------------Check The Serial Port For Data ------------------
				if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port
					if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd1, &cBuff, csize); //Write this data to the socket
						if(pty != -1){write(pty,&cBuff,csize);} //Write this data to the virtual com port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("DEBUG: http://%s:%d <== ",IP,SOCKET_PORT);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
							
							if(pty !=-1){
								printf("DEBUG: %s <== ",PTY);
								for(x=0; x<csize;x++){
									printf("%#.2x ",cBuff[x]);
								}
								printf("\n");
							}
						}
					}
					//else break;           /* Failed */
				}
				//----------------Check The PTY Port For Data ------------------
				if (pty != -1 && FD_ISSET(pty,&rset)) {//If there is a virtual port, and data is ready, write data from 
					if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd2, &cBuff, csize); //Write this data to the serial port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           /* Failed */
				}
			}
			printf("Restarting\n");
			close(sd1);/* clean up */
			sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket

		}else if(pty != -1) {//Else, if there is a virtual port then tty <=> pty
			sd2 = sockfd2; //File descriptor of the serial port
			if (sd2 < 0) { //If an error
				close(sd2); 
				close(pty);
				return -1;
			}
			FD_ZERO(&rset); //Clear file descriptors in the rset set
			while(1) {
				FD_SET(sd2,&rset);//Set sd2 in rset
				FD_SET(pty,&rset);//Set pty in rset
				sd1 = waitOnSocket(sockfd1);
				if(sd1 >= 0){break;} //Check for socket connection, if there is, break out of this loop.
				select(max(sd2,pty)+1,&rset,NULL,NULL,NULL); // Specifies which of the file descriptors is ready for reading or writing
				if (FD_ISSET(pty,&rset)) { //If there is a virtual port, and data is ready, write data from 
					if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd2, &cBuff, csize); //Write this data to the serial port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           // Failed 
				}


				if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port				  
					if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) { //If there is something worth reading from the serial port
						write(pty, &cBuff, csize); //Write this data to the virtual com port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("DEBUG: %s <== ",PTY);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           /* Failed */
				}

			}
		}else {//If there isn't a pty, then check the socket for a connection once a second
			if(DEBUG)
				printf("\rWaiting on the socket connection...\n");
			sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket
			sleep(1);
		}
	}
}
Пример #14
0
bool DebuggerServer::start() {
  TRACE(2, "DebuggerServer::start\n");
  int port = RuntimeOption::DebuggerServerPort;
  int backlog = 128;

  struct addrinfo hint;
  struct addrinfo *ai;
  memset(&hint, 0, sizeof(hint));
  hint.ai_family = AF_UNSPEC;
  hint.ai_socktype = SOCK_STREAM;
  hint.ai_flags = AI_PASSIVE;
  if (RuntimeOption::DebuggerDisableIPv6) {
    hint.ai_family = AF_INET;
  }

  if (getaddrinfo(nullptr, std::to_string(port).c_str(), &hint, &ai)) {
    Logger::Error("unable to get address information");
    return false;
  }

  SCOPE_EXIT {
    freeaddrinfo(ai);
  };

  /* use a cur pointer so we still have ai to be able to free the struct */
  struct addrinfo *cur;
  for (cur = ai; cur; cur = cur->ai_next) {
    int s_fd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
    if (s_fd < 0 && errno == EAFNOSUPPORT) {
      continue;
    }
    auto m_sock = makeSocket(s_fd, cur->ai_family, cur->ai_addr->sa_data, port);

    int yes = 1;
    setsockopt(m_sock->fd(), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    if (!m_sock->valid()) {
      Logger::Error("unable to create debugger server socket");
      return false;
    }

    if (cur->ai_family == AF_INET6) {
      int on = 1;
      setsockopt(m_sock->fd(), IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
    }

    if (bind(m_sock->fd(), cur->ai_addr, cur->ai_addrlen) < 0) {
      Logger::Error("unable to bind to port %d for debugger server", port);
      return false;
    }
    if (listen(m_sock->fd(), backlog) < 0) {
      Logger::Error("unable to listen on port %d for debugger server", port);
      return false;
    }

    m_socks.push_back(m_sock->getData());
  }

  if (m_socks.size() == 0) {
    Logger::Error("Did not bind to any sockets on port %d", port);
    return false;
  }

  m_serverThread.start();
  return true;
}
Пример #15
0
void startServer(int port) {
    // Make sure types have the required size.
    assert(sizeof(bits8)  == 1);
    assert(sizeof(bits16) == 2);
    assert(sizeof(bits32) == 4);

    int parsedValues;

    #ifdef _WIN32
        WSADATA wsaData;
        WSAStartup(0x0202, &wsaData);
    #endif

    int sock = makeSocket(port);

    char req[REQ_SIZE + 1];
    req[REQ_SIZE] = 0;

    while (1) {
        int conn = waitForConnection(sock);

        recv(conn, req, REQ_SIZE, 0);

        // Cut the string off to one line.
        char *endOfLine = strchr(req, '\n');
        if (endOfLine != NULL) {
            *endOfLine = '\0';
        }

        // Find the path.
        char path[PATH_SIZE + 1];
        parsedValues = sscanf(req, "GET %s HTTP/1.1", path);

        if (parsedValues == 1) {
            if (strcmp(path, "/") == 0) {
                // Homepage
                char *msg =
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Type: text/html\r\n"
                    "\r\n"
                    "<!DOCTYPE html>\n"
                    "<script src=\"http://almondbread.cse.unsw.edu.au/tiles.js\"></script>\n";
                send(conn, msg, strlen(msg), 0);
            } else {
                double x, y;
                int zoom;

                parsedValues = sscanf(
                    path, "/tile_x%lf_y%lf_z%d.bmp",
                    &x, &y, &zoom);

                if (parsedValues == 3) {
                    char *msg =
                        "HTTP/1.0 200 OK\r\n"
                        "Content-Type: image/bmp\r\n"
                        "\r\n";
                    send(conn, msg, strlen(msg), 0);

                    char image[FILE_SIZE];
                    mandelBitmap(image, x, y, zoom);
                    send(conn, image, FILE_SIZE, 0);
                } else {
                    // HTTP Error 404.
                }
            }
        } else {
            // HTTP Error 400.
        }

        closeSocket(conn);
    }

    // Closing the socket is unnecessary, because the OS will
    // immediately recover it thanks to SO_REUSEADDR.
}
Пример #16
0
  int
  KeyRemap4MacBook_client::sendmsg(KeyRemap4MacBook_bridge::RequestType type, void* request, uint32_t requestsize, void* reply, uint32_t replysize)
  {
    if (! lock_) { return EIO; }

    IOLockWrapper::ScopedLock lk(lock_);

    if (type == KeyRemap4MacBook_bridge::REQUEST_STATUS_MESSAGE) {
      if (config.general_hide_statusmessage) {
        if (! request) return 0;
        char* p = reinterpret_cast<KeyRemap4MacBook_bridge::StatusMessage::Request*>(request)->message;
        if (p[0] != '\0') {
          return 0;
        }
      }
    }

    // ------------------------------------------------------------
    int result = 0;
    int error = 0;
    socket_t socket;
    bool isMakeSocket = false;

    if (! makeSocket(socket)) {
      result = EIO;
      goto finish;
    }
    isMakeSocket = true;

    if (! connectSocket(socket)) {
      result = EIO;
      goto finish;
    }

    // ----------------------------------------
    struct msghdr msg;
    memset(&msg, 0, sizeof(msg));

    struct iovec aiov[3];
    size_t iolen;
    aiov[0].iov_base = reinterpret_cast<caddr_t>(&type);
    aiov[0].iov_len = sizeof(type);
    if (requestsize <= 0) {
      msg.msg_iovlen = 1;
    } else {
      aiov[1].iov_base = reinterpret_cast<caddr_t>(&requestsize);
      aiov[1].iov_len = sizeof(requestsize);
      aiov[2].iov_base = reinterpret_cast<caddr_t>(request);
      aiov[2].iov_len = requestsize;
      msg.msg_iovlen = 3;
    }
    msg.msg_iov = aiov;

    error = sock_send(socket, &msg, 0, &iolen);
    if (error) {
      printf("KeyRemap4MacBook_client::sendmsg sock_send failed(%d)\n", error);
      result = error;
      goto finish;
    }

    // ----------------------------------------
    if (replysize > 0) {
      memset(&msg, 0, sizeof(msg));

      uint32_t status = -1;
      aiov[0].iov_base = reinterpret_cast<caddr_t>(&status);
      aiov[0].iov_len = sizeof(status);
      aiov[1].iov_base = reinterpret_cast<caddr_t>(reply);
      aiov[1].iov_len = replysize;
      msg.msg_iov = aiov;
      msg.msg_iovlen = 2;

      error = sock_receive(socket, &msg, MSG_WAITALL, &iolen);
      if (error) {
        printf("KeyRemap4MacBook_client::sendmsg sock_receive failed(%d)\n", error);
        result = error;
        goto finish;
      }
    }

  finish:
    if (isMakeSocket) {
      releaseSocket(socket);
    }
    if (result) {
      printf("KeyRemap4MacBook_client::sendmsg error result (%d)\n", result);
    }
    return result;
  }
int startReceiver(int doWarn,
		  struct disk_config *disk_config,
		  struct net_config *net_config,
		  struct stat_config *stat_config,
		  const char *ifName)
{
    char ipBuffer[16];
    union serverControlMsg Msg;
    int connectReqSent=0;
    struct client_config client_config;
    int outFile=1;
    int pipedOutFile;
    struct sockaddr_in myIp;
    int pipePid = 0;
    int origOutFile;
    int haveServerAddress;

    client_config.sender_is_newgen = 0;

    net_config->net_if = getNetIf(ifName);
    zeroSockArray(client_config.socks, NR_CLIENT_SOCKS);

    client_config.S_UCAST = makeSocket(ADDR_TYPE_UCAST,
				       net_config->net_if,
				       0, RECEIVER_PORT(net_config->portBase));
    client_config.S_BCAST = makeSocket(ADDR_TYPE_BCAST,
				       net_config->net_if,
				       0, RECEIVER_PORT(net_config->portBase));

    if(net_config->ttl == 1 && net_config->mcastRdv == NULL) {
	getBroadCastAddress(net_config->net_if,
			    &net_config->controlMcastAddr,
			    SENDER_PORT(net_config->portBase));
	setSocketToBroadcast(client_config.S_UCAST);
    } else {
	getMcastAllAddress(&net_config->controlMcastAddr,
			   net_config->mcastRdv,
			   SENDER_PORT(net_config->portBase));
	if(isMcastAddress(&net_config->controlMcastAddr)) {
	    setMcastDestination(client_config.S_UCAST, net_config->net_if,
				&net_config->controlMcastAddr);
	    setTtl(client_config.S_UCAST, net_config->ttl);
	    
	    client_config.S_MCAST_CTRL =
		makeSocket(ADDR_TYPE_MCAST,
			   net_config->net_if,
			   &net_config->controlMcastAddr,
			   RECEIVER_PORT(net_config->portBase));
	    // TODO: subscribe address as receiver to!
	}
    }
    clearIp(&net_config->dataMcastAddr);
    udpc_flprintf("%sUDP receiver for %s at ", 
		  disk_config->pipeName == NULL ? "" :  "Compressed ",
		  disk_config->fileName == NULL ? "(stdout)":disk_config->fileName);
    printMyIp(net_config->net_if);
    udpc_flprintf(" on %s\n", net_config->net_if->name);

    connectReqSent = 0;
    haveServerAddress = 0;

    client_config.clientNumber= 0; /*default number for asynchronous transfer*/
    while(1) {
	// int len;
	int msglen;
	int sock;

	if (!connectReqSent) {
	    if (sendConnectReq(&client_config, net_config,
			       haveServerAddress) < 0) {
		perror("sendto to locate server");
	    }
	    connectReqSent = 1;
	}

	haveServerAddress=0;

	sock = udpc_selectSock(client_config.socks, NR_CLIENT_SOCKS,
			       net_config->startTimeout);
	if(sock < 0) {
		return -1;
	}

	// len = sizeof(server);
	msglen=RECV(sock, 
		    Msg, client_config.serverAddr, net_config->portBase);
	if (msglen < 0) {
	    perror("recvfrom to locate server");
	    exit(1);
	}
	
	if(getPort(&client_config.serverAddr) != 
	   SENDER_PORT(net_config->portBase))
	    /* not from the right port */
	    continue;

	switch(ntohs(Msg.opCode)) {
	    case CMD_CONNECT_REPLY:
		client_config.clientNumber = ntohl(Msg.connectReply.clNr);
		net_config->blockSize = ntohl(Msg.connectReply.blockSize);

		udpc_flprintf("received message, cap=%08lx\n",
			      (long) ntohl(Msg.connectReply.capabilities));
		if(ntohl(Msg.connectReply.capabilities) & CAP_NEW_GEN) {
		    client_config.sender_is_newgen = 1;
		    copyFromMessage(&net_config->dataMcastAddr,
				    Msg.connectReply.mcastAddr);
		}
		if (client_config.clientNumber == -1) {
		    udpc_fatal(1, "Too many clients already connected\n");
		}
		goto break_loop;

	    case CMD_HELLO_STREAMING:
	    case CMD_HELLO_NEW:
	    case CMD_HELLO:
		connectReqSent = 0;
		if(ntohs(Msg.opCode) == CMD_HELLO_STREAMING)
			net_config->flags |= FLAG_STREAMING;
		if(ntohl(Msg.hello.capabilities) & CAP_NEW_GEN) {
		    client_config.sender_is_newgen = 1;
		    copyFromMessage(&net_config->dataMcastAddr,
				    Msg.hello.mcastAddr);
		    net_config->blockSize = ntohs(Msg.hello.blockSize);
		    if(ntohl(Msg.hello.capabilities) & CAP_ASYNC)
			net_config->flags |= FLAG_PASSIVE;
		    if(net_config->flags & FLAG_PASSIVE)
			goto break_loop;
		}
		haveServerAddress=1;
		continue;
	    case CMD_CONNECT_REQ:
	    case CMD_DATA:
	    case CMD_FEC:
		continue;
	    default:
		break;
	}


	udpc_fatal(1, 
		   "Bad server reply %04x. Other transfer in progress?\n",
		   (unsigned short) ntohs(Msg.opCode));
    }

 break_loop:
    udpc_flprintf("Connected as #%d to %s\n", 
		  client_config.clientNumber, 
		  getIpString(&client_config.serverAddr, ipBuffer));

    getMyAddress(net_config->net_if, &myIp);

    if(!ipIsZero(&net_config->dataMcastAddr)  &&
       !ipIsEqual(&net_config->dataMcastAddr, &myIp) &&
       (ipIsZero(&net_config->controlMcastAddr) ||
       !ipIsEqual(&net_config->dataMcastAddr, &net_config->controlMcastAddr)
	)) {
	udpc_flprintf("Listening to multicast on %s\n",
		      getIpString(&net_config->dataMcastAddr, ipBuffer));
	client_config.S_MCAST_DATA = 
	  makeSocket(ADDR_TYPE_MCAST, net_config->net_if, 
		     &net_config->dataMcastAddr, 
		     RECEIVER_PORT(net_config->portBase));
    }


    if(net_config->requestedBufSize) {
      int i;
      for(i=0; i<NR_CLIENT_SOCKS; i++)
	if(client_config.socks[i] != -1)
	  setRcvBuf(client_config.socks[i],net_config->requestedBufSize);
    }

    outFile=openOutFile(disk_config);
    origOutFile = outFile;
    pipedOutFile = openPipe(outFile, disk_config, &pipePid);

    global_client_config= &client_config;
    atexit(sendDisconnectWrapper);
    {
	struct fifo fifo;
	int printUncompressedPos =
	    udpc_shouldPrintUncompressedPos(stat_config->printUncompressedPos,
					    origOutFile, pipedOutFile);

	receiver_stats_t stats = allocReadStats(origOutFile,
						stat_config->statPeriod,
						printUncompressedPos);
	
	udpc_initFifo(&fifo, net_config->blockSize);

	fifo.data = pc_makeProduconsum(fifo.dataBufSize, "receive");

	client_config.isStarted = 0;

	if((net_config->flags & (FLAG_PASSIVE|FLAG_NOKBD))) {
	  /* No console used */
	  client_config.console = NULL;
	} else {
	  if(doWarn)
	    udpc_flprintf("WARNING: This will overwrite the hard disk of this machine\n");
	  client_config.console = prepareConsole(0);
	  atexit(fixConsole);
	}

	spawnNetReceiver(&fifo,&client_config, net_config, stats);
	writer(&fifo, pipedOutFile);
	if(pipePid) {
	    close(pipedOutFile);
	}
	pthread_join(client_config.thread, NULL);

	/* if we have a pipe, now wait for that too */
	if(pipePid) {
	    udpc_waitForProcess(pipePid, "Pipe");
	}
#ifndef __MINGW32__
	fsync(origOutFile);
#endif /* __MINGW32__ */
	displayReceiverStats(stats, 1);

    }
    fixConsole();
    sendDisconnectWrapper();
    global_client_config= NULL;
    return 0;
}
Пример #18
0
int main(int argc, char *argv[])
    {
    fd_set rset;
    struct timeval timeout;
    char c[BUFFER_SIZE];
    int csize;

    int mode;
    int x;
    int y;
    int args = 0;
    int tmp;
    int result;
    int blockerror = 0;

    char argSerial[] = "-serial";
    char argPort[]   = "-port";
    char argStrip[]  = "-strip";
    char argBaud[]   = "-baud";
    char argDebug[]  = "-debug";
    char argInDebug[]  = "-indebug";
    char argOutDebug[]  = "-outdebug";
    char argNonblock[]  = "-nonblock";
    char argAux[]  = "-aux";

    int SOCKET_PORT = 0;
    int BAUD = 0;
    int STRIP = 0;
    int NONBLOCK = 0;
    int AUX_PORT = 0;
    char SERIAL[100];
        
    for (x=1; x<argc; x++)
        {
        if (!strcmp(argSerial,argv[x]))
            {
            strcpy(SERIAL,argv[x+1]);
            x++;
            args++;
            }
        else if (!strcmp(argPort,argv[x]))
            {
            SOCKET_PORT = atoi(argv[x+1]);
            x++;
            args++;
            }
        else if (!strcmp(argBaud,argv[x]))
            {
            BAUD = parseBaudRates(argv[x+1]);
            if (!BAUD) return 1;
            x++;
            args++;
            }
        else if (!strcmp(argAux, argv[x]))
            {
            AUX_PORT = atoi(argv[x+1]);
            x++;
            }
        else if (!strcmp(argStrip,argv[x]))
            STRIP = 1;
        else if (!strcmp(argInDebug,argv[x]))
            INDEBUG = 1;
        else if (!strcmp(argOutDebug,argv[x]))
            OUTDEBUG = 1;
        else if (!strcmp(argDebug,argv[x]))
            INDEBUG = OUTDEBUG = 1;
        else if (!strcmp(argNonblock,argv[x]))
            NONBLOCK = 1;
        else { 
            printf("ERROR!: Unknown argument %s\n", argv[x]); 
            return 1; 
            }
        }

    if (args < 3)
        {
        printf("--------------------------------------------------------------\n");
        printf("------------------  GMU SerialDaemon  ------------------------\n");
        printf("--------------------------------------------------------------\n");
        printf("Usage:\n");
        printf("\tserialdaemon\n");
        printf("\t\t-serial [serialPort]\n");
        printf("\t\t-port   [TCP/IP Port]\n");
        printf("\t\t-aux    [auxiliary TCP/IP Port]\n");
        printf("\t\t-baud   [baudRate]\n");
        printf("\t\t\t500000    (available on Linux only)\n");
        printf("\t\t\t460800    (available on Linux only)\n");
        printf("\t\t\t230400\n");
        printf("\t\t\t115200\n");
        printf("\t\t\t57600\n");
        printf("\t\t\t38400\n");
        printf("\t\t\t19200\n");
        printf("\t\t\t9600\n");
        printf("\t\t-strip\n");
        printf("\t\t-indebug\n");
        printf("\t\t-outdebug\n");
        printf("\t\t-debug\n");
        printf("\t\t-nonblock\n");
        printf("\n");
        printf("Notes:\n");
        printf("1) If you have declared an auxiliary port, your client program\n");
        printf("   must connect to the primary TCP/IP port, THEN the auxiliary\n"); 
		printf("   port, and both must be connected before any traffic is sent\n");
        printf("2) Baud rates 460800 and 500000 are not available on OS/X\n");
        return(1);
        }

    if (INDEBUG || OUTDEBUG)
        printf ("DEBUG: debug mode on!\n");

    sockfd_pre = makeSocket(SOCKET_PORT);
    if (sockfd_pre <= 0)
        { 
        printf("ERROR: couldn't make TCP/IP socket!\n"); 
        closeAll(); 
        return; 
        }

    if (AUX_PORT != 0)
        {
        auxfd_pre = makeSocket(AUX_PORT);
        if (auxfd_pre <= 0)
            { 
            printf("ERROR: couldn't make TCP/IP socket!\n"); 
            closeAll(); 
            return; 
            }
        }

    serialfd = makeSerialPortFd(SERIAL, BAUD);
    if (serialfd <= 0)
        { 
        printf("ERROR: couldn't open serial port!\n"); 
        closeAll(); 
        return; 
        }

    if (argc <= 1)
        mode = 0;
    else
        mode = atoi(argv[1]);

    printf("Listening for data connections on port: %i\n",SOCKET_PORT);
    if (AUX_PORT != 0)
        {
        printf("Listening for aux  connections on port: %i\n",AUX_PORT);
        }

    while(1)
        {
        /* Wait for connection on data socket */
        sockfd = waitOnSocket(sockfd_pre);
        if (INDEBUG || OUTDEBUG)
            printf("DEBUG: New data socket opened.\n");
        if (sockfd < 0)
            {
            closeAll(); 
            return;
            }

        /* Set data socket to non-blocking */
        if (NONBLOCK)
            {
            if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0)
                {
                printf("ERROR: couldn't make TCP/IP socket non-blocking!\n"); 
                closeAll(); 
                return; 
                }
            }

        /* Wait for connection on AUX socket (if specified) */
        if (auxfd_pre != NOTHING)
            {
            auxfd = waitOnSocket(auxfd_pre);
            if (INDEBUG || OUTDEBUG)
                printf("DEBUG: New aux  socket opened.\n");
            if (auxfd < 0)
                {
                closeAll(); 
                return;
                }
            }

        /* Must have a serial file descriptor (else, why are we running?) */
        if (serialfd < 0)
            {
            closeAll();
            return;
            }
    
        FD_ZERO(&rset);

        /* Main Loop */
        while(1)
            {
            /* Add connections to set */
            FD_SET(sockfd,&rset);
            if (auxfd!=NOTHING) FD_SET(auxfd,&rset);
            FD_SET(serialfd,&rset);

            /* Select on connection */
            select(max(max(sockfd,auxfd),serialfd)+1,&rset,NULL,NULL,NULL);
                        
            /* There's stuff to read on AUX */
            if (FD_ISSET(auxfd,&rset))
                { 
                if ((csize = readline(auxfd, c, BUFFER_SIZE)) >= 1)
                    {
                    c[csize] = '\0';  // after length, so no problem
                    char cmd = c[0];
                    if (c[1] != ' ')
                        printf("ERROR!: Malformed AUX command; ignoring\n");
                    char* data = &c[2];
                    switch (cmd)
                        {
                        case 'B':
                            if (INDEBUG)
                                {
                                printf("DEBUG: AUX baud change\n");
                                }
                            auxShiftBaud(data);
                            break;
                        default:
                            printf("ERROR!: Unknown AUX command; ignoring\n");
                            break;
                        }                                                       
                    }
                else break;             /* Failed */
                }
                        
            /* There's stuff to read on SOCKET */
            if (FD_ISSET(sockfd,&rset))
                {
                if ((csize= read(sockfd, c, BUFFER_SIZE)) >= 1)
                    {
                    y = csize;
                    if (STRIP==1)
                        {
                        for(x = 0, y = 0 ; x < csize; x++, y++)
                            {
                            if (c[x] == '\n')  { // get rid of it
                                y--;
                                if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n");
                                }
                            else c[y] = c[x];
                            }
                        }
                    if (OUTDEBUG)
                        {
                        c[y] = '\0';  // after length, so no problem
                        printf("DEBUG: serial <==");
                        printDebugString(c, y);
                        }
                    result = write(serialfd, c, y);
                    if (OUTDEBUG)
                        {
                        printf("DEBUG: wrote %d/%d\n", result, y);
                        }
                    }
                else break;             /* Failed */
                }
                        
            /* There's stuff to read on SERIAL */
            if (FD_ISSET(serialfd,&rset))
                {
                if ((csize = read(serialfd, c, BUFFER_SIZE)) >= 1)
                    {
                    if (STRIP==1)
                        {
                        for(x = 0 ; x < csize; x++)
                            {
                            if (c[x] == '\r' )  { // get rid of it
                                c[x] = '\n';
                                if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n");
                                }
                            else c[y] = c[x];
                            }
                        }
                    if (INDEBUG)
                        {
                        c[csize] = '\0';  // after length, so no problem
                        printf("DEBUG: serial ==>");
                        printDebugString(c, csize);
                        }
                    result = write(sockfd, c, csize);
                    if (result == EWOULDBLOCK)
                        {
                        if (!blockerror)
                            { 
                            blockerror = 1; 
                            printf("ERROR: dropping bytes writing to socket\n"); 
                            }
                        }
                    else if (INDEBUG)
                        {
                        printf("DEBUG: read %d/%d\n", result, csize);
                        }
                    }
                else break;             /* Failed */     
                }
            }

        /* Restart connection-wait loop */
        printf("Restarting\n");
        close(sockfd);  /* clean up */
        }
    }