3
// code for reading preferences and initializing host information
4
// Copyright (c) 1998-2010 by The VoxBo Development Team
6
// This file is part of VoxBo
8
// VoxBo is free software: you can redistribute it and/or modify it
9
// under the terms of the GNU General Public License as published by
10
// the Free Software Foundation, either version 3 of the License, or
11
// (at your option) any later version.
13
// VoxBo is distributed in the hope that it will be useful, but
14
// WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
// General Public License for more details.
18
// You should have received a copy of the GNU General Public License
19
// along with VoxBo. If not, see <http://www.gnu.org/licenses/>.
21
// For general information on VoxBo, including the latest complete
22
// source code and binary distributions, manual, and associated files,
23
// see the VoxBo home page at: http://www.voxbo.org/
25
// original version written by Dan Kimberg
31
#include <sys/types.h>
33
#include <sys/utsname.h>
35
#include "vbjobspec.h"
38
extern char **environ;
48
char prefsname[STRINGLEN];
51
// clear environment variables?
56
struct passwd *pw = getpwuid(uid); // look up user info
58
username=pw->pw_name; // default username
59
email=pw->pw_name; // default email address
60
homedir=pw->pw_dir; // user's home directory
63
fprintf(stderr,"vbprefs.cpp: couldn't allocate passwd structure\n");
67
// set the voxbo uid and group id
68
struct passwd *vpw = getpwnam("voxbo"); // look up voxbo user info
70
voxbouid = vpw->pw_uid;
71
voxbogid = vpw->pw_gid;
78
// sendmail="/usr/lib/sendmail";
81
superusers.insert("root");
88
if (uname(&names) == -1) {
89
fprintf(stderr,"vbprefs.cpp: uname failed, shouldn't happen\n");
92
thishost.hostname=names.nodename;
93
string tmps=thishost.hostname;
94
if (tmps.find(".") != string::npos)
95
tmps.erase(tmps.begin()+tmps.find("."),tmps.end());
96
thishost.shortname=tmps;
100
// rootdir: VOXBO_ROOT, /usr/local/VoxBo, /usr/local/voxbo, or
101
// what's in /etc/voxbo.dir
104
if (getenv("VOXBO_ROOT"))
105
rootdir=getenv("VOXBO_ROOT");
106
else if (vb_direxists("/usr/local/VoxBo"))
107
rootdir="/usr/local/VoxBo";
108
else if (vb_direxists("/usr/local/voxbo"))
109
rootdir="/usr/local/voxbo";
110
else if (vb_direxists("/usr/share/voxbo"))
111
rootdir="/usr/share/voxbo";
112
else if (vb_direxists("/usr/lib/voxbo"))
113
rootdir="/usr/lib/voxbo";
114
else if (vb_fileexists("/etc/voxbo.dir")) {
116
dd.ParseFirstLine("/etc/voxbo.dir");
121
// userdir is VOXBO_USERDIR, home/.voxbo, home/voxbo, or home/VoxBo,
122
// whichever comes first. if none exist, create home/.voxbo
125
if (getenv("VOXBO_USERDIR"))
126
userdir=getenv("VOXBO_USERDIR");
127
else if (vb_direxists(homedir+"/.voxbo"))
128
userdir=homedir+"/.voxbo";
129
else if (vb_direxists(homedir+"/voxbo"))
130
userdir=homedir+"/voxbo";
131
else if (vb_direxists(homedir+"/VoxBo"))
132
userdir=homedir+"/VoxBo";
133
// if not found, create .voxbo
134
if (userdir.size()==0)
135
createfullpath(homedir+"/.voxbo");
136
// make sure userdir has both queue and etc
137
if (!vb_direxists(userdir+"/queue"))
138
createfullpath(userdir+"/queue");
139
if (!vb_direxists(userdir+"/etc"))
140
createfullpath(userdir+"/etc");
142
if (rootdir.size()==0) {
146
// queue is in either the global or user dir
148
qname=rootdir+"/queue";
149
if (!stat(qname.c_str(),&st))
150
set_queue("voxbo_queue",qname.c_str(),st.st_ino);
152
// number of local machine cores to use for jobs. first check env
153
// var, then see if we have a queue dir, otherwise just use total
154
// number of cores on this machine
155
if (getenv("VOXBO_CORES"))
156
cores=strtol(getenv("VOXBO_CORES"));
157
else if (getenv("VOXBO_NCORES"))
158
cores=strtol(getenv("VOXBO_NCORES"));
159
else if (access((rootdir+"/drop").c_str(),W_OK)==0)
164
// now read the system file
165
sprintf(prefsname,"%s/etc/defaults",rootdir.c_str());
166
fp = fopen(prefsname,"r");
172
// read old-style user-specific config
173
sprintf(prefsname,"%s/.voxborc",homedir.c_str());
174
fp = fopen(prefsname,"r");
180
// finally read user-specific config
181
sprintf(prefsname,"%s/prefs.txt",userdir.c_str());
182
fp = fopen(prefsname,"r");
188
// set the root dir in env
189
char *str = (char *)malloc(rootdir.size()+10);
190
sprintf(str,"VOXROOT=%s",rootdir.c_str());
193
if (rootdir[rootdir.size()-1] != '/')
198
VBPrefs::read_prefs(FILE *fp,int system)
201
char line[STRINGLEN];
204
argx.SetSeparator(":");
205
while(fgets(line,STRINGLEN,fp) != NULL) {
206
if (args.ParseLine(line) < 2)
208
// handle machine-specific config stuff
209
argx.ParseLine(args[0]);
211
if (argx[0]!=thishost.shortname)
213
args[0].erase(0,argx[0].size()+1);
215
if (args[0] == "rootdir")
217
else if (args[0]=="shortname" && system)
218
thishost.shortname=args[1];
219
else if (args[0] == "sysadmin" && system)
221
else if (args[0] == "checkdir")
222
thishost.checkdirs.push_back(args[1]);
223
else if (args[0] == "benchmark" && args.size()>=4 && system) {
226
bb.interval=strtol(args[2]);
229
if (bb.name.size() && bb.interval>59 && bb.cmd.size())
230
benchmarks.push_back(bb);
232
else if (args[0] == "superusers" && system) {
234
ttt.ParseLine(args.Tail());
235
for (int i=0; i<ttt.size(); i++)
236
superusers.insert(ttt[i]);
237
if (superusers.count(username))
240
else if (args[0] == "email")
242
else if (args[0] == "sendmail" && system)
244
else if (args[0] == "serveralias" && args.size()==3 && system) {
245
if (thishost.hostname==args[1])
246
thishost.shortname=args[2];
248
else if (args[0] == "serverport" && system)
249
serverport = strtol(args[1]);
250
else if (args[0] == (string)"voxbouser" && system) {
251
struct passwd *vpw = getpwnam(args(1));
253
vpw=getpwuid(strtol(args(1)));
255
voxbouid = vpw->pw_uid;
256
voxbogid = vpw->pw_gid;
259
else if (args[0] == "setenv") {
260
strcpy(tmp,args.Tail().c_str());
261
stripchars(tmp,(char *)"=\n");
262
// used to check if it was already set, now we don't
263
char *str = (char *)malloc(args.Tail().size()+2);
264
strcpy(str,args.Tail().c_str());
267
else if (args[0] == "queuedelay" && system)
268
queuedelay = strtol(args[1]);
269
else if (args[0] == "queuedir" && args.size()==3) {
271
if (!stat(args[1].c_str(),&st))
272
set_queue(args[2],args[1],st.st_ino);
274
else if (args[0] == "defaultdir") {
276
if (defaultdir[defaultdir.size()-1] != '/')
283
VBPrefs::read_jobtypes()
286
vglob vg(rootdir+"/etc/jobtypes/*.vjt");
287
for (size_t i=0; i<vg.size(); i++) {
289
if (!tmpjt.ReadJOB1(vg[i]))
290
jobtypemap[tmpjt.shortname]=tmpjt;
292
fprintf(stderr,"[E] vbprefs: invalid jobtype file %s.\n",vg[i].c_str());
296
// read_serverfile() -- used by a single server to read just its own
297
// server info into vbp.thishost
299
// FIXME: right now checkdirs is set in the global config file, which
300
// means that once we have the server file below, we need to copy it
301
// over before overwriting the whole structure. this is ugly.
304
VBPrefs::read_serverfile()
307
string sfname=rootdir+"/etc/servers/"+thishost.hostname;
308
if (tmph.ReadFile(sfname,serverport)==0) {
309
tmph.checkdirs=thishost.checkdirs;
313
sfname=rootdir+"/etc/servers/"+thishost.shortname;
314
if (tmph.ReadFile(sfname,serverport)==0) {
315
tmph.checkdirs=thishost.checkdirs;
323
VBJobType::ReadJOB1(const string &fname)
325
char line[STRINGLEN];
329
// for processing requires lines
330
tokenlist items,item;
331
items.SetSeparator(",");
333
in.open(fname.c_str());
335
fprintf(stderr,"vbprefs: couldn't open jobtype file %s\n",fname.c_str());
339
shortname=fname; // default name
341
in.getline(line,STRINGLEN);
343
args.SetSeparator(" =");
347
//if (args.size() < 2)
349
if (strchr(";/#%",args[0][0])) // just a comment
351
if (args[0]=="shortname")
353
else if (args[0]=="description")
354
description=args.Tail();
355
else if (args[0]=="command") {
357
cmd.command=args.Tail();
358
commandlist.push_back(cmd);
360
else if (args[0]=="data") {
362
if (args.size() > 2) {
364
for (int h = 2; h < args.size(); h++)
365
jd.datalist.push_back(args[h]);
372
in.getline(line, STRINGLEN);
373
if (strncmp(line, "end", 3) == 0)
376
jd.datalist.push_back(line);
379
jobdatalist.push_back(jd);
381
else if (args[0]=="argument") {
383
if (args.size() > 1) {
384
for (int h = 1; h < args.size(); h+=2) {
385
if (args[h]=="type") {
388
else if (args[h]=="name") {
389
tmpa.name=(args[h+1]);
391
else if (args[h]=="argdesc") {
392
tmpa.description=args[h+1];
394
else if (args[h]=="prefix") {
397
else if (args[h]=="default") {
398
tmpa.defaultval=(args[h+1]);
400
else if (args[h]=="role") {
401
tmpa.role=(args[h+1]);
403
else if (args[h]=="high") {
404
tmpa.high=(args[h+1]);
406
else if (args[h]=="low") {
407
tmpa.low=(args[h+1]);
409
else if (args[h]=="end") {
410
memset((void*)line,0,STRINGLEN);
414
arguments.push_back(tmpa);
418
in.getline(line, STRINGLEN);
421
if (args[0]=="type") {
424
else if (args[0]=="name") {
427
else if (args[0]=="argdesc") {
428
for (int j = 1; j < (int)args.size(); j++)
429
tmpa.description+=(args[j] + " ");
431
else if (args[0]=="prefix") {
434
else if (args[0]=="default") {
435
tmpa.defaultval=(args[1]);
437
else if (args[0]=="role") {
440
else if (args[0]=="high") {
443
else if (args[0]=="low") {
446
else if (args[0]=="end") {
450
arguments.push_back(tmpa);
453
else if (args[0]=="invocation")
454
invocation=args.Tail();
455
else if (args[0]=="script" || args[0]=="|") {
456
if (commandlist.size())
457
commandlist[commandlist.size()-1].script.push_back(args.Tail());
459
else if (args[0]=="err_tag")
460
err_tag = args.Tail();
461
else if (args[0]=="warn_tag")
462
warn_tag = args.Tail();
463
else if (args[0]=="msg_tag")
464
msg_tag = args.Tail();
465
else if (args[0]=="retry_tag")
466
retry_tag = args.Tail();
467
else if (args[0]=="trigger") {
469
tmp.ParseLine(args.Tail());
475
tt.actionvalue=tmp[3];
476
triggerlist.push_back(tt);
479
else if (args[0]=="setenv") {
480
setenvlist.push_back(args.Tail());
482
else if (args[0]=="requires" || args[0]=="require") {
483
items.ParseLine(args.Tail());
484
for (int i=0; i<(int)items.size(); i++) {
485
item.ParseLine(items[i]);
486
if (item.size() >= 2)
487
requires[item[0]]=strtol(item[1]);
492
else if (args[0]=="fullname") {
493
continue; // ignore this unused tag
496
fprintf(stderr,"vbprefs: unrecognized keyword %s in jobtype %s\n",
497
args(0),shortname.c_str());
501
//if (command.size() < 1)
502
//return (102); // should do *something*
503
return (0); // no error!
506
VBJobType::VBJobType()
520
err_tag="VOXBO ERROR";
521
warn_tag="VOXBO WARNING";
522
msg_tag="VOXBO MESSAGE";
523
retry_tag="VOXBO RETRY";
526
nomail.push_back((string)"% Compiled module:");
527
nomail.push_back((string)"Percent done:");
531
VBJobType::getData(string key)
534
for (int i = 0; i < (int)jobdatalist.size(); i++) {
535
if (jobdatalist[i].key==key) {
536
for (int j = 0; j < (int)jobdatalist[i].datalist.size(); j++) {
537
ret.Add(jobdatalist[i].datalist[j]);
549
printf("Jobtype %s:\n",shortname.c_str());
550
printf(" description: %s\n",description.c_str());
551
printf(" invocation: %s\n",invocation.c_str());
552
printf(" err_tag: %s\n",err_tag.c_str());
553
printf(" warn_tag: %s\n",warn_tag.c_str());
554
printf(" msg_tag: %s\n",msg_tag.c_str());
555
printf(" retry_tag: %s\n",retry_tag.c_str());
556
for (i=0; i<(int)setenvlist.size(); i++) {
557
printf(" setenv: %s\n",setenvlist[i].c_str());
560
printf(" requires: ");
561
typedef pair<string,int> sipair;
562
vbforeach(sipair si,requires)
563
// for (i=0; i<(int)requires.size(); i++)
564
printf("%s(%d) ",si.first.c_str(),si.second);
567
printf(" arguments:");
568
for (i=0; i<(int)arguments.size(); i++) {
569
if (i==0) printf(" "); else printf(" ");
570
printf("%s (%s): %s\n",
571
arguments[i].name.c_str(),
572
arguments[i].role.c_str(),
573
arguments[i].description.c_str());
576
for (i=0; i<(int)commandlist.size(); i++) {
577
printf(" command: %s\n",commandlist[i].command.c_str());
578
for (j=0; j<(int)commandlist[i].script.size(); j++)
579
printf(" : %s\n",commandlist[i].script[j].c_str());
586
VBPrefs::set_queue(string name,string dir,ino_t inode)