示例#1
0
static void client_handler() {
    char cmd[MAXCMD];
    for (;;){
        cmd[0] = '\0'; // reset the buffer to be an empty string
        fprintf(stdout, "%s:%s> ", SIP, SPORT);

        /* Get command for the commandline and length */
        fgets (cmd, MAXCMD, stdin);
        int length[1];
        length[0] = strlen(cmd);
        
        /* Send command length to the server */
        /* size_t send(int sockfd, const void *buf, size_t len, int flags); */
        send(socketFD, (char*)length, sizeof(int),0);

        /* Send command to the server */
        send(socketFD, cmd, strlen(cmd),0);
        
        /* If command was "exit" we should also terminate on this side */
        if (strncmp(cmd, "exit", 4) == 0) {
            return;
        }
        /* If not we wait for the server's reply */
        handle_reply();
    }
}
void
QcWmtsTileFetcher::request_next_tile()
{
  // qInfo();

  QMutexLocker mutex_locker(&m_queue_mutex);

  if (!m_enabled || m_queue.isEmpty())
    return;

  QcTileSpec tile_spec = m_queue.takeFirst();

  // qInfo() << tile_spec;
  QcWmtsReply *wmts_reply = get_tile_image(tile_spec);

  // If the request is already finished then handle it
  // Else connect the finished signal
  if (wmts_reply->is_finished()) {
    handle_reply(wmts_reply, tile_spec);
  } else {
    connect(wmts_reply, SIGNAL(finished()),
	    this, SLOT(finished()),
	    Qt::QueuedConnection);
    m_invmap.insert(tile_spec, wmts_reply);
  }

  if (m_queue.isEmpty())
    m_timer.stop();
}
示例#3
0
void
DocumentServerRequest::finished()
{
  if (network_reply()->error() == QNetworkReply::NoError) {
    QJsonDocument * json_document = reply_to_json();
    handle_reply(json_document);
  } else
    handle_network_error();
}
示例#4
0
//-----------------------------------------------------------------------------
// name: replace_code()
// desc: ...
//-----------------------------------------------------------------------------
t_OTF_RESULT miniAudicle::replace_code( string & code, string & name, 
                                        vector< string > & args, string & filepath, 
                                        t_CKUINT docid, t_CKUINT & shred_id, 
                                        string & out )
{    
    if( documents.find( docid ) == documents.end() )
    {
        out += "internal error at miniAudicle::replace_code\n";
        return OTF_MINI_ERROR;
    }
    
    while( documents[docid]->size() && documents[docid]->back() == 0 )
        documents[docid]->pop_back();
    
    if( documents[docid]->size() == 0 )
    {
        out += "no shred to replace\n";
        return OTF_MINI_ERROR;
    }

    if( !compiler->go( name, NULL, code.c_str(), filepath ) )
    {
        last_result[docid].result = OTF_COMPILE_ERROR;
        last_result[docid].output = string( EM_lasterror() ) + "\n";
        last_result[docid].line = EM_extLineNum;
        
        out += last_result[docid].output;
        return last_result[docid].result;
    }
    
    Chuck_Msg * msg = new Chuck_Msg;

    msg->code = compiler->output();
    
    msg->code->name = name;
    msg->type = MSG_REPLACE;
    msg->param = documents[docid]->back();
    msg->reply = ( ck_msg_func )1;
    msg->args = new vector< string >( args );
    
    vm->queue_msg( msg, 1 );
    
    // check results
    t_OTF_RESULT result = handle_reply( docid, out );
    
    _doc_otf_result otf_result;
    t_CKBOOL gotit = get_last_result( docid, &otf_result );
    if( gotit && result == OTF_SUCCESS )
        shred_id = otf_result.shred_id;
    else
        shred_id = 0;
    
    return result;
}
示例#5
0
//-----------------------------------------------------------------------------
// name: clearvm()
// desc: ...
//-----------------------------------------------------------------------------
t_OTF_RESULT miniAudicle::clearvm( t_CKUINT docid, string & out )
{
    Chuck_Msg * msg = new Chuck_Msg;
    
    msg->type = MSG_CLEARVM;
    msg->reply = ( ck_msg_func )1;
    
    vm->queue_msg( msg, 1 );
    
    // check results
    return handle_reply( docid, out );
}
示例#6
0
//-----------------------------------------------------------------------------
// name: removelast()
// desc: ...
//-----------------------------------------------------------------------------
t_OTF_RESULT miniAudicle::removelast( t_CKUINT docid, string & out )
{
    Chuck_Msg * msg = new Chuck_Msg;
    
    msg->type = MSG_REMOVE;
    msg->param = 0xffffffff;
    msg->reply = ( ck_msg_func )1;
    
    vm->queue_msg( msg, 1 );
    
    // 
    return handle_reply( docid, out );
}
示例#7
0
//-----------------------------------------------------------------------------
// name: remove_shred()
// desc: ...
//-----------------------------------------------------------------------------
t_OTF_RESULT miniAudicle::remove_shred( t_CKUINT docid, t_CKINT shred_id, 
                                        string & out )
{
    Chuck_Msg * msg = new Chuck_Msg;
    
    msg->type = MSG_REMOVE;
    msg->param = shred_id;
    msg->reply = ( ck_msg_func )1;
    
    vm->queue_msg( msg, 1 );
    
    // check results
    return handle_reply( docid, out );
}
示例#8
0
 static bool process(snark::asd::protocol& protocol, const std::string& cmd)
 {
     if(cmd.find(T::command()) !=0 ) { return false; }
     timestamped_reply_t reply=protocol.send<T>(cmd);
     handle_reply(reply.data.header);
     if(!acquire) { write_output(reply); }   //don't write output in --acquire mode
     else if(comma::verbose)
     {
         std::stringstream ss;
         comma::write_json(reply.data, ss);
         comma::verbose<<ss.str()<<std::endl;
     }
     return true;
 }
