~ubuntu-branches/ubuntu/raring/voxbo/raring

« back to all changes in this revision

Viewing changes to lib/vbprefs.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2010-06-06 11:33:11 UTC
  • Revision ID: james.westby@ubuntu.com-20100606113311-v3c13imdkkd5n7ae
Tags: upstream-1.8.5~svn1172
ImportĀ upstreamĀ versionĀ 1.8.5~svn1172

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
// vbprefs.cpp
 
3
// code for reading preferences and initializing host information
 
4
// Copyright (c) 1998-2010 by The VoxBo Development Team
 
5
 
 
6
// This file is part of VoxBo
 
7
// 
 
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.
 
12
// 
 
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.
 
17
// 
 
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/>.
 
20
// 
 
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/
 
24
// 
 
25
// original version written by Dan Kimberg
 
26
 
 
27
using namespace std;
 
28
 
 
29
#include <unistd.h>
 
30
#include <pwd.h>
 
31
#include <sys/types.h>
 
32
#include <sys/stat.h>
 
33
#include <sys/utsname.h>
 
34
#include "vbutil.h"
 
35
#include "vbjobspec.h"
 
36
#include "vbprefs.h"
 
37
 
 
38
extern char **environ;
 
39
 
 
40
VBPrefs::VBPrefs()
 
41
{
 
42
}
 
43
 
 
44
void
 
45
VBPrefs::init()
 
46
{
 
47
  FILE *fp;
 
48
  char prefsname[STRINGLEN];
 
49
  struct stat st;
 
50
 
 
51
  // clear environment variables?
 
52
  // environ=NULL;
 
53
  // first set defaults
 
54
 
 
55
  uid_t uid = getuid();
 
56
  struct passwd *pw = getpwuid(uid);       // look up user info
 
57
  if (pw) {
 
58
    username=pw->pw_name;                 // default username
 
59
    email=pw->pw_name;                    // default email address
 
60
    homedir=pw->pw_dir;                   // user's home directory
 
61
  }
 
62
  else {
 
63
    fprintf(stderr,"vbprefs.cpp: couldn't allocate passwd structure\n");
 
64
    exit(5);
 
65
  }
 
66
  
 
67
  // set the voxbo uid and group id
 
68
  struct passwd *vpw = getpwnam("voxbo");  // look up voxbo user info
 
69
  if (vpw) {
 
70
    voxbouid = vpw->pw_uid;
 
71
    voxbogid = vpw->pw_gid;
 
72
  }
 
73
  else {
 
74
    voxbouid=99;
 
75
    voxbogid=99;
 
76
  }
 
77
 
 
78
  // sendmail="/usr/lib/sendmail";
 
79
  sysadmin="root";
 
80
  superusers.clear();
 
81
  superusers.insert("root");
 
82
  defaultdir='/';
 
83
  su=0;
 
84
  serverport=6004;
 
85
  benchmarks.clear();
 
86
 
 
87
  struct utsname names;
 
88
  if (uname(&names) == -1) {
 
89
    fprintf(stderr,"vbprefs.cpp: uname failed, shouldn't happen\n");
 
90
    exit(5);
 
91
  }
 
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;
 
97
  queuedelay = 30;
 
98
  jobtypemap.clear();
 
99
 
 
100
  // rootdir: VOXBO_ROOT, /usr/local/VoxBo, /usr/local/voxbo, or
 
101
  // what's in /etc/voxbo.dir
 
102
 
 
103
  rootdir="";
 
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")) {
 
115
    tokenlist dd;
 
116
    dd.ParseFirstLine("/etc/voxbo.dir");
 
117
    if (dd.size())
 
118
      rootdir=dd[1];
 
119
  }
 
120
 
 
121
  // userdir is VOXBO_USERDIR, home/.voxbo, home/voxbo, or home/VoxBo,
 
122
  // whichever comes first.  if none exist, create home/.voxbo
 
123
 
 
124
  userdir="";
 
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");
 
141
 
 
142
  if (rootdir.size()==0) {
 
143
    rootdir=userdir;
 
144
  }
 
145
  
 
146
  // queue is in either the global or user dir
 
147
  string qname;
 
148
  qname=rootdir+"/queue";
 
149
  if (!stat(qname.c_str(),&st))
 
150
    set_queue("voxbo_queue",qname.c_str(),st.st_ino);
 
151
 
 
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)
 
160
    cores=0;
 
161
  else
 
162
    cores=ncores();  
 
163
 
 
164
  // now read the system file
 
165
  sprintf(prefsname,"%s/etc/defaults",rootdir.c_str());
 
