summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c92
1 files changed, 72 insertions, 20 deletions
diff --git a/util.c b/util.c
index 238dc8e..eaee2d5 100644
--- a/util.c
+++ b/util.c
@@ -14,17 +14,20 @@
#endif
/* plundered from suckless' sic */
-int dial(char *host, char *port)
+conn *dial(char *host, char *port, int ssl)
{
static struct addrinfo hints;
int srv;
struct addrinfo *res, *r;
+ conn *c;
+ c = malloc(sizeof(conn));
+ c->fd = -1;
#ifdef WINVER
WSADATA w;
if(WSAStartup(MAKEWORD(2,2), &w)!= 0) {
fprintf(stderr, "error: failed to start winsock\n");
- return -1;
+ return c;
}
#endif
@@ -33,7 +36,7 @@ int dial(char *host, char *port)
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo(host, port, &hints, &res) != 0) {
fprintf(stderr, "error: cannot resolve hostname %s\n", host);
- return -1;
+ return c;
}
for(r = res; r; r = r->ai_next) {
if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1)
@@ -45,31 +48,80 @@ int dial(char *host, char *port)
freeaddrinfo(res);
if(!r) {
fprintf(stderr, "error: cannot connect to host %s\n", host);
- return -1;
+ return c;
}
- return srv;
+
+ c->fd = srv;
+ c->sslcontext = NULL;
+ c->sslhandle = NULL;
+
+ if(ssl) {
+ SSL_load_error_strings();
+ SSL_library_init();
+ if((c->sslcontext = SSL_CTX_new(SSLv23_client_method())) == NULL) {
+ /*if((c->sslcontext = SSL_CTX_new(TLS_client_method())) == NULL) {*/
+ ERR_print_errors_fp(stderr);
+ }
+ if((c->sslhandle = SSL_new(c->sslcontext)) == NULL) {
+ ERR_print_errors_fp(stderr);
+ }
+ if(SSL_set_fd(c->sslhandle, c->fd) != 1) {
+ ERR_print_errors_fp(stderr);
+ }
+ if(SSL_connect(c->sslhandle) != 1) {
+ ERR_print_errors_fp(stderr);
+ }
+
+ }
+ return c;
}
-int request(char *host, char *request, char *savecookie, char **body, int istext)
+int request(char *host, int ssl, char *request, char *savecookie, char **body, int istext)
{
size_t l, res;
- int fd, i, p;
+ int i, p;
char m[256];
- char c[COOKIEMAX] = "";
+ char cookie[COOKIEMAX] = "";
+ char port[4];
char *headpos;
size_t headsize, bodysize;
char headline[BUFSIZ] = "";
char *buf, *cur, *pos;
+ conn *c;
- if((fd = dial(host, "80")) == -1) return 0;
+ if(ssl) {
+ strcpy(port, "443");
+ } else {
+ strcpy(port, "80");
+ }
+ c = dial(host, port, ssl);
+ if(c->fd == -1) {
+ return 0;
+ }
- if(!send(fd, request, strlen(request), 0)) return 0;
+ if(ssl) {
+ if(!SSL_write(c->sslhandle, request, strlen(request))) {
+ ERR_print_errors_fp(stderr);
+ return 0;
+ }
+ } else {
+ if(!write(c->fd, request, strlen(request))) {
+ return 0;
+ }
+ }
/* download everything into buf */
l = 0;
buf = malloc(sizeof(char *) * BUFSIZ);
- for(; buf != NULL && (res = recv(fd, buf+l, BUFSIZ, 0)) > 0; l+=res)
- buf = realloc(buf, sizeof(char *) * (l+BUFSIZ));
+ /* TODO: rewrite this so it's clear that only the read call differs, e.g. with
+ * macros as ii does it, or maybe as a function pointer or something */
+ if(ssl) {
+ for(; buf != NULL && (res = SSL_read(c->sslhandle, buf+l, BUFSIZ)) > 0; l+=res)
+ buf = realloc(buf, sizeof(char *) * (l+BUFSIZ));
+ } else {
+ for(; buf != NULL && (res = read(c->fd, buf+l, BUFSIZ)) > 0; l+=res)
+ buf = realloc(buf, sizeof(char *) * (l+BUFSIZ));
+ }
/* strstr to find end of header */
if((headpos = strstr(buf, "\r\n\r\n")) == NULL) {
@@ -109,8 +161,8 @@ int request(char *host, char *request, char *savecookie, char **body, int istext
return 0;
}
- if(savecookie != NULL && sscanf(headline, m, c)) {
- strncat(savecookie, c, COOKIEMAX - strlen(savecookie) - 1);
+ if(savecookie != NULL && sscanf(headline, m, cookie)) {
+ strncat(savecookie, cookie, COOKIEMAX - strlen(savecookie) - 1);
}
}
@@ -119,7 +171,7 @@ int request(char *host, char *request, char *savecookie, char **body, int istext
return l;
}
-int get(char *host, char *path, char *sendcookie, char *savecookie, char **body, int istext)
+int get(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char **body, int istext)
{
char h[BUFSIZ] = "";
char c[COOKIEMAX] = "";
@@ -129,10 +181,10 @@ int get(char *host, char *path, char *sendcookie, char *savecookie, char **body,
snprintf(h, BUFSIZ, "GET %s HTTP/1.0\r\nUser-Agent: getxbook-"VERSION \
" (not mozilla)\r\nHost: %s%s\r\n\r\n", path, host, c);
- return request(host, h, savecookie, body, istext);
+ return request(host, ssl, h, savecookie, body, istext);
}
-int post(char *host, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext)
+int post(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext)
{
char h[BUFSIZ] = "";
char c[COOKIEMAX] = "";
@@ -145,16 +197,16 @@ int post(char *host, char *path, char *sendcookie, char *savecookie, char *data,
"Host: %s%s\r\n\r\n%s\r\n",
path, (int)strlen(data), host, c, data);
- return request(host, h, savecookie, body, istext);
+ return request(host, ssl, h, savecookie, body, istext);
}
-int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *savepath, int istext)
+int gettofile(char *host, int ssl, char *url, char *sendcookie, char *savecookie, char *savepath, int istext)
{
char *buf = 0;
FILE *f;
size_t i, l;
- if(!(l = get(host, url, sendcookie, savecookie, &buf, istext))) {
+ if(!(l = get(host, ssl, url, sendcookie, savecookie, &buf, istext))) {
fprintf(stderr, "Could not download %s\n", url);
return 1;
}