cvs commit: ALFS/nALFS/src/handlers alfs.c build.c check.c chroot.c conditionals.c configure.c copy.c download.c execute.c link.c log.c make.c mkdir.c move.c owner.c ownership.c package.c patch.c permissions.c postbuild.c prebuild.c remove.c search_replace.c setenv.c stage.c stamp.c su.c textdump.c unpack.c

kpfleming at linuxfromscratch.org kpfleming at linuxfromscratch.org
Sat Feb 21 11:03:33 PST 2004


kpfleming    04/02/21 12:03:33

  Modified:    nALFS/src handlers.c handlers.h parser.c parser.h
               nALFS/src/handlers alfs.c build.c check.c chroot.c
                        conditionals.c configure.c copy.c download.c
                        execute.c link.c log.c make.c mkdir.c move.c
                        owner.c ownership.c package.c patch.c permissions.c
                        postbuild.c prebuild.c remove.c search_replace.c
                        setenv.c stage.c stamp.c su.c textdump.c unpack.c
  Log:
  cleanup alloc_base_dir_new/_force functions into a single function
  add HDATA values for "base" and "shell"
  convert alloc_base_dir_new/alloc_stage_shell to use new HDATA values
  make all handler functions use const parameters where applicable
  make some handler utility functions use const parameters
  make some parser utility functions use const parameters
  reimplement <stage> handler, using new handler-parsing functions
  add handlers for <stageinfo>, <environment> and <variable>
  
  Revision  Changes    Path
  1.20      +25 -61    ALFS/nALFS/src/handlers.c
  
  Index: handlers.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- handlers.c	14 Feb 2004 04:30:21 -0000	1.19
  +++ handlers.c	21 Feb 2004 19:03:32 -0000	1.20
  @@ -348,84 +348,48 @@
   	return xstrdup("/");
   }
   
  -/* Used by new syntax (3.0). */
  -char *alloc_base_dir_new(element_s *el)
  +/* Used by new syntax (3.0+). */
  +char *alloc_base_dir_new(const element_s * const el, const int default_root)
   {
  -	element_s *s;
  +	const element_s *s;
   	char *dir;
   
  -
   	if ((dir = attr_value("base", el)) && strlen(dir)) {
   		return xstrdup(dir);
   	}
   
   	for (s = el->parent; s; s = s->parent) {
  -		if (!s->handler) continue;
  -
  -		if (s->handler->type & HTYPE_STAGE) {
  -			element_s *sinfo;
  -
  -			if ((sinfo = first_param("stageinfo", s)) == NULL) {
  -				continue;
  -			}
  -
  -			if ((dir = alloc_trimmed_param_value("base", sinfo))) {
  -				return dir;
  -			}
  -		}
  +		if (!s->handler)
  +			continue;
  +		if ((s->handler->data & HDATA_BASE) == 0)
  +			continue;
  +
  +		dir  = s->handler->alloc_data(s, HDATA_BASE);
  +		if (dir)
  +			return dir;
   	}
   
  -	return xstrdup("/");
  -}
  -
  -/* Used by new syntax (3.2) when you _must_ have <base> present */
  -char *alloc_base_dir_force(element_s *el)
  -{
  -	element_s *s;
  -	char *dir = NULL;
  -
  -	if ((dir = attr_value("base", el)) && strlen(dir)) {
  -		return xstrdup(dir);
  +	if (default_root) {
  +		return xstrdup("/");
  +	} else {
  +		return NULL;
   	}
  -
  -	for (s = el->parent; s; s = s->parent) {
  -		if (!s->handler) continue;
  -
  -		if (s->handler->type & HTYPE_STAGE) {
  -			element_s *sinfo;
  -
  -			if ((sinfo = first_param("stageinfo", s)) == NULL) {
  -				continue;
  -			}
  -
  -			if ((dir = alloc_trimmed_param_value("base", sinfo))) {
  -				return dir;
  -			}
  -		}
  -	}
  -
  -	return dir;
   }
   
  -char *alloc_stage_shell(element_s *el)
  +char *alloc_stage_shell(const element_s * const el)
   {
  -	element_s *s;
  +	const element_s *s;
   	char *shell;
   
   	for (s = el->parent; s; s = s->parent) {
  -		if (!s->handler) continue;
  -
  -		if (s->handler->type & HTYPE_STAGE) {
  -			element_s *sinfo;
  -
  -			if ((sinfo = first_param("stageinfo", s)) == NULL) {
  -				continue;
  -			}
  -
  -			if ((shell = alloc_trimmed_param_value("shell", sinfo))) {
  -				return shell;
  -			}
  -		}
  +		if (!s->handler)
  +			continue;
  +		if ((s->handler->data & HDATA_SHELL) == 0)
  +			continue;
  +
  +		shell = s->handler->alloc_data(s, HDATA_SHELL);
  +		if (shell)
  +			return shell;
   	}
   
   	return xstrdup("sh");
  
  
  
  1.14      +29 -23    ALFS/nALFS/src/handlers.h
  
  Index: handlers.h
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- handlers.h	14 Feb 2004 04:31:12 -0000	1.13
  +++ handlers.h	21 Feb 2004 19:03:32 -0000	1.14
  @@ -43,16 +43,25 @@
   } handler_type_e;
   
   typedef enum handler_data_e {
  -	HDATA_COMMAND, HDATA_NAME, HDATA_VERSION, HDATA_FILE
  +	HDATA_COMMAND = 1,
  +	HDATA_NAME = 2,
  +	HDATA_VERSION = 4,
  +	HDATA_FILE = 8,
  +	HDATA_BASE = 16,
  +	HDATA_SHELL = 32,
   } handler_data_e;
   
  -typedef char *(*handler_data_f)(element_s *, handler_data_e data);
  -typedef int (*handler_f)(element_s *);
  -typedef int (*handler_test)(element_s *, int *);
  -typedef int (*handler_setup)(element_s *);
  -typedef int (*handler_parse)(const element_s *, const char *, const char *);
  -typedef int (*handler_parse_content)(const element_s *, const char *);
  -typedef int (*handler_valid)(const element_s *);
  +typedef char *(*handler_data_f)(const element_s * const element,
  +				const handler_data_e data_requested);
  +typedef int (*handler_f)(element_s * const element);
  +typedef int (*handler_test)(element_s * const element, int * const result);
  +typedef int (*handler_setup)(element_s * const element);
  +typedef int (*handler_parse)(const element_s * const element,
  +			     const char * const name,
  +			     const char * const value);
  +typedef int (*handler_parse_content)(const element_s * const element,
  +				     const char * const content);
  +typedef int (*handler_valid)(const element_s * const element);
   
   typedef struct handler_info_s {
   	const char *name;		/* Name of the element it handles. */
  @@ -61,27 +70,25 @@
   	const char **parameters;	/* Parameters allowed. */
   	const char **attributes;	/* Attributes allowed. */
   
  -	handler_f main;
  -
   	handler_type_e type;
  +	handler_data_e data;
   	handler_data_f alloc_data;
   
  -	int is_action;		/* Whether it's the element that actually
  -				 * does something, or it's only a "container".
  -				 */
  +	handler_f main;
  +	handler_test test;		/* used by HTYPE_TEST handlers */
  +
  +	int is_action;		/* If the element actually performs something
  +				   or is only a container */
   	int priority;           /* Higher priority handlers "override" lower
   				   priority ones (allows user to make custom
   				   handlers that replace standard ones) */
  -
  -	handler_test test;	/* used by HTYPE_TEST */
   	int alternate_shell;	/* commands issued by handler should support
   				   <shell> element if present in a containing
  -				   stage
  -				*/
  -	/* The following four functions are used during profile parsing, to
  +				   element */
  +
  +	/* The following five functions are used during profile parsing, to
   	   allow handler to store private data in the element_s structure,
  -	   and to validate the provided parameters and attributes at
  -	   profile parsing time.
  +	   and to validate the provided parameters, attributes and content.
   	*/
   	handler_setup setup;	/* Function to setup handler private data. */
   	handler_valid valid;	/* Function to validate private data. */
  @@ -114,9 +121,8 @@
   char *alloc_execute_command(element_s *el);
   
   char *alloc_base_dir(element_s *el);
  -char *alloc_base_dir_new(element_s *el);
  -char *alloc_base_dir_force(element_s *el);
  -char *alloc_stage_shell(element_s *el);
  +char *alloc_base_dir_new(const element_s * const el, const int default_root);
  +char *alloc_stage_shell(const element_s * const el);
   int option_exists(const char *option, element_s *element);
   void check_options(int total, int *opts, const char *string_, element_s *el);
   char *append_param_elements(char **string, element_s *el);
  
  
  
  1.8       +6 -5      ALFS/nALFS/src/parser.c
  
  Index: parser.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/parser.c,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- parser.c	14 Feb 2004 04:32:22 -0000	1.7
  +++ parser.c	21 Feb 2004 19:03:32 -0000	1.8
  @@ -186,7 +186,7 @@
    * Different utility funtions.
    */
   
  -char *attr_value(const char *name, element_s *element)
  +char *attr_value(const char * const name, const element_s * const element)
   {
   	if (element->attr) {
   		int i;
  @@ -202,7 +202,7 @@
   	return NULL;
   }
   
  -char *raw_param_value(const char *name, const element_s *element)
  +char *raw_param_value(const char * const name, const element_s * const element)
   {
   	element_s *tmp;
   
  @@ -216,7 +216,8 @@
   	return NULL;
   }
   
  -char *alloc_trimmed_param_value(const char *name, const element_s *element)
  +char *alloc_trimmed_param_value(const char * const name,
  +				const element_s * const element)
   {
   	char *tmp;
   
  @@ -228,7 +229,7 @@
   	return tmp;
   }
   
  -element_s *next_param(element_s *param)
  +element_s *next_param(const element_s * const param)
   {
   	element_s *tmp;
   
  @@ -243,7 +244,7 @@
   	return NULL;
   }
   
  -element_s *first_param(const char *name, const element_s *element)
  +element_s *first_param(const char * const name, const element_s * const element)
   {
   	element_s *tmp;
   
  
  
  
  1.7       +6 -5      ALFS/nALFS/src/parser.h
  
  Index: parser.h
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/parser.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- parser.h	13 Feb 2004 07:08:59 -0000	1.6
  +++ parser.h	21 Feb 2004 19:03:32 -0000	1.7
  @@ -86,11 +86,12 @@
   		  element_s *profile);
   element_s *parse_profile(const char *filename);
   
  -char *attr_value(const char *name, element_s *element);
  -char *raw_param_value(const char *name, const element_s *element);
  -char *alloc_trimmed_param_value(const char *name, const element_s *element);
  -element_s *next_param(element_s *param);
  -element_s *first_param(const char *name, const element_s *element);
  +char *attr_value(const char * const name, const element_s * const element);
  +char *raw_param_value(const char * const name, const element_s * const element);
  +char *alloc_trimmed_param_value(const char * const name,
  +				const element_s * const element);
  +element_s *next_param(const element_s * const param);
  +element_s *first_param(const char * const name, const element_s * const element);
   
   element_s *get_profile_by_element(element_s *el);
   element_s *get_profile_by_name(element_s *root, const char *name);
  
  
  
  1.15      +7 -2      ALFS/nALFS/src/handlers/alfs.c
  
  Index: alfs.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/alfs.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- alfs.c	13 Feb 2004 07:08:59 -0000	1.14
  +++ alfs.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -32,11 +32,16 @@
   
   #include "handlers.h"
   #include "backend.h"
  +#include "nprint.h"
   
   
  -static int alfs_main(element_s *el)
  +static int alfs_main(element_s * const el)
   {
  -	return execute_children(el);
  +	int status;
  +
  +	status = execute_children(el);
  +
  +	return status;
   }
   
   
  
  
  
  1.14      +1 -1      ALFS/nALFS/src/handlers/build.c
  
  Index: build.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/build.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- build.c	13 Feb 2004 07:08:59 -0000	1.13
  +++ build.c	21 Feb 2004 19:03:32 -0000	1.14
  @@ -38,7 +38,7 @@
   #if HANDLER_SYNTAX_2_0
   
   
  -static int build_main(element_s *el)
  +static int build_main(element_s * const el)
   {
   	int i;
   
  
  
  
  1.13      +1 -1      ALFS/nALFS/src/handlers/check.c
  
  Index: check.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/check.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- check.c	13 Feb 2004 07:08:59 -0000	1.12
  +++ check.c	21 Feb 2004 19:03:32 -0000	1.13
  @@ -60,7 +60,7 @@
   #if HANDLER_SYNTAX_3_0
   
   
  -static int check_main(element_s *el)
  +static int check_main(element_s * const el)
   {
   	int status = 0;
   	char *package;
  
  
  
  1.15      +1 -1      ALFS/nALFS/src/handlers/chroot.c
  
  Index: chroot.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/chroot.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- chroot.c	13 Feb 2004 07:08:59 -0000	1.14
  +++ chroot.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -48,7 +48,7 @@
   
   // char *HANDLER_SYMBOL(attributes)[] = { "dir", NULL };
   
  -static int chroot_main(element_s *el)
  +static int chroot_main(element_s * const el)
   {
   	int status;
   	pid_t chroot_pid, got_pid;
  
  
  
  1.7       +10 -8     ALFS/nALFS/src/handlers/conditionals.c
  
  Index: conditionals.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/conditionals.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- conditionals.c	13 Feb 2004 07:08:59 -0000	1.6
  +++ conditionals.c	21 Feb 2004 19:03:32 -0000	1.7
  @@ -81,7 +81,7 @@
   #if HANDLER_SYNTAX_3_1
   static const char *if_parameters_3_1[] = { "then", "else", NULL };
   
  -static int if_main_3_1(element_s *element)
  +static int if_main_3_1(element_s * const element)
   {
   	char *shelltest;
   	char *packagetest;
  @@ -115,7 +115,7 @@
   static const char *if_parameters_3_2[] = { "test", "package-version", "package-built", "and", "or", "not", "then", "else", NULL };
   static const char *boolean_parameters_3_2[] = { "test", "package-version", "package-built", "and", "or", "not", NULL };
   
  -static int if_main_3_2(element_s *element)
  +static int if_main_3_2(element_s * const element)
   {
   	int i;
   	element_s *child;
  @@ -140,7 +140,7 @@
   	return execute_children_filtered(element, result_handler_type);
   }
   
  -static int and_test_3_2(element_s *element, int *result)
  +static int and_test_3_2(element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
  @@ -161,7 +161,7 @@
   	return 0;
   }
   
  -static int or_test_3_2(element_s *element, int *result)
  +static int or_test_3_2(element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
  @@ -182,7 +182,7 @@
   	return 0;
   }
   
  -static int not_test_3_2(element_s *element, int *result)
  +static int not_test_3_2(element_s * const element, int * const result)
   {
   	int i;
   	element_s *child;
  @@ -207,7 +207,7 @@
   	return 0;
   }
   
  -static int shelltest_test_3_2(element_s *element, int *result)
  +static int shelltest_test_3_2(element_s * const element, int * const result)
   {
   	char *test;
   	int status = -1;
  @@ -222,14 +222,16 @@
   	return status;
   }
   
  -static int package_version_test_3_2(element_s *element, int *result)
  +static int package_version_test_3_2(element_s * const element,
  +				    int * const result)
   {
   	(void) element;
   	(void) result;
   	return 0;
   }
   
  -static int package_built_test_3_2(element_s *element, int *result)
  +static int package_built_test_3_2(element_s * const element,
  +				  int * const result)
   {
   	(void) element;
   	(void) result;
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/configure.c
  
  Index: configure.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/configure.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- configure.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ configure.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -45,7 +45,7 @@
   static const char *configure_parameters_ver2[] =
   { "base", "command", "param", NULL };
   
  -static int configure_main_ver2(element_s *el)
  +static int configure_main_ver2(element_s * const el)
   {
   	int status;
   	char *c, *command = NULL;
  @@ -87,14 +87,14 @@
   { "param", "prefix", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "command", NULL };
   
  -static int configure_main_ver3(element_s *el)
  +static int configure_main_ver3(element_s * const el)
   {
   	int status;
   	char *c, *command = NULL;
   	char *base;
          
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/copy.c
  
  Index: copy.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/copy.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- copy.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ copy.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -49,7 +49,7 @@
   static const char *copy_parameters_ver2[] =
   { "options", "base", "source", "destination", NULL };
   
  -static int copy_main_ver2(element_s *el)
  +static int copy_main_ver2(element_s * const el)
   {
   	int status = 0;
   	int archive = option_exists("archive",el);
  @@ -133,7 +133,7 @@
   { "option", "source", "destination", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int copy_main_ver3(element_s *el)
  +static int copy_main_ver3(element_s * const el)
   {
   	int options[5];
   	int status = 0;
  @@ -173,7 +173,7 @@
   		append_str(&common_command, " -R");
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(destination);
  
  
  
  1.16      +3 -3      ALFS/nALFS/src/handlers/download.c
  
  Index: download.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/download.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- download.c	11 Feb 2004 05:08:12 -0000	1.15
  +++ download.c	21 Feb 2004 19:03:32 -0000	1.16
  @@ -53,7 +53,7 @@
   static const char *download_parameters[] =
   { "digest", "file", "url", "destination", NULL };
   
  -static int download_main(element_s *el)
  +static int download_main(element_s * const el)
   {
   	/* status assumes failure until set otherwise */
   	int status = -1;
  @@ -143,7 +143,7 @@
   static const char *download_parameters_3_2[] =
   { "digest", "file", "url", NULL };
   
  -static int download_main_3_2(element_s *el)
  +static int download_main_3_2(element_s * const el)
   {
   	/* status assumes failure until set otherwise */
   	int status = -1;
  @@ -160,7 +160,7 @@
   	}
   
   	/* <base> is mandatory, we don't want to download just anywhere! */
  -	if ((base = alloc_base_dir_force(el)) == NULL) {
  +	if ((base = alloc_base_dir_new(el, 0)) == NULL) {
   		Nprint_h_err("<base> is missing.");
   		goto free_all_and_return;
   	}
  
  
  
  1.21      +11 -8     ALFS/nALFS/src/handlers/execute.c
  
  Index: execute.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/execute.c,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- execute.c	11 Feb 2004 05:08:12 -0000	1.20
  +++ execute.c	21 Feb 2004 19:03:32 -0000	1.21
  @@ -49,7 +49,7 @@
   static const char *execute_parameters_ver2[] =
   { "base", "command", "param", NULL };
   
  -static int execute_main_ver2(element_s *el)
  +static int execute_main_ver2(element_s * const el)
   {
   	int status;
   	char *base;
  @@ -83,7 +83,8 @@
   	
   }
   
  -static char *execute_data_ver2(element_s *el, handler_data_e data)
  +static char *execute_data_ver2(const element_s * const el,
  +			       const handler_data_e data)
   {
   	(void) data;
   
  @@ -99,7 +100,7 @@
   { "param", "prefix", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "command", NULL };
   
  -static int execute_main_ver3(element_s *el)
  +static int execute_main_ver3(element_s * const el)
   {
   	int status;
   	char *base;
  @@ -111,7 +112,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  @@ -137,7 +138,8 @@
   	return status;
   }
   
  -static char *execute_data_ver3(element_s *el, handler_data_e data)
  +static char *execute_data_ver3(const element_s * const el,
  +			       const handler_data_e data)
   {
   	char *command;
   
  @@ -159,7 +161,7 @@
   { "param", "prefix", "content", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "command", NULL };
   
  -static int execute_main_ver3_2(element_s *el)
  +static int execute_main_ver3_2(element_s * const el)
   {
   	int status = -1;
   	char *base;
  @@ -185,7 +187,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  @@ -243,7 +245,8 @@
   	return status;
   }
   
  -static char *execute_data_ver3_2(element_s *el, handler_data_e data)
  +static char *execute_data_ver3_2(const element_s * const el,
  +				 const handler_data_e data)
   {
   	char *command;
   	element_s *content_param;
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/link.c
  
  Index: link.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/link.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- link.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ link.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -49,7 +49,7 @@
   { "options", "base", "target", "name", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "type", NULL };
   
  -static int link_main_ver2(element_s *el)
  +static int link_main_ver2(element_s * const el)
   {
   	int status;
   	int force = option_exists("force", el);
  @@ -140,7 +140,7 @@
   { "option", "target", "name", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "type", "base", NULL };
   
  -static int link_main_ver3(element_s *el)
  +static int link_main_ver3(element_s * const el)
   {
   	int options[2], force, no_dereference;
   	int status;
  @@ -160,7 +160,7 @@
   
   	link_name = alloc_trimmed_param_value("name", el);
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   	if (change_current_dir(base)) {
   		xfree(base);
   		xfree(link_name);
  
  
  
  1.15      +1 -1      ALFS/nALFS/src/handlers/log.c
  
  Index: log.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/log.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- log.c	13 Feb 2004 07:08:59 -0000	1.14
  +++ log.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -37,7 +37,7 @@
   #if HANDLER_SYNTAX_2_0 || HANDLER_SYNTAX_3_0
   
   
  -static int log_main(element_s *el)
  +static int log_main(element_s * const el)
   {
   	Nprint_h("%s", el->content ? el->content : "");
   
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/make.c
  
  Index: make.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/make.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- make.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ make.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -44,7 +44,7 @@
   
   static const char *make_parameters_ver2[] = { "base", "param", NULL };
   
  -static int make_main_ver2(element_s *el)
  +static int make_main_ver2(element_s * const el)
   {
   	int status;
   	char *base;
  @@ -80,14 +80,14 @@
   static const char *make_parameters_ver3[] = { "param", "prefix", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int make_main_ver3(element_s *el)
  +static int make_main_ver3(element_s * const el)
   {
   	int status;
   	char *base;
   	char *command;
   
   	
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/mkdir.c
  
  Index: mkdir.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/mkdir.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- mkdir.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ mkdir.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -49,7 +49,7 @@
   static const char *mkdir_parameters_ver2[] =
   { "options", "base", "dir", "permissions", NULL };
   
  -static int mkdir_main_ver2(element_s *el)
  +static int mkdir_main_ver2(element_s * const el)
   {
   	int status = 0;
   	int parents = option_exists("parents", el);
  @@ -122,7 +122,7 @@
   { "option", "name", "permissions", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int mkdir_main_ver3(element_s *el)
  +static int mkdir_main_ver3(element_s * const el)
   {
   	int options[1], parents;
   	int status = 0;
  @@ -139,7 +139,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/move.c
  
  Index: move.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/move.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- move.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ move.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -49,7 +49,7 @@
   static const char *move_parameters_ver2[] =
   { "options", "base", "source", "destination", NULL };
   
  -static int move_main_ver2(element_s *el)
  +static int move_main_ver2(element_s * const el)
   {
   	int status = 0;
   	int force = option_exists("force", el);
  @@ -112,7 +112,7 @@
   { "option", "source", "destination", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int move_main_ver3(element_s *el)
  +static int move_main_ver3(element_s * const el)
   {
   	int options[1], force;
   	int status = 0;
  @@ -135,7 +135,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  
  
  
  1.15      +1 -1      ALFS/nALFS/src/handlers/owner.c
  
  Index: owner.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/owner.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- owner.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ owner.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -50,7 +50,7 @@
   static const char *owner_parameters[] =
   { "options", "base", "user", "group", "name", NULL };
   
  -static int owner_main(element_s *el)
  +static int owner_main(element_s * const el)
   {
   	int status = 0;
   	int recursive = option_exists("recursive", el);
  
  
  
  1.13      +2 -2      ALFS/nALFS/src/handlers/ownership.c
  
  Index: ownership.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/ownership.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ownership.c	11 Feb 2004 05:08:12 -0000	1.12
  +++ ownership.c	21 Feb 2004 19:03:32 -0000	1.13
  @@ -42,7 +42,7 @@
   static const char *ownership_parameters[] = { "option", "name", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "user", "group", NULL };
   
  -static int ownership_main(element_s *el)
  +static int ownership_main(element_s *const el)
   {
   	int status = 0;
   	int options[1], recursive;
  @@ -61,7 +61,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   	if (change_current_dir(base)) {
   		xfree(base);
   		return -1;
  
  
  
  1.17      +6 -4      ALFS/nALFS/src/handlers/package.c
  
  Index: package.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/package.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- package.c	11 Feb 2004 05:08:12 -0000	1.16
  +++ package.c	21 Feb 2004 19:03:32 -0000	1.17
  @@ -45,7 +45,7 @@
   static const char *package_parameters_ver2[] =
   { "name", "version", "base", NULL };
   
  -static int package_main_ver2(element_s *el)
  +static int package_main_ver2(element_s * const el)
   {
   	int i;
   
  @@ -62,7 +62,8 @@
   	return i;
   }
   
  -static char *package_data_ver2(element_s *el, handler_data_e data)
  +static char *package_data_ver2(const element_s * const el,
  +			       const handler_data_e data)
   {
   	if (data == HDATA_NAME) {
   		return alloc_trimmed_param_value("name", el);
  @@ -232,7 +233,7 @@
   };
   // char *HANDLER_SYMBOL(attributes)[] = { "name", "version", "logfile", NULL };
   
  -static int package_main_ver3(element_s *el)
  +static int package_main_ver3(element_s * const el)
   {
   	int status = 0;
   	element_s *packageinfo;
  @@ -258,7 +259,8 @@
   	return status;
   }
   
  -static char *package_data_ver3(element_s *el, handler_data_e data)
  +static char *package_data_ver3(const element_s * const el,
  +			       const handler_data_e data)
   {
   	char *s;
   
  
  
  
  1.19      +5 -5      ALFS/nALFS/src/handlers/patch.c
  
  Index: patch.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/patch.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- patch.c	11 Feb 2004 05:08:12 -0000	1.18
  +++ patch.c	21 Feb 2004 19:03:32 -0000	1.19
  @@ -46,7 +46,7 @@
   
   static const char *patch_parameters_ver2[] = { "base", "param", NULL };
   
  -static int patch_main_ver2(element_s *el)
  +static int patch_main_ver2(element_s * const el)
   {
   	int status;
   	char *base;
  @@ -87,7 +87,7 @@
   static const char *patch_parameters_ver3[] = { "param", "prefix", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int patch_main_ver3(element_s *el)
  +static int patch_main_ver3(element_s * const el)
   {
   	int status;
   	char *base;
  @@ -100,7 +100,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  @@ -145,7 +145,7 @@
   						 "param", "prefix", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "mode", "path_strip", NULL };
   
  -static int patch_main_ver3_2(element_s *el)
  +static int patch_main_ver3_2(element_s * const el)
   {
           int status = -1;
   	char *base = NULL;
  @@ -164,7 +164,7 @@
   		goto free_all_and_return;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		goto free_all_and_return;
  
  
  
  1.15      +3 -3      ALFS/nALFS/src/handlers/permissions.c
  
  Index: permissions.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/permissions.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- permissions.c	11 Feb 2004 05:08:12 -0000	1.14
  +++ permissions.c	21 Feb 2004 19:03:32 -0000	1.15
  @@ -49,7 +49,7 @@
   static const char *permissions_parameters_ver2[] =
   { "base", "options", "mode", "name", NULL };
   
  -static int permissions_main_ver2(element_s *el)
  +static int permissions_main_ver2(element_s * const el)
   {
   	int status = 0;
   	int recursive = option_exists("recursive", el);
  @@ -134,7 +134,7 @@
   { "option", "name", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "mode", NULL };
   
  -static int permissions_main_ver3(element_s *el)
  +static int permissions_main_ver3(element_s * const el)
   {
   	int options[1], recursive;
   	int status = 0;
  @@ -151,7 +151,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   	if (change_current_dir(base)) {
   		xfree(base);
   		return -1;
  
  
  
  1.14      +1 -1      ALFS/nALFS/src/handlers/postbuild.c
  
  Index: postbuild.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/postbuild.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- postbuild.c	13 Feb 2004 07:08:59 -0000	1.13
  +++ postbuild.c	21 Feb 2004 19:03:32 -0000	1.14
  @@ -37,7 +37,7 @@
   
   #if HANDLER_SYNTAX_2_0
   
  -static int postbuild_main(element_s *el)
  +static int postbuild_main(element_s * const el)
   {
   	int i;
   
  
  
  
  1.14      +1 -1      ALFS/nALFS/src/handlers/prebuild.c
  
  Index: prebuild.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/prebuild.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- prebuild.c	13 Feb 2004 07:08:59 -0000	1.13
  +++ prebuild.c	21 Feb 2004 19:03:32 -0000	1.14
  @@ -37,7 +37,7 @@
   
   #if HANDLER_SYNTAX_2_0
   
  -static int prebuild_main(element_s *el)
  +static int prebuild_main(element_s * const el)
   {
   	int i;
   
  
  
  
  1.19      +4 -4      ALFS/nALFS/src/handlers/remove.c
  
  Index: remove.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/remove.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- remove.c	13 Feb 2004 07:08:59 -0000	1.18
  +++ remove.c	21 Feb 2004 19:03:32 -0000	1.19
  @@ -57,7 +57,7 @@
   }
   
   
  -static int remove_main_ver2(element_s *el)
  +static int remove_main_ver2(element_s * const el)
   {
   	int status = 0;
   	char *tok;
  @@ -96,7 +96,7 @@
   
   #if HANDLER_SYNTAX_3_0 || HANDLER_SYNTAX_3_1 
   
  -static int remove_main_ver3(element_s *el)
  +static int remove_main_ver3(element_s * const el)
   {
   	int status = 0;
   	char *name;
  @@ -126,7 +126,7 @@
   
   #if HANDLER_SYNTAX_3_2
   
  -static int remove_main_ver3_2(element_s *el)
  +static int remove_main_ver3_2(element_s * const el)
   {
   	int status   = 0;
   	char *name   = NULL;
  @@ -138,7 +138,7 @@
   		return -1;
   	}
   
  -	base = alloc_base_dir_new(el);
  +	base = alloc_base_dir_new(el, 1);
   
   	if (change_current_dir(base)) {
   		xfree(base);
  
  
  
  1.16      +3 -3      ALFS/nALFS/src/handlers/search_replace.c
  
  Index: search_replace.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/search_replace.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- search_replace.c	11 Feb 2004 05:08:12 -0000	1.15
  +++ search_replace.c	21 Feb 2004 19:03:32 -0000	1.16
  @@ -188,7 +188,7 @@
   static const char *search_replace_parameters_ver2[] =
   { "base", "find", "replace", "file", NULL };
   
  -static int search_replace_main_ver2(element_s *el)
  +static int search_replace_main_ver2(element_s * const el)
   {
   	int i;
   	char *base = alloc_base_dir(el);
  @@ -209,10 +209,10 @@
   { "find", "replace", "file", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", NULL };
   
  -static int search_replace_main_ver3(element_s *el)
  +static int search_replace_main_ver3(element_s * const el)
   {
   	int i;
  -	char *base = alloc_base_dir_new(el);
  +	char *base = alloc_base_dir_new(el, 1);
   
   	i = search_replace_main(el, base);
   
  
  
  
  1.13      +1 -1      ALFS/nALFS/src/handlers/setenv.c
  
  Index: setenv.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/setenv.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- setenv.c	6 Feb 2004 05:54:36 -0000	1.12
  +++ setenv.c	21 Feb 2004 19:03:32 -0000	1.13
  @@ -110,7 +110,7 @@
   
   static const char *setenv_parameters[] = { "variable", "value", NULL };
   
  -static int setenv_main(element_s *el)
  +static int setenv_main(element_s * const el)
   {
   	int i;
   	char *variable;
  
  
  
  1.20      +413 -225  ALFS/nALFS/src/handlers/stage.c
  
  Index: stage.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/stage.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- stage.c	13 Feb 2004 07:08:59 -0000	1.19
  +++ stage.c	21 Feb 2004 19:03:32 -0000	1.20
  @@ -1,9 +1,10 @@
   /*
  - *  stage.c - Handler.
  + *  stage.c - Handlers for <stage> and <stage>-related elements.
    * 
  - *  Copyright (C) 2002-2003
  + *  Copyright (C) 2002-2004
    *  
    *  Neven Has <haski at sezampro.yu>
  + *  Kevin P. Fleming <kpfleming at linuxfromscratch.org>
    *
    *  This program is free software; you can redistribute it and/or modify
    *  it under the terms of the GNU General Public License as published by
  @@ -50,8 +51,6 @@
   extern char **environ;
   
   
  -#if HANDLER_SYNTAX_3_0 || HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2
  -
   static INLINE int set_supplementary_groups(const char *user, gid_t gid)
   {
   	size_t size;
  @@ -140,8 +139,6 @@
   	return 0;
   }
   
  -
  -
   static INLINE int unset_variable(const char *variable)
   {
   	Nprint_h("Unsetting environment variable %s.", variable);
  @@ -212,244 +209,139 @@
   	return 0;
   }
   
  -static INLINE int set_environment(element_s *environment)
  +static const element_s *find_stageinfo(const element_s *element)
   {
  -	element_s *v;
  -
  -
  -	for (v = first_param("variable", environment); v; v = next_param(v)) {
  -		char *name, *value;
  -				
  -		name = attr_value("name", v);
  -		value = alloc_trimmed_str(v->content);
  -
  -		if (value) {
  -			char *mode = attr_value("mode", v);
  -
  -			if (mode && strcmp(mode, "append") == 0) {
  -				append_to_variable(name, value);
  -			} else if (mode && strcmp(mode, "prepend") == 0) {
  -				prepend_to_variable(name, value);
  -			} else {
  -				set_variable(name, value);
  -			}
  -
  -			xfree(value);
  +	const element_s *child;
   
  -		} else {
  -			unset_variable(name);
  +	for (child = element->children; child; child = child->next) {
  +		if (child->handler->type & HTYPE_STAGEINFO) {
  +			return child;
   		}
   	}
  -	
  -	return 0;
  -}
   
  +	return NULL;
  +}
   
  +/* common function used by all stage-like handlers to actually execute
  +   the element's children
  +*/
   
  -static int parse_stageinfo_and_execute_children(
  -	element_s *el,
  -	element_s *stageinfo)
  +static int process_stage(element_s *element)
   {
  -	int status = 0;
  +	int status;
   	pid_t pid, got_pid;
  -	char *user = NULL, *root = NULL;
  -	element_s *environment_el, *user_el, *root_el;
  -	
  -	/* <base> is read by elements under <stage> themselves. */
  -	environment_el = first_param("environment", stageinfo);
  -	user_el = first_param("user", stageinfo);
  -	root_el = first_param("root", stageinfo);
  -
  -	if (user_el) {
  -		if ((user = alloc_trimmed_str(user_el->content)) == NULL) {
  -	                Nprint_h_err("User not specified.");
  -	                return -1;
  -		}
  -	}
   
  -	if (root_el) {
  -		if ((root = alloc_trimmed_str(root_el->content)) == NULL) {
  -			Nprint_h_err("Root directory not specified.");
  -			xfree(user);
  -			return -1;
  -		}
  -	}
  +	/* if no <stageinfo> found, simply execute children */
   
  -	/* Nothing interesting found, no need for forking. */
  -	if (!environment_el && !user && !root) {
  -		xfree(user);
  -		xfree(root);
  +	if (!find_stageinfo(element))
  +		return execute_children(element);
   
  -		return execute_children(el);
  -	}
  +	/* found <stageinfo>, assume that a fork() is necessary */
   
   	pid = fork();
   
   	if (pid == 0) { /* Child. */
   		Start_receiving_sigio();
   
  -		if (root) {
  -			Nprint_h("Changing root directory to \"%s\".", root);
  -
  -			if (change_current_dir(root)) {
  -				xfree(user);
  -				xfree(root);
  -				exit(EXIT_FAILURE);
  -			}
  -			if (chroot(root)) {
  -				Nprint_h_err("    %s", strerror(errno));
  -				xfree(user);
  -				xfree(root);
  -				exit(EXIT_FAILURE);
  -			}
  -
  -			xfree(root);
  -
  -			/* clear the environment after successful chroot */
  -
  -			environ = NULL;
  -		}
  -
  -		if (user) {
  -			Nprint_h("Changing to user \"%s\".", user);
  -
  -			if (change_to_user(user) == -1) {
  -				xfree(user);
  -				exit(EXIT_FAILURE);
  -			}
  +		status = execute_children_filtered(element, HTYPE_STAGEINFO);
   
  -			xfree(user);
  -		}
  -
  -		if (environment_el) {
  -			set_environment(environment_el);
  -		}
  +		if (status)
  +			exit(status);
   
  -		exit(execute_children(el));
  +		exit(execute_children_filtered(element, ~HTYPE_STAGEINFO));
   
   	} else if (pid == -1) { /* Error. */
  -		fatal_backend_error("fork() in su/chroot element failed.");
  +		fatal_backend_error("fork() in <stage> failed.");
   	}
   
   	/* Parent. */
   
   	if ((got_pid = waitpid(pid, &status, WUNTRACED)) == -1) {
  -		fatal_backend_error("waitpid() for %ld in /chroot failed.",
  -			(long)pid);
  +		fatal_backend_error("waitpid() for %ld in <stage> failed.",
  +				    (long)pid);
   	}
   
   	if (WIFEXITED(status)) { /* Child exited normally. */
   		status = WEXITSTATUS(status);
   
   	} else if (WIFSIGNALED(status)) {
  -		Nprint_h_err("Su/chroot child (%ld) killed by signal %d%s.",
  -			(long)got_pid, WTERMSIG(status),
  -			WCOREDUMP(status) ? " (core dumped)" : "");
  +		Nprint_h_err("<stage> child (%ld) killed by signal %d%s.",
  +			     (long) got_pid, WTERMSIG(status),
  +			     WCOREDUMP(status) ? " (core dumped)" : "");
   		status = -1;
   
   	} else if (WIFSTOPPED(status)) {
  -		Nprint_h_err("Su/chroot child (%ld) stopped by signal %d.",
  -			(long)got_pid, WSTOPSIG(status));
  +		Nprint_h_err("<stage> child (%ld) stopped by signal %d.",
  +			     (long) got_pid, WSTOPSIG(status));
   		status = -1;
   
   	} else {
  -		Nprint_h_err("Su/chroot child (%ld) exited abnormaly.",
  -			(long)got_pid);
  +		Nprint_h_err("<stage> child (%ld) exited abnormally.",
  +			     (long) got_pid);
   		status = -1;
   	}
   
  -	xfree(user);
  -	xfree(root);
  -
   	return status;
   }
   
  -static const char *stage_parameters[] =
  -{ "stageinfo", "base", "root", "user", "environment", NULL };
   
  -static const char *stage_attributes[] =
  -{ "name", NULL};
  +/* <stage> handler */
  +
  +static const char *stage_attributes[] = { "name", NULL};
   
   struct stage_data {
   	char *name;
   };
   
  -// char *HANDLER_SYMBOL(attributes)[] = {
  -// "name", "description", "logfile", "mode", NULL };
  -
  -static int stage_setup(element_s *element)
  +static int stage_setup(element_s * const element)
   {
   	struct stage_data *data;
   
  -	if ((data = malloc(sizeof(struct stage_data))) == NULL)
  +	if ((data = xmalloc(sizeof(struct stage_data))) == NULL)
   		return 1;
   
   	data->name = NULL;
  -
   	element->handler_data = data;
  -	return 0;
  -}
   
  -static int stage_valid(element_s *element)
  -{
   	return 0;
   }
   
  -static int stage_attribute(element_s *element, const char *attribute,
  -			   const char *value)
  +static int stage_attribute(const element_s * const element,
  +			   const char * const attribute,
  +			   const char * const value)
   {
  -	int result = 1;
   	struct stage_data *data = (struct stage_data *) element->handler_data;
   
  -	if (strcmp(attribute, "name") == 0) {
  -		if (strlen(value)) {
  -			data->name = xstrdup(value);
  -			result = 0;
  -		} else {
  -			Nprint_err("<stage>: \"name\" cannot be empty.");
  -		}
  -	}
  +	if (strcmp(attribute, "name") == 0)
  +		if ((data->name = parse_string_attribute(value,
  +							 "<stage>: \"name\" cannot be empty.")))
  +			return 0;
   
  -	return result;
  +	return 1;
   }
   
  -static int stage_parameter(element_s *element, const char *parameter,
  -			   const char *value)
  -{
  -	int result = 1;
  -	struct stage_data *data = (struct stage_data *) element->handler_data;
  -
  -	return result;
  -}
  -
  -static int stage_main(element_s *el)
  +static int stage_main(element_s * const element)
   {
   	int status;
  -	char *stage_name = attr_value("name", el);
  -	element_s *stageinfo;
  -       
  +	struct stage_data *data = (struct stage_data *) element->handler_data;
   
   	if (*opt_be_verbose) {
  -		if (stage_name) {
  -			Nprint_h("Entering new stage: %s", stage_name);
  +		if (data->name) {
  +			Nprint_h("Entering new stage: %s", data->name);
   		} else {
   			Nprint_h("Entering new stage.");
   		}
   	}
   
  -	log_start_time(el);
  +	log_start_time(element);
   
  -	if ((stageinfo = first_param("stageinfo", el))) {
  -		status = parse_stageinfo_and_execute_children(el, stageinfo);
  -	} else {
  -		status = execute_children(el);
  -	}
  +	status = process_stage(element);
   
  -	log_end_time(el, status);
  +	log_end_time(element, status);
   
   	if (*opt_be_verbose) {
  -		if (stage_name) {
  -			Nprint_h("Exiting stage: %s", stage_name);
  +		if (data->name) {
  +			Nprint_h("Exiting stage: %s", data->name);
   		} else {
   			Nprint_h("Exiting stage.");
   		}
  @@ -458,31 +350,34 @@
   	return status;
   }
   
  -#if HANDLER_SYNTAX_3_2
  +static char *stage_data(const element_s * const element,
  +			const handler_data_e data_requested)
  +{
  +	const element_s *stageinfo;
   
  -static const char *stage_parameters_3_2[] =
  -{ "stageinfo", "base", "root", "user", "environment", "shell", NULL };
  +	/* the only data elements currently supported by the <stage>
  +	   element are HDATA_BASE and HDATA_SHELL, which actually
  +	   are supplied by an HTYPE_STAGEINFO child, if it exists
  +	*/
   
  -#endif
  +	if (!(stageinfo = find_stageinfo(element)))
  +		return NULL;
  +	
  +	return stageinfo->handler->alloc_data(stageinfo, data_requested);
  +}
   
   #if HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2
   
  -static int then_main(element_s *el)
  +static int then_main(element_s * const el)
   {
   	int status;
  -	element_s *stageinfo;
  -       
   
   	if (*opt_be_verbose)
   		Nprint_h("Executing <then> block.");
   
   	log_start_time(el);
   
  -	if ((stageinfo = first_param("stageinfo", el))) {
  -		status = parse_stageinfo_and_execute_children(el, stageinfo);
  -	} else {
  -		status = execute_children(el);
  -	}
  +	status = process_stage(el);
   
   	log_end_time(el, status);
   
  @@ -492,22 +387,16 @@
   	return status;
   }
   
  -static int else_main(element_s *el)
  +static int else_main(element_s * const el)
   {
   	int status;
  -	element_s *stageinfo;
  -       
   
   	if (*opt_be_verbose)
   		Nprint_h("Executing <else> block.");
   
   	log_start_time(el);
   
  -	if ((stageinfo = first_param("stageinfo", el))) {
  -		status = parse_stageinfo_and_execute_children(el, stageinfo);
  -	} else {
  -		status = execute_children(el);
  -	}
  +	status = process_stage(el);
   
   	log_end_time(el, status);
   
  @@ -519,8 +408,230 @@
   
   #endif /* HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2 */
   
  -#endif /* HANDLER_SYNTAX_3_0 || HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2 */
  +/* <stageinfo> handler */
  +
  +static const char *stageinfo_parameters[] = { "base", "root", "user", NULL };
  +
  +#if HANDLER_SYNTAX_3_2
  +
  +static const char *stageinfo_parameters_3_2[] = { "base", "root", "user",
  +						  "shell", NULL };
  +
  +#endif
  +
  +struct stageinfo_data {
  +	char *base;
  +	char *root;
  +	char *user;
  +	char *shell;
  +};
  +
  +static int stageinfo_setup(element_s * const element)
  +{
  +	struct stageinfo_data *data;
  +
  +	if ((data = xmalloc(sizeof(struct stageinfo_data))) == NULL)
  +		return 1;
  +
  +	data->base = NULL;
  +	data->root = NULL;
  +	data->user = NULL;
  +	data->shell = NULL;
  +	element->handler_data = data;
  +
  +	return 0;
  +}
  +
  +static int stageinfo_parameter(const element_s * const element,
  +			       const char * const parameter,
  +			       const char * const value)
  +{
  +	struct stageinfo_data *data = (struct stageinfo_data *) element->handler_data;
  +
  +	if (strcmp(parameter, "base") == 0)
  +		if ((data->base = parse_string_parameter(value,
  +							 "<stageinfo>: \"base\" cannot be empty.")))
  +			return 0;
  +
  +	if (strcmp(parameter, "user") == 0)
  +		if ((data->user = parse_string_parameter(value,
  +							 "<stageinfo>: \"user\" cannot be empty.")))
  +			return 0;
  +
  +	if (strcmp(parameter, "root") == 0)
  +		if ((data->root = parse_string_parameter(value,
  +							 "<stageinfo>: \"root\" cannot be empty.")))
  +			return 0;
  +
  +	if (strcmp(parameter, "shell") == 0)
  +		if ((data->shell = parse_string_parameter(value,
  +							  "<stageinfo>: \"shell\" cannot be empty.")))
  +			return 0;
  +
  +	return 1;
  +}
  +
  +static int stageinfo_main(element_s * const element)
  +{
  +	struct stageinfo_data *data = (struct stageinfo_data *) element->handler_data;
  +
  +	if (data->root) {
  +		Nprint_h("Changing root directory to \"%s\".", data->root);
  +
  +		if (change_current_dir(data->root))
  +			return -1;
  +
  +		if (chroot(data->root)) {
  +			Nprint_h_err("    %s", strerror(errno));
  +			return -1;
  +		}
  +
  +		/* clear the environment after successful chroot */
  +		environ = NULL;
  +	}
  +
  +	if (data->user) {
  +		Nprint_h("Changing to user \"%s\".", data->user);
  +
  +		if (change_to_user(data->user) == -1)
  +			return -1;
  +	}
  +
  +	return execute_children(element);
  +}
  +
  +static char *stageinfo_data(const element_s * const element,
  +			    const handler_data_e data_requested)
  +{
  +	struct stageinfo_data *data = (struct stageinfo_data *) element->handler_data;
  +
  +	switch (data_requested) {
  +	case HDATA_SHELL:
  +		if (data->shell)
  +			return xstrdup(data->shell);
  +		break;
  +	case HDATA_BASE:
  +		if (data->base)
  +			return xstrdup(data->base);
  +		break;
  +	default:
  +		break;
  +	}
  +
  +	return NULL;
  +}
  +
  +/* <environment> handler */
  +
  +static int environment_main(element_s * const element)
  +{
  +	return execute_children(element);
  +}
  +
  +/* <variable> handler */
  +
  +static const char *variable_attributes[] = { "mode", "name", NULL};
  +
  +enum variable_mode {
  +	VAR_SET,
  +	VAR_APPEND,
  +	VAR_PREPEND
  +};
  +
  +struct variable_data {
  +	enum variable_mode mode;
  +	char *name;
  +	char *value;
  +};
  +
  +static int variable_setup(element_s *element)
  +{
  +	struct variable_data *data;
  +
  +	if ((data = xmalloc(sizeof(struct variable_data))) == NULL)
  +		return 1;
  +
  +	data->name = NULL;
  +	data->value = NULL;
  +	data->mode = VAR_SET;
  +	element->handler_data = data;
  +
  +	return 0;
  +}
  +
  +static int variable_attribute(const element_s * const element,
  +			      const char * const attribute,
  +			      const char * const value)
  +{
  +	struct variable_data *data = (struct variable_data *) element->handler_data;
  +
  +	if (strcmp(attribute, "name") == 0)
  +		if ((data->name = parse_string_attribute(value,
  +							 "<variable>: \"name\" cannot be empty.")))
  +			return 0;
  +
  +	if (strcmp(attribute, "mode") == 0) {
  +		if (strcmp(value, "append") == 0) {
  +			data->mode = VAR_APPEND;
  +			return 0;
  +		} else if (strcmp(value, "prepend") == 0) {
  +			data->mode = VAR_PREPEND;
  +			return 0;
  +		} else
  +			Nprint_err("<variable>: unknown \"mode\" (%s)", value);
  +	}
  +
  +	return 1;
  +}
  +
  +static int variable_content(const element_s * const element,
  +			    const char * const content)
  +{
  +	struct variable_data *data = (struct variable_data *) element->handler_data;
  +
  +	if (strlen(content))
  +		data->value = xstrdup(content);
   
  +	return 0;
  +}
  +
  +static int variable_valid(const element_s * const element)
  +{
  +	struct variable_data *data = (struct variable_data *) element->handler_data;
  +
  +	if (!data->name) {
  +		Nprint_err("<variable>: \"name\" must be specified.");
  +		return 1;
  +	}
  +
  +	if (!data->value &&
  +	    ((data->mode == VAR_APPEND) || (data->mode == VAR_PREPEND))) {
  +		Nprint_err("<variable>: content cannot be empty if mode is prepend or append.");
  +		return 1;
  +	}
  +
  +	return 0;
  +}
  +
  +static int variable_main(element_s * const element)
  +{
  +	struct variable_data *data = (struct variable_data *) element->handler_data;
  +
  +	switch (data->mode) {
  +	case VAR_SET:
  +		if (data->value) {
  +			return set_variable(data->name, data->value);
  +		} else {
  +			return unset_variable(data->name);
  +		}
  +	case VAR_APPEND:
  +		return append_to_variable(data->name, data->value);
  +	case VAR_PREPEND:
  +		return prepend_to_variable(data->name, data->value);
  +	}
  +
  +	return 1;
  +}
   
   /*
    * Handlers' information.
  @@ -532,12 +643,43 @@
   		.name = "stage",
   		.description = "Enter stage: ", // FIXME
   		.syntax_version = "3.0",
  -		.parameters = stage_parameters,
  -		.main = stage_main,
   		.type = HTYPE_NORMAL | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.priority = 0
  +		.main = stage_main,
  +		.data = HDATA_BASE,
  +		.alloc_data = stage_data,
  +		.setup = stage_setup,
  +		.attributes = stage_attributes,
  +		.parse_attribute = stage_attribute,
  +	},
  +	{
  +		.name = "stageinfo",
  +		.description = "stageinfo",
  +		.syntax_version = "3.0",
  +		.type = HTYPE_STAGEINFO,
  +		.main = stageinfo_main,
  +		.alloc_data = stageinfo_data,
  +		.setup = stageinfo_setup,
  +		.parameters = stageinfo_parameters,
  +		.parse_parameter = stageinfo_parameter,
  +	},
  +	{
  +		.name = "environment",
  +		.description = "environment",
  +		.syntax_version = "3.0",
  +		.type = HTYPE_NORMAL,
  +		.main = environment_main,
  +	},
  +	{
  +		.name = "variable",
  +		.description = "variable",
  +		.syntax_version = "3.0",
  +		.type = HTYPE_NORMAL,
  +		.main = variable_main,
  +		.setup = variable_setup,
  +		.attributes = variable_attributes,
  +		.parse_attribute = variable_attribute,
  +		.parse_content = variable_content,
  +		.valid = variable_valid,
   	},
   #endif
   #if HANDLER_SYNTAX_3_1
  @@ -545,34 +687,61 @@
   		.name = "stage",
   		.description = "Enter stage: ", // FIXME
   		.syntax_version = "3.1",
  -		.parameters = stage_parameters,
  -		.main = stage_main,
   		.type = HTYPE_NORMAL | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.priority = 0
  +		.main = stage_main,
  +		.data = HDATA_BASE,
  +		.alloc_data = stage_data,
  +		.setup = stage_setup,
  +		.attributes = stage_attributes,
  +		.parse_attribute = stage_attribute,
   	},
   	{
   		.name = "then",
   		.description = "then",
   		.syntax_version = "3.1",
  -		.parameters = stage_parameters,
  -		.main = then_main,
   		.type = HTYPE_TRUE_RESULT | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.priority = 0
  +		.main = then_main,
  +		.data = HDATA_BASE,
  +		.alloc_data = stage_data,
   	},
   	{
   		.name = "else",
   		.description = "else",
   		.syntax_version = "3.1",
  -		.parameters = stage_parameters,
  -		.main = else_main,
   		.type = HTYPE_FALSE_RESULT | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.priority = 0
  +		.main = else_main,
  +		.data = HDATA_BASE,
  +		.alloc_data = stage_data,
  +	},
  +	{
  +		.name = "stageinfo",
  +		.description = "stageinfo",
  +		.syntax_version = "3.1",
  +		.type = HTYPE_STAGEINFO,
  +		.main = stageinfo_main,
  +		.alloc_data = stageinfo_data,
  +		.setup = stageinfo_setup,
  +		.parameters = stageinfo_parameters,
  +		.parse_parameter = stageinfo_parameter,
  +	},
  +	{
  +		.name = "environment",
  +		.description = "environment",
  +		.syntax_version = "3.1",
  +		.type = HTYPE_NORMAL,
  +		.main = environment_main,
  +	},
  +	{
  +		.name = "variable",
  +		.description = "variable",
  +		.syntax_version = "3.1",
  +		.type = HTYPE_NORMAL,
  +		.main = variable_main,
  +		.setup = variable_setup,
  +		.attributes = variable_attributes,
  +		.parse_attribute = variable_attribute,
  +		.parse_content = variable_content,
  +		.valid = variable_valid,
   	},
   #endif
   #if HANDLER_SYNTAX_3_2
  @@ -580,42 +749,61 @@
   		.name = "stage",
   		.description = "Enter stage: ", // FIXME
   		.syntax_version = "3.2",
  -		.parameters = stage_parameters_3_2,
  -		.attributes = stage_attributes,
  +		.type = HTYPE_NORMAL | HTYPE_STAGE,
   		.main = stage_main,
  +		.data = HDATA_BASE | HDATA_SHELL,
  +		.alloc_data = stage_data,
   		.setup = stage_setup,
  -		.valid = stage_valid,
  +		.attributes = stage_attributes,
   		.parse_attribute = stage_attribute,
  -		.parse_parameter = stage_parameter,
  -		.type = HTYPE_NORMAL | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.alternate_shell = 1,
  -		.priority = 0
   	},
   	{
   		.name = "then",
   		.description = "then",
   		.syntax_version = "3.2",
  -		.parameters = stage_parameters_3_2,
  -		.main = then_main,
   		.type = HTYPE_TRUE_RESULT | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.alternate_shell = 1,
  -		.priority = 0
  +		.main = then_main,
  +		.data = HDATA_BASE | HDATA_SHELL,
  +		.alloc_data = stage_data,
   	},
   	{
   		.name = "else",
   		.description = "else",
   		.syntax_version = "3.2",
  -		.parameters = stage_parameters_3_2,
  -		.main = else_main,
   		.type = HTYPE_FALSE_RESULT | HTYPE_STAGE,
  -		.alloc_data = NULL,
  -		.is_action = 0,
  -		.alternate_shell = 1,
  -		.priority = 0
  +		.main = else_main,
  +		.data = HDATA_BASE | HDATA_SHELL,
  +		.alloc_data = stage_data,
  +	},
  +	{
  +		.name = "stageinfo",
  +		.description = "stageinfo",
  +		.syntax_version = "3.2",
  +		.type = HTYPE_STAGEINFO,
  +		.main = stageinfo_main,
  +		.setup = stageinfo_setup,
  +		.alloc_data = stageinfo_data,
  +		.parameters = stageinfo_parameters_3_2,
  +		.parse_parameter = stageinfo_parameter,
  +	},
  +	{
  +		.name = "environment",
  +		.description = "environment",
  +		.syntax_version = "3.2",
  +		.type = HTYPE_NORMAL,
  +		.main = environment_main,
  +	},
  +	{
  +		.name = "variable",
  +		.description = "variable",
  +		.syntax_version = "3.2",
  +		.type = HTYPE_NORMAL,
  +		.main = variable_main,
  +		.setup = variable_setup,
  +		.attributes = variable_attributes,
  +		.parse_attribute = variable_attribute,
  +		.parse_content = variable_content,
  +		.valid = variable_valid,
   	},
   #endif
   	{
  
  
  
  1.13      +1 -1      ALFS/nALFS/src/handlers/stamp.c
  
  Index: stamp.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/stamp.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- stamp.c	13 Feb 2004 07:08:59 -0000	1.12
  +++ stamp.c	21 Feb 2004 19:03:32 -0000	1.13
  @@ -39,7 +39,7 @@
   
   // char *HANDLER_SYMBOL(attributes)[] = { "name", "version" };
   
  -static int stamp_main(element_s *el)
  +static int stamp_main(element_s * const el)
   {
   	int status = 0;
   	char *name;
  
  
  
  1.16      +1 -1      ALFS/nALFS/src/handlers/su.c
  
  Index: su.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/su.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- su.c	13 Feb 2004 07:08:59 -0000	1.15
  +++ su.c	21 Feb 2004 19:03:32 -0000	1.16
  @@ -140,7 +140,7 @@
   
   // char *HANDLER_SYMBOL(attributes)[] = { "user", NULL };
   
  -static int su_main(element_s *el)
  +static int su_main(element_s * const el)
   {
   	int status;
   	pid_t su_pid, got_pid;
  
  
  
  1.17      +5 -4      ALFS/nALFS/src/handlers/textdump.c
  
  Index: textdump.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/textdump.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- textdump.c	11 Feb 2004 05:08:12 -0000	1.16
  +++ textdump.c	21 Feb 2004 19:03:32 -0000	1.17
  @@ -114,7 +114,7 @@
   { "base", "file", "content", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "mode", NULL };
   
  -static int textdump_main_ver2(element_s *el)
  +static int textdump_main_ver2(element_s * const el)
   {
   	int i;
   	char *base = alloc_base_dir(el);
  @@ -135,10 +135,10 @@
   { "file", "content", NULL };
   // char *HANDLER_SYMBOL(attributes)[] = { "base", "mode", NULL };
   
  -static int textdump_main_ver3(element_s *el)
  +static int textdump_main_ver3(element_s * const el)
   {
   	int i;
  -	char *base = alloc_base_dir_new(el);
  +	char *base = alloc_base_dir_new(el, 1);
   
   	i = textdump_main(el, base);
   
  @@ -151,7 +151,8 @@
   #endif /* HANDLER_SYNTAX_3_0 || HANDLER_SYNTAX_3_1 || HANDLER_SYNTAX_3_2 */
   
   
  -static char *textdump_data(element_s *el, handler_data_e data)
  +static char *textdump_data(const element_s * const el,
  +			   const handler_data_e data)
   {
   	(void) data;
   
  
  
  
  1.22      +4 -4      ALFS/nALFS/src/handlers/unpack.c
  
  Index: unpack.c
  ===================================================================
  RCS file: /home/cvsroot/ALFS/nALFS/src/handlers/unpack.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- unpack.c	11 Feb 2004 05:08:12 -0000	1.21
  +++ unpack.c	21 Feb 2004 19:03:32 -0000	1.22
  @@ -116,7 +116,7 @@
   static const char *unpack_parameters_ver2[] =
   { "archive", "destination", NULL };
   
  -static int unpack_main_ver2(element_s *el)
  +static int unpack_main_ver2(element_s * const el)
   {
   	int status = 0;
   	char *archive, *destination;
  @@ -168,7 +168,7 @@
   static const char *unpack_parameters_ver3[] =
   { "digest", "reference", "archive", "destination", NULL };
   
  -static int unpack_main_ver3(element_s *el)
  +static int unpack_main_ver3(element_s * const el)
   {
   	int status = -1;
   	char *archive = NULL;
  @@ -255,7 +255,7 @@
   static const char *unpack_parameters_ver3_2[] =
   { "digest", "reference", "archive", NULL };
   
  -static int unpack_main_ver3_2(element_s *el)
  +static int unpack_main_ver3_2(element_s * const el)
   {
   	int status = -1;
   	char *archive = NULL;
  @@ -271,7 +271,7 @@
   	}
   
   	/* <base> is mandatory, we don't want to unpack just anywhere! */
  -	if ((base = alloc_base_dir_force(el)) == NULL) {
  +	if ((base = alloc_base_dir_new(el, 0)) == NULL) {
   		Nprint_h_err("<base> is missing.");
   		goto free_all_and_return;
   	}
  
  
  



More information about the alfs-log mailing list