/*************************************************************************** * receive_ui(): - This routine is called to read data * from a TCP connection. We look for an end-of-line and pass * full lines to the CLI parser. * * Input: FD of socket with data to read * Output: void * Effects: the Baseboard vie the CLI parser ***************************************************************************/ void receive_ui(int fd_in, int cb_data) { int nrd; /* number of bytes read */ int i; /* a temp int */ int gotline; /* set true if we get a full line */ int cn; /* index into UiCons */ UI *pui; /* pointer to UI at cn */ /* Locate the UI struct with fd equal to fd_in */ for (cn = 0 ; cn < MX_UI; cn++) { if (fd_in == UiCons[cn].fd) { break; } } /* Error if we could not find the fd */ if (MX_UI == cn) { /* Take this bogus fd out of the select loop */ del_fd(fd_in); close(fd_in); return; } pui = &(UiCons[cn]); /* We read data from the connection into the buffer in the ui struct. Once * we've read all of the data we can, we scan for a newline character and * pass any full lines to the parser. */ nrd = read(pui->fd, &(pui->cmd[pui->cmdindx]), (MXCMD - pui->cmdindx)); /* shutdown manager conn on error or on zero bytes read */ if ((nrd <= 0) && (errno != EAGAIN)) { close_ui_conn(cn); return; } pui->cmdindx += nrd; /* The commands are in the buffer. Call the parser to execute them */ do { gotline = 0; // Scan for a newline. If found, replace it with a null for (i = 0; i < pui->cmdindx; i++) { if (pui->cmd[i] == '\n') { pui->cmd[i] = (char) 0; gotline = 1; parse_and_execute(pui); (void) memmove(pui->cmd, &(pui->cmd[i+1]), (pui->cmdindx - (i+1))); pui->cmdindx -= i+1; break; } } } while ((gotline == 1) && (pui->cmdindx > 0)); return; }
int main(int argc, char **argv) { void *zmqcontext = zmq_init(1); assert(zmqcontext); void *zmqsock = zmq_socket(zmqcontext, ZMQ_REP); assert(zmqsock); char *dir = NULL; char *prefix = ""; char *presetdir = "/etc/jarred"; int prefixlen = 0; int opt; while((opt = getopt(argc, argv, "hc:b:d:p:s:")) != -1) { switch(opt) { case 'c': // connect STDASSERT(zmq_connect(zmqsock, optarg)) break; case 'b': // bind STDASSERT(zmq_bind(zmqsock, optarg)) break; case 'd': // dir dir = optarg; break; case 'p': // prefix prefix = optarg; prefixlen = strlen(optarg); break; case 's': // dir with presets presetdir = optarg; break; case 'h': print_usage(stdout); exit(0); default: print_usage(stderr); exit(1); } } if(!dir) { dir = getcwd(NULL, 0); } while(TRUE) { zmq_msg_t msg; zmq_msg_init(&msg); int rc = zmq_recv(zmqsock, &msg, 0); if(rc < 0) { if(errno == EINTR || errno == EAGAIN) continue; perror("Error receiving message"); abort(); } uint64_t opt; size_t opt_size = sizeof(opt); STDASSERT(zmq_getsockopt(zmqsock, ZMQ_RCVMORE, &opt, &opt_size)); assert(!opt); // could reopen socket, but restart is ok buffer_t *buf = malloc(sizeof(buffer_t)); buffer_init(buf, 1024); char *data = zmq_msg_data(&msg); int dlen = zmq_msg_size(&msg); if(dlen < prefixlen) { buffer_printf(buf, "{\"error\": \"uri too short\"}"); } else if(memcmp(data, prefix, prefixlen)) { buffer_printf(buf, "{\"error\": \"wrong path prefix\"}"); } else { data += prefixlen; dlen -= prefixlen; parse_and_execute(dir, presetdir, data, dlen, buf); } zmq_msg_init_data(&msg, buf->data, buf->size, (void (*)(void*, void*))free_buffer, buf); STDASSERT(zmq_send(zmqsock, &msg, 0)); } zmq_close(zmqsock); zmq_term(zmqcontext); // Free directory if needed }