summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--TODO4
-rw-r--r--config.mk6
-rw-r--r--getgbook.131
-rw-r--r--util.c58
-rw-r--r--util.h2
6 files changed, 82 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index d7e947c..f09cdb8 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/TODO b/TODO
index 6b08e9f..eb8b65d 100644
--- a/TODO
+++ b/TODO
@@ -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)
diff --git a/config.mk b/config.mk
index 2050380..6856404 100644
--- a/config.mk
+++ b/config.mk
@@ -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.
diff --git a/util.c b/util.c
index 4d2b04c..04e80b4 100644
--- a/util.c
+++ b/util.c
@@ -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;
}
diff --git a/util.h b/util.h
index 2e852ab..1a82a80 100644
--- a/util.h
+++ b/util.h
@@ -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);