166
  fp = fopen(prefsname,"r");
 
167
  if (fp) {
 
168
    read_prefs(fp,1);
 
169
    fclose(fp);
 
170
  }
 
171
 
 
172
  // read old-style user-specific config
 
173
  sprintf(prefsname,"%s/.voxborc",homedir.c_str());
 
174
  fp = fopen(prefsname,"r");
 
175
  if (fp) {
 
176
    read_prefs(fp,0);
 
177
    fclose(fp);
 
178
  }
 
179
 
 
180
  // finally read user-specific config
 
181
  sprintf(prefsname,"%s/prefs.txt",userdir.c_str());
 
182
  fp = fopen(prefsname,"r");
 
183
  if (fp) {
 
184
    read_prefs(fp,0);
 
185
    fclose(fp);
 
186
  }
 
187
 
 
188
  // set the root dir in env
 
189
  char *str = (char *)malloc(rootdir.size()+10);
 
190
  sprintf(str,"VOXROOT=%s",rootdir.c_str());
 
191
  putenv(str);
 
192
 
 
193
  if (rootdir[rootdir.size()-1] != '/')
 
194
    rootdir+='/';
 
195
}
 
196
 
 
197
void
 
198
VBPrefs::read_prefs(FILE *fp,int system)
 
199
{
 
200
  char tmp[STRINGLEN];
 
201
  char line[STRINGLEN];
 
202
  string host;
 
203
  tokenlist args,argx;
 
204
  argx.SetSeparator(":");
 
205
  while(fgets(line,STRINGLEN,fp) != NULL) {
 
206
    if (args.ParseLine(line) < 2)
 
207
      continue;
 
208
    // handle machine-specific config stuff
 
209
    argx.ParseLine(args[0]);
 
210
    if (argx.size()>1) {
 
211
      if (argx[0]!=thishost.shortname)
 
212
        continue;
 
213
      args[0].erase(0,argx[0].size()+1);
 
214
    }
 
215
    if (args[0] == "rootdir")
 
216
      rootdir=args[1];
 
217
    else if (args[0]=="shortname" && system)
 
218
      thishost.shortname=args[1];
 
219
    else if (args[0] == "sysadmin" && system)
 
220
      sysadmin=args[1];
 
221
    else if (args[0] == "checkdir")
 
222
      thishost.checkdirs.push_back(args[1]);
 
223
    else if (args[0] == "benchmark" && args.size()>=4 && system) {
 
224
      VBenchmark bb;
 
225
      bb.name=args[1];
 
226
      bb.interval=strtol(args[2]);
 
227
      bb.cmd=args.Tail(3);
 
228
      bb.scheduled=0;
 
229
      if (bb.name.size() && bb.interval>59 && bb.cmd.size())
 
230
        benchmarks.push_back(bb);
 
231
    }
 
232
    else if (args[0] == "superusers" && system) {
 
233
      tokenlist ttt;
 
234
      ttt.ParseLine(args.Tail());
 
235
      for (int i=0; i<ttt.size(); i++)
 
236
        superusers.insert(ttt[i]);
 
237
      if (superusers.count(username))
 
238
        su=1;
 
239
    }
 
240
    else if (args[0] == "email")
 
241
      email=args[1];
 
242
    else if (args[0] == "sendmail" && system)
 
243
      sendmail=args[1];
 
244
    else if (args[0] == "serveralias" && args.size()==3 && system) {
 
245
      if (thishost.hostname==args[1])
 
246
        thishost.shortname=args[2];
 
247
    }
 
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));
 
252
      if (!vpw)
 
253
        vpw=getpwuid(strtol(args(1)));
 
254
      if (vpw) {
 
255
        voxbouid = vpw->pw_uid;
 
256
        voxbogid = vpw->pw_gid;
 
257
      }
 
258
    }
 
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());
 
265
      putenv(str);
 
266
    }
 
267
    else if (args[0] == "queuedelay" && system)
 
268
      queuedelay = strtol(args[1]);
 
269
    else if (args[0] == "queuedir" && args.size()==3) {
 
270
      struct stat st;
 
271
      if (!stat(args[1].c_str(),&st))
 
272
        set_queue(args[2],args[1],st.st_ino);
 
273
    }
 
274
    else if (args[0] == "defaultdir") {
 
275
      defaultdir=args[1];
 
276
      if (defaultdir[defaultdir.size()-1] != '/')
 
277
        defaultdir+='/';
 
278
    }
 
279
  }
 
280
}
 
281
 
 
282
void
 
283
VBPrefs::read_jobtypes()
 
