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\">&nbsp;</a></TD>\n");
        !           252:            fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;close\">[Close]</A></TD>\n",
        !           289:                                L->name);
        !           290:                            break;
        !           291:                        default:
        !           292:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a>&nbsp;<A href=\"/cmd?link%%20%s&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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\">&nbsp;</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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;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&amp;close\">[Close]</A></TD>\n",
        !           369:                                L->name);
        !           370:                            break;
        !           371:                        default:
        !           372:                            fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a>&nbsp;<A href=\"/cmd?link%%20%s&amp;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&amp;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&amp;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&amp;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&amp;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>