[Initng-svn] r2307 - in initng: devtool plugins/iparser plugins/simple_launcher plugins/stcmd src

svn at initng.thinktux.net svn at initng.thinktux.net
Fri Dec 2 10:47:14 CET 2005


Author: thelich
Date: Fri Dec  2 10:47:13 2005
New Revision: 2307

Modified:
   initng/devtool/test_parser.c
   initng/plugins/iparser/initng_i_parser.c
   initng/plugins/simple_launcher/initng_simple_launcher.c
   initng/plugins/stcmd/print_service.c
   initng/src/initng_active_db.c
   initng/src/initng_common.c
   initng/src/initng_execute.c
   initng/src/initng_load_module.c
   initng/src/initng_service_cache.c
Log:
many bugs fixed - see comments in sources; almost totally rewriten simple_launcer (DEac-, try to make code more readable and follow coding rules, make more attention to what are you doing! don't forget to free allocated memory - it makes initng unstable!); now, when bug with i_parser and active_db solved - reload plugin woks as it should...

Modified: initng/devtool/test_parser.c
==============================================================================
--- initng/devtool/test_parser.c	(original)
+++ initng/devtool/test_parser.c	Fri Dec  2 10:47:13 2005
@@ -61,16 +61,33 @@
 
 #define SPACE for(i=0; i<level; i++, printf("  "))
 
+#define CIRCULAR_ERR -3
+#define DEPEND_ERR -2
+#define PARSE_ERR -1
+#define NOT_OK 0
+#define OK 1
+#define CHECKED 2
+
 static int load_service(char *name, int level);
-static void parse_all(const char *dirname);
+static int parse_all(const char *dirname);
+static int check_deps(char **dep_list, char *dep, int level);
+
 static int verbose = 0;
+static int print_each = 0;
+static int check_circular = 0;
 
 s_entry STATUS = { "status", INT, 6, NULL, "Status of testing." };
+s_entry CIRCULAR = { "circular", STRING, 8, NULL, "Name of curcular dependencied service." };
 
 int main(int argc, char *argv[], char *env[])
 {
 
     int parse_all_files = 0;
+    int summary = 1;
+    int print_dep_err = 0;
+    int result = NOT_OK;
+
+    service_h *current = NULL;
 
     /* initialise global variables */
     initng_new(argc, argv, env);
@@ -118,6 +135,18 @@
 
 	    if (strcmp(opt, "all") == 0)
 		parse_all_files = 1;
+
+	    if (strcmp(opt, "no_summary") == 0)
+		summary = 0;
+
+	    if (strcmp(opt, "check_circular") == 0)
+		check_circular = 1;
+
+	    if (strcmp(opt, "print_each") == 0)
+		print_each = 1;
+
+	    if (strcmp(opt, "print_dep_err") == 0)
+		print_dep_err = 1;
 	} 
 	else if (opt_type == 2)
 	{
@@ -126,6 +155,19 @@
 
 	    if (strcmp(opt, "a") == 0)
 		parse_all_files = 1;
+
+	    if (strcmp(opt, "s") == 0)
+		summary = 0;
+
+	    if (strcmp(opt, "c") == 0)
+		check_circular = 1;
+
+	    if (strcmp(opt, "p") == 0)
+		print_each = 1;
+
+	    if (strcmp(opt, "d") == 0)
+		print_dep_err = 1;
+		
 	} else
 	{
 	    free(srv_name);
@@ -135,15 +177,47 @@
 
     if (parse_all_files == 1)
     {
-        parse_all("system");
-        parse_all("daemon");
-        parse_all("net");
+        result = parse_all("system");
+        result &= parse_all("daemon");
+        result &= parse_all("net");
 	//parse_all("debug");
-    	parse_all("daemon/bluetooth");
+    	result &= parse_all("daemon/bluetooth");
     }
     else
     {
-        load_service(srv_name,0);
+        result = load_service(srv_name,0);
+	if (check_circular == 1)
+	    result &= check_deps(NULL,srv_name,0);
+
+	if (summary==1)
+	{
+	    if (result == NOT_OK)
+	    {
+		printf("Service %s is failed because:\n",srv_name);
+		while_service_db(current)
+		{
+		    switch (service_db_get_int(&STATUS, current))
+		    {
+			case PARSE_ERR:
+			    printf("%s has parsing errors or service file was not found\n",current->name);
+			    break;
+			case CIRCULAR_ERR: 
+			    printf("%s has circular dependency with %s\n",current->name,
+				    service_db_get_string(&CIRCULAR,current));
+			    break;
+			case DEPEND_ERR: 
+			    if (print_dep_err==1)
+				printf("%s has one of its depends failed\n",current->name);
+			    break;
+			default:
+			    break;
+		    };
+		}
+	    }
+	    else
+		printf("Service %s is ok.\n",srv_name);
+	}
+		
     }
 
   exit:
@@ -151,22 +225,25 @@
     initng_unload_all_modules();
     service_db_free_all();
     initng_free();
-    return (0);
+    return (result==NOT_OK)?OK:NOT_OK;
 }
 
-static void parse_all(const char *dirname)
+static int parse_all(const char *dirname)
 {
     struct dirent *e;
     char tmp[200];
     char tmp2[200];
     DIR *d;
     int i;
+    int result = NOT_OK;
 
     sprintf(tmp, "/etc/initng/%s", dirname);
 
     d = opendir(tmp);
     if (!d)
-        return;
+        return result;
+
+    result = OK;
 
     while ((e = readdir(d)))
     {
@@ -183,10 +260,13 @@
         strncpy(tmp, e->d_name, i - 2);
         tmp[i - 2] = '\0';
         sprintf(tmp2, "%s/%s", dirname, tmp);
-    	load_service(tmp2,0);
+    	result &= load_service(tmp2,0);
+	if (check_circular==1)
+	    result &= check_deps(NULL, tmp2, 0);
     }
 
     closedir(d);
+    return result;
 }
 
 static int load_service(char *name, int level)
@@ -194,11 +274,15 @@
     service_h *service = NULL;
     service_h *tmp_service = NULL;
     char *string=NULL;
-    int result = 0;
+    int result = NOT_OK;
+    int srv_status;
     int i;
 
-    SPACE;
-    printf("Probeparsing: %s\n", name);
+    if (verbose == 1)
+    {
+	SPACE;
+	printf("Probeparsing: %s\n", name);
+    }
 
     service = parse_service(name);
     if (!service)
@@ -208,40 +292,129 @@
         initng_free();
         exit(2);
 	*/
-	SPACE;
-	printf("%s - failed\n",name);
+	if (verbose == 1)
+	{
+	    SPACE;
+	    printf("%s - failed\n",name);
+	}
 	service = service_db_new(name, &TYPE_SERVICE);
 	if (service)
 	{
 	    service_db_add(service);
-	    service_db_set_int(&STATUS, service, -1);
+	    service_db_set_int(&STATUS, service, PARSE_ERR);
 	}
 	return result;
     }
 