284
{
 
285
  jobtypemap.clear();
 
286
  vglob vg(rootdir+"/etc/jobtypes/*.vjt");
 
287
  for (size_t i=0; i<vg.size(); i++) {
 
288
    VBJobType tmpjt;
 
289
    if (!tmpjt.ReadJOB1(vg[i]))
 
290
      jobtypemap[tmpjt.shortname]=tmpjt;
 
291
    else
 
292
      fprintf(stderr,"[E] vbprefs: invalid jobtype file %s.\n",vg[i].c_str());
 
293
  }
 
294
}
 
295
 
 
296
// read_serverfile() -- used by a single server to read just its own
 
297
// server info into vbp.thishost
 
298
 
 
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.
 
302
 
 
303
int
 
304
VBPrefs::read_serverfile()
 
305
{
 
306
  VBHost tmph;
 
307
  string sfname=rootdir+"/etc/servers/"+thishost.hostname;
 
308
  if (tmph.ReadFile(sfname,serverport)==0) {
 
309
    tmph.checkdirs=thishost.checkdirs;
 
310
    thishost=tmph;
 
311
    return 0;
 
312
  }
 
313
  sfname=rootdir+"/etc/servers/"+thishost.shortname;
 
314
  if (tmph.ReadFile(sfname,serverport)==0) {
 
315
    tmph.checkdirs=thishost.checkdirs;
 
316
    thishost=tmph;
 
317
    return 0;
 
318
  }
 
319
  return 101;
 
320
}
 
321
 
 
322
int
 
323
VBJobType::ReadJOB1(const string &fname)
 
324
{
 
325
  char line[STRINGLEN];
 
326
  tokenlist args;
 
327
  ifstream in;
 
328
  string tmp;
 
329
  // for processing requires lines
 
330
  tokenlist items,item;
 
331
  items.SetSeparator(",");
 
332
 
 
333
  in.open(fname.c_str());
 
334
  if (in.fail()) {
 
335
    fprintf(stderr,"vbprefs: couldn't open jobtype file %s\n",fname.c_str());
 
336
    return (101);
 
337
  }
 
338
 
 
339
  shortname=fname;    // default name
 
340
  while(!in.eof()) {
 
341
    in.getline(line,STRINGLEN);
 
342
    tmp=line;
 
343
    args.SetSeparator(" =");
 
344
    args.ParseLine(tmp);
 
345
    if (!args.size())
 
346
      continue;
 
347
    //if (args.size() < 2)
 
348
    //  continue;
 
349
    if (strchr(";/#%",args[0][0]))      // just a comment
 
350
      continue;
 
351
    if (args[0]=="shortname")
 
352
      shortname=args[1];
 
353
    else if (args[0]=="description")
 
354
      description=args.Tail();
 
355
    else if (args[0]=="command") {
 
356
      VBcmd cmd;
 
357
      cmd.command=args.Tail();
 
358
      commandlist.push_back(cmd);
 
359
    }
 
360
    else if (args[0]=="data") {
 
361
      jobdata jd;
 
362
      if (args.size() > 2) {
 
363
        jd.key = args[1]; 
 
364
        for (int h = 2; h < args.size(); h++)
 
365
          jd.datalist.push_back(args[h]);
 
366
      }
 
367
      else {
 
368
        tokenlist a;
 
369
        a.ParseLine(line);
 
370
        jd.key = a.Tail();
 
371
        while (!in.eof()) {
 
372
          in.getline(line, STRINGLEN);
 
373
          if (strncmp(line, "end", 3) == 0)
 
374
            break;
 
375
          else
 
376
            jd.datalist.push_back(line);
 
377
        }
 
378
      }
 
379
      jobdatalist.push_back(jd);
 
380
    } 
 
381
    else if (args[0]=="argument") {
 
382
      VBArgument tmpa;
 
383
      if (args.size() > 1) {
 
384
        for (int h = 1; h < args.size(); h+=2) {
 
385
          if (args[h]=="type") {
 
386
            tmpa.type=args[h+1];
 
387
          }
 
388
          else if (args[h]=="name") {
 
389
            tmpa.name=(args[h+1]);
 
390
          }
 
391
          else if (args[h]=="argdesc") {
 
392
            tmpa.description=args[h+1];
 
393
          }
 
394
          else if (args[h]=="prefix") {
 
395
            continue;
 
396
          }
 
397
          else if (args[h]=="default") {
 
398
            tmpa.defaultval=(args[h+1]);
 
399
          }
 
400
          else if (args[h]=="role") {
 
401
            tmpa.role=(args[h+1]);
 
402
          }
 
403
          else if (args[h]=="high") {
 
404
            tmpa.high=(args[h+1]);
 
405
          }
 
406
          else if (args[h]=="low") {
 
407
            tmpa.low=(args[h+1]);
 
408
          }
 
409
          else if (args[h]=="end") {
 
410
            memset((void*)line,0,STRINGLEN);
 
411
            break;
 
412
          }
 
413
        }
 
414
        arguments.push_back(tmpa);
 
415
      }
 
416
      else { 
 
417
        while (!in.eof()) {
 
418
          in.getline(line, STRINGLEN);
 
419
          tmp=line;
 
420
          args.ParseLine(tmp);
 
421
          if (args[0]=="type") {
 
422
            tmpa.type=args[1];
 
423
          }
 
424
          else if (args[0]=="name") {
 
425
            tmpa.name=(args[1]);
 
426
          }
 
427
          else if (args[0]=="argdesc") {
 
428
            for (int j = 1; j < (int)args.size(); j++)
 
429
              tmpa.description+=(args[j] + " ");
 
430
          }
 
431
          else if (args[0]=="prefix") {
 
432
            continue;
 
433
          }
 
434
          else if (args[0]=="default") {
 
435
            tmpa.defaultval=(args[1]);
 
436
          }
 
437
          else if (args[0]=="role") {
 
438
            tmpa.role=(args[1]);
 
439
          }
 
440
          else if (args[0]=="high") {
 
441
            tmpa.high=(args[1]);
 
442
          }
 
443
          else if (args[0]=="low") {
 
444
            tmpa.low=(args[1]);
 
445
          }
 
446
          else if (args[0]=="end") {
 
447
            break;
 
448
          }
 
449
        }
 
450
        arguments.push_back(tmpa);
 
451
      } 
 
452
    }
 
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());
 
458
    }
 
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") {
 
