00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATLoader.c,v 1.23 2004/04/22 10:25:05 hartmutkaiser Exp $";
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <ctype.h>
00028
00029
00030
00031 #include "GATUtil.h"
00032 #include "GATLoader.h"
00033
00034 #include "GATErrors.h"
00035 #include "GATTestUtils.h"
00036
00037 #include "ltdl/ltdl.h"
00038 #include "uuid.h"
00039
00040
00041 #define REGISTRATION_SUFFIX "_register"
00042
00043
00044 struct AdaptorInstance
00045 {
00046 struct AdaptorInstance *next;
00047 char *path;
00048 char *name;
00049 char *nickname;
00050 lt_dlhandle handle;
00051 };
00052
00053 struct GATLoader_S
00054 {
00055 struct AdaptorInstance *list;
00056 };
00057
00058
00059
00060 static struct AdaptorInstance *
00061 AdaptorInstance_Create(const char *path, const char *name, const char *nickname);
00062
00063 static char *
00064 CanonicaliseName(const char *original);
00065
00066 static void
00067 AdaptorInstance_Destroy(struct AdaptorInstance *this);
00068
00069 static GATResult
00070 LoadAdaptor(GATContext error_context, struct AdaptorInstance *instance,
00071 GATRegistry registry, GATTable_const system_config,
00072 GATTable_const instance_config);
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 GATLoader GATLoader_Create(void)
00085 {
00086 GATLoader this;
00087
00088 this = (GATLoader)malloc(sizeof(*this));
00089
00090 if(this)
00091 {
00092 lt_dlinit();
00093
00094 this->list = NULL;
00095 }
00096
00097 return this;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 void GATLoader_Destroy(GATLoader *this)
00107 {
00108 if(NULL != this && NULL != *this)
00109 {
00110 struct AdaptorInstance *adaptor = (*this)->list;
00111
00112 lt_dlexit();
00113
00114
00115 while (NULL != adaptor)
00116 {
00117 struct AdaptorInstance *next = adaptor;
00118 adaptor = adaptor->next;
00119 AdaptorInstance_Destroy(next);
00120 }
00121
00122 free(*this);
00123 *this = NULL;
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 GATResult
00147 GATLoader_LoadAdaptor(GATLoader this, GATContext error_context,
00148 GATRegistry registry, GATTable_const system_config,
00149 GATTable_const instance_config, const char *path, const char *name,
00150 const char *nickname)
00151 {
00152 GAT_USES_STATUS(error_context, "GATLoader_LoadAdaptor");
00153
00154 struct AdaptorInstance *last = NULL;
00155 struct AdaptorInstance *instance =
00156 AdaptorInstance_Create(path, name, nickname);
00157
00158 if (NULL != instance)
00159 {
00160
00161 struct AdaptorInstance *current = NULL;
00162 for(current = this->list; NULL != current;
00163 last = current, current = current->next)
00164 {
00165 if (!strcmp(current->nickname, instance->nickname))
00166 {
00167 GAT_CREATE_STATUS(GAT_DUPLICATE_ADAPTOR);
00168 }
00169 }
00170 }
00171 else
00172 {
00173 GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00174 }
00175
00176 if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00177 {
00178
00179 instance->handle = lt_dlopenext(instance->path);
00180
00181 if (NULL != instance->handle)
00182 {
00183 GAT_CREATE_STATUS(LoadAdaptor(error_context, instance, registry,
00184 system_config, instance_config));
00185 }
00186 else
00187 {
00188 GAT_CREATE_STATUS_MSG(GAT_FAILED_TO_LOAD_ADAPTOR, instance->path);
00189 }
00190 }
00191
00192 if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00193 {
00194
00195 if (NULL != last)
00196 {
00197 last->next = instance;
00198 }
00199 else
00200 {
00201 this->list = instance;
00202 }
00203 }
00204 else
00205 {
00206 AdaptorInstance_Destroy(instance);
00207 }
00208
00209 return GAT_RETURN_STATUS();
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 static struct AdaptorInstance *
00226 AdaptorInstance_Create(const char *path, const char *name, const char *nickname)
00227 {
00228
00229 struct AdaptorInstance *this;
00230
00231
00232 this = (struct AdaptorInstance *)malloc(sizeof(*this));
00233
00234 if(this)
00235 {
00236 this->next = NULL;
00237
00238 this->path = GATUtil_strdup(path);
00239
00240 if(!name)
00241 {
00242 this->name = CanonicaliseName(path);
00243 }
00244 else
00245 {
00246 this->name = GATUtil_strdup(name);
00247 }
00248
00249 if(!nickname)
00250 {
00251 this->nickname = GATUtil_strdup(this->name);
00252 }
00253 else
00254 {
00255 this->nickname = GATUtil_strdup(nickname);
00256 }
00257
00258 if(! this->path || ! this->name || ! this->nickname)
00259 {
00260 free(this->path);
00261 free(this->name);
00262 free(this->nickname);
00263 free(this);
00264 this = NULL;
00265 }
00266
00267 }
00268
00269 return this;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279 static void
00280 AdaptorInstance_Destroy(struct AdaptorInstance *object)
00281 {
00282 if(NULL != object)
00283 {
00284 free(object->path);
00285 free(object->name);
00286 free(object->nickname);
00287
00288
00289
00290
00291
00292
00293
00294 free(object);
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 static char *
00311 CanonicaliseName(const char *original)
00312 {
00313 char *retval;
00314 const char *start;
00315 const char *end;
00316 char *pos;
00317
00318
00319 start = strrchr(original, '/');
00320
00321 if(!start)
00322 {
00323 start = original;
00324 }
00325 else
00326 {
00327 start++;
00328 }
00329
00330
00331
00332 for(end = start;
00333 *end && (isalnum(*end) || *end == '_' || *end == '-');
00334 end++)
00335 {
00336
00337 }
00338
00339 if(!strcmp(end,".la"))
00340 {
00341
00342
00343
00344 if(start[0] == 'l' && start[1] == 'i' && start[2] == 'b')
00345 {
00346 start += 3;
00347 }
00348 }
00349
00350
00351 retval = (char *)malloc(end-start + 1);
00352
00353 if(retval)
00354 {
00355
00356 for(pos = retval; start < end ; start++, pos++)
00357 {
00358 *pos = *start;
00359 }
00360
00361 *pos = 0;
00362 }
00363
00364 return retval;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 static GATResult
00380 LoadAdaptor (GATContext error_context, struct AdaptorInstance *instance,
00381 GATRegistry registry, GATTable_const system_config,
00382 GATTable_const instance_config)
00383 {
00384 GAT_USES_STATUS(error_context, "LoadAdaptor");
00385
00386 typedef GATResult (*registrationproc_t)(GATContext, GATRegistry,
00387 GATTable_const, GATTable_const, void *);
00388
00389 registrationproc_t func = NULL;
00390
00391 char *funcname = (char *)malloc(strlen(instance->name) +
00392 sizeof(REGISTRATION_SUFFIX) + 1);
00393 if (NULL != funcname)
00394 {
00395
00396 sprintf (funcname, "%s%s", instance->name, REGISTRATION_SUFFIX);
00397 func = (registrationproc_t)lt_dlsym (instance->handle, funcname);
00398 if (NULL != func)
00399 {
00400 GAT_CREATE_STATUS(func(error_context, registry, system_config,
00401 instance_config, instance->nickname));
00402 }
00403 else
00404 {
00405 GAT_CREATE_STATUS(GAT_NO_ADAPTOR_REGISTRATION_FUNC);
00406
00407 }
00408 free (funcname);
00409 }
00410 else
00411 {
00412 GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00413
00414 }
00415
00416
00417
00418 {
00419 char buffer[256];
00420 snprintf (buffer, sizeof(buffer), "Loading adaptor %s", instance->nickname);
00421
00422 GAT_TEST_START (buffer);
00423 GAT_TEST_TRACE (GAT_SUCCEEDED(GAT_CURRENT_STATUS()), error_context);
00424 GAT_TEST_STOP ();
00425 }
00426
00427 return GAT_RETURN_STATUS();
00428 }
00429