-    if (verbose == 1)
-    {
-	printf("\n");
-//	service_db_print_u(service, stdout, 1);
-	service_db_print_all(stdout);
-    }
+    if (print_each == 1)
+	service_db_print_u(service, stdout, 1);
 
-    result = 1;
+    result = OK;
+
+    service_db_set_int(&STATUS, service, OK);
 
     while ((string = service_db_get_next_string(&NEED, service, string)))
     {
 	tmp_service = service_db_find_by_name(string);
-	if (!tmp_service || service_db_get_int(&STATUS, tmp_service)<=0)
+	if (!tmp_service || (srv_status = service_db_get_int(&STATUS, tmp_service))==0)
 	    result &= load_service(string, level+1);
+	else
+	    result &= (srv_status>NOT_OK)?OK:NOT_OK;
     }
 
-    service_db_set_int(&STATUS, service, 1);
 
-    SPACE;
-    if (result==0)
-	printf("%s - failed\n",name);
+    if (verbose == 1)
+    {
+	SPACE;
+	if (result==NOT_OK)
+	    printf("%s - failed\n",name);
+	else
+	    printf("%s - ok\n",name);
+    }
+
+    service_db_set_int(&STATUS, service, (result==NOT_OK)?DEPEND_ERR:OK);
+
+    return result;
+}
+
+static int check_deps(char **dep_list, char *dep, int level)
+{
+    int result = NOT_OK;
+    int tmp_result;
+    int status;
+    char **my_list;
+    char *string = NULL;
+    int i,j;
+    service_h *service = service_db_find_by_name(dep);
+
+    if (verbose==1)
+    {
+	SPACE;
+	printf("Checking: %s\n", dep);
+    }
+
+    if (!service)
+	status = NOT_OK;
     else
-	printf("%s - ok\n",name);
+	status = service_db_get_int(&STATUS, service);
+
+    if (status == CHECKED)
+	result=OK;
+
+    if (status == OK)
+    {
+
+	result = OK;
+
+	my_list = (char **) initng_calloc(level + 2, sizeof(char *));
+	my_list[level+1]=NULL;
+
+	while ((string = service_db_get_next_string(&NEED, service, string)))
+	{
+	    tmp_result = OK;
+
+	    for (j=0; dep_list && dep_list[j]; j++)
+	    {
+		if (strcmp(string, dep_list[j])==0)
+		{
+		    status = CIRCULAR_ERR;
+		    service_db_set_int(&STATUS, service, status);
+		    service_db_set_string(&CIRCULAR, service, i_strdup(string));
+		    if (verbose==1)
+		    {
+			SPACE;
+			printf("Service %s has circular dependency with %s\n", dep, string);
+		    }
+		    tmp_result = NOT_OK;
+		    break;
+		}
+		my_list[j]=dep_list[j];
+	    }
+
+	    if (tmp_result==OK)
+	    {
+		my_list[j]=dep;
+		tmp_result = check_deps(my_list, string, level+1);
+	    }
+
+	    result &= tmp_result;
+	}
+	free(my_list);
+    }
+
+    if (verbose == 1)
+    {
+	SPACE;
+	if (result==NOT_OK)
+	    printf("%s - failed\n",dep);
+	else
+	    printf("%s - ok\n",dep);
+    }
+
+    status = (result==OK)?CHECKED:((status!=CIRCULAR_ERR)?DEPEND_ERR:CIRCULAR_ERR);
+
+    if (service)
+	service_db_set_int(&STATUS, service, status);
 
     return result;
 }

