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