Added SILC Thread Queue API
[silc.git] / lib / silcsim / silcsim.c
1 /*
2
3   silcsim.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12   
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /*
20   These routines implement the SILC Module (SIM) support. SIM's are
21   dynamically run-time loaded shared objects that can implement some
22   routines SILC can use to extend its features. Currently all
23   SILC Crypto modules are implemented as SIM's. They all implement
24   the SILC Crypto API and can be loaded run-time into the SILC and
25   used when needed. 
26
27   Basically any SILC API can be implemented as SIM, however, currently
28   only SILC Crypto modules (ciphers and hash functions (PKCS are not
29   supported)) are supported.
30
31   This implementation expects that no SILC specific symbols needs to
32   be exported into the SIM's. This means that SIM's cannot directly
33   use SILC specific symbols or definitions. This feature can be
34   supported with SIM's but currently (with Crypto modules) this is
35   not needed. 
36
37   NOTE: These routines maybe highly system dependant thus I can expect 
38   some heavy #ifdef's here. However, I'm more happy to see some macro 
39   SIM API and restrict the #ifdef's to silcsim.h file.
40
41 */
42
43 #include "silc.h"
44
45 /* 
46    SILC Module (SIM) Context.
47
48    This context holds relevant information about the SIM loaded into
49    the system. Following short description of the fields.
50
51    void *handle
52
53        Pointer to the SIM. This is used to get the symbols out of
54        the SIM. This is initalized by system specific routine.
55
56    SilcSimType type
57
58        Type of the SIM.
59
60    char *libname;
61
62        Filename and path to the SIM library file.
63
64    int flags
65
66        Flags used with the SIM. These are system specific flags.
67        See below for more information.
68
69 */
70 struct SilcSimStruct {
71   void *handle;
72   SilcSimType type;
73   char *libname;
74   int flags;
75 };
76
77 #ifdef SILC_SIM                 /* SIM upport enabled */
78
79 /* Allocates new SIM context. This is later send to all SIM 
80    routines. */
81
82 SilcSim silc_sim_alloc(SilcSimType type, const char *libname, 
83                        SilcUInt32 flags)
84 {
85   SilcSim sim;
86
87   SILC_LOG_DEBUG(("Initializing new SIM context"));
88
89   sim = silc_calloc(1, sizeof(*sim));
90   if (!sim) {
91     SILC_LOG_ERROR(("Could not allocate new SIM context"));
92     return NULL;
93   }
94
95   sim->handle = NULL;
96   sim->type = type;
97   sim->libname = strdup(libname);
98   sim->flags = !flags ? SILC_SIM_FLAGS : flags;
99
100   return sim;
101 }
102
103 /* Free's SIM context. SIM must be closed with silc_sim_close before
104    calling this. */
105
106 void silc_sim_free(SilcSim sim)
107 {
108   assert(sim->handle == NULL);
109   silc_free(sim->libname);
110   silc_free(sim);
111 }
112
113 /* Loads SIM into the SILC system. */
114
115 int silc_sim_load(SilcSim sim)
116 {
117   assert(sim != NULL);
118
119   SILC_LOG_DEBUG(("Loading SIM '%s'", sim->libname));
120
121   /* Load the library */
122   sim->handle = dlopen(sim->libname, sim->flags);
123   if (!sim->handle) {
124     SILC_LOG_ERROR(("Error loading SIM: %s", silc_sim_error(sim)));
125     return FALSE;
126   }
127
128   return TRUE;
129 }
130
131 /* Closes SIM. This is called when execution of program is ending or
132    one explicitly wants to remove this SIM from SILC. */
133
134 int silc_sim_close(SilcSim sim)
135 {
136   assert(sim != NULL);
137
138   SILC_LOG_DEBUG(("Closing SIM '%s'", sim->libname));
139
140   /* Close the library */
141   dlclose(sim->handle);
142   sim->handle = NULL;
143
144   return TRUE;
145 }
146
147 /* Returns error string if error has occured while processing SIM's. */
148
149 const char *silc_sim_error(SilcSim sim)
150 {
151   return dlerror();
152 }
153
154 /* Returns opaque pointer for a symbol in SIM. Caller must know the
155    symbols they want to get from SIM and use the returned pointer to
156    what ever it is intended. */
157
158 void *silc_sim_getsym(SilcSim sim, const char *symbol)
159 {
160   assert(sim != NULL);
161
162   SILC_LOG_DEBUG(("Getting symbol '%s' from SIM", symbol));
163
164   return dlsym(sim->handle, symbol);
165 }
166
167 #endif /* SILC_SIM */