示例#9
0
//-----------------------------------------------------------------------------
// name: run_code()
// desc: ...
//-----------------------------------------------------------------------------
t_OTF_RESULT miniAudicle::run_code( string & code, string & name, 
                                    vector< string > & args, string & filepath, 
                                    t_CKUINT docid, t_CKUINT & shred_id, 
                                    string & out )
{    
    if( documents.find( docid ) == documents.end() )
        // invalid document id
    {
        out += "internal error at miniAudicle::run_code\n";
        return OTF_MINI_ERROR;
    }

    // compile
    if( !compiler->go( name, NULL, code.c_str(), filepath ) )
    {
        last_result[docid].result = OTF_COMPILE_ERROR;
        last_result[docid].output = string( EM_lasterror() ) + "\n";
        last_result[docid].line = EM_extLineNum;
        
        out += last_result[docid].output;
        return last_result[docid].result;
    }
    
    // allocate the VM message struct
    Chuck_Msg * msg = new Chuck_Msg;

    // fill in the VM message
    msg->code = compiler->output();
        
    msg->code->name = name;
    msg->type = MSG_ADD;
    msg->reply = ( ck_msg_func )1;
    msg->args = new vector< string >( args );
        
    // execute
    vm->queue_msg( msg, 1 );
    
    // check results
    t_OTF_RESULT result = handle_reply( docid, out );
    
    _doc_otf_result otf_result;
    t_CKBOOL gotit = get_last_result( docid, &otf_result );
    if( gotit && result == OTF_SUCCESS )
        shred_id = otf_result.shred_id;
    else
        shred_id = 0;
    
    return result;
}
示例#10
0
文件: comms.c 项目: mmeeks/libreprap
int rr_handle_readable(rr_dev device) {
  /* Grow receive buffer if it's full */
  if(device->recvbuf_fill == device->recvbufsize) {
    device->recvbuf = realloc(device->recvbuf, 2*device->recvbufsize);
  }

  ssize_t result;

  do {
    result = read(device->fd, device->recvbuf + device->recvbuf_fill, device->recvbufsize - device->recvbuf_fill);
  } while(result < 0 && errno == EINTR);
  if(result < 0) {
    return result;
  }
  device->recvbuf_fill += result;

  /* Scan for complete reply */
  size_t scan = 0;
  size_t end = device->recvbuf_fill;
  size_t reply_span = 0;
  size_t term_span = 0;
  size_t start = 0;

  do {
    /* How many non terminator chars and how many terminator chars after them*/
    reply_span = strcspn(device->recvbuf + scan, REPLY_TERMINATOR); 
    term_span = strspn(device->recvbuf + scan + reply_span, REPLY_TERMINATOR);
    start = scan;
    
    if(0 < term_span && 0 < reply_span && (start + reply_span + 1) < end) {
      /* We have a terminator after non terminator chars */
      handle_reply(device, device->recvbuf + start, reply_span);
    }
    scan += reply_span + term_span;

  } while(scan < end);

  size_t rest_size = end - start;

  /* Move the rest of the buffer to the beginning */
  if(rest_size > 0) {
    device->recvbuf_fill = rest_size;
    memmove(device->recvbuf, device->recvbuf + start, device->recvbuf_fill);
  } else {
    device->recvbuf_fill = 0;
  }

  return 0;
}
示例#11
0
//for acquaire_data command
static bool process_acquire_data(snark::asd::protocol& protocol, const std::string& cmd)
{
    if(cmd.find(snark::asd::commands::acquire_data::command()) !=0 && cmd[0]!='C') { return false; }
    comma::verbose<<"process_acquire_data"<<std::endl;
    //do it once if !acquire
    do
    {
        //send one command
        snark::asd::protocol::acquire_reply_t reply=protocol.send_acquire_data(cmd);
        handle_reply(reply.data.header.header);
        write_output(reply);
        if(sleep_seconds) { sleep(sleep_seconds);}
    }
    while(acquire);
    return true;
}
示例#12
0
static void client_handler() {
  char* cmd = (char*) calloc(MAXCMD,sizeof(char));
    for (;;){
        cmd[0] = '\0'; // reset the buffer to be an empty string
        fprintf(stdout, "%s:%s> ", SIP, SPORT);
	//Read command from commandline.
        gets(cmd);
	int length[1];
	length[0] = strlen(cmd);
        //Send command length to server
	send(socketFD, (char*)length, sizeof(int),0);
	//Send command to server
	cmd = realloc(cmd, strlen(cmd));
        send(socketFD, cmd, strlen(cmd),0);
        /* If command was "exit" we should also terminate on this side */
        if (strncmp(cmd, "exit", 4) == 0) {
            return;
        }
        /* If not we wait for the server's reply */
        handle_reply();
    }
}
void
QcWmtsTileFetcher::finished()
{
  // qInfo();

  QMutexLocker mutex_locker(&m_queue_mutex);

  QcWmtsReply *wmts_reply = qobject_cast<QcWmtsReply *>(sender());
  if (!wmts_reply) // Fixme: when ?
    return;

  QcTileSpec tile_spec = wmts_reply->tile_spec();

  if (!m_invmap.contains(tile_spec)) { // Fixme: when ?
    wmts_reply->deleteLater();
    return;
  }

  m_invmap.remove(tile_spec);

  handle_reply(wmts_reply, tile_spec);
}
示例#14
0
/*
 * FIXME: we should definately handle things more asynchronously,
 * perhaps even at the expense of having to go to the GSource
 * twice in order to get fresh input (?)
 * or should we poll ourselves on the source to see what's up?
 *
 * The whole locking concept here looks broken to me,
 * especially since 'read' can flag the connection disconnected
 * giving a nice deadlock.
 */
