Browse code

Makefile.defs: * added MODS_DIR macro

globals.h:
* added mods_dir variable

main.c:
* added `-L dir' option

* fixed Usage message which referred to the non-existent
`-p port' option

* fixed parsing of command-line options - options with missing
arguments were incorrectly reported as unknown options

sr_module.c:
* load_module() - added possibilty to load modules by name,
the path to the module file is <mods_dir>/<name>.so
(if EXTRA_DEBUG macro is defined <mods_dir>/<name>/<name>.so
is tried too) where <mods_dir> can be specified using `-L dir'
option on the command-line, otherwise the default value MODS_DIR
is used

Ondrej Martinek authored on 04/10/2007 18:09:24
Showing 4 changed files
... ...
@@ -424,6 +424,7 @@ DEFS+= $(extra_defs) \
424 424
 	 -DOS='$(OS)_' -DOS_QUOTED='"$(OS)"' -DCOMPILER='"$(CC_VER)"' -D__CPU_$(ARCH) -D__OS_$(OS) \
425 425
 	 -DSER_VER=$(SER_VER) \
426 426
 	 -DCFG_DIR='"$(cfg_target)"'\
427
+         -DMODS_DIR='"$(modules_target)"'\
427 428
 	 -DPKG_MALLOC \
428 429
 	 -DSHM_MEM  -DSHM_MMAP \
429 430
 	 -DDNS_IP_HACK \
... ...
@@ -43,10 +43,10 @@
43 43
 #define DO_REV_DNS 2
44 44
 
45 45
 
46
-
47
-extern char * cfg_file;
46
+extern char* mods_dir;   /* directory with dyn. loadable modules */
47
+extern char* cfg_file;
48 48
 extern int config_check;
49
-extern char *stat_file;
49
+extern char* stat_file;
50 50
 extern unsigned short port_no;
51 51
 
52 52
 extern pid_t creator_pid;  /* pid of first process before daemonization */
... ...
@@ -178,37 +178,38 @@ char compiled[]= __TIME__ " " __DATE__ ;
178 178
 
179 179
 
180 180
 static char help_msg[]= "\
181
-Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
181
+Usage: " NAME " [options]\n\
182 182
 Options:\n\
183
-    -f file      Configuration file (default " CFG_FILE ")\n\
183
+    -f file      Configuration file (default: " CFG_FILE ")\n\
184
+    -L dir       Modules directory (default: " MODS_DIR ")\n\
184 185
     -c           Check configuration file for errors\n\
185 186
     -l address   Listen on the specified address/interface (multiple -l\n\
186
-                  mean listening on more addresses).  The address format is\n\
187
-                  [proto:]addr[:port], where proto=udp|tcp and \n\
188
-                  addr= host|ip_address|interface_name. E.g: -l locahost, \n\
189
-                  -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
190
-                  is to listen on all the interfaces.\n\
187
+		  mean listening on more addresses).  The address format is\n\
188
+		  [proto:]addr[:port], where proto=udp|tcp and \n\
189
+		  addr= host|ip_address|interface_name. E.g: -l locahost, \n\
190
+		  -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
191
+		  is to listen on all the interfaces.\n\
191 192
     -n processes Number of child processes to fork per interface\n\
192
-                  (default: 8)\n\
193
+		  (default: 8)\n\
193 194
     -r           Use dns to check if is necessary to add a \"received=\"\n\
194
-                  field to a via\n\
195
+		  field to a via\n\
195 196
     -R           Same as `-r` but use reverse dns;\n\
196
-                  (to use both use `-rR`)\n\
197
+		  (to use both use `-rR`)\n\
197 198
     -v           Turn on \"via:\" host checking when forwarding replies\n\
198 199
     -d           Debugging mode (multiple -d increase the level)\n\
199
-    -D           1..do not fork (almost) anyway, 2..do not daemonize creator, 3..daemonize(default)\n\
200
+    -D           1..do not fork (almost) anyway, 2..do not daemonize creator, 3..daemonize (default)\n\
200 201
     -E           Log to stderr\n"
201 202
 #ifdef USE_TCP
202 203
 "    -T           Disable tcp\n\
203
-    -N           Number of tcp child processes (default: equal to `-n`)\n\
204
+    -N           Number of tcp child processes (default: equal to `-n')\n\
204 205
     -W           poll method\n"