Modified: initng/plugins/iparser/initng_i_parser.c
==============================================================================
--- initng/plugins/iparser/initng_i_parser.c	(original)
+++ initng/plugins/iparser/initng_i_parser.c	Fri Dec  2 10:47:13 2005
@@ -67,6 +67,17 @@
 static int iint_parser(s_entry * type, char **value, char *va,
                        service_h * from_service);
 
+static int is_valid(char * string);
+
+static int is_valid(char * string)
+{
+    int i;
+    for (i=0; string[i]!=0; i++)
+	if (string[i]<=32)
+	    return (FALSE);
+
+    return (TRUE);
+}
 
 static void err_print_line2t(char *point, const char *message, e_mt err,
                              const char *file, const char *func, int codeline)
@@ -337,6 +348,7 @@
     char *father_name = NULL;
     service_h *new_service = NULL;
     service_h *duplicate = NULL;
+    int len;
 
     assert(to_parse);
     assert(*to_parse);
@@ -364,6 +376,13 @@
         err_print_line(*to_parse, "Did not get a name!");
         return (FALSE);
     }
+
+    if (!is_valid(name))
+    {
+        err_print_line(*to_parse, "Name contains invalid characters.");
+        return (FALSE);
+    }
+
     /* service test : class { */
     /*             |          */
 
@@ -404,6 +423,12 @@
             return (FALSE);
         }
 
+	if (!is_valid(father_name))
+	{
+    	    err_print_line(*to_parse, "Fater name contains invalid characters.");
+    	    return (FALSE);
+	}
+
 #ifdef DEBUG
 	if(father_name)
     	    D_("Father is: %s, set from \"server : father\"\n", father_name);
@@ -434,133 +459,135 @@
             return (FALSE);
     }
 
-    /* jump to first char after start tag and begin from there. */
-    (*to_parse)++;
-    /* service test : class { */
-    /*                       | */
-
-    /* create a service entry - if there exits an duplicate, merge with this one */
+    /* create a service entry - if there exits an duplicate, skip to the end of section */ 
     if ((duplicate = service_db_find_by_exact_name(name)))
-        new_service = service_db_copy(name, duplicate);
-    else
-        new_service = service_db_new(name, type);
-
-    /* FROM NOW, we should not free name or father_name, becouse its ADDED, and required */
-
-    /* check so that it was allocated! */
-    if (!new_service)
     {
-        F_("Unable to allocate space for new service.\n");
-        err_print_line(*to_parse,
-                       "Unable to allocate space for new service.");
         free(name);
         if (father_name)
             free(father_name);
-        return (FALSE);
-    }
-
-    /* set the father to the service */
-    if (father_name)
-    {
-        if (father)
-            new_service->father = father;
-        new_service->father_name = father_name;
-    }
+        new_service = duplicate;
+        len = chars_to_end_of_this_stack(*to_parse);
+	if (len == FALSE)
+	    return (FALSE);
 
-    if (duplicate)
-    {
-        /* Service has same name as old service, remove the old one */
-        D_("Removing old service for %s\n", new_service->name);
-        /* free all the data, and service */
-        service_db_free(duplicate);
-        /* unset it */
-        duplicate = NULL;
+	(*to_parse)+=len;
     }
