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(); }
void DocumentServerRequest::finished() { if (network_reply()->error() == QNetworkReply::NoError) { QJsonDocument * json_document = reply_to_json(); handle_reply(json_document); } else handle_network_error(); }
//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // 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 ); }
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; }
//----------------------------------------------------------------------------- // 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; }
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; }
//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; }
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); }
/* * 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; }
/* * 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; }
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; } } }
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; }