00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
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 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
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   
00083   
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     
00095     
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; 
00104     }
00105 
00106     init(argc, argv);
00107   } 
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   
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     
00213     while (*p && ParseRules::is_wslfcr(*p))
00214       ++p;
00215     if ((*p == '\0') || (*p == '#'))
00216       continue;
00217 
00218     
00219     while (1) {
00220       while (*p && ParseRules::is_wslfcr(*p))
00221         ++p;
00222       if ((*p == '\0') || (*p == '#'))
00223         break;                  
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