Ver código fonte

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 18 anos atrás
pai
commit
f4194f695f
4 arquivos alterados com 126 adições e 58 exclusões
  1. 1 0
      Makefile.defs
  2. 3 3
      globals.h
  3. 37 31
      main.c
  4. 85 24
      sr_module.c

+ 1 - 0
Makefile.defs

@@ -424,6 +424,7 @@ DEFS+= $(extra_defs) \
 	 -DOS='$(OS)_' -DOS_QUOTED='"$(OS)"' -DCOMPILER='"$(CC_VER)"' -D__CPU_$(ARCH) -D__OS_$(OS) \
 	 -DSER_VER=$(SER_VER) \
 	 -DCFG_DIR='"$(cfg_target)"'\
+         -DMODS_DIR='"$(modules_target)"'\
 	 -DPKG_MALLOC \
 	 -DSHM_MEM  -DSHM_MMAP \
 	 -DDNS_IP_HACK \

+ 3 - 3
globals.h

@@ -43,10 +43,10 @@
 #define DO_REV_DNS 2
 
 
-
-extern char * cfg_file;
+extern char* mods_dir;   /* directory with dyn. loadable modules */
+extern char* cfg_file;
 extern int config_check;
-extern char *stat_file;
+extern char* stat_file;
 extern unsigned short port_no;
 
 extern pid_t creator_pid;  /* pid of first process before daemonization */

+ 37 - 31
main.c

@@ -178,37 +178,38 @@ char compiled[]= __TIME__ " " __DATE__ ;
 
 
 static char help_msg[]= "\
-Usage: " NAME " -l address [-p port] [-l address [-p port]...] [options]\n\
+Usage: " NAME " [options]\n\
 Options:\n\
-    -f file      Configuration file (default " CFG_FILE ")\n\
+    -f file      Configuration file (default: " CFG_FILE ")\n\
+    -L dir       Modules directory (default: " MODS_DIR ")\n\
     -c           Check configuration file for errors\n\
     -l address   Listen on the specified address/interface (multiple -l\n\
-                  mean listening on more addresses).  The address format is\n\
-                  [proto:]addr[:port], where proto=udp|tcp and \n\
-                  addr= host|ip_address|interface_name. E.g: -l locahost, \n\
-                  -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
-                  is to listen on all the interfaces.\n\
+		  mean listening on more addresses).  The address format is\n\
+		  [proto:]addr[:port], where proto=udp|tcp and \n\
+		  addr= host|ip_address|interface_name. E.g: -l locahost, \n\
+		  -l udp:127.0.0.1:5080, -l eth0:5062 The default behavior\n\
+		  is to listen on all the interfaces.\n\
     -n processes Number of child processes to fork per interface\n\
-                  (default: 8)\n\
+		  (default: 8)\n\
     -r           Use dns to check if is necessary to add a \"received=\"\n\
-                  field to a via\n\
+		  field to a via\n\
     -R           Same as `-r` but use reverse dns;\n\
-                  (to use both use `-rR`)\n\
+		  (to use both use `-rR`)\n\
     -v           Turn on \"via:\" host checking when forwarding replies\n\
     -d           Debugging mode (multiple -d increase the level)\n\
-    -D           1..do not fork (almost) anyway, 2..do not daemonize creator, 3..daemonize(default)\n\
+    -D           1..do not fork (almost) anyway, 2..do not daemonize creator, 3..daemonize (default)\n\
     -E           Log to stderr\n"
 #ifdef USE_TCP
 "    -T           Disable tcp\n\
-    -N           Number of tcp child processes (default: equal to `-n`)\n\
+    -N           Number of tcp child processes (default: equal to `-n')\n\
     -W           poll method\n"
 #endif
 "    -V           Version number\n\
     -h           This help message\n\
     -b nr        Maximum receive buffer size which will not be exceeded by\n\
-                  auto-probing procedure even if  OS allows\n\
+		  auto-probing procedure even if  OS allows\n\
     -m nr        Size of shared memory allocated in Megabytes\n\
-    -w dir       Change the working directory to \"dir\" (default \"/\")\n\
+    -w dir       Change the working directory to \"dir\" (default: \"/\")\n\
     -t dir       Chroot to \"dir\"\n\
     -u uid       Change uid \n\
     -g gid       Change gid \n\
@@ -260,6 +261,9 @@ void receive_stdin_loop()
 
 int own_pgid = 0; /* whether or not we have our own pgid (and it's ok
 					 to use kill(0, sig) */
