Improvements to fogbugz oo stuff to make it more schedulator-compatible.
[wvapps.git] / nss / unibounced.cc
blob50f083683f22ff56864b24ab8d0fd75d0915820f
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2004 Net Integration Technologies, Inc.
5 * UniConf Daemon bouncer to hack around the fact that the UniConf Daemon
6 * on Weaver doesn't listen on a TCP Port.
7 */
9 #include "wvunixsocket.h"
10 #include "wvtcp.h"
11 #include "wvlog.h"
12 #include "strutils.h"
13 #include "wvcrash.h"
14 #include "wvistreamlist.h"
15 #include "wvsyslog.h"
17 #include <signal.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <getopt.h>
22 static WvString filename;
23 static WvString bindaddr;
25 WvLog log("unibounced", WvLog::Info);
27 volatile bool want_to_die = false;
29 static void signal_handler(int signum)
31 log(WvLog::Notice, "Dying on signal %s.\n", signum);
32 want_to_die = true;
33 signal(signum, SIG_IGN);
36 void usage(WvStringParm argv0)
38 wvcon->print("Usage: %s [-d] [-dd] [-q[q]] [-V] [-p port] [-f filename]\n"
39 " -d Daemonize and exit\n"
40 " -v Verbose output (can be used multiple times)\n"
41 " -q Quiet output (can be used multiple times)\n"
42 " -V Print version and exit\n"
43 " -p port Listen on TCP 'port'\n"
44 " -f filename Attach to Unix Socket 'filename'\n\n", argv0);
45 exit(1);
48 static void conn_closed(WvStream &stream, void *data)
50 log("Connection closed, stopping forwarding\n");
52 stream.noautoforward();
54 if (!data)
55 return;
57 WvStream *conn = static_cast<WvStream *>(data);
58 conn->setclosecallback(0, 0);
59 conn->noautoforward();
60 conn->close();
63 static void acceptor(WvStream &stream, void *data)
65 WvTCPListener *listener = static_cast<WvTCPListener *>(data);
67 if (!listener)
68 return;
70 WvTCPConn *tcpconn = listener->accept();
71 WvUnixConn *unixconn = new WvUnixConn(filename);
73 if (!unixconn->isok())
75 log(WvLog::Error, "Could not bind to %s: %s\n",
76 filename, unixconn->errstr());
78 WVRELEASE(unixconn);
79 WVRELEASE(tcpconn);
80 return;
83 if (!tcpconn->isok())
85 log(WvLog::Error, "Accepting connection from %s failed: %s\n",
86 *(tcpconn->src()), tcpconn->errstr());
88 WVRELEASE(unixconn);
89 WVRELEASE(tcpconn);
90 return;
93 tcpconn->setclosecallback(conn_closed, unixconn);
94 unixconn->setclosecallback(conn_closed, tcpconn);
96 unixconn->autoforward(*tcpconn);
97 tcpconn->autoforward(*unixconn);
98 WvIStreamList::globallist.append(unixconn, true);
99 WvIStreamList::globallist.append(tcpconn, true);
102 void run()
104 WvTCPListener *listener = new WvTCPListener(bindaddr);
105 WvIStreamList::globallist.append(listener, true);
107 listener->setcallback(acceptor, listener);
109 while (WvIStreamList::globallist.isok() && !want_to_die)
110 WvIStreamList::globallist.runonce();
114 int main(int argc, char **argv)
116 filename = "/tmp/uniconfd";
117 bindaddr = "0.0.0.0:4111";
118 bool daemonize = false;
119 WvLog::LogLevel lvl = WvLog::Info;
121 wvcrash_setup(argv[0]);
123 signal(SIGPIPE, SIG_IGN);
124 signal(SIGINT, signal_handler);
125 signal(SIGTERM, signal_handler);
127 int c;
129 while ((c = getopt(argc, argv, "dqvVp:f:h?")) >= 0)
131 switch (c)
133 case 'd':
134 daemonize = true;
135 break;
136 case 'v':
137 if (lvl < WvLog::Debug5)
138 lvl = WvLog::LogLevel(lvl + 1);
139 break;
140 case 'q':
141 if (lvl > WvLog::Critical)
142 lvl = WvLog::LogLevel(lvl - 1);
143 break;
144 case 'V':
145 wvcon->print("UniConf bouncer version 0.0\n");
146 return 2;
147 case 'p':
148 bindaddr = WvString("0.0.0.0:%s", optarg);
149 break;
150 case 'f':
151 filename = optarg;
152 break;
153 case 'h':
154 case '?':
155 default:
156 usage(argv[0]);
157 break;
161 log("Starting up!\n");
163 if (daemonize)
165 pid_t pid = fork();
166 if (pid < 0)
168 wverr->print("Failed to fork daemon: %s\n", strerror(errno));
169 return 3;
171 else if (pid == 0)
173 setsid();
174 pid = fork();
175 if (pid < 0)
177 wverr->print("Failed to double-fork daemon: %s\n",
178 strerror(errno));
179 return 4;
181 else if (pid == 0)
183 WvSyslog syslog("unibounced", false);
185 chdir("/tmp");
187 umask(0);
189 close(0);
190 close(1);
191 close(2);
193 run();
195 else _exit(0);
197 else _exit(0);
199 else
201 WvLogConsole console_log(1, lvl);
202 run();
205 log("Done!\n");
207 return 0;