205 206
 #endif
206 207
 "    -V           Version number\n\
207 208
     -h           This help message\n\
208 209
     -b nr        Maximum receive buffer size which will not be exceeded by\n\
209
-                  auto-probing procedure even if  OS allows\n\
210
+		  auto-probing procedure even if  OS allows\n\
210 211
     -m nr        Size of shared memory allocated in Megabytes\n\
211
-    -w dir       Change the working directory to \"dir\" (default \"/\")\n\
212
+    -w dir       Change the working directory to \"dir\" (default: \"/\")\n\
212 213
     -t dir       Chroot to \"dir\"\n\
213 214
     -u uid       Change uid \n\
214 215
     -g gid       Change gid \n\
... ...
@@ -260,6 +261,9 @@ void receive_stdin_loop()
260 260
 
261 261
 int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
262 262
 					 to use kill(0, sig) */
263
+
264
+char* mods_dir = MODS_DIR;  /* directory with dyn. loadable modules */
265
+
263 266
 char* cfg_file = 0;
264 267
 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
265 268
 												  not want to exceed during the
... ...
@@ -345,7 +349,7 @@ int mlock_pages=0; /* default off, try to disable swapping */
345 345
 
346 346
 /* real time options */
347 347
 int real_time=0; /* default off, flags: 1 on only timer, 2  slow timer,
348
-					                    4 all procs (7=all) */
348
+							    4 all procs (7=all) */
349 349
 int rt_prio=0;
350 350
 int rt_policy=0; /* SCHED_OTHER */
351 351
 int rt_timer1_prio=0;  /* "fast" timer */
... ...
@@ -1236,7 +1240,7 @@ int main(int argc, char** argv)
1236 1236
 		"DBG_MSG_QA enabled, ser may exit abruptly\n");
1237 1237
 #endif
1238 1238
 
1239
-	options=  "f:cm:dVhEb:l:n:vrRDTN:W:w:t:u:g:P:G:"
1239
+	options=  ":f:cm:dVhEb:l:L:n:vrRDTN:W:w:t:u:g:P:G:"
1240 1240
 #ifdef STATS
1241 1241
 		"s:"
1242 1242
 #endif
... ...
@@ -1251,7 +1255,7 @@ int main(int argc, char** argv)
1251 1251
 			break;
1252 1252
 		}
1253 1253
 	}
1254
-	/* process command line (get port no, cfg. file path etc) */
1254
+	/* process command line (cfg. file path etc) */
1255 1255
 	optind = 1;  /* reset getopt */
1256 1256
 	/* switches required before script processing */
