Bayonne 3 - API
 All Classes Namespaces Files Functions Variables Typedefs Macros
env.cpp
Go to the documentation of this file.
1 // Copyright (C) 2008-2011 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU Bayonne.
4 //
5 // GNU Bayonne is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU Bayonne is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with GNU Bayonne. If not, see <http://www.gnu.org/licenses/>.
17 
18 #include <config.h>
19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
21 #include <bayonne.h>
22 
23 #ifdef HAVE_PWD_H
24 #include <pwd.h>
25 #endif
26 
27 using namespace BAYONNE_NAMESPACE;
28 using namespace UCOMMON_NAMESPACE;
29 
30 shell_t *Env::sys;
31 bool Env::daemon_flag = true;
32 bool Env::tool_flag = false;
33 
34 void Env::init(shell_t *args)
35 {
36  sys = args;
37 
38 #ifdef _MSWINDOWS_
39  const char *rundir = strdup(str(env("APPDATA")) + "/bayonne");
40  const char *prefix = "C:\\Program Files\\bayonne";
41  const char *plugins = "C:\\Program Files\\bayonne\\plugins";
42 
43  set("config", _STR(str(prefix) + "/bayonne.ini"));
44  set("configs", _STR(str(prefix) + "\\config\\"));
45  set("services", _STR(str(prefix) + "/services"));
46  set("controls", rundir);
47  set("control", "\\\\.\\mailslot\\bayonne_ctrl");
48  set("snapshot", _STR(str(rundir) + "/snapshot.log"));
49  set("boards", _STR(str(rundir) + "/boards.log"));
50  set("spans", _STR(str(rundir) + "/spans.log"));
51  set("logfiles", _STR(str(prefix) + "/logs"));
52  set("logfile", _STR(str(prefix) + "/logs/bayonne.log"));
53  set("calls", _STR(str(prefix) + "/logs/bayonne.calls"));
54  set("stats", _STR(str(prefix) + "/logs/bayonne.stats"));
55  set("scripts", _STR(str(prefix) + "/scripts"));
56  set("appaudio", _STR(str(prefix) + "/audio"));
57  set("sounds", _STR(str(prefix) + "/sounds"));
58  set("definitions", _STR(str(prefix) + "/scripts"));
59  set("shell", "cmd.exe");
60  set("voices", _STR(str(prefix) + "\\voices"));
61  set("temp", "C:\\Program Files\\bayonne\\temp");
62 
63  prefix = "C:\\Program Files\\bayonne\\datafiles";
64 
65 #else
66  const char *prefix = DEFAULT_VARPATH "/lib/bayonne";
67  const char *rundir = DEFAULT_VARPATH "/run/bayonne";
68  const char *plugins = DEFAULT_LIBPATH "/bayonne";
69 
70  set("reply", "/tmp/.bayonne.");
71  set("config", DEFAULT_CFGPATH "/bayonne.conf");
72  set("configs", DEFAULT_CFGPATH "/bayonne/");
73  set("services", DEFAULT_SCRPATH);
74  set("controls", DEFAULT_VARPATH "/run/bayonne");
75  set("control", DEFAULT_VARPATH "/run/bayonne/control");
76  set("snapshot", DEFAULT_VARPATH "/run/bayonne/snapshot");
77  set("boards", DEFAULT_VARPATH "/run/bayonne/boards");
78  set("spans", DEFAULT_VARPATH "/run/bayonne/spans");
79  set("logfiles", DEFAULT_VARPATH "/log");
80  set("logfile", DEFAULT_VARPATH "/log/bayonne.log");
81  set("calls", DEFAULT_VARPATH "/log/bayonne.calls");
82  set("stats", DEFAULT_VARPATH "/log/bayonne.stats");
83  set("scripts", DEFAULT_VARPATH "/lib/bayonne/scripts");
84  set("audio", DEFAULT_DATADIR "/bayonne");
85  set("sounds", DEFAULT_DATADIR "/sounds");
86  set("applications", DEFAULT_DATADIR "/bayonne");
87  set("definitions", DEFAULT_DATADIR "/bayonne");
88  set("shell", "/bin/sh");
89  set("voices", DEFAULT_DATADIR "/phrasebook");
90  set("temp", DEFAULT_VARPATH "/tmp/bayonne");
91 #endif
92 
93 #ifdef HAVE_PWD_H
94  const char *home_prefix = NULL;
95  struct passwd *pwd = getpwuid(getuid());
96  umask(007);
97 
98  if(getuid() && pwd && pwd->pw_dir && *pwd->pw_dir == '/') {
99  if(!eq(pwd->pw_shell, "/bin/false") && !eq(pwd->pw_dir, "/var/", 5) && !eq(pwd->pw_dir, "/srv/", 5)) {
100  umask(077);
101  daemon_flag = false;
102  }
103  else // alternate media prefix possible if not root startup...
104  prefix = strdup(pwd->pw_dir);
105  }
106 
107  // if user mode (testing)...
108  if(!daemon_flag && pwd)
109  home_prefix = strdup(str(pwd->pw_dir) + "/.bayonne");
110 
111  // tool mode only uses ~/.bayonne if also actually exists...
112  if(home_prefix && tool_flag && !fsys::isdir(home_prefix))
113  home_prefix = NULL;
114 
115  if(home_prefix) {
116  rundir = strdup(str("/tmp/bayonne-") + str(pwd->pw_name));
117  prefix = home_prefix;
118 
119  set("config", _STR(str(pwd->pw_dir) + "/.bayonnerc"));
120  set("configs", home_prefix);
121  set("scripts", home_prefix);
122  set("sysconfigs", _STR(str(DEFAULT_CFGPATH) + "/bayonne"));
123  set("services", prefix);
124  set("controls", rundir);
125  set("control", _STR(str(rundir) + "/control"));
126  set("snapshot", _STR(str(rundir) + "/snapshot"));
127  set("boards", _STR(str(rundir) + "/boards"));
128  set("spans", _STR(str(rundir) + "/spans"));
129  set("logfiles", rundir);
130  set("logfile", _STR(str(rundir) + "/logfile"));
131  set("calls", _STR(str(rundir) + "/calls"));
132  set("stats", _STR(str(rundir) + "/stats"));
133  set("prefix", prefix);
134  set("shell", pwd->pw_shell);
135  }
136 #endif
137 
138  set("voice", "default");
139  set("extension", ".au");
140  set("prefix", prefix);
141  set("rundir", rundir);
142  set("plugins", plugins);
143 }
144 
145 void Env::tool(shell_t *args)
146 {
147  tool_flag = true;
148  init(args);
149 }
150 
151 const char *Env::config(const char *name)
152 {
153  // if we have cached copy of config path, use it...
154  const char *result = env(name);
155  if(result)
156  return result;
157 
158  const char *sysconfig = env("sysconfig");
159 
160  string_t filename = str(env("configs")) + str(name);
161 
162  if(sysconfig && !fsys::isfile(*filename))
163  filename = str(sysconfig) + str(name);
164 
165  // cache and use requested config path...
166  set(name, *filename);
167  return env(name);
168 }
169 
170 const char *Env::path(pathinfo_t& pi, const char *path, char *buffer, size_t size, bool writeflag)
171 {
172  const char *ext = strrchr(path, '/');
173 
174  // file: and tool: can be used anywhere, but for toolmode only...
175  if(case_eq(path, "file:", 5) || case_eq(path, "tool:")) {
176  if(!tool_flag)
177  return NULL;
178 
179  String::set(buffer, size, path + 5);
180  return buffer;
181  }
182 
183  // out: can be used to override for writing absolute path in tool mode...
184  if(case_eq(path, "out:", 4)) {
185  if(!tool_flag || !writeflag)
186  return NULL;
187 
188  String::set(buffer, size, path + 4);
189  return buffer;
190  }
191 
192  // writeflag used to restrict what bayonne can modify. We disable this
193  // for various bayonne tools.
194  if(tool_flag)
195  writeflag = false;
196 
197  // all other xxx: paths cannot include subdirectories...
198  if(ext && strchr(path + 2, ':'))
199  return NULL;
200 
201  // xxx.ext is a local file, not phrase library, in tool mode...
202  if(!ext && strchr(path, '.') && tool_flag && !strchr(path + 2, ':'))
203  ext = path;
204 
205  if(ext) {
206  ext = strchr(ext, '.');
207  if(ext)
208  ext = "";
209  else
210  ext = env("extension");
211 
212  if(*path != '/' && tool_flag)
213  snprintf(buffer, size, "%s/%s%s",
214  env("prefix"), path, ext);
215  else
216  snprintf(buffer, size, "%s%s", path, ext);
217 
218  return buffer;
219  }
220 
221  const char *voice = pi.voices;
222  if(!voice)
223  voice = env("voice");
224 
225  ext = strchr(path, '.');
226 
227  if(ext)
228  ext = "";
229  else
230  ext = env("extension");
231 
232  // tmp: to access bayonne temporary files...
233  if(case_eq(path, "tmp:", 4) || case_eq(path, "temp:", 5)) {
234  snprintf(buffer, size, "%s/%s%s",
235  env("temp"), strchr(path, ':') + 1, ext);
236  return buffer;
237  }
238 
239  // we cannot write to system sounds directory...
240  if(case_eq(path, "sound:", 6) || case_eq(path, "sounds:", 7)) {
241  if(writeflag)
242  return NULL;
243 
244  snprintf(buffer, size, "%s/%s%s",
245  env("sounds"), strchr(path, ':') + 1, ext);
246  }
247 
248 
249  // lib: optional way to always specify use library
250  else if(case_eq(path, "lib:", 4))
251  path += 4;
252  else if(strchr(path, ':'))
253  return NULL;
254 
255  // normally cannot write to phrasebook library unless toolmode
256  if(writeflag)
257  return NULL;
258 
259  // can optionally force path through voice library setting
260  if(strchr(voice, '/')) {
261  snprintf(buffer, size, "%s/%s%s", voice, path, ext);
262  return buffer;
263  }
264 
265  if(pi.book) {
266  snprintf(buffer, size, "%s%s%s/%s%s",
267  env("voices"), pi->path(), voice, path, ext);
268 
269  return buffer;
270  }
271  return NULL;
272 }
273 
274 
#define BAYONNE_NAMESPACE
Definition: bayonne.h:25
GNU Bayonne library namespace.