/usr/include/lcmaps/_lcmaps.h is in lcmaps-basic-interface 1.6.1-2build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | #ifndef _LCMAPS_H
#define _LCMAPS_H
#ifdef LCMAPS_USE_DLOPEN
#include <dlfcn.h>
#endif
/**
\defgroup LcmapsHiddenInterface The dark side of the LCMAPS interface
\brief This part of the interface should not be used or observed directly
The macros and declarations in this section define most of the
internal mechanics of the interface such as calling dlopen() and
dlsym(). They are only meant to be used by the public part of the
interface. The documentation serves as an aid in development, and
is at the very most useful as a (bad) example.
\warning Reading beyond this point may cause severe damage to one's appreciation
of C programming.
*/
/*!
\file _lcmaps.h
\brief LCMAPS programming interface
\authors Grid Security Middleware Team, Nikhef
The following macro soup is too long, overly complicated and hard
to follow. Here is why. An old bug in LCMAPS (actually, VOMS) was
that it missed certain 'version' functions. Each component in gLite
was required to have the functions getMajorVersion, getMinorVersion
and getPatchVersion. Early versions of LCMAPS did not export these
functions and none of the VOMS versions ever did (or ever
will). Some versions of LCMAPS called these functions assuming they
came from the VOMS library; in truth, the calls resolved to the
functions (under the same name, as C doesn't support scoping or
namespacing) in the LCAS library. In later versions of LCMAPS
these calls were removed. This bug remained hidden for a long time
as LCAS was always used in conjunction with LCMAPS. But when LCMAPS
is used without LCAS, the above functions are no longer resolvable
and calling them throws a run-time error. The workaround that is
applied e.g. in gLExec is to load the LCAS library if an old
version of LCMAPS is detected.
Users of the interface that a) do not use LCAS in conjunction with
LCMAPS and b) want to have the legacy behaviour of loading LCAS to
provide the above missing functions should #define
LCMAPS_UGLY_VERSION_BUG_HACK prior to including lcmaps.h.
The logic followed by this macro is then as follows:
- try to load the interface library with RTLD_NOW
- if this fails, try to reload with RTLD_LAZY
- if this also fails, the library is probably missing -> THE END
- else, load the helper library; dlsym the getMajorVersion function;
- if this fails, it's THE END
- otherwise reload (again) with RTLD_NOW. This could fail but shouldn't.
\ingroup LcmapsHiddenInterface
*/
/**
\brief The getMajorVersion prototype
This function is there only for testing whether the loading of the library
in combination with the helper library will succeed.
*/
typedef int getMajorVersion_t (void);
/**
\brief the major version funtion, present in newer LCMAPS libraries
This funtion is loaded if present and used (only once) to return the library version.
*/
typedef int lcmaps_get_major_version_t (void);
/**
\brief the major version funtion, present in newer LCMAPS libraries
This funtion is loaded if present and used (only once) to return the library minor version.
*/
typedef int lcmaps_get_minor_version_t (void);
/**
\brief the major version funtion, present in newer LCMAPS libraries
This funtion is loaded if present and used (only once) to return the library patchlevel version.
*/
typedef int lcmaps_get_patch_version_t (void);
# ifndef LCMAPS_USE_DLOPEN
lcmaps_get_major_version_t lcmaps_get_major_version;
lcmaps_get_minor_version_t lcmaps_get_minor_version;
lcmaps_get_patch_version_t lcmaps_get_patch_version;
#endif /* LCMAPS_USE_DLOPEN */
/**
\brief Collection of members to be included in the handle struct
The LCMAPS_HANDLE structure varies for each interface,
but they have some members in common.
*/
#define LCMAPS_HANDLE_VERSION_MEMBERS \
getMajorVersion_t *getMajorVersion; \
lcmaps_get_major_version_t *lcmaps_get_major_version; \
lcmaps_get_minor_version_t *lcmaps_get_minor_version; \
lcmaps_get_patch_version_t *lcmaps_get_patch_version; \
int majorversion,minorversion,patchversion
#ifdef LCMAPS_USE_DLOPEN
#define _LCMAPS_MAJOR_VERSION(l) ((l)->majorversion)
#define _LCMAPS_MINOR_VERSION(l) ((l)->minorversion)
#define _LCMAPS_PATCH_VERSION(l) ((l)->patchversion)
#define _LCMAPS_SET_LIBFILE_PATH(l,p) ((l)->libfilename = (p))
#define _LCMAPS_SET_HELPER_PATH(l,p) ((l)->helpername = (p))
#define LCMAPS_LOAD_FUNC(l,f) \
( \
dlerror(), \
(l)->f = (f ## _t *) dlsym(l->handle, #f), \
((l)->errmsg = dlerror()) == NULL \
)
/* Calling a loaded function is generally done through the following functions */
#define _LCMAPS_CALL(l,f) ( (l)->f )
#define _LCMAPS_LOAD_INTERFACE(l,d) \
( ( (l)->handle = dlopen((l)->libfilename, (d) | RTLD_GLOBAL)) != NULL )
/* store the error message and raise the error flag */
#define _LCMAPS_FAIL(l) ( ((l)->errmsg = dlerror()), 0)
/* #define LCMAPS_SUCCESS(l) ((l)->errmsg = dlerror(), 1) */
#ifdef LCMAPS_UGLY_VERSION_BUG_HACK
# define LCMAPS_FIXVOMSHACKSO "liblcas" LIBSUFF
#else
# define LCMAPS_FIXVOMSHACKSO "libvomsfix" LIBSUFF
#endif
#define _LCMAPS_LOAD_HELPER(l) \
( \
(l)->helper = dlopen(LCMAPS_FIXVOMSHACKSO, RTLD_NOW | RTLD_GLOBAL) \
)
#define _LCMAPS_GET_VERSION_LEVEL(l,v) \
( \
(l)->v ## version = \
( LCMAPS_LOAD_FUNC(l, lcmaps_get_ ## v ## _version) ? \
( (l)->lcmaps_get_ ## v ## _version() ) : \
0 \
) \
)
#define _LCMAPS_GET_VERSIONS(l) \
( \
_LCMAPS_GET_VERSION_LEVEL(l,major), \
_LCMAPS_GET_VERSION_LEVEL(l,minor), \
_LCMAPS_GET_VERSION_LEVEL(l,patch), \
1 \
)
/* loading the helper and finding getMajorVersion in case of an 'old' lcmaps */
#define _LCMAPS_LOAD_INTERFACE_WITH_HELPER(l) \
( \
_LCMAPS_LOAD_INTERFACE(l, RTLD_LAZY) && \
_LCMAPS_LOAD_HELPER(l) && \
LCMAPS_LOAD_FUNC(l, getMajorVersion) && \
(dlclose((l)->handle) == 0) && \
_LCMAPS_LOAD_INTERFACE(l,RTLD_NOW) \
)
#define _LCMAPS_LOAD_INTERFACE_WITH_FIX(l) \
( \
( \
( _LCMAPS_LOAD_INTERFACE(l,RTLD_NOW) \
|| _LCMAPS_LOAD_INTERFACE_WITH_HELPER(l) \
) && _LCMAPS_GET_VERSIONS(l) ) \
|| _LCMAPS_FAIL(l) \
)
#define _LCMAPS_ERRMSG(l) (l->errmsg)
#define _LCMAPS_REQUIRE_FUNC(l,f) LCMAPS_LOAD_FUNC(l,f)
#define LCMAPS_CLOSE_HANDLE(l) \
( \
dlerror(), \
( (l)->handle ? dlclose((l)->handle) : 1), \
( (l)->helper ? dlclose((l)->helper) : 1), \
( (l)->handle = (l)->helper = NULL ), \
( ( (l)->errmsg = dlerror() ) == NULL ) \
)
#else /* LCMAPS_USE_DLOPEN */
#define _LCMAPS_MAJOR_VERSION(l) (lcmaps_get_major_version())
#define _LCMAPS_MINOR_VERSION(l) (lcmaps_get_minor_version())
#define _LCMAPS_PATCH_VERSION(l) (lcmaps_get_patch_version())
#define _LCMAPS_SET_LIBFILE_PATH(l,p) (1)
#define _LCMAPS_SET_HELPER_PATH(l,p) (1)
#define LCMAPS_LOAD_FUNC(l,f) (1)
#define _LCMAPS_REQUIRE_FUNC(l,f) (1)
#define _LCMAPS_CALL(l,f) ( f )
#define _LCMAPS_ERRMSG(l) "This build is broken, LCMAPS_USE_DLOPEN is undefined."
#define LCMAPS_CLOSE_HANDLE(l) (1)
#endif /* LCMAPS_USE_DLOPEN */
#endif /* _LCMAPS_H */
|