uint8_t pdu_parser(uint8_t *pdu) { uint8_t i = 3; uint8_t ret_val = 1; int16_t write_len = 0; uint16_t reply_len = 0; SMS_DEBUG("pdu_parser called: %d\n", pdu[i]); if (pdu[i++] == '+') { SMS_DEBUG("pdu_parser called: %d\n", pdu[i]); if (!strncmp((char *) pdu + i, "CMGL", 4)) { SMS_DEBUG("messages will be received\r\n"); uint8_t smsc_len, sender_len; if (reply_len == 0) { while (pdu[++i] != '\n'); i ++; /* get length of smsc number */ sscanf((char *) pdu + i, "%02hhX", &smsc_len); /* we ignore some flags "0000" */ i += (smsc_len * 2) + 4; /* get data length */ sscanf((char *) pdu + i, "%02hhX", &sender_len); /* get number of message sender */ strncpy(nummer, (char *) pdu + i, sender_len + 5); nummer[sender_len + 5] = '\0'; i = i + sender_len + 5 + 18; read_sms((uint8_t *) pdu + i); } SMS_DEBUG("ecmd: %s\n", text); do { if (reply_len < (int16_t)sizeof(write_buffer)) { write_len = ecmd_parse_command((char *) text, write_buffer + reply_len, sizeof(write_buffer) - reply_len - 1); SMS_DEBUG("ret_len ecmd parser: %d\r\n", write_len); if (is_ECMD_AGAIN(write_len)) { reply_len += -(10 + write_len); *(write_buffer + reply_len) = ' '; reply_len++; } else if (write_len > 0) { SMS_DEBUG("finished: \"%s\"\n", write_buffer); ret_val = 0; reply_len += write_len; break; } SMS_DEBUG("%s\n", write_buffer); } else { break; } } while (write_len <= 0); write_buffer[reply_len] = '\0'; sms_send((uint8_t *) nummer, (uint8_t *) write_buffer, NULL, 1); } } return ret_val; }
void ecmd_lufa_periodic(void) { if (!must_parse) ecmd_lufa_rx(); if (must_parse && write_len == 0) { must_parse = 0; if (recv_len <= 1) { recv_len = 0; return; } write_len = ecmd_parse_command(recv_buffer, write_buffer, sizeof(write_buffer)); if (is_ECMD_AGAIN(write_len)) { /* convert ECMD_AGAIN back to ECMD_FINAL */ write_len = ECMD_AGAIN(write_len); must_parse = 1; } else if (is_ECMD_ERR(write_len)) return; else { recv_len = 0; } write_buffer[write_len++] = '\r'; write_buffer[write_len++] = '\n'; } if (write_len) ecmd_lufa_tx(); }
static void jabber_parse_ecmd(char *message) { int16_t remain = sizeof(STATE->outbuf) - 1; int16_t written = 0; while (remain > 0) { int16_t len = ecmd_parse_command(message, STATE->outbuf + written, remain); if (is_ECMD_AGAIN(len)) { len = ECMD_AGAIN(len); written += len; remain -= len; if (remain) { STATE->outbuf[written++] = '\n'; remain--; } continue; } else if (is_ECMD_ERR(len)) { strncpy_P(STATE->outbuf, PSTR("parse error"), sizeof(STATE->outbuf)); len = 11; } written = len; break; } STATE->outbuf[written] = 0; }
void uecmd_net_main() { if (!uip_newdata()) return; char *p = (char *) uip_appdata; /* This may be 1-2 chars too big in case there is a \r or \n, but it saves us a counting loop */ char cmd[uip_datalen() + 1]; char *dp = cmd; /* Copy over into temporary buffer, remove \r \n if present, add \0 */ while (p < (char *) uip_appdata + uip_datalen()) { if (*p == '\r' || *p == '\n') break; *dp++ = *p++; } *dp = 0; uip_slen = 0; while (uip_slen < UIP_BUFSIZE - UIP_IPUDPH_LEN) { int16_t len = ecmd_parse_command(cmd, ((char *) uip_appdata) + uip_slen, (UIP_BUFSIZE - UIP_IPUDPH_LEN) - uip_slen); uint8_t real_len = len; if (!is_ECMD_FINAL(len)) { /* what about the errors ? */ /* convert ECMD_AGAIN back to ECMD_FINAL */ real_len = (uint8_t) ECMD_AGAIN(len); } uip_slen += real_len + 1; ((char *) uip_appdata)[uip_slen - 1] = '\n'; if (real_len == len || len == 0) break; } /* Sent data out */ uip_udp_conn_t echo_conn; uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr); echo_conn.rport = BUF->srcport; echo_conn.lport = HTONS(ECMD_UDP_PORT); uip_udp_conn = &echo_conn; uip_process(UIP_UDP_SEND_CONN); router_output(); uip_slen = 0; }
uint8_t ecmd_usb_setup(uint8_t data[8]) { usbRequest_t *rq = (void *)data; if (rq->wValue.word == 1) { /* Write */ recv_count = 0; } else { /* Read */ uint8_t len = ecmd_parse_command(recv_buffer, send_buffer, ECMD_USB_BUFFER_LEN); if (len > 0) recv_buffer[len] = 0; send_count = 0; } return USB_NO_MSG; }
void debug_process_uart (void) { #if defined(ECMD_PARSER_SUPPORT) && !defined(SOFT_UART_SUPPORT) #define LEN 60 #define OUTPUTLEN 40 static char buf[LEN+1]; static char *ptr = buf; if (usart(UCSR,A) & _BV(usart(RXC))) { char data = usart(UDR); if (data == '\n' || data == '\r') { char *output = malloc(OUTPUTLEN); if (output == NULL) debug_printf("malloc() failed!\n"); *ptr = '\0'; printf_P(PSTR("\n")); #ifdef DEBUG_ECMD debug_printf("parsing command '%s'\n", buf); #endif int l; do { l = ecmd_parse_command(buf, output, LEN); if (is_ECMD_FINAL(l) || is_ECMD_AGAIN(l)) { output[is_ECMD_AGAIN(l) ? ECMD_AGAIN(l) : l] = 0; printf_P(PSTR("%s\n"), output); } } while (is_ECMD_AGAIN(l)); free(output); ptr = buf; } else { debug_uart_put(data, stdout); if (data == '\b') {if (ptr > &buf[0]) ptr--;} else { if (ptr < &buf[LEN-1]) *ptr++ = data; else debug_printf("not enough space for storing '%c'\n", data); } } } #endif /* ECMD_PARSER_SUPPORT && !SOFT_UART_SUPPORT*/ }
static void jabber_parse_ecmd (char *message) { int16_t len = ecmd_parse_command(message, STATE->outbuf, ECMD_OUTPUTBUF_LENGTH - 1); if (len <= -10) { JABDEBUG ("jabber_ecmd doesn't support multiple reply lines (yet)\n"); len = -len - 10; } if (len < 0) strcpy_P (STATE->outbuf, PSTR ("parse error")); else STATE->outbuf[len] = 0; }
int16_t parse_ecmd_twi_slave (void) { TWIDEBUG("parse_ecmd_twi_slave\n"); twi_get_rx_data(cmd_rx_buffer); ecmd_len = ecmd_parse_command(cmd_rx_buffer, cmd_tx_buffer, sizeof(cmd_tx_buffer)); twi_set_tx_data(cmd_tx_buffer); /*dont know how to return multiple lines in tx_buffer*/ //if (is_ECMD_AGAIN(ecmd_len)) { /* convert ECMD_AGAIN back to ECMD_FINAL */ //ecmd_len = ECMD_AGAIN(ecmd_len); //} //else if (is_ECMD_ERR(ecmd_len)) // return; return ECMD_FINAL_OK; }
void cron_execute(struct cron_event_linkedlist *exec) { if (exec->event.cmd == CRON_JUMP) { #ifdef DEBUG_CRON debug_printf("cron: match (JUMP %p)\n", &(exec->event.handler)); #endif #ifndef DEBUG_CRON_DRYRUN exec->event.handler(&(exec->event.extradata)); #endif } else if (exec->event.cmd == CRON_ECMD) { // ECMD PARSER #ifdef DEBUG_CRON debug_printf("cron: match (%s)\n", (char *) &(exec->event.ecmddata)); #endif #ifndef DEBUG_CRON_DRYRUN char output[ECMD_INPUTBUF_LENGTH]; #ifdef DEBUG_CRON int16_t l = #endif ecmd_parse_command((char *) &(exec->event.ecmddata), output, sizeof(output) - 1); #ifdef DEBUG_CRON if (is_ECMD_AGAIN(l)) l = ECMD_AGAIN(l); if (is_ECMD_FINAL(l)) { output[l] = 0; debug_printf("cron output %s\n", output); } else { debug_printf("cron output error %d\n", l); } #endif #endif } /* Execute job endless if repeat value is equal to zero otherwise * decrement the value and check if is equal to zero. * If that is the case, it is time to kick out this cronjob. */ if (exec->event.repeat > 0 && !(--exec->event.repeat)) cron_jobrm(exec); }
void uecmd_net_main() { if (!uip_newdata ()) return; char *p = (char *)uip_appdata; /* Add \0 to the data and remove \n from the data */ do { if (*p == '\r' || *p == '\n') { break; } } while ( ++p <= ((char *)uip_appdata + uip_datalen())); /* Parse the Data */ *p = 0; char cmd[p - (char *)uip_appdata]; strncpy(cmd, uip_appdata, p - (char *)uip_appdata + 1); uip_slen = 0; while (uip_slen < UIP_BUFSIZE - UIP_IPUDPH_LEN) { int16_t len = ecmd_parse_command(cmd, ((char *)uip_appdata) + uip_slen, (UIP_BUFSIZE - UIP_IPUDPH_LEN) - uip_slen); uint8_t real_len = len; if (!is_ECMD_FINAL(len)) { /* what about the errors ? */ /* convert ECMD_AGAIN back to ECMD_FINAL */ real_len = (uint8_t) ECMD_AGAIN(len); } uip_slen += real_len + 1; ((char *)uip_appdata)[uip_slen - 1] = '\n'; if (real_len == len || len == 0) break; } /* Sent data out */ uip_udp_conn_t echo_conn; uip_ipaddr_copy(echo_conn.ripaddr, BUF->srcipaddr); echo_conn.rport = BUF->srcport; echo_conn.lport = HTONS(ECMD_UDP_PORT); uip_udp_conn = &echo_conn; uip_process(UIP_UDP_SEND_CONN); router_output(); uip_slen = 0; }
int16_t parse_cmd_call(char *cmd, char *output, uint16_t len) { char filename[10]; char line[ECMD_INPUTBUF_LENGTH]; uint8_t lsize = 0; uint8_t run = 0; vfs_size_t filesize; sscanf_P(cmd, PSTR("%s"), &filename); // should check for ".es" extention! current_script.handle = vfs_open(filename); if (current_script.handle == NULL) { SCRIPTDEBUG("%s not found\n", filename); return ECMD_FINAL(1); } filesize = vfs_size(current_script.handle); SCRIPTDEBUG("start %s from %i bytes\n", filename, filesize); current_script.linenumber = 0; current_script.filepointer = 0; // open file as long it is open, we have not reached max lines and // not the end of the file as we know it while ((current_script.handle != NULL) && (run++ < ECMD_SCRIPT_MAXLINES) && (filesize > current_script.filepointer)) { lsize = readline(line); SCRIPTDEBUG("(linenr:%i, pos:%i, bufsize:%i)\n", current_script.linenumber, current_script.filepointer, lsize); SCRIPTDEBUG("exec: %s\n", line); if (lsize != 0) { ecmd_parse_command(line, output, len); } } SCRIPTDEBUG("end\n"); parse_cmd_exit(cmd, output, len); return ECMD_FINAL_OK; }
static void irc_handle_ecmd (void) { int16_t len = ecmd_parse_command(STATE->inbuf, STATE->outbuf, ECMD_OUTPUTBUF_LENGTH - 1); if ((STATE->reparse = is_ECMD_AGAIN(len)) != 0) { /* convert ECMD_AGAIN back to ECMD_FINAL */ len = ECMD_AGAIN(len); } if (is_ECMD_ERR(len)) strcpy_P(STATE->outbuf, PSTR("parse error")); else STATE->outbuf[len] = 0; return; }
void newdata(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; uint16_t diff = ECMD_INPUTBUF_LENGTH - state->in_len; if (diff > 0) { int cplen; if (uip_datalen() <= diff) cplen = uip_datalen(); else cplen = diff; memcpy(state->inbuf, uip_appdata, cplen); state->in_len += cplen; #ifdef DEBUG_ECMD_NET debug_printf("copied %d bytes\n", cplen); #endif } else { #ifdef DEBUG_ECMD_NET debug_printf("buffer full\n"); #endif } char *lf = memchr(state->inbuf, '\n', state->in_len); if (lf != NULL || memchr(uip_appdata, '\n', uip_datalen()) != NULL) { #ifdef DEBUG_ECMD_NET debug_printf("calling parser\n"); #endif if (lf) *lf = '\0'; else state->inbuf[ECMD_INPUTBUF_LENGTH-1] = '\0'; /* kill \r */ int l; for (l = 0; l < ECMD_INPUTBUF_LENGTH; l++) if (state->inbuf[l] == '\r') state->inbuf[l] = '\0'; /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); #ifdef DEBUG_ECMD_NET debug_printf("parser returned %d\n", l); #endif /* check if the parse has to be called again */ if (l <= -10) { #ifdef DEBUG_ECMD_NET debug_printf("parser needs to be called again\n"); #endif state->parse_again = 1; l = -l - 10; } #ifdef DEBUG_ECMD_NET debug_printf("parser really returned %d\n", l); #endif if (l > 0) { state->outbuf[l++] = '\n'; state->out_len = l; } if (!state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("clearing buffer\n"); #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; } } }
void ecmd_net_main(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; if (!uip_poll()) { #ifdef DEBUG_ECMD_NET debug_printf("ecmd_net_main()\n"); #endif } if(uip_connected()) { #ifdef DEBUG_ECMD_NET debug_printf("new connection\n"); #endif state->in_len = 0; state->out_len = 0; state->parse_again = 0; state->close_requested = 0; memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); } if(uip_acked()) { state->out_len = 0; if (state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("transmission done, calling parser again\n"); #endif /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ int l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); /* check if the parse has to be called again */ if (l <= -10) { state->parse_again = 1; l = -l - 10; } else state->parse_again = 0; if (l > 0) { state->outbuf[l++] = '\n'; state->out_len = l; } } } if(uip_newdata()) { newdata(); } if(uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) { if (state->out_len > 0) { #ifdef DEBUG_ECMD_NET debug_printf("sending %d bytes\n", state->out_len); #endif uip_send(state->outbuf, state->out_len); } else if (state->close_requested) uip_close(); } }
int16_t parse_cmd_if(char *cmd, char *output, uint16_t len) { char cmpcmd[ECMD_SCRIPT_COMPARATOR_LENGTH]; char comparator[3]; char konst[ECMD_SCRIPT_COMPARATOR_LENGTH]; // char cmd[]= "if ( whm != 00:01 ) then exit"; uint8_t success = 0; // default false sscanf_P(cmd, PSTR("( %s %s %s ) then "), &cmpcmd, &comparator, &konst); char *ecmd = strstr_P(cmd, PSTR("then")); if (ecmd == NULL) { SCRIPTDEBUG("cmd not found\n"); return ECMD_FINAL(1); } ecmd += 5; SCRIPTDEBUG("ecmd: %s\n", ecmd); SCRIPTDEBUG("cmpcmd: %s\n", cmpcmd); SCRIPTDEBUG("comparator: %s\n", comparator); SCRIPTDEBUG("konst: %s\n", konst); // if cmpcmd starts with % it is a variable if (cmpcmd[0] == '%') { uint8_t varpos = cmpcmd[1] - '0'; // get variable and set it to output strcpy(output, vars[varpos].value); } else { // if not, it is a command // execute cmp! and check output if (!ecmd_parse_command(cmpcmd, output, len)) { SCRIPTDEBUG("compare wrong\n"); return ECMD_FINAL(1); } } SCRIPTDEBUG("cmp '%s' %s '%s'\n", output, comparator, konst); // check comparator if (strcmp(comparator, STR_EQUALS) == 0) { SCRIPTDEBUG("try " STR_EQUALS "\n"); success = (strcmp(output, konst) == 0); } else if (strcmp(comparator, STR_NOTEQUALS) == 0) { SCRIPTDEBUG("try " STR_NOTEQUALS "\n"); success = (strcmp(output, konst) != 0); } else { uint16_t outputvalue = atoi(output); uint16_t konstvalue = atoi(konst); // debug_printf("cmp atoi: %i %s %i\n", outputvalue, comparator, konstvalue); if (strcmp(comparator, OK) == 0) { SCRIPTDEBUG("try " OK "\n"); success = outputvalue; } else if (strcmp(comparator, NOT) == 0) { SCRIPTDEBUG("try " NOT "\n"); success = (outputvalue != 0); } else if (strcmp(comparator, EQUALS) == 0) { SCRIPTDEBUG("try " EQUALS "\n"); success = (outputvalue == konstvalue); } else if (strcmp(comparator, NOTEQUALS) == 0) { SCRIPTDEBUG("try " NOTEQUALS "\n"); success = (outputvalue != konstvalue); } else if (strcmp(comparator, GREATER) == 0) { SCRIPTDEBUG("try " GREATER "\n"); success = (outputvalue > konstvalue); } else if (strcmp(comparator, LOWER) == 0) { SCRIPTDEBUG("try " LOWER "\n"); success = (outputvalue < konstvalue); } else if (strcmp(comparator, GREATEREQUALS) == 0) { SCRIPTDEBUG("try " GREATEREQUALS "\n"); success = (outputvalue >= konstvalue); } else if (strcmp(comparator, LOWEREQUALS) == 0) { SCRIPTDEBUG("try " LOWEREQUALS "\n"); success = (outputvalue <= konstvalue); } else { // debug_printf("unknown comparator: %s\n", comparator); return ECMD_FINAL(3); } } // if compare ok, execute command after then if (success) { SCRIPTDEBUG("OK, do: %s\n", ecmd); if (ecmd_parse_command(ecmd, output, len)) { SCRIPTDEBUG("done: %s\n", output); return ECMD_FINAL(snprintf_P(output, len, PSTR("%s"), output)); } return ECMD_FINAL(2); } SCRIPTDEBUG("success was: %i\n", success); return ECMD_FINAL(1); }
void ecmd_net_main(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; if (!uip_poll()) { #ifdef DEBUG_ECMD_NET debug_printf("ecmd_net_main()\n"); #endif } if(uip_connected()) { #ifdef DEBUG_ECMD_NET debug_printf("new connection\n"); #endif state->in_len = 0; state->out_len = 0; state->parse_again = 0; state->parse_again = 0; state->close_requested = 0; #ifdef ECMD_PAM_SUPPORT state->pam_state = PAM_UNKOWN; #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); } #ifdef ECMD_PAM_SUPPORT if (state->pam_state == PAM_DENIED) { state->out_len = sprintf_P(state->outbuf, PSTR("authentification failed\n")); state->close_requested = 1; } #endif if(uip_acked() #ifdef ECMD_PAM_SUPPORT || (state->pam_state == PAM_SUCCESS && state->in_len) #endif ) { state->out_len = 0; if (state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("transmission done, calling parser again\n"); #endif /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ int l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); /* check if the parse has to be called again */ if (is_ECMD_AGAIN(l)) { state->parse_again = 1; l = ECMD_AGAIN(l); } else { state->parse_again = 0; /* We have to clear the input buffer */ state->in_len = 0; } if (l > 0) { state->outbuf[l++] = '\n'; state->out_len = l; } } } if(uip_newdata()) { newdata(); } if(uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) { if (state->out_len > 0) { #ifdef DEBUG_ECMD_NET debug_printf("sending %d bytes\n", state->out_len); #endif uip_send(state->outbuf, state->out_len); } else if (state->close_requested) uip_close(); } }
void newdata(void) { struct ecmd_connection_state_t *state = &uip_conn->appstate.ecmd; uint16_t diff = ECMD_INPUTBUF_LENGTH - state->in_len; if (diff > 0) { int cplen; if (uip_datalen() <= diff) cplen = uip_datalen(); else cplen = diff; memcpy(state->inbuf + state->in_len, uip_appdata, cplen); state->in_len += cplen; #ifdef DEBUG_ECMD_NET debug_printf("copied %d bytes\n", cplen); #endif } else { #ifdef DEBUG_ECMD_NET debug_printf("buffer full\n"); #endif } char *lf = memchr(state->inbuf, '\n', state->in_len); if (lf != NULL || memchr(uip_appdata, '\n', uip_datalen()) != NULL) { #ifdef DEBUG_ECMD_NET debug_printf("calling parser\n"); #endif if (lf) *lf = '\0'; else state->inbuf[ECMD_INPUTBUF_LENGTH-1] = '\0'; /* kill \r */ int l; for (l = 0; l < ECMD_INPUTBUF_LENGTH; l++) if (state->inbuf[l] == '\r') state->inbuf[l] = '\0'; /* if the first character is ! close the connection after the last * byte is sent */ uint8_t skip = 0; if (state->inbuf[0] == '!') { skip = 1; state->close_requested = 1; } #ifdef ECMD_PAM_SUPPORT if (state->pam_state == PAM_UNKOWN) { if (strncmp_P(state->inbuf + skip, PSTR("auth "), 5) != 0) { /* No authentification request */ auth_required: state->out_len = sprintf_P(state->outbuf, PSTR("authentification required\n")); memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; return; } else { char *user = state->inbuf + skip + 5; /* "auth " */ char *pass = strchr(user + 1,' '); if (! pass) goto auth_required; *pass = 0; do { pass++; } while (*pass == ' '); char *p = strchr(pass, ' '); if (p) *p = 0; /* Do the Pam request, the pam request will cache username and * passwort if its necessary. */ pam_auth(user, pass, &state->pam_state); if (p && p[1] != 0) { /* There ist something after the PAM request */ memmove(state->inbuf, p+1, strlen(p+1) + 1); skip = 0; state->in_len = strlen(p+1); if (state->pam_state == PAM_PENDING) state->parse_again = 1; } else { state->in_len = 0; return; } } } if (state->pam_state == PAM_PENDING || state->pam_state == PAM_DENIED) return; /* Pam Subsystem promisses to change this state */ #endif /* parse command and write output to state->outbuf, reserving at least * one byte for the terminating \n */ l = ecmd_parse_command(state->inbuf + skip, state->outbuf, ECMD_OUTPUTBUF_LENGTH-1); #ifdef DEBUG_ECMD_NET debug_printf("parser returned %d\n", l); #endif /* check if the parse has to be called again */ if (is_ECMD_AGAIN(l)) { #ifdef DEBUG_ECMD_NET debug_printf("parser needs to be called again\n"); #endif state->parse_again = 1; l = ECMD_AGAIN(l); } #ifdef DEBUG_ECMD_NET debug_printf("parser really returned %d\n", l); #endif if (l > 0) { if (state->outbuf[l] != ECMD_NO_NEWLINE) state->outbuf[l++] = '\n'; state->out_len = l; } if (!state->parse_again) { #ifdef DEBUG_ECMD_NET debug_printf("clearing buffer\n"); #endif memset(state->inbuf, 0, ECMD_INPUTBUF_LENGTH); state->in_len = 0; } } }