+
+char* mods_dir = MODS_DIR;  /* directory with dyn. loadable modules */
+
 char* cfg_file = 0;
 unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
 												  not want to exceed during the
@@ -345,7 +349,7 @@ int mlock_pages=0; /* default off, try to disable swapping */
 
 /* real time options */
 int real_time=0; /* default off, flags: 1 on only timer, 2  slow timer,
-					                    4 all procs (7=all) */
+							    4 all procs (7=all) */
 int rt_prio=0;
 int rt_policy=0; /* SCHED_OTHER */
 int rt_timer1_prio=0;  /* "fast" timer */
@@ -1236,7 +1240,7 @@ int main(int argc, char** argv)
 		"DBG_MSG_QA enabled, ser may exit abruptly\n");
 #endif
 
-	options=  "f:cm:dVhEb:l:n:vrRDTN:W:w:t:u:g:P:G:"
+	options=  ":f:cm:dVhEb:l:L:n:vrRDTN:W:w:t:u:g:P:G:"
 #ifdef STATS
 		"s:"
 #endif
@@ -1251,7 +1255,7 @@ int main(int argc, char** argv)
 			break;
 		}
 	}
-	/* process command line (get port no, cfg. file path etc) */
+	/* process command line (cfg. file path etc) */
 	optind = 1;  /* reset getopt */
 	/* switches required before script processing */
 	while((c=getopt(argc,argv,options))!=-1) {
@@ -1263,6 +1267,9 @@ int main(int argc, char** argv)
 					config_check=1;
 					log_stderr=1; /* force stderr logging */
 					break;
+			case 'L':
+					mods_dir = optarg;
+					break;
 			case 'm':
 					shm_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
 					if (tmp &&(*tmp)){
@@ -1305,21 +1312,20 @@ int main(int argc, char** argv)
 			case 'u':
 			case 'g':
 			case 'P':
-		        case 'G':
+			case 'G':
 			case 's':
 					break;
 			case '?':
-					if (isprint(optopt))
-						fprintf(stderr, "Unknown option `-%c. Use -h for help.\n", optopt);
-					else
-						fprintf(stderr,
-								"Unknown option character `\\x%x. Use -h for help.\n",
-								optopt);
+					if (isprint(optopt)) {
+						fprintf(stderr, "Unknown option `-%c'. Use -h for help.\n", optopt);
+					} else {
+						fprintf(stderr, "Unknown option character `\\x%x'. Use -h for help.\n",
+							optopt);
+					}
 					goto error;
 			case ':':
-					fprintf(stderr,
-								"Option `-%c requires an argument. Use -h for help.\n",
-								optopt);
+					fprintf(stderr, "Option `-%c' requires an argument. Use -h for help.\n",
+						optopt);
 					goto error;
 			default:
 					abort();
@@ -1396,7 +1402,7 @@ try_again:
 			case 'b':
 					maxbuffer=strtol(optarg, &tmp, 10);
 					if (tmp &&(*tmp)){
-						fprintf(stderr, "bad max buffer size number: -p %s\n",
+						fprintf(stderr, "bad max buffer size number: -b %s\n",
 											optarg);
 						goto error;
 					}
@@ -1481,9 +1487,9 @@ try_again:
 			case 'P':
 					pid_file=optarg;
 					break;
-		        case 'G':
-				        pgid_file=optarg;
-				        break;
+			case 'G':
+					pgid_file=optarg;
+					break;
 			case 's':
 				#ifdef STATS
 					stat_file=optarg;

+ 85 - 24
sr_module.c

@@ -33,7 +33,7 @@
  *  2003-03-29  cleaning pkg_mallocs introduced (jiri)
  *  2003-04-24  module version checking introduced (jiri)
  *  2004-09-19  compile flags are checked too (andrei)
- *  2005-01-07  removed find_module-overloading problems, added 
+ *  2005-01-07  removed find_module-overloading problems, added
  *               find_export_record
  *  2006-02-07  added fix_flag (andrei)
  */
@@ -49,7 +49,9 @@
 #include "route_struct.h"
 #include "flags.h"
 #include "trim.h"
+#include "globals.h"
 
+#include <sys/stat.h>
 #include <regex.h>
 #include <dlfcn.h>
 #include <strings.h>
@@ -71,19 +73,19 @@ struct sr_module* modules=0;
 #endif
 
 #ifdef STATIC_AUTH
-        extern struct module_exports* auth_exports();
+	extern struct module_exports* auth_exports();
 #endif
 
 #ifdef STATIC_RR
-        extern struct module_exports* rr_exports();
+	extern struct module_exports* rr_exports();
 #endif
 
 #ifdef STATIC_USRLOC
-        extern struct module_exports* usrloc_exports();
+	extern struct module_exports* usrloc_exports();
 #endif
 
 #ifdef STATIC_SL
-        extern struct module_exports* sl_exports();
+	extern struct module_exports* sl_exports();
 #endif
 
 
@@ -213,15 +215,74 @@ int load_module(char* path)
 	char* error;
 	struct module_exports* exp;
 	struct sr_module* t;
+	struct stat stat_buf;
+	char* modname;
+	int len;
 
 #ifndef RTLD_NOW
 /* for openbsd */
 #define RTLD_NOW DL_LAZY
 #endif
+
+	if (!strchr(path, '/') && !strchr(path, '.')) {
+		/* module name was given, we try to construct the path */
+		modname = path;
+
+		/* try path <MODS_DIR>/<modname>.so */
+		path = (char*)pkg_malloc(
+			strlen(mods_dir) + 1 /* "/" */ +
+			strlen(modname) + 3 /* ".so" */ + 1);
+		strcpy(path, mods_dir);
+		len = strlen(path);
+		if (len != 0 && path[len - 1] != '/') {
+			strcat(path, "/");
+		}
+		strcat(path, modname);
+		strcat(path, ".so");
+
+#ifdef EXTRA_DEBUG
+		if (stat(path, &stat_buf) == -1) {
+			DBG("load_module: module file not found <%s>\n", path);
+			pkg_free(path);
+
+			/* try path <MODS_DIR>/<modname>/<modname>.so */
+			path = (char*)pkg_malloc(
+				strlen(mods_dir) + 1 /* "/" */ +
+				strlen(modname) + 1 /* "/" */ +
+				strlen(modname) + 3 /* ".so" */ + 1);
+			strcpy(path, mods_dir);
+			len = strlen(path);
+			if (len != 0 && path[len - 1] != '/') {
+				strcat(path, "/");
+			}
+			strcat(path, modname);
+			strcat(path, "/");
+			strcat(path, modname);
+			strcat(path, ".so");
+
+			if (stat(path, &stat_buf) == -1) {
+				DBG("load_module: module file not found <%s>\n", path);
+				pkg_free(path);
+				LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n",
+					modname);
+				goto error;
+			}
+		}
+#else /* !EXTRA_DEBUG */
+		if (stat(path, &stat_buf) == -1) {
+			DBG("load_module: module file not found <%s>\n", path);
+			pkg_free(path);
+			LOG(L_ERR, "ERROR: load_module: could not find module <%s>\n",
+				modname);
+			goto error;
+		}
+#endif /* !EXTRA_DEBUG */
+	}
+
 	handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
 	if (handle==0){
 		LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
-					path, dlerror() );
+			path, dlerror());
 		goto error;
 	}
 
