Browse code

core: loadpath can now use a list of directories

- loadpath can use a list of directories separated by ':',
e.g.: loadpath "modules:modules_s:modules_k".
First match wins (e.g. for loadmodule "textops" if
modules/textops.so or modules/textops/textops.so exists, it will
be loaded and the search will stop).

Andrei Pelinescu-Onciul authored on 03/04/2009 15:31:01
Showing 2 changed files
... ...
@@ -6,6 +6,10 @@ $Id$
6 6
 sip-router changes
7 7
 
8 8
 core:
9
+  - module search path support: loadpath takes now a list of directories
10
+    separated by ':'. The list is searched in-order. For each directory d
11
+    $d/${module_name}.so and $d/${module_name}/${module_name}.so are tried.
12
+  - dns TXT, EBL and PTR support (both cache and non-cached resolver)
9 13
   - support for dual module interfaces: ser and kamailio
10 14
 config script changes:
11 15
   - script mode can be switched between ser compatible, kamailio compatible
... ...
@@ -21,6 +25,8 @@ config script changes:
21 21
   - while()
22 22
   - max_while_loops - maximum iterations allowed for a while, can be changed
23 23
     at runtime. Default 100.
24
+build system:
25
+  - multiple modules directories are now supported (defined in Makefile.dirs)
24 26
 
25 27
 
26 28
 
... ...
@@ -238,7 +238,7 @@ static inline int version_control(void *handle, char *path)
238 238
  * @param modname - path or module name
239 239
  * @return 0 on success , <0 on error
240 240
  */
241
-int load_module(char* path)
241
+int load_module(char* mod_path)
242 242
 {
243 243
 	void* handle;
244 244
 	char* error;
... ...
@@ -248,6 +248,10 @@ int load_module(char* path)
248 248
 	struct sr_module* t;
249 249
 	struct stat stat_buf;
250 250
 	char* modname;
251
+	char* mdir;
252
+	char* nxt_mdir;
253
+	char* path;
254
+	int mdir_len;
251 255
 	int len;
252 256
 	int dlflags;
253 257
 	int new_dlflags;
... ...
@@ -257,49 +261,64 @@ int load_module(char* path)
257 257
 /* for openbsd */
258 258
 #define RTLD_NOW DL_LAZY
259 259
 #endif
260
-
260
+	path=mod_path;
261 261
 	if (!strchr(path, '/') && !strchr(path, '.')) {
262 262
 		/* module name was given, we try to construct the path */
263 263
 		modname = path;
264
-
265
-		/* try path <MODS_DIR>/<modname>.so */
266
-		path = (char*)pkg_malloc(
267
-			strlen(mods_dir) + 1 /* "/" */ +
268
-			strlen(modname) + 3 /* ".so" */ + 1);
269
-		strcpy(path, mods_dir);
270
-		len = strlen(path);
271
-		if (len != 0 && path[len - 1] != '/') {
272
-			strcat(path, "/");
273
-		}
274
-		strcat(path, modname);
275
-		strcat(path, ".so");
276
-
277
-		if (stat(path, &stat_buf) == -1) {
278
-			DBG("load_module: module file not found <%s>\n", path);
279
-			pkg_free(path);
280
-
281
-			/* try path <MODS_DIR>/<modname>/<modname>.so */
282
-			path = (char*)pkg_malloc(
283
-				strlen(mods_dir) + 1 /* "/" */ +
284
-				strlen(modname) + 1 /* "/" */ +
285
-				strlen(modname) + 3 /* ".so" */ + 1);
286
-			strcpy(path, mods_dir);
287
-			len = strlen(path);
288
-			if (len != 0 && path[len - 1] != '/') {
289
-				strcat(path, "/");
264
+		mdir=mods_dir; /* search path */
265
+		do{
266
+			nxt_mdir=strchr(mdir, ':');
267
+			if (nxt_mdir) mdir_len=(int)(nxt_mdir-mdir);
268
+			else mdir_len=strlen(mdir);
269
+			
270
+			/* try path <MODS_DIR>/<modname>.so */
271
+			path = (char*)pkg_malloc(mdir_len + 1 /* "/" */ +
272
+									strlen(modname) + 3 /* ".so" */ + 1);
273
+			if (path==0) goto error;
274
+			memcpy(path, mdir, mdir_len);
275
+			len = mdir_len;
276
+			if (len != 0 && path[len - 1] != '/'){
277
+				path[len]='/';
278
+				len++;
290 279
 			}
291
-			strcat(path, modname);
292
-			strcat(path, "/");
280
+			path[len]=0;
293 281
 			strcat(path, modname);
294 282
 			strcat(path, ".so");
295 283
 
296 284
 			if (stat(path, &stat_buf) == -1) {
297 285
 				DBG("load_module: module file not found <%s>\n", path);
298 286
 				pkg_free(path);
299
-				LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n",
300
-					modname);
301
-				goto error;
287
+
288
+				/* try path <MODS_DIR>/<modname>/<modname>.so */
289
+				path = (char*)pkg_malloc(
290
+					mdir_len + 1 /* "/" */ +
291
+					strlen(modname) + 1 /* "/" */ +
292
+					strlen(modname) + 3 /* ".so" */ + 1);
293
+				if (path==0) goto error;
294
+				memcpy(path, mdir, mdir_len);
295
+				len = mdir_len;
296
+				if (len != 0 && path[len - 1] != '/') {
297
+					path[len]='/';
298
+					len++;
299
+				}
300
+				path[len]=0;
301
+				strcat(path, modname);
302
+				strcat(path, "/");
303
+				strcat(path, modname);
304
+				strcat(path, ".so");
305
+
306
+				if (stat(path, &stat_buf) == -1) {
307
+					DBG("load_module: module file not found <%s>\n", path);
308
+					pkg_free(path);
309
+					path=0;
310
+				}
302 311
 			}
312
+			mdir=nxt_mdir?nxt_mdir+1:0;
313
+		}while(path==0 && mdir);
314
+		if (path==0){
315
+			LOG(L_ERR, "ERROR: load_module: could not find module <%s> in"
316
+						" <%s>\n", modname, mods_dir);
317
+			goto error;
303 318
 		}
304 319
 	}
305 320
 	retries=2;
... ...
@@ -373,18 +392,21 @@ reload:
373 373
 		}
374 374
 	}
375 375
 	if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
376
+	if (path && path!=mod_path)
377
+		pkg_free(path);
376 378
 	return 0;
377 379
 
378 380
 error1:
379 381
 	dlclose(handle);
380 382
 error:
381 383
 skip:
384
+	if (path && path!=mod_path)
385
+		pkg_free(path);
382 386
 	return -1;
383 387
 }
384 388
 
385 389
 
386 390
 
387
-
388 391
 /* searches the module list for function name in module mod and returns 
389 392
  *  a pointer to the "name" function record union or 0 if not found
390 393
  * sets also *mod_if_ver to the module interface version (needed to know