9 #include "../layout/dlist.h"
11 struct ClientList clients;
13 void vbadcmd(ParseState *ps, const char *fmt, va_list al) {
14 oprintf(&ps->cl->ch,"error ");
15 ovprintf(&ps->cl->ch,fmt,al);
16 owrite(&ps->cl->ch,"\n",1);
19 const void *any_lookup(ParseState *ps, const void *inf, size_t sz) {
23 (tname= *(const char *const*)inf);
24 inf= (const char*)inf + sz)
25 if (!thiswordstrcmp(ps,tname))
30 const void *any_needword_lookup(ParseState *ps, const void *infs,
31 size_t sz, const char *what) {
33 if (!ps_needword(ps)) return 0;
34 r= any_lookup(ps,infs,sz);
35 if (!r) { badcmd(ps,"unknown %s",what); return 0; }
39 void ps_callword(ParseState *ps, const CmdInfo *infs, const char *what) {
41 ci= some_needword_lookup(ps,infs,what);
42 if (ci) ci->fn(ps,ci);
45 static void *client_iferr(oop_source *evts, oop_read *cl_read,
46 oop_rd_event evt, const char *errmsg, int errnoval,
47 const char *data, size_t recsz, void *cl_v) {
50 cl->ch.error(&cl->ch, "read",
51 oop_rd_errmsg(cl_read, evt,
52 errnoval, OOP_RD_STYLE_GETLINE));
56 static void *client_ifok(oop_source *evts, oop_read *cl_read,
57 oop_rd_event evt, const char *errmsg, int errnoval,
58 const char *data, size_t recsz, void *cl_v) {
62 if (evt == OOP_RD_EOF) {
63 cl->ch.error(&cl->ch,0,0);
68 return client_iferr(evts,cl_read,evt,errmsg,errnoval,data,recsz,cl_v);
72 ps_callword(&ps, toplevel_cmds, "command");
76 static void *client_exception(oop_source *evts, int fd,
77 oop_event evt, void *cl_v) {
79 cl->ch.error(&cl->ch,"comms error","exception");
83 static void new_client(int fd, OutBufferError error,
84 char *desc, Selector default_selectors) {
88 cl= mmalloc(sizeof(*cl));
90 cl->sel= default_selectors;
96 events->on_fd(events, fd, OOP_EXCEPTION, client_exception, cl);
98 cl->rd= oop_rd_new_fd(events, fd, 0,0);
99 if (!cl->rd) diee("oop_rd_new_fd");
100 r= oop_rd_read(cl->rd, OOP_RD_STYLE_GETLINE, 1024,
103 if (r) diee("oop_rd_read");
105 LIST_LINK_TAIL(clients, cl);
108 static void stdin_error(OutBufferChain *ch, const char *e1, const char *e2) {
111 fprintf(stderr,"stdin: %s: %s\n", e1, e2);
115 void stdin_client(void) {
116 new_client(0, stdin_error, (char*)"stdin", sel_picio|sel_picioh);