@@ -538,7 +599,7 @@ int init_modules(void)
 
 action_u_t *fixup_get_param(void **cur_param, int cur_param_no, int required_param_no) {
 	action_u_t *a, a2;
-        /* cur_param points to a->u.string, get pointer to a */
+	/* cur_param points to a->u.string, get pointer to a */
 	a = (void*) ((char *)cur_param - ((char *)&a2.u.string-(char *)&a2));
 	return a + required_param_no - cur_param_no;
 }
@@ -567,7 +628,7 @@ int fix_flag( modparam_t type, void* val,
 	int f, len;
 	char* s;
 	char *p;
-	
+
 	if ((type & PARAM_STRING)==0){
 		LOG(L_CRIT, "BUG: %s: fix_flag(%s): bad parameter type\n",
 					mod_name, param_name);
@@ -617,12 +678,12 @@ int fix_flag( modparam_t type, void* val,
  * parameter types
  */
 int fix_param(int type, void** param)
-{	
+{
     fparam_t* p;
     str name, s;
     unsigned int num;
     int err;
-    
+
     p = (fparam_t*)pkg_malloc(sizeof(fparam_t));
     if (!p) {
 	ERR("No memory left\n");
@@ -630,21 +691,21 @@ int fix_param(int type, void** param)
     }
     memset(p, 0, sizeof(fparam_t));
     p->orig = *param;
-    
+
     switch(type) {
     case FPARAM_UNSPEC:
 	ERR("Invalid type value\n");
 	goto error;
-	
+
     case FPARAM_STRING:
 	p->v.asciiz = *param;
 	break;
-	
+
     case FPARAM_STR:
 	p->v.str.s = (char*)*param;
 	p->v.str.len = strlen(p->v.str.s);
 	break;
-	
+
     case FPARAM_INT:
 	s.s = (char*)*param;
 	s.len = strlen(s.s);
@@ -657,7 +718,7 @@ int fix_param(int type, void** param)
 	    return 1;
 	}
 	break;
-	
+
     case FPARAM_REGEX:
 	if ((p->v.regex = pkg_malloc(sizeof(regex_t))) == 0) {
 	    ERR("No memory left\n");
@@ -669,7 +730,7 @@ int fix_param(int type, void** param)
 	    goto error;
 	}
 	break;
-	
+
     case FPARAM_AVP:
 	name.s = (char*)*param;
 	name.len = strlen(name.s);
@@ -681,13 +742,13 @@ int fix_param(int type, void** param)
 	}
 	name.s++;
 	name.len--;
-	
+
 	if (parse_avp_ident(&name, &p->v.avp) < 0) {
 	    ERR("Error while parsing attribute name\n");
 	    goto error;
 	}
 	break;
-	
+
     case FPARAM_SELECT:
 	name.s = (char*)*param;
 	name.len = strlen(name.s);
@@ -697,7 +758,7 @@ int fix_param(int type, void** param)
 	    pkg_free(p);
 	    return 1;
 	}
-	
+
 	if (parse_select(&name.s, &p->v.select) < 0) {
 	    ERR("Error while parsing select identifier\n");
 	    goto error;
@@ -714,11 +775,11 @@ int fix_param(int type, void** param)
 	}
 	break;
     }
-    
+
     p->type = type;
     *param = (void*)p;
     return 0;
-    
+
  error:
     pkg_free(p);
     return E_UNSPEC;
@@ -762,7 +823,7 @@ int fixup_var_str_2(void** param, int param_no)
 /*
  * Fixup variable integer, the parameter can be
  * AVP, SELECT, or ordinary integer. AVP and select
- * identifiers will be resolved to their values and 
+ * identifiers will be resolved to their values and
  * converted to int if necessary during runtime
  *
  * 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)
     case FPARAM_INT:
 	*dst = param->v.i;
 	return 0;
-	
+
     case FPARAM_REGEX:
     case FPARAM_UNSPEC:
     case FPARAM_STRING:
     case FPARAM_STR:
 	return -1;
-	
+
     case FPARAM_AVP:
 	avp = search_first_avp(param->v.avp.flags, param->v.avp.name, &val, 0);
 	if (!avp) {