gboolean
giop_connection_handle_input (LinkConnection *lcnx)
{
	GIOPRecvBuffer *buf;
	GIOPConnection *cnx = (GIOPConnection *) lcnx;

	do {
		int n;

		if (!cnx->incoming_msg)
			cnx->incoming_msg = giop_recv_buffer_use_buf (cnx);

		buf = cnx->incoming_msg;

		n = link_connection_read (
			lcnx, buf->cur, buf->left_to_read, FALSE);

		if (n == 0) /* We'll be back */
			return TRUE;

		if (n < 0 || !buf->left_to_read) /* HUP */
			goto msg_error;

/*		fprintf (stderr, "Read %d\n", n);
		giop_dump (stderr, buf->cur, n, 0); */

		buf->left_to_read -= n;
		buf->cur += n;

		if (buf->left_to_read == 0) {

#ifdef G_ENABLE_DEBUG
			if (giop_debug_hook_incoming_mangler)
				giop_debug_hook_incoming_mangler (buf);
#endif

			switch (buf->state) {

			case GIOP_MSG_READING_HEADER:
				if (giop_recv_msg_reading_body (buf, cnx->parent.is_auth)) {
					dprintf (ERRORS, "OOB incoming msg header data\n");
					goto msg_error;
				}
				buf->state = GIOP_MSG_READING_BODY;
				break;

			case GIOP_MSG_READING_BODY: {

				dprintf (GIOP, "Incoming IIOP body:\n");

				buf->cur = buf->message_body + 12;
				if ((buf->cur + buf->msg.header.message_size) > buf->end) {
					dprintf (ERRORS, "broken incoming length data\n");
					goto msg_error;
				}
				do_giop_dump (stderr, buf->cur, buf->msg.header.message_size, 12);

				buf->state = GIOP_MSG_READY;

				if (giop_recv_buffer_demarshal (buf)) {
					dprintf (ERRORS, "broken incoming header data\n");
					goto msg_error;
				}

				if (MORE_FRAGMENTS_FOLLOW (buf)) {
					if (giop_recv_buffer_handle_fragmented (&buf, cnx))
						goto msg_error;

					else {
						cnx->incoming_msg = NULL;
						goto frag_out;
					}

				} else if (buf->msg.header.message_type == GIOP_FRAGMENT) {
					if (giop_recv_buffer_handle_fragmented (&buf, cnx))
						goto msg_error;
					/* else last fragment */
				}
				break;
			}

			case GIOP_MSG_AWAITING_FRAGMENTS:
			case GIOP_MSG_READY:
				g_assert_not_reached ();
				break;
			}
		}

	} while (cnx->incoming_msg &&
		 buf->left_to_read > 0 &&
		 buf->state != GIOP_MSG_READY);

	cnx->incoming_msg = NULL;

	switch (buf->msg.header.message_type) {
	case GIOP_REPLY:
	case GIOP_LOCATEREPLY:
		dprintf (MESSAGES, "handling reply\n");
		if (handle_reply (buf)) /* dodgy inbound data, pull the cnx */
			link_connection_state_changed (lcnx, LINK_DISCONNECTED);
		break;

	case GIOP_REQUEST:
		dprintf (MESSAGES, "handling request\n");
		ORBit_handle_request (cnx->orb_data, buf);
		break;

	case GIOP_LOCATEREQUEST:
		dprintf (MESSAGES, "handling locate request\n");
		ORBit_handle_locate_request (cnx->orb_data, buf);
		break;

	case GIOP_CANCELREQUEST:
	case GIOP_MESSAGEERROR:
		dprintf (ERRORS, "dropping an unusual & unhandled input buffer 0x%x",
			 buf->msg.header.message_type);
		giop_recv_buffer_unuse (buf);
		break;

	case GIOP_CLOSECONNECTION:
		dprintf (MESSAGES, "received close connection\n");
		giop_recv_buffer_unuse (buf);
		link_connection_state_changed (lcnx, LINK_DISCONNECTED);
		break;

	case GIOP_FRAGMENT:
		dprintf (ERRORS, "Fragment got in the wrong channel\n");
	default:
		dprintf (ERRORS, "dropping an out of bound input buffer "
			 "on the floor 0x%x\n", buf->msg.header.message_type);
		goto msg_error;
		break;
	}

 frag_out:	
	return TRUE;

 msg_error:
	cnx->incoming_msg = NULL;

	buf->msg.header.message_type = GIOP_MESSAGEERROR;
	buf->msg.header.message_size = 0;

	giop_recv_buffer_unuse (buf);

	/* Zap it for badness.
	 * XXX We should probably handle oversized
	 * messages more graciously XXX */
	link_connection_state_changed (LINK_CONNECTION (cnx),
				       LINK_DISCONNECTED);

	return TRUE;
}
示例#15
0
/*
 * The main handler for an artnet packet. calls
 * the appropriate handler function
 */
