• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Plugin.cc

Go to the documentation of this file.
00001 /** @file
00002 
00003   Plugin init
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #include <stdio.h>
00025 #include "ink_platform.h"
00026 #include "ink_file.h"
00027 #include "Compatability.h"
00028 #include "ParseRules.h"
00029 #include "I_RecCore.h"
00030 #include "I_Layout.h"
00031 #include "InkAPIInternal.h"
00032 #include "Main.h"
00033 #include "Plugin.h"
00034 #include "ink_cap.h"
00035 
00036 static const char *plugin_dir = ".";
00037 
00038 typedef void (*init_func_t) (int argc, char *argv[]);
00039 
00040 // Plugin registration vars
00041 //
00042 //    plugin_reg_list has an entry for each plugin
00043 //      we've successfully been able to load
00044 //    plugin_reg_current is used to associate the
00045 //      plugin we're in the process of loading with
00046 //      it struct.  We need this global pointer since
00047 //      the API doesn't have any plugin context.  Init
00048 //      is single threaded so we can get away with the
00049 //      global pointer
00050 //
00051 DLL<PluginRegInfo> plugin_reg_list;
00052 PluginRegInfo *plugin_reg_current = NULL;
00053 
00054 PluginRegInfo::PluginRegInfo()
00055   : plugin_registered(false), plugin_path(NULL), sdk_version(PLUGIN_SDK_VERSION_UNKNOWN),
00056     plugin_name(NULL), vendor_name(NULL), support_email(NULL)
00057 { }
00058 
00059 static void
00060 plugin_load(int argc, char *argv[])
00061 {
00062   char path[PATH_NAME_MAX + 1];
00063   void *handle;
00064   init_func_t init;
00065   PluginRegInfo *plugin_reg_temp;
00066 
00067   if (argc < 1) {
00068     return;
00069   }
00070   ink_filepath_make(path, sizeof(path), plugin_dir, argv[0]);
00071 
00072   Note("loading plugin '%s'", path);
00073 
00074   plugin_reg_temp = plugin_reg_list.head;
00075   while (plugin_reg_temp) {
00076     if (strcmp(plugin_reg_temp->plugin_path, path) == 0) {
00077       Warning("multiple loading of plugin %s", path);
00078       break;
00079     }
00080     plugin_reg_temp = (plugin_reg_temp->link).next;
00081   }
00082   // elevate the access to read files as root if compiled with capabilities, if not
00083   // change the effective user to root
00084   {
00085     uint32_t elevate_access = 0;
00086     REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
00087     ElevateAccess access(elevate_access != 0);
00088 
00089     handle = dlopen(path, RTLD_NOW);
00090     if (!handle) {
00091       Fatal("unable to load '%s': %s", path, dlerror());
00092     }
00093 
00094     // Allocate a new registration structure for the
00095     //    plugin we're starting up
00096     ink_assert(plugin_reg_current == NULL);
00097     plugin_reg_current = new PluginRegInfo;
00098     plugin_reg_current->plugin_path = ats_strdup(path);
00099 
00100     init = (init_func_t) dlsym(handle, "TSPluginInit");
00101     if (!init) {
00102       Fatal("unable to find TSPluginInit function in '%s': %s", path, dlerror());
00103       return; // this line won't get called since Fatal brings down ATS
00104     }
00105 
00106     init(argc, argv);
00107   } // done elevating access
00108 
00109   plugin_reg_list.push(plugin_reg_current);
00110   plugin_reg_current = NULL;
00111 }
00112 
00113 static char *
00114 plugin_expand(char *arg)
00115 {
00116   RecDataT data_type;
00117   char *str = NULL;
00118 
00119   if (*arg != '$') {
00120     return (char *) NULL;
00121   }
00122   // skip the $ character
00123   arg += 1;
00124 
00125   if (RecGetRecordDataType(arg, &data_type) != REC_ERR_OKAY) {
00126     goto not_found;
00127   }
00128 
00129   switch (data_type) {
00130   case RECD_STRING:
00131     {
00132       RecString str_val;
00133       if (RecGetRecordString_Xmalloc(arg, &str_val) != REC_ERR_OKAY) {
00134         goto not_found;
00135       }
00136       return (char *) str_val;
00137       break;
00138     }
00139   case RECD_FLOAT:
00140     {
00141       RecFloat float_val;
00142       if (RecGetRecordFloat(arg, &float_val) != REC_ERR_OKAY) {
00143         goto not_found;
00144       }
00145       str = (char *)ats_malloc(128);
00146       snprintf(str, 128, "%f", (float) float_val);
00147       return str;
00148       break;
00149     }
00150   case RECD_INT:
00151     {
00152       RecInt int_val;
00153       if (RecGetRecordInt(arg, &int_val) != REC_ERR_OKAY) {
00154         goto not_found;
00155       }
00156       str = (char *)ats_malloc(128);
00157       snprintf(str, 128, "%ld", (long int) int_val);
00158       return str;
00159       break;
00160     }
00161   case RECD_COUNTER:
00162     {
00163       RecCounter count_val;
00164       if (RecGetRecordCounter(arg, &count_val) != REC_ERR_OKAY) {
00165         goto not_found;
00166       }
00167       str = (char *)ats_malloc(128);
00168       snprintf(str, 128, "%ld", (long int) count_val);
00169       return str;
00170       break;
00171     }
00172   default:
00173     goto not_found;
00174     break;
00175   }
00176 
00177 
00178 not_found:
00179   Warning("plugin.config: unable to find parameter %s", arg);
00180   return NULL;
00181 }
00182 
00183 void
00184 plugin_init(void)
00185 {
00186   char path[PATH_NAME_MAX + 1];
00187   char line[1024], *p;
00188   char *argv[64];
00189   char *vars[64];
00190   int argc;
00191   int fd;
00192   int i;
00193   static bool INIT_ONCE = true;
00194 
00195   if (INIT_ONCE) {
00196     api_init();
00197     plugin_dir = TSPluginDirGet();
00198     INIT_ONCE = false;
00199   }
00200 
00201   Layout::get()->relative_to(path, sizeof(path), Layout::get()->sysconfdir, "plugin.config");
00202   fd = open(path, O_RDONLY);
00203   if (fd < 0) {
00204     Warning("unable to open plugin config file '%s': %d, %s", path, errno, strerror(errno));
00205     return;
00206   }
00207 
00208   while (ink_file_fd_readline(fd, sizeof(line) - 1, line) > 0) {
00209     argc = 0;
00210     p = line;
00211 
00212     // strip leading white space and test for comment or blank line
00213     while (*p && ParseRules::is_wslfcr(*p))
00214       ++p;
00215     if ((*p == '\0') || (*p == '#'))
00216       continue;
00217 
00218     // not comment or blank, so rip line into tokens
00219     while (1) {
00220       while (*p && ParseRules::is_wslfcr(*p))
00221         ++p;
00222       if ((*p == '\0') || (*p == '#'))
00223         break;                  // EOL
00224 
00225       if (*p == '\"') {
00226         p += 1;
00227 
00228         argv[argc++] = p;
00229 
00230         while (*p && (*p != '\"')) {
00231           p += 1;
00232         }
00233         if (*p == '\0') {
00234           break;
00235         }
00236         *p++ = '\0';
00237       } else {
00238         argv[argc++] = p;
00239 
00240         while (*p && !ParseRules::is_wslfcr(*p) && (*p != '#')) {
00241           p += 1;
00242         }
00243         if ((*p == '\0') || (*p == '#')) {
00244           break;
00245         }
00246         *p++ = '\0';
00247       }
00248     }
00249 
00250     for (i = 0; i < argc; i++) {
00251       vars[i] = plugin_expand(argv[i]);
00252       if (vars[i]) {
00253         argv[i] = vars[i];
00254       }
00255     }
00256 
00257     plugin_load(argc, argv);
00258 
00259     for (i = 0; i < argc; i++)
00260       ats_free(vars[i]);
00261   }
00262 
00263   close(fd);
00264 }
00265 

Generated by  doxygen 1.7.1