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 <dlfcn.h> 30 #include <cx/string.h> 31 32 #include "../daemon/func.h" 33 #include "../daemon/log.h" 34 #include "../daemon/config.h" 35 36 #include "init.h" 37 38 int init_test(pblock *pb, Session *sn, Request *rq) { 39 printf("init-test\n"); 40 return REQ_PROCEED; 41 } 42 43 int load_modules(pblock *pb, Session *sn, Request *rq) { 44 char *shlib = pblock_findval("shlib", pb); 45 char *funcs = pblock_findval("funcs", pb); 46 47 if(shlib == NULL || funcs == NULL) { 48 log_ereport(LOG_MISCONFIG, "load-modules: missing parameters"); 49 if(!shlib && funcs) { 50 log_ereport( 51 LOG_MISCONFIG, 52 "load-modules: missing shlib parameter"); 53 } else if(!shlib && !funcs) { 54 log_ereport( 55 LOG_MISCONFIG, 56 "load-modules: missing funcs parameter"); 57 } else { 58 log_ereport( 59 LOG_MISCONFIG, 60 "load-modules: missing shlib and funcs parameters"); 61 } 62 } 63 64 // load lib 65 void *lib = dlopen(shlib, RTLD_GLOBAL | RTLD_NOW); 66 if(lib == NULL) { 67 char *dlerr = dlerror(); 68 fprintf(stderr, "Cannot load library %s %s\n", shlib, dlerr); 69 70 log_ereport(LOG_FAILURE, "Cannot load library %s: %s", shlib, dlerr); 71 72 return REQ_ABORTED; 73 } 74 75 // load function symbols 76 pool_handle_t *init_pool = cfg_get_init_pool(); 77 int b = 0; 78 for(int i=0;;i++) { 79 if(funcs[i] == '-') { 80 funcs[i] = '_'; 81 } 82 if(funcs[i] == ',' || funcs[i] == 0) { 83 if(funcs[i] == 0) { 84 b = 1; 85 } 86 87 // TODO: although this works fine, is not really clean to just 88 // destroy the string with random 0-bytes 89 // maybe use cxstr here 90 funcs[i] = 0; 91 92 // we have a function name 93 void *sym = dlsym(lib, funcs); 94 if(sym == NULL) { 95 fprintf(stderr, "Cannot load symbol %s\n", funcs); 96 dlclose(lib); 97 return REQ_ABORTED; 98 } 99 struct FuncStruct fc; 100 ZERO(&fc, sizeof(struct FuncStruct)); 101 fc.func = (FuncPtr)sym; 102 fc.name = pool_strdup(init_pool, funcs); 103 add_function(&fc); 104 105 if(b) { 106 break; 107 } 108 109 funcs += i + 1; 110 i = 0; 111 } 112 } 113 114 // if exists, execute nsapi_module_init 115 void *sym = dlsym(lib, "nsapi_module_init"); 116 if(sym) { 117 /* 118 * We remove shlib and funcs from the pblock. The module init function 119 * gets all remaining parameters. 120 */ 121 pblock_remove("shlib", pb); 122 pblock_remove("funcs", pb); 123 124 FuncPtr init_func = (FuncPtr)sym; 125 int ret = init_func(pb, NULL, NULL); 126 if(ret != REQ_PROCEED && ret != REQ_NOACTION) { 127 log_ereport( 128 LOG_FAILURE, 129 "nsapi_module_init for module %s failed", 130 shlib); 131 return REQ_ABORTED; 132 } 133 } 134 135 return REQ_PROCEED; 136 } 137