int handle(node n, artnet_packet p) {

  if (check_callback(n, p, n->callbacks.recv))
    return 0;

  switch (p->type) {
    case ARTNET_POLL:
      handle_poll(n, p);
      break;
    case ARTNET_REPLY:
      handle_reply(n,p);
      break;
    case ARTNET_DMX:
      handle_dmx(n, p);
      break;
    case ARTNET_ADDRESS:
      handle_address(n, p);
      break;
    case ARTNET_INPUT:
      _artnet_handle_input(n, p);
      break;
    case ARTNET_TODREQUEST:
      handle_tod_request(n, p);
      break;
    case ARTNET_TODDATA:
      handle_tod_data(n, p);
      break;
    case ARTNET_TODCONTROL:
      handle_tod_control(n, p);
      break;
    case ARTNET_RDM:
      handle_rdm(n, p);
      break;
    case ARTNET_VIDEOSTEUP:
      printf("vid setup\n");
      break;
    case ARTNET_VIDEOPALETTE:
      printf("video palette\n");
      break;
    case ARTNET_VIDEODATA:
      printf("video data\n");
      break;
    case ARTNET_MACMASTER:
      printf("mac master\n");
      break;
    case ARTNET_MACSLAVE:
      printf("mac slave\n");
      break;
    case ARTNET_FIRMWAREMASTER:
      handle_firmware(n, p);
      break;
    case ARTNET_FIRMWAREREPLY:
      handle_firmware_reply(n, p);
      break;
    case ARTNET_IPPROG :
      handle_ipprog(n, p);
      break;
    case ARTNET_IPREPLY:
      printf("ip reply\n");
      break;
    case ARTNET_MEDIA:
      printf("media \n");
      break;
    case ARTNET_MEDIAPATCH:
      printf("media patch\n");
      break;
    case ARTNET_MEDIACONTROLREPLY:
      printf("media control reply\n");
      break;
    default:
      n->state.report_code = ARTNET_RCPARSEFAIL;
      printf("artnet but not yet implemented!, op was %hx\n", p->type);
  }
  return 0;
}
示例#16
0
文件: bootpgw.c 项目: ryo/netbsd-src
int
main(int argc, char **argv)
{
	int timeout;
	struct bootp *bp;
	struct servent *servp;
	struct hostent *hep;
	char *stmp;
	socklen_t ba_len, ra_len;
	int n;
	int nfound;
	struct pollfd set[1];
	int standalone;

	progname = strrchr(argv[0], '/');
	if (progname) progname++;
	else progname = argv[0];

	/*
	 * Initialize logging.
	 */
	report_init(0);				/* uses progname */

	/*
	 * Log startup
	 */
	report(LOG_INFO, "version %s.%d", VERSION, PATCHLEVEL);

	/* Debugging for compilers with struct padding. */
	assert(sizeof(struct bootp) == BP_MINPKTSZ);

	/* Get space for receiving packets and composing replies. */
	pktbuf = malloc(MAX_MSG_SIZE);
	if (!pktbuf) {
		report(LOG_ERR, "malloc failed");
		exit(1);
	}
	bp = (struct bootp *) pktbuf;

	/*
	 * Check to see if a socket was passed to us from inetd.
	 *
	 * Use getsockname() to determine if descriptor 0 is indeed a socket
	 * (and thus we are probably a child of inetd) or if it is instead
	 * something else and we are running standalone.
	 */
	s = 0;
	ba_len = sizeof(bind_addr);
	bzero((char *) &bind_addr, ba_len);
	errno = 0;
	standalone = TRUE;
	if (getsockname(s, (struct sockaddr *) &bind_addr, &ba_len) == 0) {
		/*
		 * Descriptor 0 is a socket.  Assume we are a child of inetd.
		 */
		if (bind_addr.sin_family == AF_INET) {
			standalone = FALSE;
			bootps_port = ntohs(bind_addr.sin_port);
		} else {
			/* Some other type of socket? */
			report(LOG_INFO, "getsockname: not an INET socket");
		}
	}
	/*
	 * Set defaults that might be changed by option switches.
	 */
	stmp = NULL;
	timeout = actualtimeout;
	gethostname(myhostname, sizeof(myhostname));
	myhostname[sizeof(myhostname) - 1] = '\0';
	hep = gethostbyname(myhostname);
	if (!hep) {
		printf("Can not get my IP address\n");
		exit(1);
	}
	bcopy(hep->h_addr, (char *)&my_ip_addr, sizeof(my_ip_addr));

	/*
	 * Read switches.
	 */
	for (argc--, argv++; argc > 0; argc--, argv++) {
		if (argv[0][0] != '-')
			break;
		switch (argv[0][1]) {

		case 'd':				/* debug level */
			if (argv[0][2]) {
				stmp = &(argv[0][2]);
			} else if (argv[1] && argv[1][0] == '-') {
				/*
				 * Backwards-compatible behavior:
				 * no parameter, so just increment the debug flag.
				 */
				debug++;
				break;
			} else {
				argc--;
				argv++;
				stmp = argv[0];
			}
			if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
				fprintf(stderr,
						"%s: invalid debug level\n", progname);
				break;
			}
			debug = n;
			break;

		case 'h':				/* hop count limit */
			if (argv[0][2]) {
				stmp = &(argv[0][2]);
			} else {
				argc--;
				argv++;
				stmp = argv[0];
			}
			if (!stmp || (sscanf(stmp, "%d", &n) != 1) ||
				(n < 0) || (n > 16))
			{
				fprintf(stderr,
						"bootpgw: invalid hop count limit\n");
				break;
			}
			maxhops = (u_int)n;
			break;

		case 'i':				/* inetd mode */
			standalone = FALSE;
			break;

		case 's':				/* standalone mode */
			standalone = TRUE;
			break;

		case 't':				/* timeout */
			if (argv[0][2]) {
				stmp = &(argv[0][2]);
			} else {
				argc--;
				argv++;
				stmp = argv[0];
			}
			if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
				fprintf(stderr,
						"%s: invalid timeout specification\n", progname);
				break;
			}
			actualtimeout = n * 60000;
			/*
			 * If the actual timeout is zero, pass INFTIM
			 * to poll so it blocks indefinitely, otherwise,
			 * use the actual timeout value.
			 */
			timeout = (n > 0) ? actualtimeout : INFTIM;
			break;

		case 'w':				/* wait time */
			if (argv[0][2]) {
				stmp = &(argv[0][2]);
			} else {
				argc--;
				argv++;
				stmp = argv[0];
			}
			if (!stmp || (sscanf(stmp, "%d", &n) != 1) ||
				(n < 0) || (n > 60))
			{
				fprintf(stderr,
						"bootpgw: invalid wait time\n");
				break;
			}
			minwait = (u_int)n;
			break;

		default:
			fprintf(stderr, "%s: unknown switch: -%c\n",
					progname, argv[0][1]);
			usage();
			break;

		} /* switch */
	} /* for args */

	/* Make sure server name argument is suplied. */
	servername = argv[0];
	if (!servername) {
		fprintf(stderr, "bootpgw: missing server name\n");
		usage();
	}
	/*
	 * Get address of real bootp server.
	 */
	if (inet_aton(servername, &serv_addr.sin_addr) == 0) {
		hep = gethostbyname(servername);
		if (!hep) {
			fprintf(stderr, "bootpgw: can't get addr for %s\n", servername);
			exit(1);
		}
		memcpy(&serv_addr.sin_addr, hep->h_addr,
		    sizeof(serv_addr.sin_addr));
	}

	if (standalone) {
		/*
		 * Go into background and disassociate from controlling terminal.
		 * XXX - This is not the POSIX way (Should use setsid). -gwr
		 */
		if (debug < 3) {
			if (fork())
				exit(0);
#ifdef	NO_SETSID
			setpgrp(0,0);
#ifdef TIOCNOTTY
			n = open("/dev/tty", O_RDWR);
			if (n >= 0) {
				ioctl(n, TIOCNOTTY, (char *) 0);
				(void) close(n);
			}
#endif	/* TIOCNOTTY */
#else	/* SETSID */
			if (setsid() < 0)
				perror("setsid");
#endif	/* SETSID */
		} /* if debug < 3 */
		/*
		 * Nuke any timeout value
		 */
		timeout = INFTIM;

		/*
		 * Here, bootpd would do:
		 *	chdir
		 *	tzone_init
		 *	rdtab_init
		 *	readtab
		 */

		/*
		 * Create a socket.
		 */
		if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
			report(LOG_ERR, "socket: %s", get_network_errmsg());
			exit(1);
		}
		/*
		 * Get server's listening port number
		 */
		servp = getservbyname("bootps", "udp");
		if (servp) {
			bootps_port = ntohs((u_short) servp->s_port);
		} else {
			bootps_port = (u_short) IPPORT_BOOTPS;
			report(LOG_ERR,
				   "udp/bootps: unknown service -- assuming port %d",
				   bootps_port);
		}

		/*
		 * Bind socket to BOOTPS port.
		 */
		bind_addr.sin_family = AF_INET;
		bind_addr.sin_port = htons(bootps_port);
		bind_addr.sin_addr.s_addr = INADDR_ANY;
		if (bind(s, (struct sockaddr *) &bind_addr,
				 sizeof(bind_addr)) < 0)
		{
			report(LOG_ERR, "bind: %s", get_network_errmsg());
			exit(1);
		}
	} /* if standalone */
	/*
	 * Get destination port number so we can reply to client
	 */
	servp = getservbyname("bootpc", "udp");
	if (servp) {
		bootpc_port = ntohs(servp->s_port);
	} else {
		report(LOG_ERR,
			   "udp/bootpc: unknown service -- assuming port %d",
			   IPPORT_BOOTPC);
		bootpc_port = (u_short) IPPORT_BOOTPC;
	}

	/* no signal catchers */

	/*
	 * Process incoming requests.
	 */
	set[0].fd = s;
	set[0].events = POLLIN;
	for (;;) {
		nfound = poll(set, 1, timeout);
		if (nfound < 0) {
			if (errno != EINTR) {
				report(LOG_ERR, "poll: %s", get_errmsg());
			}
			continue;
		}
		if (nfound == 0) {
			report(LOG_INFO, "exiting after %d minute%s of inactivity",
				   actualtimeout / 60000,
				   actualtimeout == 60000 ? "" : "s");
			exit(0);
		}
		ra_len = sizeof(clnt_addr);
		n = recvfrom(s, pktbuf, MAX_MSG_SIZE, 0,
					 (struct sockaddr *) &clnt_addr, &ra_len);
		if (n <= 0) {
			continue;
		}
		if (debug > 3) {
			report(LOG_INFO, "recvd pkt from IP addr %s",
				   inet_ntoa(clnt_addr.sin_addr));
		}
		if (n < (int)sizeof(struct bootp)) {
			if (debug) {
				report(LOG_INFO, "received short packet");
			}
			continue;
		}
		pktlen = n;

		switch (bp->bp_op) {
		case BOOTREQUEST:
			handle_request();
			break;
		case BOOTREPLY:
			handle_reply();
			break;
		}
	}
}
示例#17
0
文件: comms.c 项目: atoun/repsnapper
int
rr_dev_handle_readable (rr_dev dev)
{
  int i;

  /* Grow receive buffer if it's full */
  if (dev->recvbuf_fill >= dev->recvbufsize) {
    dev->recvbufsize *= 2;
    dev->recvbuf = realloc (dev->recvbuf, dev->recvbufsize + 1);
  }

  ssize_t result;

  do {
    result = read (dev->fd, dev->recvbuf + dev->recvbuf_fill, dev->recvbufsize - dev->recvbuf_fill);
  } while (result < 0 && errno == EINTR);

  if (result < 0)
    return result;

  dev->recvbuf_fill += result;

  /* string terminate */
  dev->recvbuf[dev->recvbuf_fill] = '\0';

  /* validate the stream is ascii and of the correct length */
  for (i = 0; i < dev->recvbuf_fill; i++) {
    if (dev->recvbuf[i] == '\0' || !isascii (dev->recvbuf[i])) {
      rr_dev_log (dev, RR_DEBUG_ALWAYS,
		  "invalid char in recvbuf at char %d (0x%2x) full "
		  "msg: '%s', truncating here", i, dev->recvbuf[i],
		  dev->recvbuf);
      dev->recvbuf_fill = i;
      dev->recvbuf[dev->recvbuf_fill] = '\0';
      break;
    }
  }

  /* spot control characters */
  if (dev->recvbuf[0] == 1) {
    rr_dev_log (dev, RR_DEBUG_ALWAYS,
		"unusual - control character 0x%2x 0x%2x\n",
		dev->recvbuf[0], dev->recvbuf[1]);
    memmove (dev->recvbuf, dev->recvbuf + 2, dev->recvbuf_fill - 2);
    dev->recvbuf_fill -= 2;
  }

  /* Scan the buffer and shift it down if we detect a full command */
  size_t reply_span, term_span;
  while (1) {
    /* How many non terminator chars and how many terminator chars after them */
    reply_span = strcspn (dev->recvbuf, REPLY_TERMINATOR);
    term_span = strspn (dev->recvbuf + reply_span, REPLY_TERMINATOR);

    if (term_span > 0) {
      if (reply_span > 0)
	handle_reply (dev, dev->recvbuf, reply_span, term_span);
      /* else - perhaps a prepended \n having sent in reaction to \r previously */

      size_t len = reply_span + term_span;
      assert (dev->recvbuf_fill >= len);
      dev->recvbuf_fill -= len;
      memmove (dev->recvbuf, dev->recvbuf + len, dev->recvbuf_fill + 1);
      continue;
    }
    break;
  }

  return 0;
}