blob: 71c8be86e792a81f83be0721052c5eacfb6aa325 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2000-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2008 David Sugar, Tycho Softworks.
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include "server.h"
19#include <getopt.h>
20#include <sys/wait.h>
21#include <iostream>
22#include <fstream>
23
24
25using namespace std;
26
27#ifdef CCXX_NAMESPACES
28namespace ost {
29using namespace std;
30#endif
31
32bool multicast = false;
33bool daemon = false;
34bool drop = false;
35bool answer = false;
36
37static int initial(int argc, char **argv)
38{
39 static bool usage = false;
40
41 static struct option long_options[] = {
42 {"hangup", 0, 0, 'd'},
43 {"drop", 0, 0, 'd'},
44 {"background", 0, 0, 'D'},
45 {"foreground", 0, 0, 'F'},
46 {"daemon", 0, 0, 'D'},
47 {"multicast", 0, 0, 'm'},
48 {"unicast", 0, 0, 'u'},
49 {"help", 0, 0, 'h'},
50 {"priority", 1, 0, 'p'},
51 {0, 0, 0, 0}};
52
53 int idx, opt;
54 char *cp = strchr(argv[0], '/');
55 if(cp)
56 ++cp;
57 else
58 cp = argv[0];
59
60 if(*cp == 'm')
61 multicast = true;
62
63 while(EOF != (opt = getopt_long(argc, argv, "mudp:FDh", long_options, &idx)))
64 {
65 switch(opt)
66 {
67 case 'm':
68 multicast = true;
69 break;
70 case 'u':
71 multicast = false;
72 break;
73 case 'p':
74 keythreads.setValue("priority", optarg);
75 break;
76 case 'F':
77 daemon = false;
78 break;
79 case 'D':
80 daemon = true;
81 break;
82 case 'd':
83 drop = true;
84 break;
85 default:
86 usage = true;
87 }
88 }
89 if(usage)
90 {
91 std::cerr << "use: phone [options] [parties...]" << std::endl;
92 exit(-1);
93 }
94 return optind;
95}
96
97static int getPid()
98{
99 int pid, fd;
100 char buf[20];
101
102 fd = ::open(".phonepid", O_RDONLY);
103 if(fd < 0)
104 return 0;
105
106 ::read(fd, buf, 16);
107 buf[10] = 0;
108 ::close(fd);
109 pid = atol(buf);
110 if(kill(pid, 0))
111 return 0;
112 return pid;
113}
114
115#ifdef CCXX_NAMESPACES
116extern "C" {
117#endif
118
119int main(int argc, char **argv)
120{
121 int pid = 0, wpid = 0;
122 int idx;
123 std::ofstream fifo;
124
125 chdir(getenv("HOME"));
126 if(canAccess(".phonepid"))
127 if(canModify(".phonectrl"))
128 pid = getPid();
129
130 idx = initial(argc, argv);
131
132 if(!pid)
133 {
134 ::remove(".phonectrl");
135 ::mkfifo(".phonectrl", 0660);
136 pid = ::fork();
137 if(!pid)
138 {
139 server();
140 exit(0);
141 }
142 if(daemon)
143 ::waitpid(pid, NULL, 0);
144 else
145 wpid = pid;
146 }
147 fifo.open(".phonectrl", std::ios::out);
148 if(!fifo.is_open())
149 {
150 std::cerr << "phone: cannot get control interface" << std::endl;
151 exit(-1);
152 }
153 if(idx == argc && drop)
154 fifo << "DROP *" << std::endl;
155
156 while(idx < argc)
157 {
158 if(drop)
159 fifo << "DROP " << argv[idx++] << std::endl;
160 else
161 fifo << "JOIN " << argv[idx++] << std::endl;
162 }
163
164 fifo.close();
165
166 if(wpid > 0)
167 ::waitpid(wpid, NULL, 0);
168
169 exit(0);
170}
171
172#ifdef CCXX_NAMESPACES
173} }
174#endif