• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Environment management routines for the CUPS scheduler.
3  *
4  * Copyright 2007-2016 by Apple Inc.
5  * Copyright 1997-2006 by Easy Software Products, all rights reserved.
6  *
7  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8  */
9 
10 /*
11  * Include necessary headers...
12  */
13 
14 #include "cupsd.h"
15 
16 
17 /*
18  * Local globals...
19  */
20 
21 static int	num_common_env = 0;	/* Number of common env vars */
22 static char	*common_env[MAX_ENV];	/* Common env vars */
23 
24 
25 /*
26  * Local functions...
27  */
28 
29 static void	clear_env(void);
30 static int	find_env(const char *name);
31 
32 
33 /*
34  * 'cupsdInitEnv()' - Initialize the current environment with standard variables.
35  */
36 
37 void
cupsdInitEnv(void)38 cupsdInitEnv(void)
39 {
40  /*
41   * Clear existing environment variables...
42   */
43 
44   clear_env();
45 
46 #if defined(__APPLE__)
47  /*
48   * Add special voodoo magic for macOS - this allows macOS
49   * programs to access their bundle resources properly...
50   *
51   * This string is replaced in cupsdStartProcess()...
52   */
53 
54   cupsdSetString(common_env, "<CFProcessPath>");
55   num_common_env = 1;
56 #endif	/* __APPLE__ */
57 }
58 
59 
60 /*
61  * 'cupsdLoadEnv()' - Copy common environment variables into an array.
62  */
63 
64 int					/* O - Number of environment variables */
cupsdLoadEnv(char * envp[],int envmax)65 cupsdLoadEnv(char *envp[],		/* I - Environment array */
66              int  envmax)		/* I - Maximum number of elements */
67 {
68   int	i;				/* Looping var */
69 
70 
71  /*
72   * Leave room for a NULL pointer at the end...
73   */
74 
75   envmax --;
76 
77  /*
78   * Copy pointers to the environment...
79   */
80 
81   for (i = 0; i < num_common_env && i < envmax; i ++)
82     envp[i] = common_env[i];
83 
84  /*
85   * NULL terminate the environment array and return the number of
86   * elements we added...
87   */
88 
89   envp[i] = NULL;
90 
91   return (i);
92 }
93 
94 
95 /*
96  * 'cupsdSetEnv()' - Set a common environment variable.
97  */
98 
99 void
cupsdSetEnv(const char * name,const char * value)100 cupsdSetEnv(const char *name,		/* I - Name of variable */
101             const char *value)		/* I - Value of variable */
102 {
103   int	i;				/* Index into environent array */
104 
105 
106  /*
107   * If "value" is NULL, try getting value from current environment...
108   */
109 
110   if (!value)
111     value = getenv(name);
112 
113   if (!value)
114     return;
115 
116  /*
117   * Do not allow dynamic linker variables when running as root...
118   */
119 
120   if (!RunUser && (!strncmp(name, "DYLD_", 5) || !strncmp(name, "LD_", 3)))
121     return;
122 
123  /*
124   * See if this variable has already been defined...
125   */
126 
127   if ((i = find_env(name)) < 0)
128   {
129    /*
130     * Check for room...
131     */
132 
133     if (num_common_env >= (int)(sizeof(common_env) / sizeof(common_env[0])))
134     {
135       cupsdLogMessage(CUPSD_LOG_ERROR,
136                       "cupsdSetEnv: Too many environment variables set!");
137       return;
138     }
139 
140     i = num_common_env;
141     num_common_env ++;
142   }
143 
144  /*
145   * Set the new environment variable...
146   */
147 
148   cupsdSetStringf(common_env + i, "%s=%s", name, value);
149 
150   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSetEnv: %s", common_env[i]);
151 }
152 
153 
154 /*
155  * 'cupsdSetEnvf()' - Set a formatted common environment variable.
156  */
157 
158 void
cupsdSetEnvf(const char * name,const char * value,...)159 cupsdSetEnvf(const char *name,		/* I - Name of variable */
160              const char *value,		/* I - Printf-style value of variable */
161 	     ...)			/* I - Additional args as needed */
162 {
163   char		v[4096];		/* Formatting string value */
164   va_list	ap;			/* Argument pointer */
165 
166 
167  /*
168   * Format the value string...
169   */
170 
171   va_start(ap, value);
172   vsnprintf(v, sizeof(v), value, ap);
173   va_end(ap);
174 
175  /*
176   * Set the env variable...
177   */
178 
179   cupsdSetEnv(name, v);
180 }
181 
182 
183 /*
184  * 'cupsdUpdateEnv()' - Update the environment for the configured directories.
185  */
186 
187 void
cupsdUpdateEnv(void)188 cupsdUpdateEnv(void)
189 {
190  /*
191   * Set common variables...
192   */
193 
194 #define set_if_undefined(name,value) if (find_env(name) < 0) cupsdSetEnv(name,value)
195 
196   set_if_undefined("CUPS_CACHEDIR", CacheDir);
197   set_if_undefined("CUPS_DATADIR", DataDir);
198   set_if_undefined("CUPS_DOCROOT", DocumentRoot);
199   set_if_undefined("CUPS_FONTPATH", FontPath);
200   set_if_undefined("CUPS_REQUESTROOT", RequestRoot);
201   set_if_undefined("CUPS_SERVERBIN", ServerBin);
202   set_if_undefined("CUPS_SERVERROOT", ServerRoot);
203   set_if_undefined("CUPS_STATEDIR", StateDir);
204   set_if_undefined("DYLD_INSERT_LIBRARIES", NULL);
205   set_if_undefined("DYLD_LIBRARY_PATH", NULL);
206   set_if_undefined("HOME", TempDir);
207   set_if_undefined("LD_ASSUME_KERNEL", NULL);
208   set_if_undefined("LD_LIBRARY_PATH", NULL);
209   set_if_undefined("LD_PRELOAD", NULL);
210   set_if_undefined("NLSPATH", NULL);
211   if (find_env("PATH") < 0)
212     cupsdSetEnvf("PATH", "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR
213 			 ":/bin:/usr/bin", ServerBin);
214   set_if_undefined("SERVER_ADMIN", ServerAdmin);
215   set_if_undefined("SHLIB_PATH", NULL);
216   set_if_undefined("SOFTWARE", CUPS_MINIMAL);
217   set_if_undefined("TMPDIR", TempDir);
218   set_if_undefined("TZ", NULL);
219   set_if_undefined("USER", "root");
220   set_if_undefined("VG_ARGS", NULL);
221 
222   cupsdSetEnvf("CUPS_MAX_MESSAGE", "%d", CUPSD_SB_BUFFER_SIZE - 1);
223 }
224 
225 
226 /*
227  * 'clear_env()' - Clear common environment variables.
228  */
229 
230 static void
clear_env(void)231 clear_env(void)
232 {
233   int	i;				/* Looping var */
234 
235 
236   for (i = 0; i < num_common_env; i ++)
237     cupsdClearString(common_env + i);
238 
239   num_common_env = 0;
240 }
241 
242 
243 /*
244  * 'find_env()' - Find a common environment variable.
245  */
246 
247 static int				/* O - Index or -1 if not found */
find_env(const char * name)248 find_env(const char *name)		/* I - Variable name */
249 {
250   int		i;			/* Looping var */
251   size_t	namelen;		/* Length of name */
252 
253 
254   for (i = 0, namelen = strlen(name); i < num_common_env; i ++)
255     if (!strncmp(common_env[i], name, namelen) && common_env[i][namelen] == '=')
256       return (i);
257 
258   return (-1);
259 }
260