fixes init script for non ipv6 enabled systems #472755
[packages/xinetd.git] / xinetd / env.c
1 /*
2  * (c) Copyright 1992 by Panagiotis Tsirigotis
3  * (c) Sections Copyright 1998-2001 by Rob Braun
4  * All rights reserved.  The file named COPYRIGHT specifies the terms 
5  * and conditions for redistribution.
6  */
7
8
9 #include "config.h"
10 #include <syslog.h>
11 #include <string.h>
12 #include <sys/types.h>
13
14 #include "pset.h"
15 #include "env.h"
16 #include "msg.h"
17
18 extern char **environ ;
19 env_h std_env ;            /* created from environ */
20
21 status_e initenv(void)
22 {
23    std_env = env_make( environ ) ;
24    return( ( std_env == NULL ) ? FAILED : OK ) ;
25 }
26
27 static status_e make_env_with_strings(struct environment *, env_h, pset_h);
28 static status_e make_env_from_vars(struct environment *, env_h, pset_h) ;
29 static status_e update_env_with_strings(env_h, pset_h) ;
30
31
32 status_e setup_environ( struct service_config *scp, struct service_config *def )
33 {
34    struct environment   *ep = SC_ENV( scp ) ;
35
36    if ( ! SC_SPECIFIED( scp, A_PASSENV ) )
37    {
38       if ( ! SC_SPECIFIED( def, A_PASSENV ) )
39       {
40          if ( ! SC_SPECIFIED( scp, A_ENV ) )
41          {
42             ep->env_type = STD_ENV ;
43             ep->env_handle = std_env ;
44             return( OK ) ;
45          }
46          else
47             return( 
48                make_env_with_strings( ep, std_env, SC_ENV_VAR_DEFS(scp) ) ) ;
49       }
50       else   /* SC_SPECIFIED( def, A_PASSENV ) */
51       {
52          struct environment *dep = SC_ENV( def ) ;
53
54          if ( dep->env_type == NO_ENV &&
55                   make_env_from_vars( dep, std_env,
56                                  SC_PASS_ENV_VARS(def) ) == FAILED )
57             return( FAILED ) ;
58
59          if ( ! SC_SPECIFIED( scp, A_ENV ) )
60          {
61             ep->env_type = DEF_ENV ;
62             ep->env_handle = dep->env_handle ;
63             return( OK ) ;
64          }
65          else
66             return( make_env_with_strings( ep, 
67                            dep->env_handle, SC_ENV_VAR_DEFS(scp) ) ) ;
68       }
69    }
70    else   /* SC_SPECIFIED( scp, A_PASSENV ) */
71    {
72       if ( make_env_from_vars( ep, std_env, SC_PASS_ENV_VARS(scp) ) == FAILED )
73          return( FAILED ) ;
74
75       if ( ! SC_SPECIFIED( scp, A_ENV ) )
76          return( OK ) ;
77       else
78       {
79          if ( update_env_with_strings( 
80                      ep->env_handle, SC_ENV_VAR_DEFS(scp) ) == FAILED )
81          {
82             env_destroy( ep->env_handle ) ;
83             return( FAILED ) ;
84          }
85          return( OK ) ;
86       }
87    }
88 }
89
90
91 /*
92  * Create a new environment from environ and env_strings
93  * env_strings contains strings of the form "var=value"
94  */
95 static status_e make_env_with_strings( struct environment *ep, 
96                                         env_h env, 
97                                         pset_h env_strings )
98 {
99    env_h      new_env ;
100    const char *func = "make_env_with_strings" ;
101
102    if ( ( new_env = env_create( env ) ) == ENV_NULL )
103    {
104       out_of_memory( func ) ;
105       return( FAILED ) ;
106    }
107
108    if ( update_env_with_strings( new_env, env_strings ) == FAILED )
109    {
110       env_destroy( new_env ) ;
111       return( FAILED ) ;
112    }
113
114    ep->env_type = CUSTOM_ENV ;
115    ep->env_handle = new_env ;
116    return( OK ) ;
117 }
118
119
120 static status_e make_env_from_vars( struct environment *ep, 
121                                      env_h env, 
122                                      pset_h vars )
123 {
124    env_h               new_env ;
125    char               *varname ;
126    unsigned            u ;
127    const char         *func = "make_env_from_vars" ;
128
129    if ( ( new_env = env_create( ENV_NULL ) ) == ENV_NULL )
130    {
131       out_of_memory( func ) ;
132       return( FAILED ) ;
133    }
134    
135    for ( u = 0 ; u < pset_count( vars ) ; u++ )
136    {
137       varname = (char *) pset_pointer( vars, u ) ;
138       if ( env_addvar( new_env, env, varname ) == ENV_ERR )
139          switch ( env_errno )
140          {
141             case ENV_EBADVAR:
142                msg( LOG_ERR, func, "Unknown variable %s", varname ) ;
143                break ;
144             
145             case ENV_ENOMEM:
146                out_of_memory( func ) ;
147                env_destroy( new_env ) ;
148                return( FAILED ) ;
149          }
150    }
151
152    ep->env_type = CUSTOM_ENV ;
153    ep->env_handle = new_env ;
154    return( OK ) ;
155 }
156
157
158 static status_e update_env_with_strings( env_h env, pset_h strings )
159 {
160    unsigned u ;
161    const char *func = "update_env_with_strings" ;
162
163    for ( u = 0 ; u < pset_count( strings ) ; u++ )
164    {
165       char *p = (char *) pset_pointer( strings, u ) ;
166
167       if ( env_addstr( env, p ) == ENV_ERR )
168          switch ( env_errno )
169          {
170             case ENV_ENOMEM:
171                out_of_memory( func ) ;
172                return( FAILED ) ;
173             
174             case ENV_EBADSTRING:
175                msg( LOG_ERR, func, "Bad environment string: %s", p ) ;
176                break ;
177          }
178    }
179    return( OK ) ;
180 }
181