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