1 | #include"adconn.h"
|
---|
2 |
|
---|
3 | #include<qapplication.h>
|
---|
4 | #include"bconsole.h"
|
---|
5 | #include"bsocket.h"
|
---|
6 | #include"httpconnect.h"
|
---|
7 | #include"socks.h"
|
---|
8 | #include"httppoll.h"
|
---|
9 |
|
---|
10 | #include<stdio.h>
|
---|
11 |
|
---|
12 | class App::Private
|
---|
13 | {
|
---|
14 | public:
|
---|
15 | Private() {}
|
---|
16 |
|
---|
17 | ByteStream *bs;
|
---|
18 | BConsole *c;
|
---|
19 | int mode;
|
---|
20 | };
|
---|
21 |
|
---|
22 | App::App(int mode, const QString &host, int port, const QString &serv, const QString &proxy_host, int proxy_port, const QString &proxy_user, const QString &proxy_pass)
|
---|
23 | :QObject(0)
|
---|
24 | {
|
---|
25 | d = new Private;
|
---|
26 | d->c = new BConsole;
|
---|
27 | connect(d->c, SIGNAL(connectionClosed()), SLOT(con_connectionClosed()));
|
---|
28 | connect(d->c, SIGNAL(readyRead()), SLOT(con_readyRead()));
|
---|
29 | d->bs = 0;
|
---|
30 |
|
---|
31 | d->mode = mode;
|
---|
32 |
|
---|
33 | if(mode == 0 || mode == 1) {
|
---|
34 | BSocket *s = new BSocket;
|
---|
35 | d->bs = s;
|
---|
36 | connect(s, SIGNAL(connected()), SLOT(st_connected()));
|
---|
37 | connect(s, SIGNAL(error(int)), SLOT(st_error(int)));
|
---|
38 | if(mode == 0) {
|
---|
39 | fprintf(stderr, "adconn: Connecting to %s:%d ...\n", host.latin1(), port);
|
---|
40 | s->connectToHost(host, port);
|
---|
41 | }
|
---|
42 | else {
|
---|
43 | fprintf(stderr, "adconn: Connecting to '%s' server at %s ...\n", serv.latin1(), host.latin1());
|
---|
44 | s->connectToServer(host, serv);
|
---|
45 | }
|
---|
46 | }
|
---|
47 | else if(mode == 2) {
|
---|
48 | HttpConnect *s = new HttpConnect;
|
---|
49 | d->bs = s;
|
---|
50 | connect(s, SIGNAL(connected()), SLOT(st_connected()));
|
---|
51 | connect(s, SIGNAL(error(int)), SLOT(st_error(int)));
|
---|
52 | fprintf(stderr, "adconn: Connecting to %s:%d via %s:%d (https)\n", host.latin1(), port, proxy_host.latin1(), proxy_port);
|
---|
53 | if(!proxy_user.isEmpty())
|
---|
54 | s->setAuth(proxy_user, proxy_pass);
|
---|
55 | s->connectToHost(proxy_host, proxy_port, host, port);
|
---|
56 | }
|
---|
57 | else if(mode == 3) {
|
---|
58 | SocksClient *s = new SocksClient;
|
---|
59 | d->bs = s;
|
---|
60 | connect(s, SIGNAL(connected()), SLOT(st_connected()));
|
---|
61 | connect(s, SIGNAL(error(int)), SLOT(st_error(int)));
|
---|
62 | fprintf(stderr, "adconn: Connecting to %s:%d via %s:%d (socks)\n", host.latin1(), port, proxy_host.latin1(), proxy_port);
|
---|
63 | if(!proxy_user.isEmpty())
|
---|
64 | s->setAuth(proxy_user, proxy_pass);
|
---|
65 | s->connectToHost(proxy_host, proxy_port, host, port);
|
---|
66 | }
|
---|
67 | else if(mode == 4) {
|
---|
68 | HttpPoll *s = new HttpPoll;
|
---|
69 | d->bs = s;
|
---|
70 | connect(s, SIGNAL(connected()), SLOT(st_connected()));
|
---|
71 | connect(s, SIGNAL(error(int)), SLOT(st_error(int)));
|
---|
72 | fprintf(stderr, "adconn: Connecting to %s via %s:%d (poll)\n", host.latin1(), proxy_host.latin1(), proxy_port);
|
---|
73 | if(!proxy_user.isEmpty())
|
---|
74 | s->setAuth(proxy_user, proxy_pass);
|
---|
75 | s->connectToHost(proxy_host, proxy_port, host);
|
---|
76 | }
|
---|
77 | }
|
---|
78 |
|
---|
79 | App::~App()
|
---|
80 | {
|
---|
81 | delete d->bs;
|
---|
82 | delete d->c;
|
---|
83 | delete d;
|
---|
84 | }
|
---|
85 |
|
---|
86 | void App::st_connected()
|
---|
87 | {
|
---|
88 | fprintf(stderr, "adconn: Connected\n");
|
---|
89 |
|
---|
90 | // map the signals
|
---|
91 | connect(d->bs, SIGNAL(connectionClosed()), SLOT(st_connectionClosed()));
|
---|
92 | connect(d->bs, SIGNAL(delayedCloseFinished()), SLOT(st_delayedCloseFinished()));
|
---|
93 | connect(d->bs, SIGNAL(readyRead()), SLOT(st_readyRead()));
|
---|
94 | }
|
---|
95 |
|
---|
96 | void App::st_connectionClosed()
|
---|
97 | {
|
---|
98 | fprintf(stderr, "adconn: Connection closed by foreign host.\n");
|
---|
99 | quit();
|
---|
100 | }
|
---|
101 |
|
---|
102 | void App::st_delayedCloseFinished()
|
---|
103 | {
|
---|
104 | quit();
|
---|
105 | }
|
---|
106 |
|
---|
107 | void App::st_readyRead()
|
---|
108 | {
|
---|
109 | QByteArray a = d->bs->read();
|
---|
110 | d->c->write(a);
|
---|
111 | }
|
---|
112 |
|
---|
113 | void App::st_error(int x)
|
---|
114 | {
|
---|
115 | fprintf(stderr, "adconn: Stream error [%d].\n", x);
|
---|
116 | quit();
|
---|
117 | }
|
---|
118 |
|
---|
119 | void App::con_connectionClosed()
|
---|
120 | {
|
---|
121 | fprintf(stderr, "adconn: Closing.\n");
|
---|
122 | d->bs->close();
|
---|
123 | if(d->bs->bytesToWrite() == 0)
|
---|
124 | quit();
|
---|
125 | }
|
---|
126 |
|
---|
127 | void App::con_readyRead()
|
---|
128 | {
|
---|
129 | QByteArray a = d->c->read();
|
---|
130 | d->bs->write(a);
|
---|
131 | }
|
---|
132 |
|
---|
133 |
|
---|
134 | int main(int argc, char **argv)
|
---|
135 | {
|
---|
136 | QApplication app(argc, argv, false);
|
---|
137 |
|
---|
138 | if(argc < 2) {
|
---|
139 | printf("usage: adconn [options] [host]\n");
|
---|
140 | printf(" [host] must be in the form 'host:port' or 'domain#server'\n");
|
---|
141 | printf(" When using proxy 'poll', [host] must be a URL\n");
|
---|
142 | printf(" Options:\n");
|
---|
143 | printf(" --proxy=[https|poll|socks],host:port\n");
|
---|
144 | printf(" --proxy-auth=user,pass\n");
|
---|
145 | printf("\n");
|
---|
146 | return 0;
|
---|
147 | }
|
---|
148 |
|
---|
149 | int mode = 0;
|
---|
150 | QString proxy_host;
|
---|
151 | int proxy_port=0;
|
---|
152 | QString proxy_user, proxy_pass;
|
---|
153 |
|
---|
154 | for(int at = 1; at < argc; ++at) {
|
---|
155 | QString s = argv[at];
|
---|
156 |
|
---|
157 | // is it an option?
|
---|
158 | if(s.left(2) == "--") {
|
---|
159 | QString name;
|
---|
160 | QStringList args;
|
---|
161 | int n = s.find('=', 2);
|
---|
162 | if(n != -1) {
|
---|
163 | name = s.mid(2, n-2);
|
---|
164 | ++n;
|
---|
165 | args = QStringList::split(',', s.mid(n), true);
|
---|
166 | }
|
---|
167 | else {
|
---|
168 | name = s.mid(2);
|
---|
169 | args.clear();
|
---|
170 | }
|
---|
171 |
|
---|
172 | // eat the arg
|
---|
173 | --argc;
|
---|
174 | for(int x = at; x < argc; ++x)
|
---|
175 | argv[x] = argv[x+1];
|
---|
176 | --at; // don't advance
|
---|
177 |
|
---|
178 | // process option
|
---|
179 | if(name == "proxy") {
|
---|
180 | QString type = args[0];
|
---|
181 | QString s = args[1];
|
---|
182 | int n = s.find(':');
|
---|
183 | if(n == -1) {
|
---|
184 | printf("invalid host:port for proxy\n");
|
---|
185 | return 0;
|
---|
186 | }
|
---|
187 | proxy_host = s.mid(0, n);
|
---|
188 | ++n;
|
---|
189 | proxy_port = s.mid(n).toInt();
|
---|
190 |
|
---|
191 | if(type == "https") {
|
---|
192 | mode = 2;
|
---|
193 | }
|
---|
194 | else if(type == "poll") {
|
---|
195 | mode = 4;
|
---|
196 | }
|
---|
197 | else if(type == "socks") {
|
---|
198 | mode = 3;
|
---|
199 | }
|
---|
200 | else {
|
---|
201 | printf("no such proxy type '%s'\n", type.latin1());
|
---|
202 | return 0;
|
---|
203 | }
|
---|
204 | }
|
---|
205 | else if(name == "proxy-auth") {
|
---|
206 | proxy_user = args[0];
|
---|
207 | proxy_pass = args[1];
|
---|
208 | }
|
---|
209 | else {
|
---|
210 | printf("Unknown option '%s'\n", name.latin1());
|
---|
211 | return 0;
|
---|
212 | }
|
---|
213 | }
|
---|
214 | }
|
---|
215 |
|
---|
216 | if(argc < 2) {
|
---|
217 | if(mode == 4)
|
---|
218 | printf("No URL specified\n");
|
---|
219 | else
|
---|
220 | printf("No host specified!\n");
|
---|
221 | return 0;
|
---|
222 | }
|
---|
223 |
|
---|
224 | QString host, serv;
|
---|
225 | int port=0;
|
---|
226 |
|
---|
227 | if(mode == 4) {
|
---|
228 | host = argv[1];
|
---|
229 | }
|
---|
230 | else {
|
---|
231 | QString s = argv[1];
|
---|
232 | int n = s.find(':');
|
---|
233 | if(n == -1) {
|
---|
234 | n = s.find('#');
|
---|
235 | if(n == -1) {
|
---|
236 | printf("No port or server specified!\n");
|
---|
237 | return 0;
|
---|
238 | }
|
---|
239 |
|
---|
240 | if(mode >= 2) {
|
---|
241 | printf("Can't use domain#server with proxy!\n");
|
---|
242 | return 0;
|
---|
243 | }
|
---|
244 | host = s.mid(0, n);
|
---|
245 | ++n;
|
---|
246 | serv = s.mid(n);
|
---|
247 | mode = 1;
|
---|
248 | }
|
---|
249 | else {
|
---|
250 | host = s.mid(0, n);
|
---|
251 | ++n;
|
---|
252 | port = s.mid(n).toInt();
|
---|
253 | }
|
---|
254 | }
|
---|
255 |
|
---|
256 | App *a = new App(mode, host, port, serv, proxy_host, proxy_port, proxy_user, proxy_pass);
|
---|
257 | QObject::connect(a, SIGNAL(quit()), &app, SLOT(quit()));
|
---|
258 | app.exec();
|
---|
259 | delete a;
|
---|
260 |
|
---|
261 | return 0;
|
---|
262 | }
|
---|