Annotation of embedaddon/mpd/src/web.c, revision 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>