1257 1257
 	while((c=getopt(argc,argv,options))!=-1) {
... ...
@@ -1263,6 +1267,9 @@ int main(int argc, char** argv)
1263 1263
 					config_check=1;
1264 1264
 					log_stderr=1; /* force stderr logging */
1265 1265
 					break;
1266
+			case 'L':
1267
+					mods_dir = optarg;
1268
+					break;
1266 1269
 			case 'm':
1267 1270
 					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
1268 1271
 					if (tmp &&(*tmp)){
... ...
@@ -1305,21 +1312,20 @@ int main(int argc, char** argv)
1305 1305
 			case 'u':
1306 1306
 			case 'g':
1307 1307
 			case 'P':
1308
-		        case 'G':
1308
+			case 'G':
1309 1309
 			case 's':
1310 1310
 					break;
1311 1311
 			case '?':
1312
-					if (isprint(optopt))
1313
-						fprintf(stderr, "Unknown option `-%c. Use -h for help.\n", optopt);
1314
-					else
1315
-						fprintf(stderr,
1316
-								"Unknown option character `\\x%x. Use -h for help.\n",
1317
-								optopt);
1312
+					if (isprint(optopt)) {
1313
+						fprintf(stderr, "Unknown option `-%c'. Use -h for help.\n", optopt);
1314
+					} else {
1315
+						fprintf(stderr, "Unknown option character `\\x%x'. Use -h for help.\n",
1316
+							optopt);
1317
+					}
1318 1318
 					goto error;
1319 1319
 			case ':':
1320
-					fprintf(stderr,
1321
-								"Option `-%c requires an argument. Use -h for help.\n",
1322
-								optopt);
1320
+					fprintf(stderr, "Option `-%c' requires an argument. Use -h for help.\n",
1321
+						optopt);
1323 1322
 					goto error;
1324 1323
 			default:
1325 1324
 					abort();
... ...
@@ -1396,7 +1402,7 @@ try_again:
1396 1396
 			case 'b':
1397 1397
 					maxbuffer=strtol(optarg, &tmp, 10);
1398 1398
 					if (tmp &&(*tmp)){
1399
-						fprintf(stderr, "bad max buffer size number: -p %s\n",
1399
+						fprintf(stderr, "bad max buffer size number: -b %s\n",
1400 1400
 											optarg);
1401 1401
 						goto error;
1402 1402
 					}
... ...
@@ -1481,9 +1487,9 @@ try_again:
1481 1481
 			case 'P':
1482 1482
 					pid_file=optarg;
1483 1483
 					break;
1484
-		        case 'G':
1485
-				        pgid_file=optarg;
1486
-				        break;
1484
+			case 'G':
1485
+					pgid_file=optarg;
1486
+					break;
1487 1487
 			case 's':
1488 1488
 				#ifdef STATS
1489 1489
 					stat_file=optarg;
... ...
@@ -33,7 +33,7 @@
33 33
  *  2003-03-29  cleaning pkg_mallocs introduced (jiri)
34 34
  *  2003-04-24  module version checking introduced (jiri)
35 35
  *  2004-09-19  compile flags are checked too (andrei)
36
- *  2005-01-07  removed find_module-overloading problems, added 
36
+ *  2005-01-07  removed find_module-overloading problems, added
37 37
  *               find_export_record
38 38
  *  2006-02-07  added fix_flag (andrei)
39 39
  */
... ...
@@ -49,7 +49,9 @@
49 49
 #include "route_struct.h"
50 50
 #include "flags.h"
51 51
 #include "trim.h"
52
+#include "globals.h"
52 53
 
54
+#include <sys/stat.h>
53 55
 #include <regex.h>
54 56
 #include <dlfcn.h>
55 57
 #include <strings.h>
... ...
@@ -71,19 +73,19 @@ struct sr_module* modules=0;
71 71
 #endif
72 72
 
73 73
 #ifdef STATIC_AUTH
74
-        extern struct module_exports* auth_exports();
74
+	extern struct module_exports* auth_exports();
75 75
 #endif
76 76
 
77 77
 #ifdef STATIC_RR
78
-        extern struct module_exports* rr_exports();
78
+	extern struct module_exports* rr_exports();
79 79
 #endif
80 80
 
81 81
 #ifdef STATIC_USRLOC
82
-        extern struct module_exports* usrloc_exports();
82
+	extern struct module_exports* usrloc_exports();
83 83
 #endif
84 84
 
85 85
 #ifdef STATIC_SL
86
-        extern struct module_exports* sl_exports();
86
+	extern struct module_exports* sl_exports();
87 87
 #endif
88 88
 
89 89
 
... ...
@@ -213,15 +215,74 @@ int load_module(char* path)
213 213
 	char* error;
214 214
 	struct module_exports* exp;
215 215
 	struct sr_module* t;
216
+	struct stat stat_buf;
217
+	char* modname;
218
+	int len;
216 219
 
217 220
 #ifndef RTLD_NOW
218 221
 /* for openbsd */
219 222
 #define RTLD_NOW DL_LAZY
220 223
 #endif
224
+
225
+	if (!strchr(path, '/') && !strchr(path, '.')) {
226
+		/* module name was given, we try to construct the path */
227
+		modname = path;
228
+
229
+		/* try path <MODS_DIR>/<modname>.so */
230
+		path = (char*)pkg_malloc(
231
+			strlen(mods_dir) + 1 /* "/" */ +
232
+			strlen(modname) + 3 /* ".so" */ + 1);
233
+		strcpy(path, mods_dir);
234
+		len = strlen(path);
235
+		if (len != 0 && path[len - 1] != '/') {
236
+			strcat(path, "/");
237
+		}
238
+		strcat(path, modname);
239
+		strcat(path, ".so");
240
+
241
+#ifdef EXTRA_DEBUG
242
+		if (stat(path, &stat_buf) == -1) {
243
+			DBG("load_module: module file not found <%s>\n", path);
244
+			pkg_free(path);
245
+
246
+			/* try path <MODS_DIR>/<modname>/<modname>.so */
247
+			path = (char*)pkg_malloc(
248
+				strlen(mods_dir) + 1 /* "/" */ +
249
+				strlen(modname) + 1 /* "/" */ +
250
+				strlen(modname) + 3 /* ".so" */ + 1);
251
+			strcpy(path, mods_dir);
252
+			len = strlen(path);
253
+			if (len != 0 && path[len - 1] != '/') {
254
+				strcat(path, "/");
255
+			}
256
+			strcat(path, modname);
257
+			strcat(path, "/");
258
+			strcat(path, modname);
259
+			strcat(path, ".so");
260
+
261
+			if (stat(path, &stat_buf) == -1) {
262
+				DBG("load_module: module file not found <%s>\n", path);
263
+				pkg_free(path);
264
+				LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n",
265
+					modname);
266
+				goto error;
267
+			}
268
+		}
269
+#else /* !EXTRA_DEBUG */
270
+		if (stat(path, &stat_buf) == -1) {
271
+			DBG("load_module: module file not found <%s>\n", path);
272
+			pkg_free(path);
273
+			LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n",
274
+				modname);
275
+			goto error;
276
+		}
277
+#endif /* !EXTRA_DEBUG */
278
+	}
279
+
221 280
 	handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
222 281
 	if (handle==0){
223 282
 		LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
224
-					path, dlerror() );
283
+			path, dlerror());
225 284
 		goto error;
