Really sorry the subject line got mangled. -Girish
On Wed, Nov 16, 2011 at 7:38 AM, Girish Venkatachalam <[email protected]> wrote: > Dear boys and girls, > > Here we have a cool C program to download from the command line. > > It is self contained and does not take care of URL handling and will > fail in some > cases but I bet it will work in nearly all of the cases. > > Now the code is here: > > $ cat htdl.c > #include <stdio.h> > #include <unistd.h> > #include <netinet/in.h> > #include <arpa/inet.h> > #include <sys/socket.h> > #include <string.h> > #include <stdlib.h> > #include <fcntl.h> > #include <netdb.h> > > #define HTTP_GET_CMD "GET /%s HTTP 1.1\r\n\r\n" > > int > dl(char *url) > { > int c, ret = -1, fd = -1; > int bytes, off; > struct hostent *h; > struct sockaddr_in s; > char *p, *p2, host[1024], ip[40], outf[1024]; > char cmd[1024], buf[8192], path[1024]; > > c = socket(AF_INET, SOCK_STREAM, 0); > if(c < 0) { > perror("socket"); > } > > p = strstr(url, "//"); > p += 2; > p2 = strchr(p, '/'); > strlcpy(host, p, p2 - p + 1); > strlcpy(path, p2 + 1, sizeof(path)); > > printf("Performing DNS Lookup for the host [%s]...\n", host); > h = gethostbyname(host); > if(h == NULL) { > printf("Lookup failed, are you connected to Internet?\n"); > exit(128); > } > strlcpy(ip, inet_ntoa(*(struct in_addr *)h->h_addr_list[0]), > sizeof(ip)); > s.sin_port = htons(80); > s.sin_family = PF_INET; > s.sin_addr.s_addr = inet_addr(ip); > printf("Connecting to %s\n", ip); > ret = connect(c, (struct sockaddr *)&s, sizeof(s)); > if(ret < 0) { > perror("connect"); > printf("Could not connect...exiting\n"); > exit(128); > } > printf("Connected!\n"); > > p = strrchr(p, '/'); > strlcpy(outf, p + 1, sizeof(outf)); > /* Now we are connected, now we can download and write to a file > * , so let us open the file first > */ > fd = open(outf, O_WRONLY | O_TRUNC | O_CREAT, 0644); > if(fd == -1) { > printf("Could not open downloaded file into current dir," > "check permissions\n"); > perror("open"); > exit(128); > } > > /* Let us send the command to get the file and figure out how > * the server responds */ > snprintf(cmd, sizeof(cmd), HTTP_GET_CMD, path); > ret = send(c, cmd, strlen(cmd), 0); > if(ret < 0) { > perror("send"); > exit(128); > } > > printf("Sent command [%s] to get the file using HTTP GET\n", cmd); > > bytes = read(c, buf, sizeof(buf)); > p = strstr(buf, "\r\n\r\n"); > off = (p + 4) - buf; > write(fd, buf + off, bytes - off); > > while( (bytes = read(c, buf, sizeof(buf))) ) { > write(fd, buf, bytes); > printf("Wrote %d bytes to file\n", bytes); > } > close(c); > close(fd); > printf("Wrote %s to file\n", outf); > return 0; > > } > > int > main(int argc, char **argv) > { > if(argc < 2) { > printf("Please give the URL to download!\n"); > exit(128); > } > dl(argv[1]); > return 0; > } > > > You can look at the code with vim colors: > ftp://tulip.pye.org/htdl.c.html > > Or download this from there: > ftp://tulip.pye.org/htdl.c > > Once you download it on your Linux box,compile it like this: > > $ make htdl > > Then it will create an exe by name htdl > > $ ./htdl http://ftp.openssl.org/source/openssl-0.9.6.tar.gz > > Or you can give any URL that uses HTTP. > > It will download the binary file(or even text file) into the current > directory under > the file name part of the URL(the last part after the final /) > > Now do you want me to explain the code? > > If you want it I will send a separate mail. > > But you have work to do now. Play with it and see how it works. > > -Girish > > -- > G3 Tech > Networking appliance company > web: http://g3tech.in mail: [email protected] > -- G3 Tech Networking appliance company web: http://g3tech.in mail: [email protected] _______________________________________________ ILUGC Mailing List: http://www.ae.iitm.ac.in/mailman/listinfo/ilugc
