Annotation of embedaddon/mpd/src/web.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * web.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "web.h"
10: #include "util.h"
11:
12:
13: /*
14: * DEFINITIONS
15: */
16:
17: /* Set menu options */
18: enum {
19: SET_OPEN,
20: SET_CLOSE,
21: SET_SELF,
22: SET_DISABLE,
23: SET_ENABLE
24: };
25:
26:
27: /*
28: * INTERNAL FUNCTIONS
29: */
30:
31: static int WebSetCommand(Context ctx, int ac, char *av[], void *arg);
32:
33: static int WebServletRun(struct http_servlet *servlet,
34: struct http_request *req, struct http_response *resp);
35: static void WebServletDestroy(struct http_servlet *servlet);
36:
37: static void WebLogger(int sev, const char *fmt, ...);
38:
39: static void WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...);
40: static void WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl);
41: static void WebConsoleSessionShowPrompt(ConsoleSession cs);
42:
43: static void WebRunBinCmd(FILE *f, const char *query, int priv);
44: static void WebRunCmd(FILE *f, const char *query, int priv);
45: static void WebShowSummary(FILE *f, int priv);
46:
47: /*
48: * GLOBAL VARIABLES
49: */
50:
51: const struct cmdtab WebSetCmds[] = {
52: { "open", "Open the web" ,
53: WebSetCommand, NULL, 2, (void *) SET_OPEN },
54: { "close", "Close the web" ,
55: WebSetCommand, NULL, 2, (void *) SET_CLOSE },
56: { "self {ip} [{port}]", "Set web ip and port" ,
57: WebSetCommand, NULL, 2, (void *) SET_SELF },
58: { "enable [opt ...]", "Enable web option" ,
59: WebSetCommand, NULL, 2, (void *) SET_ENABLE },
60: { "disable [opt ...]", "Disable web option" ,
61: WebSetCommand, NULL, 2, (void *) SET_DISABLE },
62: { NULL },
63: };
64:
65:
66: /*
67: * INTERNAL VARIABLES
68: */
69:
70: static const struct confinfo gConfList[] = {
71: { 0, WEB_AUTH, "auth" },
72: { 0, 0, NULL },
73: };
74:
75: static struct pevent_ctx *gWebCtx = NULL;
76:
77: /*
78: * WebInit()
79: */
80:
81: int
82: WebInit(Web w)
83: {
84: /* setup web-defaults */
85: memset(w, 0, sizeof(*w));
86:
87: Enable(&w->options, WEB_AUTH);
88:
89: ParseAddr(DEFAULT_WEB_IP, &w->addr, ALLOW_IPV4|ALLOW_IPV6);
90: w->port = DEFAULT_WEB_PORT;
91:
92: return 0;
93: }
94:
95: /*
96: * WebOpen()
97: */
98:
99: int
100: WebOpen(Web w)
101: {
102: char addrstr[INET6_ADDRSTRLEN];
103:
104: if (w->srv) {
105: Log(LG_ERR, ("web: web already running"));
106: return -1;
107: }
108:
109: gWebCtx = pevent_ctx_create(MB_WEB, NULL);
110: if (!gWebCtx) {
111: Log(LG_ERR, ("%s: error pevent_ctx_create: %d", __FUNCTION__, errno));
112: return(-1);
113: }
114:
115: if (!(w->srv = http_server_start(gWebCtx, w->addr.u.ip4,
116: w->port, NULL, "mpd web server", WebLogger))) {
117: Log(LG_ERR, ("%s: error http_server_start: %d", __FUNCTION__, errno));
118: return(-1);
119: }
120:
121: w->srvlet.arg=NULL;
122: w->srvlet.hook=NULL;
123: w->srvlet.run=WebServletRun;
124: w->srvlet.destroy=WebServletDestroy;
125:
126: if (http_server_register_servlet(w->srv, &w->srvlet, NULL, ".*", 10) < 0) {
127: Log(LG_ERR, ("%s: error http_server_register_servlet: %d", __FUNCTION__, errno));
128: return(-1);
129: }
130:
131: Log(LG_ERR, ("web: listening on %s %d",
132: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
133: return 0;
134: }
135:
136: /*
137: * WebClose()
138: */
139:
140: int
141: WebClose(Web w)
142: {
143: if (!w->srv) {
144: Log(LG_ERR, ("web: web is not running"));
145: return -1;
146: }
147:
148: http_server_stop(&w->srv);
149: if (gWebCtx) pevent_ctx_destroy(&gWebCtx);
150:
151: return 0;
152: }
153:
154: /*
155: * WebStat()
156: */
157:
158: int
159: WebStat(Context ctx, int ac, char *av[], void *arg)
160: {
161: Web w = &gWeb;
162: char addrstr[64];
163:
164: Printf("Web configuration:\r\n");
165: Printf("\tState : %s\r\n", w->srv ? "OPENED" : "CLOSED");
166: Printf("\tIP-Address : %s\r\n", u_addrtoa(&w->addr,addrstr,sizeof(addrstr)));
167: Printf("\tPort : %d\r\n", w->port);
168:
169: Printf("Web options:\r\n");
170: OptStat(ctx, &w->options, gConfList);
171:
172: return 0;
173: }
174:
175: /*
176: * ConsoleSessionWriteV()
177: */
178:
179: static void
180: WebConsoleSessionWriteV(ConsoleSession cs, const char *fmt, va_list vl)
181: {
182: vfprintf((FILE *)(cs->cookie), fmt, vl);
183: }
184:
185: /*
186: * WebConsoleSessionWrite()
187: */
188:
189: static void
190: WebConsoleSessionWrite(ConsoleSession cs, const char *fmt, ...)
191: {
192: va_list vl;
193:
194: va_start(vl, fmt);
195: WebConsoleSessionWriteV(cs, fmt, vl);
196: va_end(vl);
197: }
198:
199: /*
200: * WebConsoleShowPrompt()
201: */
202:
203: static void
204: WebConsoleSessionShowPrompt(ConsoleSession cs)
205: {
206: if (cs->context.lnk)
207: cs->write(cs, "[%s] ", cs->context.lnk->name);
208: else if (cs->context.bund)
209: cs->write(cs, "[%s] ", cs->context.bund->name);
210: else if (cs->context.rep)
211: cs->write(cs, "[%s] ", cs->context.rep->name);
212: else
213: cs->write(cs, "[] ");
214: }
215:
216: static void
217: WebShowCSS(FILE *f)
218: {
219: fprintf(f, "body {font-family: Arial, Helvetica, Sans-Serif; background-color: #EEEEEE; }\n");
220: fprintf(f, "table {background-color: #FFFFFF; }\n");
221: fprintf(f, "th, td {padding: 0 2pt 0 2pt; }\n");
222: fprintf(f, "th {background-color: #00B000; }\n");
223: fprintf(f, "td {background-color: #EEEEEE; }\n");
224: fprintf(f, "td.r {background-color: #EECCCC; }\n");
225: fprintf(f, "td.y {background-color: #EEEEBB; }\n");
226: fprintf(f, "td.g {background-color: #BBEEBB; }\n");
227: fprintf(f, "td.d {background-color: #CCCCCC; }\n");
228: fprintf(f, "pre {background-color: #FFFFFF; }\n");
229: fprintf(f, "a, a:visited, a:link { color: blue; }\n");
230: }
231:
232: static void
233: WebShowSummary(FILE *f, int priv)
234: {
235: int b,l;
236: Bund B;
237: Link L;
238: Rep R;
239: char buf[64],buf2[64];
240:
241: fprintf(f, "<H2>Current status summary</H2>\n");
242: fprintf(f, "<table>\n");
243: fprintf(f, "<TR><TH>Bund</TH><TH colspan=2>Iface</TH><TH>IPCP</TH><TH>IPV6CP</TH><TH>CCP</TH><TH>ECP</TH>"
244: "<TH>Link</TH><TH>LCP</TH><TH>User</TH><TH colspan=2>Device</TH><TH>Peer</TH><TH>IP</TH><TH colspan=3></TH>%s</TR>",
245: priv?"<TH>State</TH>":"");
246: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
247: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
248: for (b = 0; b<gNumLinks; b++) {
249: if ((L=gLinks[b]) != NULL && L->bund == NULL && L->rep == NULL) {
250: fprintf(f, "<TR>\n");
251: fprintf(f, "<TD colspan=\"7\"> </a></TD>\n");
252: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20link\">%s</a></TD>\n",
253: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
254: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20lcp\">%s</a></TD>\n",
255: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
256: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20auth\">%s</a></TD>\n",
257: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
258: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
259: L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
260: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
261: L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
262: if (L->state != PHYS_STATE_DOWN) {
263: PhysGetPeerAddr(L, buf, sizeof(buf));
264: fprintf(f, "<TD>%s</TD>\n", buf);
265: fprintf(f, "<TD></TD>\n");
266: PhysGetCallingNum(L, buf, sizeof(buf));
267: PhysGetCalledNum(L, buf2, sizeof(buf2));
268: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
269: fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n",
270: buf2, buf);
271: } else {
272: fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n",
273: buf, buf2);
274: }
275: } else {
276: fprintf(f, "<TD></TD>\n");
277: fprintf(f, "<TD></TD>\n");
278: fprintf(f, "<TD colspan=3></TD>\n");
279: }
280: if (priv) {
281: if (!L->tmpl) {
282: switch (L->state) {
283: case PHYS_STATE_DOWN:
284: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&open\">[Open]</A></TD>\n",
285: L->name);
286: break;
287: case PHYS_STATE_UP:
288: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&close\">[Close]</A></TD>\n",
289: L->name);
290: break;
291: default:
292: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&open\">[Open]</a> <A href=\"/cmd?link%%20%s&close\">[Close]</a></TD>\n",
293: L->name, L->name);
294: }
295: } else {
296: fprintf(f, "<TD></TD>\n");
297: }
298: }
299: fprintf(f, "</TR>\n");
300: }
301: }
302: for (b = 0; b<gNumBundles; b++) {
303: if ((B=gBundles[b]) != NULL) {
304: int rows = B->n_links?B->n_links:1;
305: int first = 1;
306: fprintf(f, "<TR>\n");
307: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20bund\">%s</a></TD>\n",
308: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->name);
309: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20iface\">%s</a></TD>\n",
310: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, B->iface.ifname);
311: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20iface\">%s</a></TD>\n",
312: rows, B->tmpl?"d":(B->iface.up?"g":"r"), B->name, (B->iface.up?"Up":"Down"));
313: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20ipcp\">%s</a></TD>\n",
314: rows, B->tmpl?"d":FSM_COLOR(B->ipcp.fsm.state), B->name,FsmStateName(B->ipcp.fsm.state));
315: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20ipv6cp\">%s</a></TD>\n",
316: rows, B->tmpl?"d":FSM_COLOR(B->ipv6cp.fsm.state), B->name,FsmStateName(B->ipv6cp.fsm.state));
317: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20ccp\">%s</a></TD>\n",
318: rows, B->tmpl?"d":FSM_COLOR(B->ccp.fsm.state), B->name,FsmStateName(B->ccp.fsm.state));
319: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?bund%%20%s&show%%20ecp\">%s</a></TD>\n",
320: rows, B->tmpl?"d":FSM_COLOR(B->ecp.fsm.state), B->name,FsmStateName(B->ecp.fsm.state));
321: if (B->n_links == 0) {
322: fprintf(f, "<TD colspan=\"11\"> </a></TD>\n</TR>\n");
323: }
324: for (l = 0; l < NG_PPP_MAX_LINKS; l++) {
325: if ((L=B->links[l]) != NULL) {
326: if (first)
327: first = 0;
328: else
329: fprintf(f, "<TR>\n");
330: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20link\">%s</a></TD>\n",
331: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->name);
332: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20lcp\">%s</a></TD>\n",
333: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
334: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20auth\">%s</a></TD>\n",
335: L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
336: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
337: L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
338: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
339: L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
340: if (L->state != PHYS_STATE_DOWN) {
341: PhysGetPeerAddr(L, buf, sizeof(buf));
342: fprintf(f, "<TD>%s</TD>\n", buf);
343: if (L->bund != NULL)
344: fprintf(f, "<TD>%s</TD>\n", inet_ntoa(L->bund->ipcp.peer_addr));
345: else
346: fprintf(f, "<TD></TD>\n");
347: PhysGetCallingNum(L, buf, sizeof(buf));
348: PhysGetCalledNum(L, buf2, sizeof(buf2));
349: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
350: fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n",
351: buf2, buf);
352: } else {
353: fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n",
354: buf, buf2);
355: }
356: } else {
357: fprintf(f, "<TD></TD>\n");
358: fprintf(f, "<TD></TD>\n");
359: fprintf(f, "<TD colspan=3></TD>\n");
360: }
361: if (priv) {
362: switch (L->state) {
363: case PHYS_STATE_DOWN:
364: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&open\">[Open]</A></TD>\n",
365: L->name);
366: break;
367: case PHYS_STATE_UP:
368: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&close\">[Close]</A></TD>\n",
369: L->name);
370: break;
371: default:
372: fprintf(f, "<TD><A href=\"/cmd?link%%20%s&open\">[Open]</a> <A href=\"/cmd?link%%20%s&close\">[Close]</a></TD>\n",
373: L->name, L->name);
374: }
375: }
376: fprintf(f, "</TR>\n");
377: }
378: }
379: }
380: }
381: for (b = 0; b<gNumReps; b++) {
382: if ((R=gReps[b]) != NULL) {
383: int shown = 0;
384: #define FSM_COLOR(s) (((s)==ST_OPENED)?"g":(((s)==ST_INITIAL)?"r":"y"))
385: #define PHYS_COLOR(s) (((s)==PHYS_STATE_UP)?"g":(((s)==PHYS_STATE_DOWN)?"r":"y"))
386: int rows = (R->links[0]?1:0) + (R->links[1]?1:0);
387: if (rows == 0)
388: rows = 1;
389: fprintf(f, "<TR>\n");
390: fprintf(f, "<TD rowspan=\"%d\" colspan=6>Repeater</TD>\n", rows);
391: fprintf(f, "<TD rowspan=\"%d\" class=\"%s\"><A href=\"/cmd?rep%%20%s&show%%20repeater\">%s</a></TD>\n",
392: rows, R->p_up?"g":"r", R->name, R->name);
393: for (l = 0; l < 2; l++) {
394: if ((L=R->links[l]) != NULL) {
395: if (shown)
396: fprintf(f, "<TR>\n");
397: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
398: PHYS_COLOR(L->state), L->name, L->name);
399: fprintf(f, "<TD colspan=2></TD>\n");
400: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
401: PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
402: fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&show%%20device\">%s</a></TD>\n",
403: PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
404: if (L->state != PHYS_STATE_DOWN) {
405: PhysGetPeerAddr(L, buf, sizeof(buf));
406: fprintf(f, "<TD>%s</TD>\n", buf);
407: if (L->bund != NULL)
408: fprintf(f, "<TD>%s</TD>\n", inet_ntoa(L->bund->ipcp.peer_addr));
409: else
410: fprintf(f, "<TD></TD>\n");
411: PhysGetCallingNum(L, buf, sizeof(buf));
412: PhysGetCalledNum(L, buf2, sizeof(buf2));
413: if (PhysGetOriginate(L) == LINK_ORIGINATE_REMOTE) {
414: fprintf(f, "<TD>%s</TD><TD><=</TD><TD>%s</TD>\n",
415: buf2, buf);
416: } else {
417: fprintf(f, "<TD>%s</TD><TD>=></TD><TD>%s</TD>\n",
418: buf, buf2);
419: }
420: } else {
421: fprintf(f, "<TD></TD>\n");
422: fprintf(f, "<TD></TD>\n");
423: fprintf(f, "<TD colspan=3></TD>\n");
424: }
425: fprintf(f, "<TD></TD>\n");
426: fprintf(f, "</TR>\n");
427:
428: shown = 1;
429: }
430: }
431: if (!shown) {
432: fprintf(f, "<TD colspan = \"11\"></TD>\n");
433: fprintf(f, "</TR>\n");
434: }
435: }
436: }
437: fprintf(f, "</TABLE>\n");
438: }
439:
440: static void
441: WebRunBinCmd(FILE *f, const char *query, int priv)
442: {
443: Console c = &gConsole;
444: struct console_session css;
445: ConsoleSession cs = &css;
446: char *buf;
447: char *tmp;
448: int argc, k;
449: char *argv[MAX_CONSOLE_ARGS];
450:
451: memset(cs, 0, sizeof(*cs));
452:
453: cs->cookie = f;
454: cs->console = c;
455: cs->close = NULL;
456: cs->write = WebConsoleSessionWrite;
457: cs->writev = WebConsoleSessionWriteV;
458: cs->prompt = WebConsoleSessionShowPrompt;
459: cs->context.cs = cs;
460: cs->context.priv = priv;
461:
462: tmp = buf = Mstrdup(MB_WEB, query);
463: for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
464: if (argv[argc][0] != '\0')
465: if (++argc >= MAX_CONSOLE_ARGS)
466: break;
467:
468: for (k = 0; k < argc; k++) {
469: int ac, rtn;
470: char *av[MAX_CONSOLE_ARGS];
471: char *buf1;
472:
473: buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
474: http_request_url_decode(argv[k], buf1);
475: Log2(LG_CONSOLE, ("[%s] WEB: %s",
476: cs->context.lnk ? cs->context.lnk->name :
477: (cs->context.bund? cs->context.bund->name : ""),
478: buf1));
479: ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
480: cs->context.errmsg[0] = 0;
481: rtn = DoCommandTab(&cs->context, gCommands, ac, av);
482: Freee(buf1);
483: fprintf(f, "RESULT: %d %s\n", rtn, cs->context.errmsg);
484: }
485: Freee(buf);
486: RESETREF(cs->context.lnk, NULL);
487: RESETREF(cs->context.bund, NULL);
488: RESETREF(cs->context.rep, NULL);
489: }
490:
491: static void
492: WebRunCmd(FILE *f, const char *query, int priv)
493: {
494: Console c = &gConsole;
495: struct console_session css;
496: ConsoleSession cs = &css;
497: char *buf;
498: char *tmp;
499: int argc, k;
500: char *argv[MAX_CONSOLE_ARGS];
501:
502: memset(cs, 0, sizeof(*cs));
503:
504: cs->cookie = f;
505: cs->console = c;
506: cs->close = NULL;
507: cs->write = WebConsoleSessionWrite;
508: cs->writev = WebConsoleSessionWriteV;
509: cs->prompt = WebConsoleSessionShowPrompt;
510: cs->context.cs = cs;
511: cs->context.priv = priv;
512:
513: tmp = buf = Mstrdup(MB_WEB, query);
514: for (argc = 0; (argv[argc] = strsep(&tmp, "&")) != NULL;)
515: if (argv[argc][0] != '\0')
516: if (++argc >= MAX_CONSOLE_ARGS)
517: break;
518:
519: fprintf(f, "<P><A href=\"/\"><< Back</A></P>\n");
520:
521: if (argc == 0) {
522: fprintf(f, "<P>No command cpecified!</P>\n");
523: goto done;
524: }
525:
526: fprintf(f, "<PRE>\n");
527: for (k = 0; k < argc; k++) {
528: int ac;
529: char *av[MAX_CONSOLE_ARGS];
530: char *buf1;
531:
532: buf1 = Malloc(MB_WEB, strlen(argv[k]) + 1);
533: http_request_url_decode(argv[k], buf1);
534: Log2(LG_CONSOLE, ("[%s] WEB: %s",
535: cs->context.lnk ? cs->context.lnk->name :
536: (cs->context.bund? cs->context.bund->name : ""),
537: buf1));
538:
539: cs->prompt(cs);
540: cs->write(cs, "%s\n", buf1);
541:
542: ac = ParseLine(buf1, av, sizeof(av) / sizeof(*av), 0);
543: DoCommand(&cs->context, ac, av, NULL, 0);
544: Freee(buf1);
545: }
546: fprintf(f, "</PRE>\n");
547: done:
548: Freee(buf);
549: fprintf(f, "<P><A href=\"/\"><< Back</A></P>\n");
550: RESETREF(cs->context.lnk, NULL);
551: RESETREF(cs->context.bund, NULL);
552: RESETREF(cs->context.rep, NULL);
553: }
554:
555: static void
556: WebServletRunCleanup(void *cookie) {
557: GIANT_MUTEX_UNLOCK();
558: }
559:
560: static int
561: WebServletRun(struct http_servlet *servlet,
562: struct http_request *req, struct http_response *resp)
563: {
564: FILE *f;
565: const char *path;
566: const char *query;
567: int priv = 0;
568:
569: if (Enabled(&gWeb.options, WEB_AUTH)) {
570: const char *username;
571: const char *password;
572: ConsoleUser u;
573: struct console_user iu;
574:
575: /* Get username and password */
576: if ((username = http_request_get_username(req)) == NULL)
577: username = "";
578: if ((password = http_request_get_password(req)) == NULL)
579: password = "";
580:
581: strlcpy(iu.username, username, sizeof(iu.username));
582: RWLOCK_RDLOCK(gUsersLock);
583: u = ghash_get(gUsers, &iu);
584: RWLOCK_UNLOCK(gUsersLock);
585:
586: if ((u == NULL) || strcmp(u->password, password)) {
587: http_response_send_basic_auth(resp, "Access Restricted");
588: return (1);
589: }
590: priv = u->priv;
591: }
592:
593: if (!(f = http_response_get_output(resp, 1))) {
594: return 0;
595: }
596: if (!(path = http_request_get_path(req)))
597: return 0;
598: if (!(query = http_request_get_query_string(req)))
599: return 0;
600:
601: if (!strcmp(path,"/mpd.css")) {
602: http_response_set_header(resp, 0, "Content-Type", "text/css");
603: WebShowCSS(f);
604: } else if (!strcmp(path,"/bincmd")) {
605: http_response_set_header(resp, 0, "Content-Type", "text/plain");
606: http_response_set_header(resp, 1, "Pragma", "no-cache");
607: http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
608:
609: pthread_cleanup_push(WebServletRunCleanup, NULL);
610: GIANT_MUTEX_LOCK();
611: WebRunBinCmd(f, query, priv);
612: GIANT_MUTEX_UNLOCK();
613: pthread_cleanup_pop(0);
614: } else if (!strcmp(path,"/") || !strcmp(path,"/cmd")) {
615: http_response_set_header(resp, 0, "Content-Type", "text/html");
616: http_response_set_header(resp, 1, "Pragma", "no-cache");
617: http_response_set_header(resp, 1, "Cache-Control", "no-cache, must-revalidate");
618:
619: pthread_cleanup_push(WebServletRunCleanup, NULL);
620: GIANT_MUTEX_LOCK();
621: fprintf(f, "<!DOCTYPE HTML "
622: "PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
623: "\"http://www.w3.org/TR/html4/strict.dtd\">\n");
624: fprintf(f, "<HTML>\n");
625: fprintf(f, "<HEAD><TITLE>Multi-link PPP Daemon for FreeBSD (mpd)</TITLE>\n");
626: fprintf(f, "<LINK rel='stylesheet' href='/mpd.css' type='text/css'>\n");
627: fprintf(f, "</HEAD>\n<BODY>\n");
628: fprintf(f, "<H1>Multi-link PPP Daemon for FreeBSD</H1>\n");
629:
630: if (!strcmp(path,"/"))
631: WebShowSummary(f, priv);
632: else if (!strcmp(path,"/cmd"))
633: WebRunCmd(f, query, priv);
634:
635: GIANT_MUTEX_UNLOCK();
636: pthread_cleanup_pop(0);
637:
638: fprintf(f, "</BODY>\n</HTML>\n");
639: } else {
640: http_response_send_error(resp, 404, NULL);
641: }
642: return 1;
643: }
644:
645: static void
646: WebServletDestroy(struct http_servlet *servlet)
647: {
648: }
649:
650: static void
651: WebLogger(int sev, const char *fmt, ...)
652: {
653: va_list args;
654:
655: va_start(args, fmt);
656: vLogPrintf(fmt, args);
657: va_end(args);
658: }
659:
660: /*
661: * WebSetCommand()
662: */
663:
664: static int
665: WebSetCommand(Context ctx, int ac, char *av[], void *arg)
666: {
667: Web w = &gWeb;
668: int port;
669:
670: switch ((intptr_t)arg) {
671:
672: case SET_OPEN:
673: WebOpen(w);
674: break;
675:
676: case SET_CLOSE:
677: WebClose(w);
678: break;
679:
680: case SET_ENABLE:
681: EnableCommand(ac, av, &w->options, gConfList);
682: break;
683:
684: case SET_DISABLE:
685: DisableCommand(ac, av, &w->options, gConfList);
686: break;
687:
688: case SET_SELF:
689: if (ac < 1 || ac > 2)
690: return(-1);
691:
692: if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4))
693: Error("Bogus IP address given %s", av[0]);
694:
695: if (ac == 2) {
696: port = strtol(av[1], NULL, 10);
697: if (port < 1 || port > 65535)
698: Error("Bogus port given %s", av[1]);
699: w->port=port;
700: }
701: break;
702:
703: default:
704: return(-1);
705:
706: }
707:
708: return 0;
709: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>