diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | config.mk | 6 | ||||
-rw-r--r-- | getgbook.1 | 31 | ||||
-rw-r--r-- | util.c | 58 | ||||
-rw-r--r-- | util.h | 2 |
6 files changed, 82 insertions, 24 deletions
@@ -9,6 +9,7 @@ SCRIPTS = makebookpdf.sh DOC = README COPYING LEGAL BIN = $(SRC:.c=) +MAN = $(SRC:.c=.1) OBJ = $(SRC:.c=.o) $(LIB) all: $(BIN) @@ -30,10 +31,14 @@ util.a: $(LIB) @ranlib $@ install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(SCRIPTS) $(DESTDIR)$(PREFIX)/bin + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + for f in $(MAN); do sed "s/VERSION/$(VERSION)/g" < $$f > $(DESTDIR)$(MANPREFIX)/man1/$$f; done uninstall: cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) $(SCRIPTS) + cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) clean: rm -f -- $(BIN) $(OBJ) util.a index.html @@ -4,8 +4,6 @@ getabook getbnbook -use "" rather than "\0" in headermax - # other todos use wide string functions when dealing with stuff returned over http; it's known utf8 @@ -22,8 +20,6 @@ add https support to get write some little tests -create man pages - have websummary.sh print the date of release, e.g. getxbook 0.3 (sig) (2011-08-02) @@ -3,6 +3,7 @@ VERSION = 0.3 # paths PREFIX = /usr/local +MANPREFIX = $(PREFIX)/share/man CFLAGS = -ansi -pedantic -Wall -Wextra -Werror -g -D_POSIX_C_SOURCE=200112L \ -DVERSION=\"$(VERSION)\" @@ -15,4 +16,9 @@ CFLAGS = -ansi -pedantic -Wall -Wextra -Werror -g -D_POSIX_C_SOURCE=200112L \ CC = cc LDFLAGS = +# mingw +#CC = gcc +#CFLAGS = -ansi -Wall -DVERSION=\"$(VERSION)\" -DWINVER=0x0501 +#LDFLAGS = -lws2_32 + LD = $(CC) diff --git a/getgbook.1 b/getgbook.1 new file mode 100644 index 0000000..9440030 --- /dev/null +++ b/getgbook.1 @@ -0,0 +1,31 @@ +.\" See COPYING file for copyright, license and warranty details. +.TH GETGBOOK 1 getgbook\-VERSION +.SH NAME +getgbook \- downloads books from google books +.SH SYNOPSIS +.B getgbook +.RB [-c|-n] +.RB bookid +.SH DESCRIPTION +getgbook downloads pages of books from google books' "book +preview" service. Some pages are not available, in which +case they will be skipped. +.SH OPTIONS +.TP +.B \-c +Downloads from page codes given on stdin (one code per line). +Google books page codes are on of the following, followed by +a number: +.RB PP +.RB PR +.RB PA +.RB PT +.TP +.B \-n +Downloads from page numbers given on stdin (one number per +line). +.TP +.B bookid +is the unique ID Google assigns to each book. It is 12 +characters long. It can be found by looking for the 'id=' +part of the URL of its Google Books page. @@ -3,10 +3,15 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include "util.h" +#ifndef WINVER #include <netdb.h> #include <netinet/in.h> #include <sys/socket.h> -#include "util.h" +#else +#include <winsock2.h> +#include <ws2tcpip.h> +#endif /* plundered from suckless' sic */ int dial(char *host, char *port) { @@ -14,6 +19,14 @@ int dial(char *host, char *port) { int srv; struct addrinfo *res, *r; + #ifdef WINVER + WSADATA w; + if(WSAStartup(MAKEWORD(2,2), &w)!= 0) { + fprintf(stderr, "error: failed to start winsock\n"); + return -1; + } + #endif + memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -39,35 +52,42 @@ int dial(char *host, char *port) { int get(char *host, char *path, char *sendcookie, char *savecookie, char **buf) { size_t l, res; int fd, i, p; - char h[HEADERMAX] = "\0"; + char h[HDRMAX] = ""; char c[COOKIEMAX] = ""; + char t[BUFSIZ]; + char *t2; char m[256]; - FILE *srv; if((fd = dial(host, "80")) == -1) return 0; - srv = fdopen(fd, "r+"); - if(sendcookie) + if(sendcookie && sendcookie[0]) snprintf(c, COOKIEMAX, "\r\nCookie: %s", sendcookie); - fprintf(srv, "GET %s HTTP/1.0\r\nUser-Agent: getxbook-"VERSION \ - " (not mozilla)\r\nHost: %s%s\r\n\r\n", path, host, c); - fflush(srv); + snprintf(h, HDRMAX, "GET %s HTTP/1.0\r\nUser-Agent: getxbook-"VERSION \ + " (not mozilla)\r\nHost: %s%s\r\n\r\n", path, host, c); + if(!send(fd, h, HDRMAX, 0)) return 0; + *buf = NULL; + l = 0; snprintf(m, 256, "Set-Cookie: %%%ds;", COOKIEMAX-1); - - while(h[0] != '\r') { - if(!fgets(h, HEADERMAX, srv)) return 0; - if(sscanf(h, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) + while((res = recv(fd, t, BUFSIZ, 0)) > 0) { + if(sscanf(t, "HTTP/%d.%d %d", &i, &i, &p) == 3 && p != 200) return 0; - if(savecookie != NULL && sscanf(h, m, c)) + if(savecookie != NULL && + (t2 = strstr(t, "Set-Cookie: ")) != NULL && sscanf(t2, m, c)) strncat(savecookie, c, COOKIEMAX); + if((t2 = strstr(t, "\r\n\r\n")) != NULL) { + t2+=4; + l = res - (t2 - t); + *buf = malloc(sizeof(char *) * l); + memcpy(*buf, t2, l); + break; + } } - *buf = malloc(sizeof(char *) * BUFSIZ); - for(l=0; (res = fread(*buf+l, 1, BUFSIZ, srv)) > 0; l+=res) + *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); + for(; (res = recv(fd, *buf+l, BUFSIZ, 0)) > 0; l+=res) *buf = realloc(*buf, sizeof(char *) * (l+BUFSIZ)); - fclose(srv); return l; } @@ -80,13 +100,13 @@ int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *s fprintf(stderr, "Could not download %s\n", url); return 1; } - if((f = fopen(savepath, "w")) == NULL) { + if((f = fopen(savepath, "wb")) == NULL) { fprintf(stderr, "Could not create file %s\n", savepath); free(buf); return 1; } - for(i=0; i < l; i+=512) - if(!fwrite(buf+i, l-i > 512 ? 512 : l-i, 1, f)) { + for(i=0; i < l; i+=BUFSIZ) + if(!fwrite(buf+i, l-i > BUFSIZ ? BUFSIZ : l-i, 1, f)) { fprintf(stderr, "Error writing file %s\n", savepath); free(buf); fclose(f); return 1; } @@ -1,6 +1,6 @@ /* See COPYING file for copyright and license details. */ #define COOKIEMAX 1024 -#define HEADERMAX 1024 +#define HDRMAX 1024 int dial(char *host, char *port); int get(char *host, char *path, char *sendcookie, char *savecookie, char **buf); int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *savepath); |