468
      tokenlist tmp;
 
469
      tmp.ParseLine(args.Tail());
 
470
      if (tmp.size()==4) {
 
471
        VBTrigger tt;
 
472
        tt.cond=tmp[0];
 
473
        tt.condvalue=tmp[1];
 
474
        tt.action=tmp[2];
 
475
        tt.actionvalue=tmp[3];
 
476
        triggerlist.push_back(tt);
 
477
      }
 
478
    }
 
479
    else if (args[0]=="setenv") {
 
480
      setenvlist.push_back(args.Tail());
 
481
    }
 
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]);
 
488
        else
 
489
          requires[item[0]]=0;
 
490
      }
 
491
    }
 
492
    else if (args[0]=="fullname") {
 
493
      continue;  // ignore this unused tag
 
494
    }
 
495
    else {
 
496
      fprintf(stderr,"vbprefs: unrecognized keyword %s in jobtype %s\n",
 
497
              args(0),shortname.c_str());
 
498
    }
 
499
  }
 
500
  in.close();
 
501
  //if (command.size() < 1)
 
502
  //return (102);  // should do *something*
 
503
  return (0);  // no error!
 
504
}
 
505
 
 
506
VBJobType::VBJobType()
 
507
{
 
508
  init();
 
509
}
 
510
 
 
511
void
 
512
VBJobType::init()
 
513
{
 
514
  shortname="";
 
515
  // fullname="";
 
516
  description="";
 
517
  invocation="";
 
518
  commandlist.clear();
 
519
  setenvlist.clear();
 
520
  err_tag="VOXBO ERROR";
 
521
  warn_tag="VOXBO WARNING";
 
522
  msg_tag="VOXBO MESSAGE";
 
523
  retry_tag="VOXBO RETRY";
 
524
  requires.clear();
 
525
  nomail.clear();
 
526
  nomail.push_back((string)"% Compiled module:");
 
527
  nomail.push_back((string)"Percent done:");
 
528
}
 
529
 
 
530
tokenlist
 
531
VBJobType::getData(string key)
 
532
{
 
533
  tokenlist ret;
 
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]);
 
538
      }
 
539
      break;
 
540
    }
 
541
  }
 
542
  return ret;
 
543
}
 
544
 
 
545
void
 
546
VBJobType::print()
 
547
{
 
548
  int i,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());
 
558
  }
 
559
 
 
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);
 
565
  printf("\n");
 
566
 
 
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());
 
574
  }
 
575
 
 
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());
 
580
  }
 
581
}
 
582
 
 
583
// add/replace queue
 
584
 
 
585
void
 
586
VBPrefs::set_queue(string name,string dir,ino_t inode)
 
587
{
 
588
  queue.name=name;
 
589
  queue.dir=dir;
 
590
  queue.inode=inode;
 
591
}