#include #include #include #include #include #include #include #if _WIN32 #include #else #include #endif #include #include "socket.h" #include "bufio.h" #include "lookup.h" #include "tls.h" #define USE_TLS 1 static void main_gets_catch(struct bufio *io, void *line, size_t len, enum bufio_errno err, void *fd) { static char buf[1024]; int n; if (len > 0) { for (n = len - 1; n > 0; n--) if (((char *)line)[n] != '\r' && ((char *)line)[n] != '\n') break; warnx("read %d bytes: %.*s", (int)len, n + 1, line); } if (err != 0) { if (BUFIO_EOF(err)) { bufio_close(io); warnx("got EOF"); return /* void */; } else errx(EXIT_FAILURE, "bufio_gets: %s", bufio_errlist[err]); } bufio_gets(io, buf, sizeof buf, &main_gets_catch, io, &(struct timeval){ 2, 0 }); return /* void */; } /* main_gets_catch() */ static void main_write_catch(struct bufio *io, void *request, size_t len, enum bufio_errno err, void *fd) { static char buf[1024]; if (err != 0) errx(EXIT_FAILURE, "bufio_write: %s", bufio_errlist[err]); warnx("wrote %d bytes", (int)len); if (len != strlen(request)) { bufio_write(io, (char *)request + len, strlen((char *)request + len), &main_write_catch, io, &(struct timeval){ 2, 0 }); return /* void */; } bufio_gets(io, buf, sizeof buf, &main_gets_catch, io, &(struct timeval){ 2, 0 }); return /* void */; } /* main_write_catch() */ static void main_connect_catch(struct socket *s, enum socket_errno so_errno, void *arg) { static const char request[] = "GET / HTTP/1.0\n\n"; static int caught; struct bufio *io; enum bufio_errno bio_errno; if (caught) return /* void */; caught = 1; assert(so_errno == SOCKET_ESUCCESS); warnx("connected google.com"); assert(io = bufio_open(0, 0, &bio_errno)); bufio_set_source(io, socket_to_source(s)); bufio_set_sink(io, socket_to_sink(s)); bufio_write(io, request, sizeof request - 1, &main_write_catch, io, &(struct timeval){ 2, 0 }); return /* void */; } /* main_connect_catch() */ int main(void) { struct socket *s; struct socket_name so_name; enum socket_errno so_errno; #if USE_TLS struct tls_identity *tid; #endif #if _WIN32 WSADATA wsaData; #endif #if _WIN32 if (NO_ERROR != WSAStartup(MAKEWORD(2, 2), &wsaData)) err(EXIT_FAILURE, "WSAStartup"); #endif event_init(); lookup_init(0, 0, 0); tls_init(); #if USE_TLS #if _WIN32 socket_name_init_host(&so_name, "google.com", "443", LOOKUP_IN_A|LOOKUP_IN_AAAA, 0); #else socket_name_init_host(&so_name, "google.com", "https", LOOKUP_IN_A|LOOKUP_IN_AAAA, 0); #endif assert(tid = tls_identity_open(0, 0, 0)); #else #if _WIN32 socket_name_init_host(&so_name, "google.com", "80", LOOKUP_IN_A|LOOKUP_IN_AAAA, 0); #else socket_name_init_host(&so_name, "google.com", "http", LOOKUP_IN_A|LOOKUP_IN_AAAA, 0); #endif #endif if (0 == (s = socket_open(&so_name, 0, 0, 0, &so_errno))) err(EXIT_FAILURE, "socket_open"); #if USE_TLS socket_enable_tls(s, tid); #endif #if EARLY_IO main_connect_catch(s, 0, s); #endif socket_connect(s, &main_connect_catch, s, 0); event_loop(0); warnx("exiting"); return 0; } /* main() */