Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

policy.cpp

// Copyright (C) 2000-2001 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#ifdef  __FreeBSD__
#define getopt(a, b, c) getopt()
#include <unistd.h>
#undef getopt
#endif

#include <cc++/misc.h>
#include <getopt.h>
#include "ivrconfig.h"
#ifdef HAVE_MKSTEMP
#include <fstream>
#include <stdlib.h> // mkstemp for Linux, Solaris
#include <unistd.h> // for BSD
#include <errno.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

#ifdef      COMMON_OST_NAMESPACE
namespace ost {
using namespace std;
#endif

static struct option long_options[] = {
      {"add", 1, 0, 'a'},
      {"delete", 1, 0, 'd'},
      {"del", 1, 0, 'd'},
      {"change", 1, 0, 'c'},
      {"index", 0, 0, 'i'},
      {"list", 0, 0, 'l'},
      {0, 0, 0, 0}};

typedef enum
{
      OP_NONE,
      OP_ADD,
      OP_DEL,
      OP_CHANGE,
      OP_LIST,
      OP_INDEX
}     op_t;

static void Change(fstream &cf, fstream &of, char *group, char **options)
{
      char buffer[256];
      char match[65];
      char *sp;

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;

            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            sprintf(match, "[%s-trunks]", group);
            if(!strnicmp(match, sp, strlen(match)))
                  break;
            sprintf(match, "[%s-policy]", group);
            if(!strnicmp(match, sp, strlen(match)))
                  break;
            of << buffer << endl;
      }

      of << match << endl;
      while(*options)
            of << *(options++) << endl;
      of << endl;

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;

            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            if(*sp == '[')
            {
                  of << buffer << endl;
                  return;
            }
      }
}

static void Del(fstream &cf, fstream &of, char *group)
{
      char buffer[256];
      char *sp;

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;
            of << buffer << endl;
            if(!strnicmp(buffer, "[trunks]", 8))
                  break;
            if(!strnicmp(buffer, "[policy]", 8))
                  break;
      }

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;

            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            if(!strnicmp(sp, "groups", 6))
                  break;
            if(!strnicmp(sp, "policies", 8))
                  break;
            of << buffer << endl;
      }
      sp = strchr(sp, '=');
      sp = strtok(++sp, " \t\n\r");
      of << "groups =";
      while(sp)
      {
            cout << sp;
            if(stricmp(sp, group))
                  of << " " << sp;
            sp = strtok(NULL, " \t\n\r");
      }
      of << endl; 
}

static void Add(fstream &cf, fstream &of, char *group, char **options)
{
      char buffer[256];
      char match[65];
      char *sp;

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1); 
            if(cf.eof())
                  return;
            of << buffer << endl;
            if(!strnicmp(buffer, "[trunks]", 8))
                  break;
            if(!strnicmp(buffer, "[policy]", 8))
                  break;
      }

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;

            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            if(!strnicmp(sp, "groups", 6))
                  break;
            if(!strnicmp(sp, "policies", 8))
                  break;  
            of << buffer << endl;
      }

      sp = strchr(sp, '=');
      sp = strtok(++sp, " \t\n\r");
      of << "groups =";
      while(sp)
      {
            of << " " << sp;
            if(!stricmp(sp, group))
            {
                  cerr << "bayonne_policy: " << group << ": already exists" << endl;
                  exit(-1);
            }
            sp = strtok(NULL, " \t\n\r");
      }
      of << " " << group << endl;
      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;
            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            if(*sp == '[')
            {
                  of << "[" << group << "]" << endl;
                  while(*options)
                        of << *(options++) << endl;
                  of << endl;
                  of << buffer << endl;
                  return;
            }
            else
                  of << buffer << endl;
      }

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;
            
            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            sprintf(match, "[%s-trunks]", group);
            if(!strnicmp(match, sp, strlen(match)))
                  break;
            sprintf(match, "[%s-policy]", group);
            if(!strnicmp(match, sp, strlen(match)))
                  break;

            of << buffer << endl;
      }

      for(;;)
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  return;

            sp = buffer;
            while(*sp == ' ' || *sp == '\t')
                  ++sp;
            if(*sp == '[')
            {
                  of << buffer << endl;
                  return;
            }
      }
}           

