[insert project logo here (125x200px max)]

Navigator

Mailinglists

Please report any errors or ommissions you find to our `Help' mailinglist, or post a message in the Forums.

Copyright and Licensing Information

Snap is (c) Jonathan T. Moore, 1999-2002 and licensed under the GNU General Public License (GPL).

All other parts of Splash are (c) Willem de Bruijn, 2002-2003 and licensed under the BSD Open Source License.

All sourcecode is made publicly available.

Acknowledgement

Splash and the Splash website are hosted by SourceForge.net

SourceForge.net Logo

osi-open source certified logo

Splash - Documentation

SNMP Plus a Lightweight API for SNAP Handling

Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

snap-1.1-wjdb/lib/snap_svc_library_handler.c

Go to the documentation of this file.
00001 /*
00002     snap service handler
00003     library handler source file
00004     (c) 2003 Willem de Bruijn
00005     all code falls under the BSD License
00006 */
00007 
00008 /*
00009 dlopen() API programming tips (from http://www.linux.se/doc/HOWTO/Program-Library-HOWTO/dl-libraries.html)
00010 
00011 if a library exports a function named '_init' this is executed before dlopen(..) returns
00012 equally, '_fini' will be executed before dlclose(..) returns (if it exists)
00013 unfortunately, this behaviour is currently broken under Linux due to crt.o exporting the same symbols
00014 
00015 link the ELF object compiled using the dlopen() API againts libdl (add '-ldl' to your gcc statements)
00016 optionally (and preferably ;) you can also add the '-Wl,--export-dynamic' statement
00017 
00018 check the exports from a library using 'nm' (man page under nm(1))
00019 */
00020 
00021 #include <stdlib.h>
00022 
00023 #include <dlfcn.h>  /* for the dlopen() API*/
00024 #include <dirent.h> /* for scandir() */
00025 #include <string.h>
00026 #include <errno.h>
00027 
00028 #include "d_printf.h"
00029 
00030 #include "snap_svc_library_handler.h"
00031 
00032 /*
00033     LOW LEVEL dlopen() API FUNCTIONS 
00034 */
00035 int snap_svc_logerrors(int dLineNo){
00036     char* strError;
00037     int dErrorCount = 0;
00038     
00039     do {
00040         strError = dlerror();
00041         if (strError){
00042             d_printf(20,"\nsnap_svc : encountered dlopen API error at line %d: %s\n", dLineNo, strError);
00043             dErrorCount++;
00044         }
00045     } while (strError);
00046     
00047     return dErrorCount;
00048 }
00049 
00050 /* open a library, return OK ? false : true */
00051 int snap_svc_open(void** hDll, char* strLib){
00052 
00053     *hDll = dlopen(strLib,RTLD_NOW);
00054     if (! *hDll)
00055         return snap_svc_logerrors(__LINE__);
00056     else
00057         return 0;
00058 }
00059 
00060 /* bind a library function to a pointer */
00061 int snap_svc_bind(void* hDll, char* strFunc, void** hFunc){
00062     int dErrorsOccurred = 0;
00063     
00064     if (!hDll){
00065         d_printf(20,"snap_svc : trying to bind from closed library at %d\n", __LINE__);
00066         return -1;
00067     }
00068         
00069     
00070     *hFunc = dlsym(hDll,strFunc);
00071     if (!hFunc)
00072         /* 
00073             it is possible to retrieve NULL handles 
00074             therefore we test for errors before exiting with a failure
00075         */
00076         dErrorsOccurred = snap_svc_logerrors(__LINE__);
00077     
00078     return dErrorsOccurred;
00079 }
00080 
00081 /* close a library */
00082 int snap_svc_close(void** hDll){
00083     int dErrorsOccurred = 0;
00084     
00085     if (! *hDll)
00086         d_printf(20,"snap_svc : trying to close a library with a NULL handle at %d\n", __LINE__);
00087         
00088     if (dlclose(*hDll))
00089         dErrorsOccurred = snap_svc_logerrors(__LINE__);
00090     
00091     *hDll = NULL;
00092     
00093     return dErrorsOccurred;
00094 }
00095 
00096 /*
00097     DERIVED FUNCTIONS
00098 */
00099 
00100 /* helper functions for snap_svc_openmultiple */
00101 int snap_svc_openmultiple_selector_empty(const struct dirent* curentry){
00102     return (!strncmp(".so",&curentry->d_name[_D_EXACT_NAMLEN(curentry) - 3],3));
00103 }
00104 
00105 int snap_svc_openmultiple_selector_snapsvc(const struct dirent* curentry){
00106     
00107     /* the macro below uses different calculation methods based on the underlying OS */
00108     if (_D_EXACT_NAMLEN(curentry) <= (12 + 3) ) /* shorter than or equal to strncmp item1 + ".so" ? fail */
00109         return 0;
00110     else
00111         if (strncmp(".so",&curentry->d_name[_D_EXACT_NAMLEN(curentry) - 3],3))
00112             return 0;
00113         else{
00114             if (!strncmp("libsnap_svc_", curentry->d_name, 12))
00115                 d_printf(100,"\nsnap_svc : found a library: %s\n",curentry->d_name);
00116             return (!strncmp("libsnap_svc_", curentry->d_name, 12));
00117         }
00118     
00119 }
00120 /* 
00121     open all libraries in directory strDir that are accepted by the fileselector function
00122     returns the number of succesfully opened libraries, -1 on error
00123 */
00124 int snap_svc_openmultiple(void*** hDllList, char* strDir, snap_svc_fileselector thisSelector){
00125     struct dirent** returnEntries;
00126     int dEntryCount, dCurEntry=0, dSuccessCount=0;
00127 
00128     if (*hDllList){
00129         d_printf(50,"snap_svc : warning : received a non NULL pointer in snap_svc_openmultiple at lineno %d\n", __LINE__);  
00130         *hDllList = NULL;
00131     }
00132     
00133     dEntryCount = scandir(strDir, &returnEntries, thisSelector, alphasort);
00134     if (dEntryCount == -1){
00135         d_printf(20,"snap_svc : an error occurred while scanning a directory at lineno %d : dir %s error %d",__LINE__, strDir, errno);
00136         return -1;
00137     }
00138     
00139     if (dEntryCount == 0)
00140         return 0;
00141         
00142     /* try to load the files */
00143     *hDllList = (void**) calloc( (dEntryCount + 1) , sizeof(void*) );
00144     for (; dCurEntry < dEntryCount; dCurEntry++){
00145         if (! snap_svc_open(&(*hDllList)[dCurEntry], returnEntries[dCurEntry]->d_name) )
00146             dSuccessCount++;
00147         if ((int) (*hDllList)[dCurEntry] == -1)
00148             d_printf(20,"snap_svc : warning : a libpointer to -1 was returned at line %d, this will break memory mgmt\n",__LINE__);
00149         free (returnEntries[dCurEntry]);
00150     }
00151     (int) ((*hDllList)[dEntryCount]) = -1;
00152     free (returnEntries);
00153     
00154     return dSuccessCount;
00155 }
00156 
00157 /* try to close multiple libraries */
00158 int snap_svc_closemultiple(void*** hDllList){
00159     int dCurEntry = 0, dErrorCount = 0;
00160     
00161     if (!*hDllList)
00162         return 0;
00163         
00164     while (((int) ((*hDllList)[dCurEntry])) != -1){ /* while not at end of queue */
00165         if ( (*hDllList)[dCurEntry] ){
00166             dErrorCount = snap_svc_close(&(*hDllList)[dCurEntry]) % 1;
00167             (*hDllList)[dCurEntry] = NULL;
00168         }
00169         dCurEntry++;
00170     }
00171     free (*hDllList);
00172     hDllList = NULL;
00173     
00174     return dErrorCount;
00175 }