~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/module/library.cc

  • Committer: Monty Taylor
  • Date: 2009-05-19 21:30:11 UTC
  • mto: (1022.4.2 update-to-gcc-44)
  • mto: This revision was merged to the branch mainline in revision 1031.
  • Revision ID: mordred@inaugust.com-20090519213011-4tpejk7l2f1q7wrh
Added support for using gnutls instead of openssl for the md5 plugin. On Debian,
linking openssl against GPL software is sort of frowned on because it's one
of those murky areas. In this case, we can support gnutls by just changing a
header, so it saves us an argument with someone down the road.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include "config.h"
21
 
 
22
 
#include <dlfcn.h>
23
 
 
24
 
#include <cerrno>
25
 
#include <string>
26
 
 
27
 
#include <boost/filesystem.hpp>
28
 
 
29
 
#include "drizzled/plugin.h"
30
 
#include "drizzled/definitions.h"
31
 
#include "drizzled/error.h"
32
 
#include "drizzled/errmsg_print.h"
33
 
#include "drizzled/module/library.h"
34
 
 
35
 
using namespace std;
36
 
namespace fs=boost::filesystem;
37
 
 
38
 
namespace drizzled
39
 
{
40
 
 
41
 
module::Library::Library(const std::string &name_arg,
42
 
                         void *handle_arg,
43
 
                         const Manifest *manifest_arg)
44
 
 : name(name_arg), handle(handle_arg), manifest(manifest_arg)
45
 
{}
46
 
 
47
 
module::Library::~Library()
48
 
{
49
 
  /**
50
 
   * @TODO: This breaks valgrind at the moment. 
51
 
  if (handle)
52
 
    dlclose(handle);
53
 
  */
54
 
}
55
 
 
56
 
const fs::path module::Library::getLibraryPath(const string &plugin_name)
57
 
{
58
 
  string plugin_lib_name("lib");
59
 
  plugin_lib_name.append(plugin_name);
60
 
  plugin_lib_name.append("_plugin");
61
 
#if defined(TARGET_OS_OSX)
62
 
  plugin_lib_name.append(".dylib");
63
 
#else
64
 
  plugin_lib_name.append(".so");
65
 
#endif
66
 
 
67
 
  /* Compile dll path */
68
 
  return plugin_dir / plugin_lib_name;
69
 
}
70
 
 
71
 
module::Library *module::Library::loadLibrary(const string &plugin_name, bool builtin)
72
 
{
73
 
  /*
74
 
    Ensure that the dll doesn't have a path.
75
 
    This is done to ensure that only approved libraries from the
76
 
    plugin directory are used (to make this even remotely secure).
77
 
  */
78
 
  size_t found= plugin_name.find(FN_LIBCHAR);
79
 
  if (found != string::npos)
80
 
  {
81
 
    errmsg_printf(ERRMSG_LVL_ERROR, "%s",ER(ER_PLUGIN_NO_PATHS));
82
 
    return NULL;
83
 
  }
84
 
 
85
 
  void *dl_handle= NULL;
86
 
  string dlpath("");
87
 
 
88
 
  if (builtin)
89
 
  {
90
 
    dlpath.assign("<builtin>");
91
 
    dl_handle= dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
92
 
    if (dl_handle == NULL)
93
 
    {
94
 
      const char *errmsg= dlerror();
95
 
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY),
96
 
                    dlpath.c_str(), errno, errmsg);
97
 
      (void)dlerror();
98
 
 
99
 
      return NULL;
100
 
    }
101
 
  }
102
 
  else
103
 
  {
104
 
  /* Open new dll handle */
105
 
    dlpath.assign(Library::getLibraryPath(plugin_name).file_string());
106
 
    dl_handle= dlopen(dlpath.c_str(), RTLD_NOW|RTLD_GLOBAL);
107
 
    if (dl_handle == NULL)
108
 
    {
109
 
      const char *errmsg= dlerror();
110
 
      uint32_t dlpathlen= dlpath.length();
111
 
      if (not dlpath.compare(0, dlpathlen, errmsg))
112
 
      { // if errmsg starts from dlpath, trim this prefix.
113
 
        errmsg+= dlpathlen;
114
 
        if (*errmsg == ':') errmsg++;
115
 
        if (*errmsg == ' ') errmsg++;
116
 
      }
117
 
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_OPEN_LIBRARY),
118
 
                    dlpath.c_str(), errno, errmsg);
119
 
 
120
 
      // This, in theory, should cause dlerror() to deallocate the error
121
 
      // message. Found this via Google'ing :)
122
 
      (void)dlerror();
123
 
 
124
 
      return NULL;
125
 
    }
126
 
  }
127
 
 
128
 
  string plugin_decl_sym("_drizzled_");
129
 
  plugin_decl_sym.append(plugin_name);
130
 
  plugin_decl_sym.append("_plugin_");
131
 
 
132
 
  /* Find plugin declarations */
133
 
  void *sym= dlsym(dl_handle, plugin_decl_sym.c_str());
134
 
  if (sym == NULL)
135
 
  {
136
 
    const char* errmsg= dlerror();
137
 
    errmsg_printf(ERRMSG_LVL_ERROR, errmsg);
138
 
    errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_CANT_FIND_DL_ENTRY),
139
 
                  plugin_decl_sym.c_str(), dlpath.c_str());
140
 
    (void)dlerror();
141
 
    dlclose(dl_handle);
142
 
    return NULL;
143
 
  }
144
 
 
145
 
  const Manifest *module_manifest= static_cast<module::Manifest *>(sym); 
146
 
  if (module_manifest->drizzle_version != DRIZZLE_VERSION_ID)
147
 
  {
148
 
    errmsg_printf(ERRMSG_LVL_ERROR,
149
 
                  _("Plugin module %s was compiled for version %" PRIu64 ", "
150
 
                    "which does not match the current running version of "
151
 
                    "Drizzle: %" PRIu64"."),
152
 
                 dlpath.c_str(), module_manifest->drizzle_version,
153
 
                 static_cast<uint64_t>(DRIZZLE_VERSION_ID));
154
 
    return NULL;
155
 
  }
156
 
 
157
 
  return new (nothrow) module::Library(plugin_name, dl_handle, module_manifest);
158
 
}
159
 
 
160
 
} /* namespace drizzled */