-
-    /* set type if not set. */
-    if (father)
-        new_service->type = type;
-
-    /* carry on until segment stop or eof, this will handle all lines in current section */
-    while ((*to_parse)[0] != '\0' && (*to_parse)[0] != '}')
+    else
     {
-        stype_h *t = NULL;
-        stype_h *y = NULL;
-
-        /* upgrade line pointer that print_line_error uses */
-        g_pointer = (*to_parse);
-        /* skip spaces and empty lines with them */
-        JUMP_SPACES(*to_parse);
+	/* jump to first char after start tag and begin from there. */
+	(*to_parse)++;
+	/* service test : class { */
+	/*                       | */
 
-        /* check that this is not the end */
-        if (!(*to_parse)[0])
-            break;
-
-        /* if the row is ending */
-        if ((*to_parse)[0] == '\n' || (*to_parse)[0] == ';')
-        {
-            /* walk to next one */
-            (*to_parse)++;
-            continue;
-        }
+        new_service = service_db_new(name, type);
 
-        /* skip lines with '#' */
-        if ((*to_parse)[0] == '#')
-        {
-            REALLY_JUMP_TO_NEXT_ROW(*to_parse);
-            continue;
-        }
+	/* FROM NOW, we should not free name or father_name, becouse its ADDED, and required */
 
-        /****  Check for subclasses ****/
-        /* try to find the service type keyword */
-        while_stypes(t)
-        {
-            /* look for matching keywords */
-            if (st_cmp(to_parse, t->name))
-            {
-                y = t;
-                break;
-            }
-        }
-        /* if found */
-        if (y)
-        {
-            /* parse it */
-            if (!parse_service_line(to_parse, watch_for, NULL, y,
+	/* check so that it was allocated! */
+	if (!new_service)
+	{
+    	    F_("Unable to allocate space for new service.\n");
+    	    err_print_line(*to_parse,
+                       "Unable to allocate space for new service.");
+    	    free(name);
+    	    if (father_name)
+        	free(father_name);
+    	    return (FALSE);
+	}
+
+	/* set the father to the service */
+	if (father_name)
+	{
+    	    if (father)
+        	new_service->father = father;
+    	    new_service->father_name = father_name;
+	}
+
+	/* set type if not set. */
+	if (father)
+    	    new_service->type = type;
+
+	/* carry on until segment stop or eof, this will handle all lines in current section */
+	while ((*to_parse)[0] != '\0' && (*to_parse)[0] != '}')
+	{
+    	    stype_h *t = NULL;
+    	    stype_h *y = NULL;
+
+    	    /* upgrade line pointer that print_line_error uses */
+    	    g_pointer = (*to_parse);
+    	    /* skip spaces and empty lines with them */
+    	    JUMP_SPACES(*to_parse);
+
+    	    /* check that this is not the end */
+    	    if (!(*to_parse)[0])
+        	break;
+
+    	    /* if the row is ending */
+    	    if ((*to_parse)[0] == '\n' || (*to_parse)[0] == ';')
+    	    {
+        	/* walk to next one */
+        	(*to_parse)++;
+        	continue;
+    	    }
+
+    	    /* skip lines with '#' */
+    	    if ((*to_parse)[0] == '#')
+    	    {
+        	REALLY_JUMP_TO_NEXT_ROW(*to_parse);
+        	continue;
+    	    }
+
+    	    /****  Check for subclasses ****/
+    	    /* try to find the service type keyword */
+    	    while_stypes(t)
+    	    {
+        	/* look for matching keywords */
+        	if (st_cmp(to_parse, t->name))
+        	{
+            	    y = t;
+            	    break;
+        	}
+    	    }
+    	    /* if found */
+    	    if (y)
+    	    {
+        	/* parse it */
+        	if (!parse_service_line(to_parse, watch_for, NULL, y,
                                     filename, match, exact_match) == FALSE)
-            {
-                err_print_line(*to_parse, "Parse of service line failed!");
-                service_db_free(new_service);
-		new_service = NULL;
-                return (FALSE);
-            }
-            JUMP_TO_NEXT_ROW(*to_parse);
-            continue;
-        }
-
-        /* parse line - search for keywords in g.option_table */
-        if (parse_opt(to_parse, type, new_service))
-        {
-            /* ok, this line is parsed, go to next */
-            JUMP_TO_NEXT_ROW(*to_parse);
-            continue;
-        }
-
-        /* Bad content, coud not be parsed */
-        /* free and reset */
-        service_db_free(new_service);
-        new_service = NULL;
-        return (FALSE);
-    }
-
-    service_db_set_string(&FROM_FILE, new_service, i_strdup(filename));
-    /* add to service db */
-    if (!service_db_add(new_service))
-    {
-        F_("Could not add service to service db!\n");
-        service_db_free(new_service);
-        new_service = NULL;
-        return (FALSE);
+        	{
+            	    err_print_line(*to_parse, "Parse of service line failed!");
+            	    service_db_free(new_service);
+		    new_service = NULL;
+            	    return (FALSE);
+        	}
+        	JUMP_TO_NEXT_ROW(*to_parse);
+        	continue;
+    	    }
+
+    	    /* parse line - search for keywords in g.option_table */
+    	    if (parse_opt(to_parse, type, new_service))
+    	    {
+        	/* ok, this line is parsed, go to next */
+        	JUMP_TO_NEXT_ROW(*to_parse);
+        	continue;
+    	    }
+
+    	    /* Bad content, coud not be parsed */
+    	    /* free and reset */
+    	    service_db_free(new_service);
+    	    new_service = NULL;
+    	    return (FALSE);
+	}
+
+	service_db_set_string(&FROM_FILE, new_service, i_strdup(filename));
+	/* add to service db */
+	if (!service_db_add(new_service))
+	{
+    	    F_("Could not add service to service db!\n");
+    	    service_db_free(new_service);
+    	    new_service = NULL;
+    	    return (FALSE);
+	}
     }
 
     if (strcmp(new_service->name, watch_for) == 0)
@@ -684,6 +711,13 @@
 
         /* copy the string */
         var_name = i_strndup(*where, var_len);
+
+	if (!is_valid(var_name))
+	{
+            err_print_line(*where, "Variable name contains invalid characters.");
+            return (FALSE);
+	}
+
         (*where) += var_len;
         /* Parsometer
          *

Modified: initng/plugins/simple_launcher/initng_simple_launcher.c
==============================================================================
--- initng/plugins/simple_launcher/initng_simple_launcher.c	(original)
+++ initng/plugins/simple_launcher/initng_simple_launcher.c	Fri Dec  2 10:47:13 2005
@@ -55,9 +55,9 @@
 
 static int simple_exec(process_h * p, active_h * s, size_t c, char **v);
 
-#define WHITESPACE( E) ((E)==' '||(E)=='\t'||(E)=='\n'||(E)=='\r'||(E)=='\v')
+#define WHITESPACE " \t\n\r\v"
 
-static void D_argv( char *o, char **argv) {
+static void D_argv(const char *o, char **argv) {
 	int i;
 	if( argv)
 		for( i = 0; argv[i]; i++)
@@ -70,198 +70,219 @@
  *       => \t  /bin/executeable\0--ham\0-flt\0  --moo\0hoho\0 lalala
  *    argv:     ^[0]              ^[1]   ^[2]    ^[3]   ^[4]   ^[5]
  *    argc: 6
- * @author DEac-
+ * @idea DEac-
+ * @author TheLich
  */
-static char **split_argv( char *e, size_t *argc) {
-	int i = 0;
-	int j = 0;
-	void *b = NULL;
-	char **argv = malloc( sizeof *argv);
-	if( !argv) {
-		F_( "malloc returns NULL: %s\n", strerror( errno));
-		return NULL;
-	}
-	if( !e)
-		return NULL;
-	*argc = 0;
-	for( ; e[i]; i++) {
-		/* till no whitespace... */
-		for( ; WHITESPACE( e[i]); i++);
-		/* begin of a word found, no get the length */
-		for( j = i; e[i] && !WHITESPACE( e[i]); i++);
-		/* whitespaces at the end can be gorgotten */
-		if( j == i)
-			break;
-		/* make argv taller and increase argc */
-		(*argc)++;
-		b = realloc( argv, (1+ *argc)* sizeof *argv);
-		if( !b) {
-			F_( "realloc returns NULL: %s\n", strerror( errno));
-			/* realloc false, clean up */
-			free( argv);
-			return NULL;
-		}
-		argv = b;
-		/* push it to argv */
-		argv[*argc-1] = e+j;
-		if( !e[i])
-			break;
-		/* set the terminating-null at the end of arg */
-		e[i] = 0;
+static char **split_argv(char *string, size_t *argc)
+{
+    int len=0;
+    char *new_str;
+    char **array = (char **) initng_calloc(1, sizeof(char *));
+    size_t i=0;
+    
+    if (string)
+    {
+	while (string[0]!=0)
+	{
+	    len = strcspn(string, WHITESPACE);
+	    if (len!=0)
+	    {
+		i++;
+		new_str=(char *) i_strndup(string, len);
+		array = (char **) initng_realloc(array, sizeof(char *) * (i+1));
+		array[i-1]=new_str;
+	    }
+	    else
+		len = 1;
+
+	    string+=len;
 	}
-	argv[*argc] = NULL;
-	return argv;
+    }
+    array[i]=NULL;
+    *argc = i;
+    return array;
 }
 
 /* Completely rewritten function.
- * Contains old Code from SaTaN0rX and new Code from DEac-.
+ * Contains old Code from SaTaN0rX and DEac-.
  */
+
 /** Searches for exec in PATH.
  * 
- * @author DEac-
+ * @author TheLich
  * @param exec filename, which searched.
- * @return executeable file with absolute path.\nIf exec was absolute, this will be a pointer to exec.\nOn failure, it will return NULL.
+ * @return executeable file with absolute path.\nIf exec was absolute, this will be a pointer to exec.
+ * On failure, it will return NULL.
  */
-static char *expand_exec( char *exec) {
-	if( !exec)
-		return NULL;
-	/* 11/20/2005 SaTaN0rX: preliminary support for searching the PATH
-	 * only search the PATH if this is NOT already an absolute path
-	 */
-	if( exec[0] != '/') {
-		size_t exec_len = strlen( exec);
-		int i = 0;
-		const char *PATH = getenv("PATH");
-
-		D_("initng_s_launch: %s contains is not absolute path, searching $PATH\n", exec);
-		if( !PATH) {
-			D_("using default path\n");
-			PATH = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin";
-		}
-		D_("PATH determined to be %s\n", PATH);
-
-		for( ; PATH[i]; i++) {
-			char *filename = NULL;
-			int j = 0;
-			struct stat test;
-
-			/* ':' is the delimeter */
-			for( ; PATH[i] == ':'; i++);
-
-			/* now, their's a possible path */
-			for( j = i; PATH[i] && PATH[i] != ':'; i++);
-			if( i == j) /* ... or the end of PATH, nothing found. */
-				return NULL;
-			if( PATH[j] != '/') {
-				F_("PATH-entry without '/' at the begin. Skip.\n");
-				continue;
-			}
-
-			/* create the complete path to a possible file */
-			filename = malloc( exec_len+ i-j +2);
-			if( !filename) {
-				F_( "malloc returns NULL.\n");
-				return NULL;
-			}
-			memcpy( filename, PATH+j, i-j);
-			j = i-j;
-			if( filename[j] != '/')  /* '/' for delimeter path and file */
-				filename[j++] = '/';
-			memcpy( filename+j, exec, exec_len);
-			/* don't forget the terminating-null */
-			filename[exec_len+j] = 0;
-
-			/* now test, if this file exists and it's executeable? */
-			if( stat( filename, &test) == -1)
-				F_( "stat failes on '%s': %s\n", filename, strerror( errno));
-			else if( test.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR |
-						S_ISVTX | S_ISGID | S_ISUID | S_IFREG)) {
-				/* filename is an executable */
-				D_("Found %s as Executable\n", filename);
-				return filename;
-			}
-			free( filename);
-		}
-	} else
-		return exec;
-	F_( "No executeable found\n");
+static char *expand_exec(char *exec) {
+    
+    char *filename = NULL;
+
+    if(!exec)
 	return NULL;
+
+    /* 11/20/2005 SaTaN0rX: preliminary support for searching the PATH
+     * only search the PATH if this is NOT already an absolute path
+     */
+
+    if(exec[0] != '/') {
+	size_t exec_len = strlen(exec);
+	int len;
+	const char *PATH = getenv("PATH");
+	char *new_str = NULL;
+	struct stat test;
+
+	D_("initng_s_launch: %s is not absolute path, searching $PATH\n", exec);
+
+	if(!PATH)
+	{
+	    D_("No $PATH found, using default path\n");
+	    PATH = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin";
+	}
+
+	D_("PATH determined to be %s\n", PATH);
+
+	while (PATH[0]!=0)
+	{
+	    len = strcspn(PATH, ":");
+	    if (len!=0)
+	    {
+		new_str = (char *) i_strndup(PATH, len);
+		filename = (char *) initng_calloc(exec_len+len+2, sizeof(char));
+		strcpy(filename, new_str);
+		if (new_str[len-1] != '/')
+		    strcat(filename, "/");
+		strcat(filename, exec);
+		free(new_str);
+
+		if((stat(filename, &test) != -1) && (test.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR |
+		    S_ISVTX | S_ISGID | S_ISUID | S_IFREG)))
+		    break;
+
+		free(filename);
+		filename = NULL;
+	    }
+	    else
+		len = 1;
+
+	    PATH += len;
+	}
+    } else
+	return exec;
+
+    if (!filename)
+	F_( "No executeable found\n");
+
+    return filename;
 }
 
 static int initng_s_launch(active_h * service, process_h * process) {
-	int i, j;
-	char *e = NULL;
-	char *t = NULL;
-	char *u = NULL;
-	char **a = NULL;
-	void *b = NULL;
-	size_t argc = 0;
-	size_t c = 0;
-	char **argv = NULL;
+    char *exec = NULL;
+    char *exec_args = NULL;
+    char *t = NULL;
+    size_t exec_c;
+    size_t exec_args_c;
+    char *argv0;
+    char **exec_argv = NULL;
+    char **exec_args_argv = NULL;
+    int i;
+    int result = FAIL;
     assert(service);
     assert(service->name);
 
     /* WE ARE EXECUTING A START FILE */
-    if (active_db_is_var(&EXEC, process->pt->name, service)) {
-        while( (e = active_db_get_string_var( &EXEC, process->pt->name, service))) {
-			t = fix_variables( e, service);
-			/* argv-entries are pointer to t[x] */
-			argv = split_argv( t, &argc);
-			if( !argv) {
-				D_( "split_argv returns NULL.\n");
-				free( t);
-				continue;
-			}
-			argv[0] = expand_exec( argv[0]);
-			if( !argv[0]) {
-				D_( "expand_exec returns NULL.\n");
-				free( t);
-				continue;
-			}
-
-			/* exec_args should be parsed at the moment, too */
-			u = active_db_get_string_var( &EXEC_ARGS, process->pt->name, service);
-			u = fix_variables( u, service);
-			a = split_argv( u, &c);
-			if( c) {
-				if( !a) {
-					D_( "split_argv returns NULL.\n");
-					if( argv[0] != t)
-						free( argv[0]);
-					free( t);
-					free( u);
-					continue;
-				}
-				b = realloc( argv, (argc+c+1)* sizeof*argv);
-				/* if realloc fails, then only argv will used */
-				if( !b) {
-					F_( "realloc returns NULL.\n");
-					free( u);
-					u = NULL;
-				} else {
-					argv = b;
-					memcpy( argv+argc, a, (c+1)*sizeof*argv);
-					argc += c;
-				}
-			}
-
-            if( simple_exec( process, service, argc, argv)) {
-				if( argv[0] != t)
-					free( argv[0]);
-                free( t);
-				if( u)
-					free( u);
-                return TRUE;
-            }
-            D_("%s did not work\n", t);
-            free( t);
-			if( u)
-				free( u);
-        }
-        return FAIL;
+    while ((exec = active_db_get_string_var(&EXEC, process->pt->name, service)))
+    {
+	t = fix_variables(exec, service);
+	/* argv-entries are pointer to t[x] */
+	exec_argv = split_argv(t, &exec_c);
+	free(t);
+
+	if (!exec_argv[0])
+	{
+	    D_( "split_argv on exec returns NULL.\n");
+	    free(exec_argv);
+	    continue;
+	}
+
+	argv0 = expand_exec(exec_argv[0]);
+	if (!argv0)
+	{
+	    D_("%s was not found in search path.\n", exec_argv[0]);
+	    /* each element of argv must be freed! */
+	    for (i = 0; exec_argv[i]; i++)
+	        free(exec_argv[i]);
+	    free(exec_argv);
+	    continue;
+	}
+	else
+	{
+	    if (argv0 != exec_argv[0])
+	    {
+		free(exec_argv[0]);
+		exec_argv[0] = argv0;
+	    }
+	}
+
+	/* exec_args should be parsed at the moment, too */
+	exec_args = active_db_get_string_var(&EXEC_ARGS, process->pt->name, service);
+	if (exec_args)
+	{
+	    t = fix_variables(exec_args, service);
+	    exec_args_argv = split_argv(t, &exec_args_c);
+	    free(t);
+
+	    if (!exec_args_argv[0])
+	    {
+		D_( "split_argv exec_args returns NULL.\n");
+		free(exec_args_argv);
+		/* each element of argv must be freed! */
+		for (i = 0; exec_argv[i]; i++)
+		    free(exec_argv[i]);
+		free(exec_argv);
+		continue;
+	    }
+		
+	    exec_argv = (char **) initng_realloc(exec_argv,(exec_c+exec_args_c+1) * sizeof(char *));
+	    for (i=0; exec_args_argv[i]; i++)
+	    {
+		exec_argv[i+exec_c] = i_strdup(exec_args_argv[i]);
+		free(exec_args_argv[i]);
+	    }
+
+	    exec_argv[i+exec_c] = NULL;
+	    exec_c += exec_args_c;
+	    free(exec_args_argv);
+	}
+
+	result = simple_exec(process, service, exec_c, exec_argv);
+	if (result==TRUE)
+	    break;
     }
 
-    return FALSE;
+    if (result != TRUE)
+    {
+	if (result == FAIL)
+	{
+	    /* there was no exec in service */
+	    result = FALSE;
+
+	}
+	else
+	{
+	    /* exec found, but could not launch any */
+	    D_("%s did not work\n", t);
+	    if(exec_argv)
+	    {
+		for (i = 0; exec_argv[i]; i++)
+		    free(exec_argv[i]);
+		free(exec_argv);
+	    }
+	    result = FAIL;
+	}
+    }
+
+    return result;
 }
 
 /* 2005-11-28 DEac-: char *e, char *ea => char **argv, size_t argc
@@ -276,14 +297,13 @@
     assert(s);
     assert(s->name);
     assert(argc);
-	assert(argv);
+    assert(argv);
 
     if ((pid_fork = initng_fork(s, process_to_exec)) == 0) {
-		int i;
 
         D_("FROM_FORK simple_exec(%i,%s, ...);\n", argc, argv[0]);
 
-		D_argv( "simple_exec: ", argv);
+		D_argv("simple_exec: ", argv);
 
         /* FINALLY EXECUTE *//* execve replaces the running process */
         execve(argv[0], argv, new_environ(s));
@@ -313,12 +333,12 @@
 int module_init(const char *version)
 {
     D_("initng_simple_plugin: module_init();\n");
-    /*
-       if (strcmp(version, INITNG_VERSION) != 0)
-       {
-       F_("This module, is compiled for \"%s\" version, and initng is compiled on \"%s\" version, wont load this module!\n", INITNG_VERSION, version);
-       return (FALSE);
-       } */
+
+    if (strcmp(version, INITNG_VERSION) != 0)
+    {
+	F_("This module, is compiled for \"%s\" version, and initng is compiled on \"%s\" version, wont load this module!\n", INITNG_VERSION, version);
+	return (FALSE);
+    }
 
     initng_add_hook(LAUNCH, 40, &initng_s_launch);
     initng_sdt_add(&EXEC);

Modified: initng/plugins/stcmd/print_service.c
==============================================================================
--- initng/plugins/stcmd/print_service.c	(original)
+++ initng/plugins/stcmd/print_service.c	Fri Dec  2 10:47:13 2005
@@ -35,8 +35,11 @@
 
 #include "print_service.h"
 
+#define IS_PRINTABLE(x) (x >= 32 || x == '\n' || x == '\t' || x == '\r')
+
 static void service_db_print_u(service_h * s, FILE * fd, int intro);
 static void active_db_print_u(active_h * s, FILE * fd, int intro);
+static void print_string_value(char * string, FILE * fd);
 
 /* P R I N T   S E R V I C E */
 
@@ -53,6 +56,19 @@
     return;
 }
 
+/* there may be unprintable characters in string - should escape them when printing */
+static void print_string_value(char * string, FILE * fd)
+{
+    int i;
+    for (i=0; string[i]!=0; i++)
+    {
+	if (IS_PRINTABLE(string[i]))
+	    fprintf(fd, "%c", string[i]);
+	else
+	    fprintf(fd, "^%c", string[i]^0x40);
+    }
+}
+
 static void service_db_print_u(service_h * s, FILE * fd, int intro)
 {
     /*data path */
@@ -87,8 +103,9 @@
                     F_("empty value!\n");
                     continue;
                 }
-                fprintf(fd, " @@ %s:\t\"%s\"\n", tmp->type->opt_name,
-                        tmp->t.s);
+                fprintf(fd, " @@ %s:\t\"", tmp->type->opt_name);
+		print_string_value(tmp->t.s, fd);
+		fprintf(fd, "\"\n");
                 continue;
             case VARIABLE_STRING:
             case VARIABLE_STRINGS:
@@ -97,8 +114,9 @@
                     F_("empty value!\n");
                     continue;
                 }
-                fprintf(fd, " @@ %s %s:\t\"%s\"\n", tmp->type->opt_name,
-                        tmp->vn, tmp->t.s);
+                fprintf(fd, " @@ %s %s:\t\"\n", tmp->type->opt_name, tmp->vn);
+		print_string_value(tmp->t.s, fd);
+		fprintf(fd, "\"\n");
                 continue;
             case INT:
                 fprintf(fd, " @@ %s:\t\"%i\"\n", tmp->type->opt_name,

Modified: initng/src/initng_active_db.c
==============================================================================
--- initng/src/initng_active_db.c	(original)
+++ initng/src/initng_active_db.c	Fri Dec  2 10:47:13 2005
@@ -317,6 +317,7 @@
 int active_db_dep_on(active_h * service, active_h * check)
 {
     s_call *current, *s = NULL;
+    int result = FALSE;
 
     assert(service);
     assert(check);
@@ -329,10 +330,10 @@
         if (current->ptype != DEP_ON)
             continue;
 
-        if ((*current->c.dep_on_check) (service, check) == TRUE)
-            return (TRUE);
+        if ((result = (*current->c.dep_on_check) (service, check) == TRUE))
+            break;
     }
-    return (FALSE);
+    return result;
 }
 
 
@@ -359,6 +360,7 @@
                                   int *stack)
 {
     active_h *current = NULL;
+    int result = FALSE;
 
     if (current == service)
         return (FALSE);
@@ -379,11 +381,11 @@
     {
         if (active_db_dep_on(service, current))
         {
-            if (active_db_dep_on_deep(current, check))
-                return (TRUE);
+            if ((result = active_db_dep_on_deep(current, check)))
+                break;
         }
     }
-    return (FALSE);
+    return result;
 }
 
 /* compensate time */

Modified: initng/src/initng_common.c
==============================================================================
--- initng/src/initng_common.c	(original)
+++ initng/src/initng_common.c	Fri Dec  2 10:47:13 2005
@@ -62,9 +62,10 @@
     for (i = 1; (g.Argv)[i]; i++)
     {
         /* if we got a match */
-        if ((g.Argv)[i][0] == '-' && strstr(name, (g.Argv)[i] + 1))
+        if ((g.Argv)[i][0] == '-')
         {
-            return (TRUE);
+	    if (strcmp(name, (g.Argv)[i]+1)==0 || service_match(name, (g.Argv)[i]+1))
+        	return (TRUE);
         }
     }
     return (FALSE);

Modified: initng/src/initng_execute.c
==============================================================================
--- initng/src/initng_execute.c	(original)
+++ initng/src/initng_execute.c	Fri Dec  2 10:47:13 2005
@@ -99,7 +99,7 @@
         F_("initng_execute(%s): FAILED LAUNCHING, returned FAIL\n",
            service->name);
     else
-        D_("initng_execute(%s): FAILED LAUNCHING, resturned FALSE\n",
+        D_("initng_execute(%s): FAILED LAUNCHING, returned FALSE\n",
            service->name);
 
     /* on failure remove the process from list, and free it */

Modified: initng/src/initng_load_module.c
==============================================================================
--- initng/src/initng_load_module.c	(original)
+++ initng/src/initng_load_module.c	Fri Dec  2 10:47:13 2005
@@ -396,8 +396,7 @@
     DIR *d;
     struct dirent *e;
     char *module_path;
-    int len;
-    char module_name[NAME_MAX + 1];
+    char *module_name;
 
     m_h *current, *safe = NULL;
 
@@ -417,10 +416,13 @@
         /* check for files, ending with .so */
         if (fnmatch("lib*.so", e->d_name, 0) == 0)
         {
+	    module_name = i_strndup(e->d_name+3,strlen(e->d_name+3)-3);
+
             /* search the plugin name, for blacklisted */
-            if (service_blacklisted(e->d_name))
+            if (service_blacklisted(module_name))
             {
-                F_("Plugin %s blacklisted.\n", e->d_name);
+                F_("Plugin %s blacklisted.\n", module_name);
+		free(module_name);
                 continue;
             }
 
@@ -428,12 +430,6 @@
             strcpy(module_path, INITNG_PLUGIN_DIR "/");
             strcat(module_path, e->d_name);
 
-
-            /* set name */
-            strcpy(module_name, e->d_name + 3); /* skip "lib" */
-            len = strlen(module_name);
-            module_name[len - 3] = '\0';    /* remove ".so" */
-
             /* open the module */
             current = open_module(module_path, module_name);
 

Modified: initng/src/initng_service_cache.c
==============================================================================
--- initng/src/initng_service_cache.c	(original)
+++ initng/src/initng_service_cache.c	Fri Dec  2 10:47:13 2005
@@ -94,7 +94,12 @@
     INIT_LIST_HEAD(&(new_serv->data.list));
 
     /* copy over all strings */
-    d_copy_all(&s->list, &new_serv->list);
+    d_copy_all(&s->data.list, &new_serv->data.list);
+
+    /* we must clear pointers, otherwise this servise 
+     * will not be added to list
+    */
+    new_serv->list.prev = new_serv->list.next = NULL;
 
     return (new_serv);
 }


More information about the Initng-svn mailing list