226 285
 	}
227 286
 
... ...
@@ -538,7 +599,7 @@ int init_modules(void)
538 538
 
539 539
 action_u_t *fixup_get_param(void **cur_param, int cur_param_no, int required_param_no) {
540 540
 	action_u_t *a, a2;
541
-        /* cur_param points to a->u.string, get pointer to a */
541
+	/* cur_param points to a->u.string, get pointer to a */
542 542
 	a = (void*) ((char *)cur_param - ((char *)&a2.u.string-(char *)&a2));
543 543
 	return a + required_param_no - cur_param_no;
544 544
 }
... ...
@@ -567,7 +628,7 @@ int fix_flag( modparam_t type, void* val,
567 567
 	int f, len;
568 568
 	char* s;
569 569
 	char *p;
570
-	
570
+
571 571
 	if ((type & PARAM_STRING)==0){
572 572
 		LOG(L_CRIT, "BUG: %s: fix_flag(%s): bad parameter type\n",
573 573
 					mod_name, param_name);
... ...
@@ -617,12 +678,12 @@ int fix_flag( modparam_t type, void* val,
617 617
  * parameter types
618 618
  */
619 619
 int fix_param(int type, void** param)
620
-{	
620
+{
621 621
     fparam_t* p;
622 622
     str name, s;
623 623
     unsigned int num;
624 624
     int err;
625
-    
625
+
626 626
     p = (fparam_t*)pkg_malloc(sizeof(fparam_t));
627 627
     if (!p) {
628 628
 	ERR("No memory left\n");
... ...
@@ -630,21 +691,21 @@ int fix_param(int type, void** param)
630 630
     }
631 631
     memset(p, 0, sizeof(fparam_t));
632 632
     p->orig = *param;
633
-    
633
+
634 634
     switch(type) {
635 635
     case FPARAM_UNSPEC:
636 636
 	ERR("Invalid type value\n");
637 637
 	goto error;
638
-	
638
+
639 639
     case FPARAM_STRING:
640 640
 	p->v.asciiz = *param;
641 641
 	break;
642
-	
642
+
643 643
     case FPARAM_STR:
644 644
 	p->v.str.s = (char*)*param;
645 645
 	p->v.str.len = strlen(p->v.str.s);
646 646
 	break;
647
-	
647
+
648 648
     case FPARAM_INT:
649 649
 	s.s = (char*)*param;
650 650
 	s.len = strlen(s.s);
... ...
@@ -657,7 +718,7 @@ int fix_param(int type, void** param)
657 657
 	    return 1;
658 658
 	}
659 659
 	break;
660
-	
660
+
661 661
     case FPARAM_REGEX:
662 662
 	if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) {
663 663
 	    ERR("No memory left\n");
... ...
@@ -669,7 +730,7 @@ int fix_param(int type, void** param)
669 669
 	    goto error;
670 670
 	}
671 671
 	break;
672
-	
672
+
673 673
     case FPARAM_AVP:
674 674
 	name.s = (char*)*param;
675 675
 	name.len = strlen(name.s);
... ...
@@ -681,13 +742,13 @@ int fix_param(int type, void** param)
681 681
 	}
682 682
 	name.s++;
683 683
 	name.len--;
684
-	
684
+
685 685
 	if (parse_avp_ident(&name, &p->v.avp) < 0) {
686 686
 	    ERR("Error while parsing attribute name\n");
687 687
 	    goto error;
688 688
 	}
689 689
 	break;
690
-	
690
+
691 691
     case FPARAM_SELECT:
692 692
 	name.s = (char*)*param;
693 693
 	name.len = strlen(name.s);
... ...
@@ -697,7 +758,7 @@ int fix_param(int type, void** param)
697 697
 	    pkg_free(p);
698 698
 	    return 1;
699 699
 	}
700
-	
700
+
701 701
 	if (parse_select(&name.s, &p->v.select) < 0) {
702 702
 	    ERR("Error while parsing select identifier\n");
703 703
 	    goto error;
... ...
@@ -714,11 +775,11 @@ int fix_param(int type, void** param)
714 714
 	}
715 715
 	break;
716 716
     }
717
-    
717
+
718 718
     p->type = type;
719 719
     *param = (void*)p;
720 720
     return 0;
721
-    
721
+
722 722
  error:
723 723
     pkg_free(p);
724 724
     return E_UNSPEC;
... ...
@@ -762,7 +823,7 @@ int fixup_var_str_2(void** param, int param_no)
762 762
 /*
763 763
  * Fixup variable integer, the parameter can be
764 764
  * AVP, SELECT, or ordinary integer. AVP and select
765
- * identifiers will be resolved to their values and 
765
+ * identifiers will be resolved to their values and
766 766
  * converted to int if necessary during runtime
767 767
  *
768 768
  * The parameter value will be converted to fparam structure
... ...
@@ -943,13 +1004,13 @@ int get_int_fparam(int* dst, struct sip_msg* msg, fparam_t* param)
943 943
     case FPARAM_INT:
944 944
 	*dst = param->v.i;
945 945
 	return 0;
946
-	
946
+
947 947
     case FPARAM_REGEX:
948 948
     case FPARAM_UNSPEC:
949 949
     case FPARAM_STRING:
950 950
     case FPARAM_STR:
951 951
 	return -1;
952
-	
952
+
953 953
     case FPARAM_AVP:
954 954
 	avp = search_first_avp(param->v.avp.flags, param->v.avp.name, &val, 0);
955 955
 	if (!avp) {