From: Alan Cox Date: Fri, 25 Mar 2016 17:40:02 +0000 (+0000) Subject: socktest: turns into a tool for fetching files via http X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=145f26df486da5ac7f34c17eaa067b31c8e94e30;p=FUZIX.git socktest: turns into a tool for fetching files via http Handy for debugging --- diff --git a/Applications/util/socktest.c b/Applications/util/socktest.c index d2ad1a40..121aa0c1 100644 --- a/Applications/util/socktest.c +++ b/Applications/util/socktest.c @@ -1,69 +1,163 @@ #include #include #include +#include +#include +#include +#include +#include #define AF_INET 1 #define SOCK_STREAM 3 #define IPPROTO_TCP 6 -struct in_addr { - uint32_t s_addr; -}; +struct sockaddr_in addr; +struct sockaddr_in laddr; -struct sockaddr_in { - uint16_t sin_family; - uint16_t sin_port; - struct in_addr sin_addr; - uint8_t sin_zero[8]; -}; - -struct sockaddr_in addr = { - AF_INET, - 0xEA1D, - { 0xF400A8C0 }, -}; - -struct sockaddr_in laddr = { - AF_INET, - 0x0A0A, - { 0x010000C0 }, -}; +static int writes(int fd, const char *p) +{ + return write(fd, p, strlen(p)); +} int main(int argc, char *argv[]) { - int fd; - int r; - char buf[5]; - - fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (fd < 0) - perror("af_inet sock_stream pf_tcp"); - close(fd); - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - perror("af_inet sock_stream 0"); - exit(1); - } - if (bind(fd, (struct sockaddr *)&laddr, sizeof(addr)) < 0) { - perror("bind"); - exit(1); - } - - if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("connect"); - exit(1); - } - if (write(fd, "Hello", 5) == -1) { - perror("write"); - exit(1); - } - if ((r = read(fd, buf, 5)) < 0) { - perror("read"); - exit(1); - } - printf("Read %d bytes\n", r); - write(1, buf, r); - close(fd); - return 0; + int fd, fd2; + int r; + unsigned long t = 0; + char buf[512]; + static char line[81]; + char *lp; + char *p; + int state = 0; + + if (argc != 2) { + writes(2, argv[0]); + write(2, ": url\n", 6); + exit(1); + } + + if (strncmp(argv[1], "http://", 7)) { + writes(2, argv[0]); + writes(2, ": only http:// supported.\n"); + exit(1); + } + + p = strchr(argv[1] + 7, '/'); + if (p == NULL) { + writes(2, argv[0]); + writes(2, ": no path element.\n"); + exit(1); + } + *p++ = 0; + lp = strchr(argv[1] + 7, ':'); + if (lp == NULL) + addr.sin_port = htons(80); + else { + *lp = 0; + addr.sin_port = htons(atoi(lp + 1)); + } + + if (inet_pton(AF_INET, argv[1] + 7, &addr.sin_addr.s_addr) <= 0) { + writes(2, argv[1] + 7); + writes(2, ": unknown address.\n"); + exit(1); + } + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) { + perror("af_inet sock_stream 0"); + exit(1); + } + laddr.sin_family = AF_INET; + laddr.sin_addr.s_addr = htonl(INADDR_ANY); + laddr.sin_port = htons(8000); + + if (bind(fd, (struct sockaddr *) &laddr, sizeof(addr)) < 0) { + perror("bind"); + exit(1); + } + + addr.sin_family = AF_INET; + printf("%lx\n", addr.sin_addr.s_addr); + + if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("connect"); + exit(1); + } + if (writes(fd, "GET /test HTTP/1.1\r\nHost: test.test\r\n\r\n") == + -1) { + perror("write"); + exit(1); + } + + lp = line; + + while ((r = read(fd, buf, 512)) > 0) { + if (r < 0) { + perror("read"); + exit(1); + } + p = buf; + switch (state) { + case 0: + case 1: + while (p < buf + r) { + if (*p != '\n') { + if (*p != '\r' && lp != line + 80) + *lp++ = *p; + p++; + continue; + } + /* We have a line */ + if (lp != line) { + *lp = 0; + write(1, "|", 1); + writes(1, line); + write(1, "\n", 1); + if (state == 0) { + lp = strchr(line, ' '); + if (lp == NULL + || atoi(lp + 1) != 200) + exit(1); + } + state = 1; + lp = line; + p++; + continue; + } else { + p++; + /* nl/nl end of headers - begin xfer */ + fd2 = + open("output", + O_WRONLY | O_TRUNC | + O_CREAT, 0700); + if (fd2 == -1) { + perror("output"); + exit(1); + } + r -= (p - buf); + if (r && write(fd2, p, r) != r) { + perror("write"); + exit(1); + } + state = 2; + break; + } + } + break; + case 2: + if (write(fd2, buf, r) != r) { + perror("write"); + exit(1); + } + t += r; + printf("%ld\r", t); + fflush(stdout); + break; + } + } + printf("\nRead %ld bytes\n", t); + close(fd); + close(fd2); + return 0; }