1 |
1 |
2 #include <stdlib.h> |
2 #include <stdlib.h> |
3 #include <unistd.h> |
3 #include <stdbool.h> |
|
4 #include <err.h> |
4 #include <stdio.h> |
5 #include <stdio.h> |
5 #include <string.h> |
6 #include <getopt.h> |
6 #include <event.h> |
|
7 #include <assert.h> |
|
8 |
7 |
9 #include <err.h> |
|
10 #include <event2/event.h> |
8 #include <event2/event.h> |
11 |
9 |
12 #include "sock.h" |
10 #include "sock.h" |
13 #include "line_proto.h" |
11 #include "line_proto.h" |
14 |
12 |
15 #define CONNECT_HOST "irc.fixme.fi" |
13 #define CONNECT_HOST "irc.fixme.fi" |
16 #define CONNECT_SERV "6697" |
14 #define CONNECT_SERV "6697" |
17 #define LINE_LENGTH 512 |
15 #define LINE_LENGTH 512 |
18 |
16 |
19 void on_line (const char *line, void *arg) { |
17 static struct option options[] = { |
|
18 {"help", 0, NULL, 'h' }, |
|
19 {"hostname", 1, NULL, 'H' }, |
|
20 {"port", 1, NULL, 'P' }, |
|
21 {"ssl", 0, NULL, 'S' }, |
|
22 {0, 0, 0, 0 }, |
|
23 }; |
|
24 |
|
25 void usage (const char *exe) |
|
26 { |
|
27 printf("Usage: %s [OPTIONS]\n", exe); |
|
28 printf("\n"); |
|
29 printf(" --help / -h display this message\n"); |
|
30 printf(" --hostname / -H HOST set hostname to connect to\n"); |
|
31 printf(" --port / -P PORT set service port to connect to\n"); |
|
32 printf(" --ssl / -S use SSL\n"); |
|
33 } |
|
34 |
|
35 void on_line (const char *line, void *arg) |
|
36 { |
20 printf("<<< %s\n", line); |
37 printf("<<< %s\n", line); |
21 } |
38 } |
22 |
39 |
23 int main (int argc, char **argv) { |
40 int main (int argc, char **argv) |
|
41 { |
|
42 int opt, option_index; |
24 struct event_base *ev_base; |
43 struct event_base *ev_base; |
25 struct sock_stream *sock; |
44 struct sock_stream *sock; |
26 struct line_proto *lp; |
45 struct line_proto *lp; |
27 struct error_info _err; |
46 struct error_info _err; |
|
47 |
|
48 const char *hostname = CONNECT_HOST, *portname = CONNECT_SERV; |
|
49 bool ssl = 0; |
|
50 |
|
51 // parse options |
|
52 while ((opt = getopt_long(argc, argv, "hH:P:S", options, &option_index)) != -1) { |
|
53 switch (opt) { |
|
54 case 'h': |
|
55 usage(argv[0]); |
|
56 return EXIT_SUCCESS; |
|
57 |
|
58 case 'H': |
|
59 hostname = optarg; |
|
60 break; |
|
61 |
|
62 case 'P': |
|
63 portname = optarg; |
|
64 break; |
|
65 |
|
66 case 'S': |
|
67 ssl = true; |
|
68 |
|
69 case '?': |
|
70 usage(argv[0]); |
|
71 return EXIT_FAILURE; |
|
72 } |
|
73 } |
28 |
74 |
29 // initialize libevent |
75 // initialize libevent |
30 if ((ev_base = event_base_new()) == NULL) |
76 if ((ev_base = event_base_new()) == NULL) |
31 err(1, "event_base_new"); |
77 err(1, "event_base_new"); |
32 |
78 |
33 // initialize sock module |
79 // initialize sock module |
34 if (sock_init(ev_base, &_err)) |
80 if (sock_init(ev_base, &_err)) |
35 errx(1, "sock_init: %s", error_msg(&_err)); |
81 errx(1, "sock_init: %s", error_msg(&_err)); |
36 |
82 |
37 // over-simplified connect |
83 // over-simplified connect |
38 if (sock_ssl_connect(&sock, CONNECT_HOST, CONNECT_SERV, &_err)) |
84 if (ssl) { |
39 errx(1, "sock_gnutls_connect: %s", error_msg(&_err)); |
85 if (sock_ssl_connect(&sock, hostname, portname, &_err)) |
|
86 errx(1, "sock_ssl_connect: %s", error_msg(&_err)); |
|
87 |
|
88 } else { |
|
89 if (sock_tcp_connect(&sock, hostname, portname, &_err)) |
|
90 errx(1, "sock_tcp_connect: %s", error_msg(&_err)); |
|
91 |
|
92 } |
40 |
93 |
41 // line protocol, with safety margin for buffer |
94 // line protocol, with safety margin for buffer |
42 if (line_proto_create(&lp, sock, LINE_LENGTH * 2, on_line, NULL, &_err)) |
95 if (line_proto_create(&lp, sock, LINE_LENGTH * 2, on_line, NULL, &_err)) |
43 errx(1, "line_proto_create: %s", error_msg(&_err)); |
96 errx(1, "line_proto_create: %s", error_msg(&_err)); |
44 |
97 |