1 /*****************************************************************************
2  * Copyright (C) 2011-13 Qualys, Inc
3  * Copyright (C) 2013 The Apache Software Foundation
4  *
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * QUALYS licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  ****************************************************************************/
20 
21 /* libloader: load libraries, making all symbols exported
22  * universally visible.  Equivalent to LoadFile in HTTPD.
23  *
24  * Written for ironbee plugin, whose module architecture
25  * is not compatible with trafficserver's plugins.
26  * May be useful for other plugins with non-trivial
27  * library dependencies.
28  */
29 
30 #include <dlfcn.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ts/ts.h>
34 
35 typedef struct {
36   void *handle;
37   void *next;
38 } link_handle;
39 
40 static link_handle *libs = NULL;
41 
42 static void
unloadlibs(void)43 unloadlibs(void)
44 {
45   link_handle *p = libs;
46   while (p != NULL) {
47     link_handle *next = p->next;
48     dlclose(p->handle);
49     TSfree(p);
50     p = next;
51   }
52   libs = NULL;
53 }
54 
55 void
TSPluginInit(int argc,const char * argv[])56 TSPluginInit(int argc, const char *argv[])
57 {
58   int i;
59   TSPluginRegistrationInfo info;
60 
61   info.plugin_name   = (char *)"libloader";
62   info.vendor_name   = (char *)"Apache Software Foundation";
63   info.support_email = (char *)"dev@trafficserver.apache.org";
64 
65   if (TSPluginRegister(&info) != TS_SUCCESS) {
66     TSError("[libloader] Plugin registration failed.\n");
67     return;
68   }
69 
70   atexit(unloadlibs);
71 
72   for (i = 1; i < argc; ++i) {
73     const char *lib = argv[i];
74     void *handle    = dlopen(lib, RTLD_GLOBAL | RTLD_NOW);
75     if (handle) {
76       link_handle *l = TSmalloc(sizeof(link_handle));
77       l->handle      = handle;
78       l->next        = libs;
79       libs           = l;
80       TSDebug("libloader", " loaded %s", lib);
81     } else {
82       TSError("[libloader] failed to load %s: %s\n", lib, dlerror());
83     }
84   }
85   return;
86 }
87