CUBRID Engine  latest
environment_variable.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * environment_variable.c : Functions for manipulating the environment variable
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <ctype.h>
30 #include <assert.h>
31 
32 #include "porting.h"
33 #include "error_code.h"
34 #include "environment_variable.h"
35 
36 /* available root directory symbols; NULL terminated array */
37 static const char envvar_Prefix_name[] = "CUBRID";
38 static const char *envvar_Prefix = NULL;
39 static const char *envvar_Root = NULL;
40 
41 #define _ENVVAR_MAX_LENGTH 255
42 
43 typedef enum
44 {
49 } ENV_ERR_MSG;
50 
51 static const char *env_msg[] = {
52  "The directory in $%s is invalid. (%s)\n",
53  "The root directory environment variable $%s is not set.\n",
54  "The $%s should be an absolute path. (%s)\n",
55  "The $%s is too long. (%s)\n"
56 };
57 
58 static void
60 {
61 #if defined(WINDOWS)
62  return;
63 #else
64  const char *cubrid_tmp = envvar_get ("TMP");
65 
66  if (cubrid_tmp)
67  {
68  char name[_ENVVAR_MAX_LENGTH];
69  size_t len = strlen (cubrid_tmp);
70  size_t limit = 108 - 12;
71  /* 108 = sizeof (((struct sockaddr_un *) 0)->sun_path) */
72  /* 12 = ("CUBRID65384" + 1) */
73  envvar_name (name, _ENVVAR_MAX_LENGTH, "TMP");
74  if (!IS_ABS_PATH (cubrid_tmp))
75  {
76  fprintf (stderr, env_msg[ENV_MUST_ABS_PATH], name, cubrid_tmp);
77  fflush (stderr);
78  exit (1);
79  }
80  if (len > limit)
81  {
82  fprintf (stderr, env_msg[ENV_TOO_LONG], name, cubrid_tmp);
83  fflush (stderr);
84  exit (1);
85  }
86  }
87 #endif
88 }
89 
90 /*
91  * envvar_prefix - find a recognized prefix symbol
92  * return: prefix symbol
93  */
94 const char *
96 {
97  if (!envvar_Prefix)
98  {
99 #if !defined (DO_NOT_USE_CUBRIDENV)
100  envvar_Root = getenv (envvar_Prefix_name);
101  if (envvar_Root != NULL)
102  {
103 #if !defined (WINDOWS)
104  if (access (envvar_Root, F_OK) != 0)
105  {
107  fflush (stderr);
108  exit (1);
109  }
110 #endif
111 
113  }
114  else
115  {
116  fprintf (stderr, env_msg[ENV_DONT_EXISTS_ROOT], envvar_Prefix_name);
117  fflush (stderr);
118  exit (1);
119  }
121 #else
123  envvar_Root = CUBRID_PREFIXDIR;
124 #endif
125  }
126 
127  return envvar_Prefix;
128 }
129 
130 /*
131  * envvar_root - get value of the root directory environment variable
132  * return: root directory
133  */
134 const char *
136 {
137  if (envvar_Root == NULL)
138  {
139  envvar_prefix ();
140  }
141 
142  return envvar_Root;
143 }
144 
145 /*
146  * envvar_name - add the prefix symbol to an environment variable name
147  * return: prefixed name
148  * buf(out): string buffer to store the prefixed name
149  * size(out): size of the buffer
150  * name(in): an environment variable name
151  */
152 const char *
153 envvar_name (char *buf, size_t size, const char *name)
154 {
155  const char *prefix;
156  char *pname;
157 
158  pname = buf;
159  prefix = envvar_prefix ();
160  while (size > 1 && *prefix)
161  {
162  *pname++ = *prefix++;
163  size--;
164  }
165  if (size > 1)
166  {
167  *pname++ = '_';
168  size--;
169  }
170  while (size > 1 && *name)
171  {
172  *pname++ = *name++;
173  size--;
174  }
175  *pname = '\0';
176 
177  return buf;
178 }
179 
180 /*
181  * envvar_get - get value of an prefixed environment variable
182  * return: a string containing the value for the specified environment
183  * variable
184  * name(in): environment variable name without prefix
185  *
186  * Note: the prefix symbol will be added to the name
187  */
188 const char *
189 envvar_get (const char *name)
190 {
191  char buf[_ENVVAR_MAX_LENGTH];
192 
193  return getenv (envvar_name (buf, _ENVVAR_MAX_LENGTH, name));
194 }
195 
196 /*
197  * enclosing_method - change value of an prefixed environment variable
198  * return: error code
199  * name(in): environment variable name without prefix
200  * val(in): the value to be set to the environment variable
201  *
202  * Note: the prefix symbol will be added to the name
203  */
204 int
205 envvar_set (const char *name, const char *val)
206 {
207  char buf[_ENVVAR_MAX_LENGTH];
208  int ret;
209 
210  envvar_name (buf, _ENVVAR_MAX_LENGTH, name);
211  ret = setenv (buf, val, 1);
212  if (ret != 0)
213  {
214  return ER_FAILED;
215  }
216 
217  return NO_ERROR;
218 }
219 
220 /*
221  * envvar_expand - expand environment variables (${ENV}) with their values
222  * within the string
223  * return: error code
224  * string(in): string containing environment variables
225  * buffer(out): output buffer
226  * maxlen(in): maximum length of output buffer
227  *
228  * Note:
229  * The environment variables must be prefixed with a '$' and are
230  * enclosed by '{' and '}' or terminated by a non alpha numeric character
231  * except for '_'.
232  * If all of the referenced environment variables were expanded,
233  * NO_ERROR is returned. If a reference could not be expanded, the output
234  * buffer will contain the name of the unresolved variable.
235  * This function can handle up to 10 environment variables. It is an error
236  * if exceeds.
237  */
238 int
239 envvar_expand (const char *string, char *buffer, size_t maxlen)
240 {
241 #define _ENVVAR_MAX_EXPANSION (10 * 2 + 1)
242  struct _fragment
243  {
244  const char *str;
245  size_t len;
246  } fragments[_ENVVAR_MAX_EXPANSION], *cur, *fen;
247  char env[_ENVVAR_MAX_LENGTH], *val;
248  const char *s, *e;
249 
250  s = strchr (string, '$');
251  if (!s)
252  {
253  /* no environment variable in the string */
254  (void) strlcpy (buffer, string, maxlen);
255  return NO_ERROR;
256  }
257 
258  cur = fragments;
259  fen = fragments + _ENVVAR_MAX_EXPANSION;
260 
261  do
262  {
263  env[0] = '\0';
264 
265  if (s[1] == '{')
266  {
267  for (e = s + 1; *e && *e != '}'; e++)
268  ;
269  if (*e && (e - s - 2) < _ENVVAR_MAX_LENGTH)
270  {
271  /* ${ENV}; copy the name of the environment variable */
272  (void) strlcpy (env, s + 2, e - s - 1);
273  e++;
274  }
275  }
276  else
277  {
278  for (e = s + 1; *e && (isalnum (*e) || *e == '_'); e++)
279  ;
280  if ((e - s - 1) < _ENVVAR_MAX_LENGTH)
281  {
282  /* $ENV; copy the name of the environment variable */
283  (void) strlcpy (env, s + 1, e - s);
284  }
285  }
286 
287  if (env[0])
288  {
289  /* a environment variable is referred; get the value */
290  val = getenv (env);
291  if (!val)
292  {
293  /* error */
294  (void) strlcpy (buffer, env, maxlen);
295  return ER_FAILED;
296  }
297  if (s > string)
298  {
299  /* a fragment */
300  cur->str = string;
301  cur->len = s - string;
302  if (++cur > fen)
303  {
304  /* error */
305  *buffer = '\0';
306  return ER_FAILED;
307  }
308  }
309  /* a fragment of the value */
310  cur->str = val;
311  cur->len = strlen (val);
312  if (++cur > fen)
313  {
314  /* error */
315  *buffer = '\0';
316  return ER_FAILED;
317  }
318  }
319  else
320  {
321  cur->str = string;
322  cur->len = e - string;
323  if (++cur > fen)
324  {
325  /* error */
326  *buffer = '\0';
327  return ER_FAILED;
328  }
329  }
330 
331  string = e;
332  s = strchr (string, '$');
333  }
334  while (s);
335 
336  if (*string)
337  {
338  cur->str = string;
339  cur->len = strlen (string);
340  cur++;
341  }
342  cur->str = NULL;
343  cur->len = 0;
344 
345  /* assemble fragments */
346  for (cur = fragments; cur->len && maxlen > 1; cur++)
347  {
348  if (cur->len >= maxlen)
349  {
350  cur->len = maxlen - 1;
351  }
352  (void) memcpy (buffer, cur->str, cur->len);
353  buffer += cur->len;
354  maxlen -= cur->len;
355  }
356  *buffer = '\0';
357 
358  return NO_ERROR;
359 }
360 
361 char *
362 envvar_bindir_file (char *path, size_t size, const char *filename)
363 {
364  assert (filename != NULL);
365 
366 #if !defined (DO_NOT_USE_CUBRIDENV)
367  if (envvar_Root == NULL)
368  {
369  envvar_root ();
370  }
371  snprintf (path, size, "%s/bin/%s", envvar_Root, filename);
372 #else
373  snprintf (path, size, "%s/%s", CUBRID_BINDIR, filename);
374 #endif
375 
376  path[size - 1] = '\0';
377  return path;
378 }
379 
380 char *
381 envvar_libdir_file (char *path, size_t size, const char *filename)
382 {
383  assert (filename != NULL);
384 
385 #if !defined (DO_NOT_USE_CUBRIDENV)
386  if (envvar_Root == NULL)
387  {
388  envvar_root ();
389  }
390  snprintf (path, size, "%s/lib/%s", envvar_Root, filename);
391 #else
392  snprintf (path, size, "%s/%s", CUBRID_LIBDIR, filename);
393 #endif
394 
395  path[size - 1] = '\0';
396  return path;
397 }
398 
399 char *
400 envvar_javadir_file (char *path, size_t size, const char *filename)
401 {
402  assert (filename != NULL);
403 
404 #if !defined (DO_NOT_USE_CUBRIDENV)
405  if (envvar_Root == NULL)
406  {
407  envvar_root ();
408  }
409  snprintf (path, size, "%s/java/%s", envvar_Root, filename);
410 #else
411  snprintf (path, size, "%s/%s", CUBRID_JAVADIR, filename);
412 #endif
413 
414  path[size - 1] = '\0';
415  return path;
416 }
417 
418 char *
419 envvar_localedir_file (char *path, size_t size, const char *langpath, const char *filename)
420 {
421  assert (filename != NULL);
422 
423 #if !defined (DO_NOT_USE_CUBRIDENV)
424  if (envvar_Root == NULL)
425  {
426  envvar_root ();
427  }
428  snprintf (path, size, "%s/msg/%s/%s", envvar_Root, langpath, filename);
429 #else
430  snprintf (path, size, "%s/%s/%s", CUBRID_LOCALEDIR, langpath, filename);
431 #endif
432 
433  path[size - 1] = '\0';
434  return path;
435 }
436 
437 char *
438 envvar_confdir_file (char *path, size_t size, const char *filename)
439 {
440  assert (filename != NULL);
441 
442 #if !defined (DO_NOT_USE_CUBRIDENV)
443  if (envvar_Root == NULL)
444  {
445  envvar_root ();
446  }
447  snprintf (path, size, "%s/conf/%s", envvar_Root, filename);
448 #else
449  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
450 #endif
451 
452  path[size - 1] = '\0';
453  return path;
454 }
455 
456 char *
457 envvar_vardir_file (char *path, size_t size, const char *filename)
458 {
459  assert (filename != NULL);
460 
461 #if !defined (DO_NOT_USE_CUBRIDENV)
462  if (envvar_Root == NULL)
463  {
464  envvar_root ();
465  }
466  snprintf (path, size, "%s/var/%s", envvar_Root, filename);
467 #else
468  snprintf (path, size, "%s/%s", CUBRID_VARDIR, filename);
469 #endif
470 
471  path[size - 1] = '\0';
472  return path;
473 }
474 
475 char *
476 envvar_tmpdir_file (char *path, size_t size, const char *filename)
477 {
478  assert (filename != NULL);
479 
480 #if !defined (DO_NOT_USE_CUBRIDENV)
481  if (envvar_Root == NULL)
482  {
483  envvar_root ();
484  }
485  snprintf (path, size, "%s/tmp/%s", envvar_Root, filename);
486 #else
487  snprintf (path, size, "%s/%s", CUBRID_TMPDIR, filename);
488 #endif
489 
490  path[size - 1] = '\0';
491  return path;
492 }
493 
494 char *
495 envvar_logdir_file (char *path, size_t size, const char *filename)
496 {
497  assert (filename != NULL);
498 
499 #if !defined (DO_NOT_USE_CUBRIDENV)
500  if (envvar_Root == NULL)
501  {
502  envvar_root ();
503  }
504  snprintf (path, size, "%s/log/%s", envvar_Root, filename);
505 #else
506  snprintf (path, size, "%s/%s", CUBRID_LOGDIR, filename);
507 #endif
508 
509  path[size - 1] = '\0';
510  return path;
511 }
512 
513 void
514 envvar_trim_char (char *env_val, const int c)
515 {
516  char *buf;
517  size_t size;
518 
519  if (env_val == NULL)
520  {
521  return;
522  }
523 
524  size = strlen (env_val);
525 
526  if (*env_val == c && size > 2)
527  {
528  buf = (char *) malloc (1 + size);
529  if (buf != NULL)
530  {
531  strcpy (buf, env_val);
532  strncpy (env_val, buf + 1, size - 2);
533  env_val[size - 2] = '\0';
534 
535  free (buf);
536  }
537  }
538 }
539 
540 char *
541 envvar_ldmldir_file (char *path, size_t size, const char *filename)
542 {
543  assert (filename != NULL);
544 
545 #if !defined (DO_NOT_USE_CUBRIDENV)
546  if (envvar_Root == NULL)
547  {
548  envvar_root ();
549  }
550  snprintf (path, size, "%s/locales/data/ldml/%s", envvar_Root, filename);
551 #else
552  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
553 #endif
554 
555  path[size - 1] = '\0';
556  return path;
557 }
558 
559 char *
560 envvar_codepagedir_file (char *path, size_t size, const char *filename)
561 {
562  assert (filename != NULL);
563 
564 #if !defined (DO_NOT_USE_CUBRIDENV)
565  if (envvar_Root == NULL)
566  {
567  envvar_root ();
568  }
569  snprintf (path, size, "%s/locales/data/codepages/%s", envvar_Root, filename);
570 #else
571  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
572 #endif
573 
574  path[size - 1] = '\0';
575  return path;
576 }
577 
578 char *
579 envvar_localedatadir_file (char *path, size_t size, const char *filename)
580 {
581  assert (filename != NULL);
582 
583 #if !defined (DO_NOT_USE_CUBRIDENV)
584  if (envvar_Root == NULL)
585  {
586  envvar_root ();
587  }
588  snprintf (path, size, "%s/locales/data/%s", envvar_Root, filename);
589 #else
590  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
591 #endif
592 
593  path[size - 1] = '\0';
594  return path;
595 }
596 
597 char *
598 envvar_loclib_dir_file (char *path, size_t size, const char *filename)
599 {
600  assert (filename != NULL);
601 
602 #if !defined (DO_NOT_USE_CUBRIDENV)
603  if (envvar_Root == NULL)
604  {
605  envvar_root ();
606  }
607  snprintf (path, size, "%s/locales/loclib/%s", envvar_Root, filename);
608 #else
609  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
610 #endif
611 
612  path[size - 1] = '\0';
613  return path;
614 }
615 
616 char *
617 envvar_cubrid_dir (char *path, size_t size)
618 {
619 #if !defined (DO_NOT_USE_CUBRIDENV)
620  if (envvar_Root == NULL)
621  {
622  envvar_root ();
623  }
624  snprintf (path, size, "%s", envvar_Root);
625 #else
626  snprintf (path, size, "%s", CUBRID_CONFDIR);
627 #endif
628 
629  path[size - 1] = '\0';
630  return path;
631 }
632 
633 char *
634 envvar_tzdata_dir_file (char *path, size_t size, const char *filename)
635 {
636  assert (filename != NULL);
637 
638 #if !defined (DO_NOT_USE_CUBRIDENV)
639  if (envvar_Root == NULL)
640  {
641  envvar_root ();
642  }
643  snprintf (path, size, "%s/timezones/tzdata/%s", envvar_Root, filename);
644 #else
645  snprintf (path, size, "%s/%s", CUBRID_CONFDIR, filename);
646 #endif
647 
648  path[size - 1] = '\0';
649  return path;
650 }
char * envvar_logdir_file(char *path, size_t size, const char *filename)
const char * envvar_root(void)
#define NO_ERROR
Definition: error_code.h:46
static const char * envvar_Prefix
#define ER_FAILED
Definition: error_code.h:47
static void envvar_check_environment(void)
static const char * envvar_Root
int envvar_set(const char *name, const char *val)
#define _ENVVAR_MAX_LENGTH
#define _ENVVAR_MAX_EXPANSION
static const char * env_msg[]
char * envvar_libdir_file(char *path, size_t size, const char *filename)
char * envvar_javadir_file(char *path, size_t size, const char *filename)
char * envvar_localedatadir_file(char *path, size_t size, const char *filename)
#define assert(x)
const char * envvar_name(char *buf, size_t size, const char *name)
const char * envvar_prefix(void)
char * envvar_bindir_file(char *path, size_t size, const char *filename)
#define NULL
Definition: freelistheap.h:34
static const char envvar_Prefix_name[]
const char * envvar_get(const char *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: porting.c:2584
char * envvar_vardir_file(char *path, size_t size, const char *filename)
#define strlen(s1)
Definition: intl_support.c:43
char * envvar_tmpdir_file(char *path, size_t size, const char *filename)
char * envvar_codepagedir_file(char *path, size_t size, const char *filename)
char * envvar_loclib_dir_file(char *path, size_t size, const char *filename)
char * envvar_tzdata_dir_file(char *path, size_t size, const char *filename)
#define IS_ABS_PATH(p)
Definition: porting.h:357
char * envvar_localedir_file(char *path, size_t size, const char *langpath, const char *filename)
int envvar_expand(const char *string, char *buffer, size_t maxlen)
char * envvar_cubrid_dir(char *path, size_t size)
void envvar_trim_char(char *env_val, const int c)
char * envvar_ldmldir_file(char *path, size_t size, const char *filename)
char * envvar_confdir_file(char *path, size_t size, const char *filename)