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