FreeSWITCH API Documentation  1.7.0
switch_config.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  *
29  * switch_config.c -- Configuration File Parser
30  *
31  */
32 
33 #include <switch.h>
34 #include <switch_config.h>
35 
37 {
38  FILE *f;
39  char *path = NULL;
40  char path_buf[1024];
41 
42  if (!file_path) {
43  return 0;
44  }
45 
46  if (switch_is_file_path(file_path)) {
47  path = file_path;
48  } else {
49  switch_snprintf(path_buf, sizeof(path_buf), "%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR, file_path);
50  path = path_buf;
51  }
52 
53  memset(cfg, 0, sizeof(*cfg));
54  cfg->lockto = -1;
55 
56  if (!(f = fopen(path, "r"))) {
57  if (!switch_is_file_path(file_path)) {
58  int last = -1;
59  char *var, *val;
60 
61  switch_snprintf(path_buf, sizeof(path_buf), "%s%sfreeswitch.conf", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR);
62  path = path_buf;
63 
64  if ((f = fopen(path, "r")) == 0) {
65  return 0;
66  }
67 
68  cfg->file = f;
69  switch_set_string(cfg->path, path);
70 
71  while (switch_config_next_pair(cfg, &var, &val)) {
72  if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) {
73  cfg->lockto = cfg->sectno;
74  return 1;
75  }
76  }
77 
79  memset(cfg, 0, sizeof(*cfg));
80  return 0;
81  }
82 
83  return 0;
84  } else {
85  cfg->file = f;
86  switch_set_string(cfg->path, path);
87  return 1;
88  }
89 }
90 
92 {
93 
94  if (cfg->file) {
95  fclose(cfg->file);
96  }
97 
98  memset(cfg, 0, sizeof(*cfg));
99 }
100 
101 SWITCH_DECLARE(int) switch_config_next_pair(switch_config_t *cfg, char **var, char **val)
102 {
103  int ret = 0;
104  char *p, *end;
105 
106  *var = *val = NULL;
107 
108  if ( !cfg->path[0] ){
109  return 0;
110  }
111 
112  for (;;) {
113  cfg->lineno++;
114 
115  if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
116  ret = 0;
117  break;
118  }
119  *var = cfg->buf;
120 
121  if (**var == '[' && (end = strchr(*var, ']')) != 0) {
122  *end = '\0';
123  (*var)++;
124  if (**var == '+') {
125  (*var)++;
126  switch_copy_string(cfg->section, *var, sizeof(cfg->section));
127  cfg->sectno++;
128 
129  if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) {
130  break;
131  }
132  cfg->catno = 0;
133  cfg->lineno = 0;
134  *var = "";
135  *val = "";
136  return 1;
137  } else {
138  switch_copy_string(cfg->category, *var, sizeof(cfg->category));
139  cfg->catno++;
140  }
141  continue;
142  }
143 
144  if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') {
145  continue;
146  }
147 
148  if (!strncmp(*var, "__END__", 7)) {
149  break;
150  }
151 
152  if ((end = strchr(*var, '#')) != 0 || (end = strchr(*var, ';')) != 0) {
153  *end = '\0';
154  end--;
155  } else if ((end = strchr(*var, '\n')) != 0) {
156  if (*(end - 1) == '\r') {
157  end--;
158  }
159  *end = '\0';
160  }
161 
162  p = *var;
163  while ((*p == ' ' || *p == '\t') && p != end) {
164  *p = '\0';
165  p++;
166  }
167  *var = p;
168 
169  if ((*val = strchr(*var, '=')) == 0) {
170  ret = -1;
171  /* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */
172  continue;
173  } else {
174  p = *val - 1;
175  *(*val) = '\0';
176  (*val)++;
177  if (*(*val) == '>') {
178  *(*val) = '\0';
179  (*val)++;
180  }
181 
182  while ((*p == ' ' || *p == '\t') && p != *var) {
183  *p = '\0';
184  p--;
185  }
186 
187  p = *val;
188  while ((*p == ' ' || *p == '\t') && p != end) {
189  *p = '\0';
190  p++;
191  }
192  *val = p;
193  ret = 1;
194  break;
195  }
196  }
197 
198  return ret;
199 }
200 
201 /* For Emacs:
202  * Local Variables:
203  * mode:c
204  * indent-tabs-mode:t
205  * tab-width:4
206  * c-basic-offset:4
207  * End:
208  * For VIM:
209  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
210  */
void switch_config_close_file(switch_config_t *cfg)
Close a previously opened configuration file.
Definition: switch_config.c:91
typedefSWITCH_BEGIN_EXTERN_C struct switch_config switch_config_t
Definition: switch_config.h:61
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
Main Library Header.
static switch_bool_t switch_is_file_path(const char *file)
int switch_config_open_file(switch_config_t *cfg, char *file_path)
Open a configuration file.
Definition: switch_config.c:36
#define SWITCH_DECLARE(type)
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:665
Basic Configuration File Parser.
memset(buf, 0, buflen)
int switch_config_next_pair(switch_config_t *cfg, char **var, char **val)
Retrieve next name/value pair from configuration file.