UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <unistd.h> 32 33 #include "admin.h" 34 #include "../util/pblock.h" 35 36 #include "../config/conf.h" 37 #include "../config/objconf.h" 38 39 static Page *root_page; 40 41 int admin_init(pblock *pb, Session *sn, Request *rq) { 42 log_ereport(LOG_VERBOSE, "admin-init"); 43 pool_handle_t *pool = pool_create(); 44 root_page = admin_page_create(pool, NULL, admin_root); 45 46 Page *ls_page = admin_page_create(pool, "listener", adm_listener); 47 admin_add_page(root_page, ls_page); 48 Page *cfgls_page = admin_page_create(pool, NULL, adm_cfglistener); 49 admin_add_page(ls_page, cfgls_page); 50 51 Page *auth_page = admin_page_create(pool, "auth", adm_auth); 52 admin_add_page(root_page, auth_page); 53 54 return REQ_PROCEED; 55 } 56 57 int admin_service(pblock *pb, Session *sn, Request *rq) { 58 pblock_removekey(pb_key_content_type, rq->srvhdrs); 59 pblock_nvinsert("content-type", "text/plain", rq->srvhdrs); 60 protocol_status(sn, rq, 200, NULL); 61 http_start_response(sn, rq); 62 63 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); 64 uri++; 65 uri = strchr(uri, '/'); 66 size_t uri_len = uri ? strlen(uri) : 0; 67 // start with second character to skip leading '/' 68 int s = 0; 69 int i = 1; 70 Page *page = root_page; 71 for(;i<=uri_len;i++) { 72 char c = uri[i]; 73 if(c == '/' || c == '\0') { 74 if(i-s > 1) { 75 // we have the path element name 76 char *name = uri+s+1; 77 size_t name_len = i-s-1; 78 79 // get matching admin page 80 Page *child = page->children; 81 page = NULL; 82 while(child) { 83 if(child->name) { 84 if(!strncmp(child->name, name, name_len)) { 85 page = child; 86 break; 87 } 88 } else { 89 page = child; 90 break; 91 } 92 child = child->next; 93 } 94 95 if(!page) { 96 break; 97 } 98 99 s = i; 100 } 101 } 102 } 103 104 // service admin page 105 if(page) { 106 AdminRequest arq; 107 arq.sn = sn; 108 arq.rq = rq; 109 page->service(page, &arq); 110 } else { 111 net_printf(sn->csd, "page not found\n"); 112 } 113 114 return REQ_PROCEED; 115 } 116 117 int admin_root(Page *page, AdminRequest *rq) { 118 return REQ_PROCEED; 119 } 120 121 int adm_listener(Page *page, AdminRequest *rq) { 122 SYS_NETFD out = rq->sn->csd; 123 124 125 126 return REQ_PROCEED; 127 } 128 129 int adm_cfglistener(Page *page, AdminRequest *rq) { 130 printf("adm_cfglistener\n"); 131 return REQ_PROCEED; 132 } 133 134 int adm_auth(Page *page, AdminRequest *rq) { 135 printf("adm_auth\n"); 136 return REQ_PROCEED; 137 } 138 139 140 // public admin API 141 142 Page* admin_page_create(pool_handle_t *pool, char *name, admin_service_f f) { 143 Page *p = pool_malloc(pool, sizeof(Page)); 144 ZERO(p, sizeof(Page)); 145 if(name) { 146 p->name = pool_strdup(pool, name); 147 } 148 p->service = f; 149 return p; 150 } 151 152 void admin_add_page(Page *parent, Page *child) { 153 child->parent = parent; 154 Page *ch = parent->children; 155 if(ch) { 156 while(ch->next) { 157 ch = ch->next; 158 } 159 ch->next = child; 160 } else { 161 parent->children = child; 162 } 163 } 164