static void protocol_parse(KFile *fd, const char *buf) { const struct CmdTemplate *templ; /* Command check. */ templ = parser_get_cmd_template(buf); if (!templ) { kfile_print(fd, "-1 Invalid command.\r\n"); protocol_prompt(fd); return; } parms args[PARSER_MAX_ARGS]; /* Args Check. TODO: Handle different case. see doc/PROTOCOL . */ if (!parser_get_cmd_arguments(buf, templ, args)) { kfile_print(fd, "-2 Invalid arguments.\r\n"); protocol_prompt(fd); return; } /* Execute. */ if(!parser_execute_cmd(templ, args)) { NAK(fd, "Error in executing command."); } if (!protocol_reply(fd, templ, args)) { NAK(fd, "Invalid return format."); } protocol_prompt(fd); return; }
void main(int argc, char *argv[]) { char *devdir; int i, rv, netfd, bsize; int datafd; #ifndef plan9 void (*oldhandler)(); #endif devdir = nil; /* make connection */ if (argc != 2) { fprint(stderr, "usage: %s network!destination!service\n", argv[0]); exits("incorrect number of arguments"); } /* read options line from stdin into lnbuf */ i = readline(0); /* read stdin into tempfile to get size */ datafd = tempfile(); bsize = prereadfile(datafd); /* network connection is opened after data is in to avoid timeout */ if ((netfd=dial(argv[1], 0, 0, 0)) < 0) { fprint(stderr, "dialing %s\n", devdir); perror("dial"); exits("can't dial"); } /* write out the options we read above */ if (write(netfd, lnbuf, i) != i) { error(0, "write error while sending options\n"); exits("write error while sending options"); } /* send the size of the file to be sent */ sprint(lnbuf, "%d\n", bsize); i = strlen(lnbuf); if ((rv=write(netfd, lnbuf, i)) != i) { perror("write error while sending size"); error(0, "write returned %d\n", rv); exits("write error while sending size"); } if (seek(datafd, 0L, 0) < 0) { error(0, "error seeking temp file\n"); exits("seek error"); } /* mirror performance in readfile() in lpdaemon */ #ifdef plan9 atnotify(alarmhandler, 1); #else oldhandler = signal(SIGALRM, alarmhandler); #endif dbgstate = 1; if(!recvACK(netfd)) { error(0, "failed to receive ACK before sending data\n"); exits("recv ack1 failed"); } dbgstate = 2; if ((i=pass(datafd, netfd, bsize)) != 0) { NAK(netfd); error(0, "failed to send %d bytes\n", i); exits("send data failed"); } ACK(netfd); dbgstate = 3; if(!recvACK(netfd)) { error(0, "failed to receive ACK after sending data\n"); exits("recv ack2 failed"); } /* get response, as from lp -q */ dbgstate = 4; while((rv=read(netfd, jobbuf, RDSIZE)) > 0) { if((write(1, jobbuf, rv)) != rv) { error(0, "write error while sending to stdout\n"); exits("write error while sending to stdout"); } } dbgstate = 5; #ifdef plan9 atnotify(alarmhandler, 0); /* close down network connections and go away */ exits(""); #else signal(SIGALRM, oldhandler); exit(0); #endif }