blob: 71c8be86e792a81f83be0721052c5eacfb6aa325 [file] [log] [blame]
// Copyright (C) 2000-2005 Open Source Telecom Corporation.
// Copyright (C) 2006-2008 David Sugar, Tycho Softworks.
//
// 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.
#include "server.h"
#include <getopt.h>
#include <sys/wait.h>
#include <iostream>
#include <fstream>
using namespace std;
#ifdef CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif
bool multicast = false;
bool daemon = false;
bool drop = false;
bool answer = false;
static int initial(int argc, char **argv)
{
static bool usage = false;
static struct option long_options[] = {
{"hangup", 0, 0, 'd'},
{"drop", 0, 0, 'd'},
{"background", 0, 0, 'D'},
{"foreground", 0, 0, 'F'},
{"daemon", 0, 0, 'D'},
{"multicast", 0, 0, 'm'},
{"unicast", 0, 0, 'u'},
{"help", 0, 0, 'h'},
{"priority", 1, 0, 'p'},
{0, 0, 0, 0}};
int idx, opt;
char *cp = strchr(argv[0], '/');
if(cp)
++cp;
else
cp = argv[0];
if(*cp == 'm')
multicast = true;
while(EOF != (opt = getopt_long(argc, argv, "mudp:FDh", long_options, &idx)))
{
switch(opt)
{
case 'm':
multicast = true;
break;
case 'u':
multicast = false;
break;
case 'p':
keythreads.setValue("priority", optarg);
break;
case 'F':
daemon = false;
break;
case 'D':
daemon = true;
break;
case 'd':
drop = true;
break;
default:
usage = true;
}
}
if(usage)
{
std::cerr << "use: phone [options] [parties...]" << std::endl;
exit(-1);
}
return optind;
}
static int getPid()
{
int pid, fd;
char buf[20];
fd = ::open(".phonepid", O_RDONLY);
if(fd < 0)
return 0;
::read(fd, buf, 16);
buf[10] = 0;
::close(fd);
pid = atol(buf);
if(kill(pid, 0))
return 0;
return pid;
}
#ifdef CCXX_NAMESPACES
extern "C" {
#endif
int main(int argc, char **argv)
{
int pid = 0, wpid = 0;
int idx;
std::ofstream fifo;
chdir(getenv("HOME"));
if(canAccess(".phonepid"))
if(canModify(".phonectrl"))
pid = getPid();
idx = initial(argc, argv);
if(!pid)
{
::remove(".phonectrl");
::mkfifo(".phonectrl", 0660);
pid = ::fork();
if(!pid)
{
server();
exit(0);
}
if(daemon)
::waitpid(pid, NULL, 0);
else
wpid = pid;
}
fifo.open(".phonectrl", std::ios::out);
if(!fifo.is_open())
{
std::cerr << "phone: cannot get control interface" << std::endl;
exit(-1);
}
if(idx == argc && drop)
fifo << "DROP *" << std::endl;
while(idx < argc)
{
if(drop)
fifo << "DROP " << argv[idx++] << std::endl;
else
fifo << "JOIN " << argv[idx++] << std::endl;
}
fifo.close();
if(wpid > 0)
::waitpid(wpid, NULL, 0);
exit(0);
}
#ifdef CCXX_NAMESPACES
} }
#endif