static void List(char *group)
{
      char buffer[65];
      char *keys[128];
      char **key = keys;

      if(group)
            sprintf(buffer, "/bayonne/%s-trunks", group);
      else
            sprintf(buffer, "/bayonne/trunks");
      Keydata policy(buffer);
      while(*key)
      {
            if(stricmp(*key, "groups"))
                  cout << *key << "=" << policy.getLast(*key) << endl;
            ++key;
      }
      exit(0);
}

static void Index(void)
{
      Keydata trunks("/bayonne/trunks");
      char *cp = (char *)trunks.getLast("groups");
      cp = strtok(cp, " \t\n");
      while(cp)
      {
            cout << cp << endl;
            cp = strtok(NULL, " \t\n");
      }
      exit(0);
}           

extern "C" int main(int argc, char **argv)
{
      static op_t op = OP_NONE;
      static bool usage = false;
      char conf[256];
      char buffer[256]; 
      char *group = NULL;
      int opt, opt_index;
      std::fstream cf, of;
      char *tmp = tmpnam(NULL);

      bool modify = true;
      
      while(EOF != (opt = getopt_long(argc, argv, "a:d:c:li",
         long_options, &opt_index)))
            switch(opt)
            {
            case 'a':
                  op = OP_ADD;
                  group = optarg;
                  break;
            case 'd':
                  op = OP_DEL;
                  group = optarg;
                  break;
            case 'c':
                  op = OP_CHANGE;
                  group = optarg;
                  break;
            case 'i':
                  modify = false;
                  op = OP_INDEX;
                  break;
            case 'l':
                  modify = false;
                  op = OP_LIST;
                  break;
            default:
                  usage = true;
            }

      if(usage || op == OP_NONE)
      {
            cerr << "bayonne_policy: [--add | --change || --delete || --list] policy [options]" << endl;
            exit(-1);
      }

      strcpy(conf, ETC_PREFIX);
      strcat(conf, "bayonne.conf");

      if(modify)
      {
            cf.open(conf, ios::in | ios::out);
            if(!cf.is_open())
            {
                  cerr << "bayonne_policy: " << conf << ": denied" << endl;
                  exit(-1);
            }
            remove(tmp);
            of.open(tmp, ios::in | ios::out);
            // WARNING big fat race condition right here
            chmod(tmp, 0600);
            remove(tmp);
            if(!of.is_open())
            {
                  cerr << "bayonne_policy: tempfile: denied" << endl;
                  exit(-1);
            }
      }

      switch(op)
      {
      case OP_ADD:
            Add(cf, of, group, &argv[optind]);
            break;
      case OP_DEL:
            Del(cf, of, group);
            break;
      case OP_CHANGE:
            Change(cf, of, group, &argv[optind]);
            break; 
      case OP_INDEX:
            Index();
            break;
      case OP_LIST:
            List(argv[optind]);
            break;
      }
      while(!cf.eof())
      {
            cf.getline(buffer, sizeof(buffer) - 1);
            if(cf.eof())
                  break;
            of << buffer << endl;
      }
      cf.sync();
      of.sync();
      of.seekp(0);
      cf.close();
      cf.open(conf, ios::out | ios::trunc);
      for(;;)
      {
            of.getline(conf, sizeof(conf) - 1);
            if(of.eof())
                  break;
            cf << conf << endl;
      }
      cf.sync();
      cf.close();
      of.close();
}

#ifdef      CCXX_NAMESPACES
};
#endif





























Generated by  Doxygen 1.6.0   Back to index