Annotation of src/usr.bin/ftp/http.c, Revision 1.2
1.2 ! millert 1: /* $OpenBSD: http.c,v 1.1 1996/09/03 18:00:06 deraadt Exp $ */
1.1 deraadt 2:
3: /*
4: * Copyright (c) 1996 Theo de Raadt
5: * Copyright (c) 1996 Brian Mitchell
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
29:
30: #include <sys/types.h>
31: #include <sys/file.h>
32: #include <sys/socket.h>
33: #include <netinet/in.h>
34:
35: #include <ctype.h>
36: #include <err.h>
37: #include <netdb.h>
38: #include <pwd.h>
39: #include <signal.h>
40: #include <stdio.h>
41: #include <stdlib.h>
42: #include <string.h>
43: #include <unistd.h>
44:
45: /*
46: * This function lets you retrieve files from the WWW. It will accept
47: * any http:// url. It conects and retrieves the file, saving it in
48: * the current directory.
49: *
50: * Limitations:
51: * http://host does not work, nor http://host/ - you have to specifically
52: * specify the filename you want to transfer.
53: */
54: int
55: http_fetch(url)
56: char *url;
57: {
58: char *hostname, *filename, basename[MAXPATHLEN] = "/";
59: char buf[8192], *bufp, *req = NULL;
60: struct sockaddr_in addr;
61: struct hostent *he;
62: FILE *write_to;
63: char *s, *p;
64: int bytes, c, d;
65: int sock = -1, file = -1, ret = 1;
66:
67: s = url + strlen("http://");
68: p = strchr(s, '/');
69: if (p)
70: *p = '\0';
71: else
72: p = s + strlen(s);
73: if (p - s > MAXHOSTNAMELEN-1) {
74: warn("hostname too long");
75: return (1);
76: }
77: hostname = s;
78: filename = p + 1;
79:
80: p = strrchr(filename, '/');
81: if (p == NULL) {
82: if (strlen(s) > MAXPATHLEN-1) {
83: warn("filename too long");
84: return (1);
85: }
86: strcpy(basename, filename);
87: } else {
88: p++;
89: if (strlen(p) > MAXPATHLEN-1) {
90: warn("filename too long");
91: return (1);
92: }
93: strcpy(basename, p);
94: }
95: if (strlen(basename) == 0)
96: strcpy(basename, "index.html");
97:
98: req = (char *)malloc(sizeof("GET ") + strlen(filename) +3);
99: if (!req) {
100: warn("no memory");
101: return (1);
102: }
103: sprintf(req, "GET /%s\n", filename);
104:
105: he = gethostbyname(hostname);
106: if (!he) {
1.2 ! millert 107: herror("gethostbyname");
1.1 deraadt 108: goto die;
109: }
110:
111: sock = socket(AF_INET, SOCK_STREAM, 0);
112: if (sock == -1) {
113: perror("socket");
114: goto die;
115: }
116:
117: memset(&addr, 0, sizeof addr);
118: addr.sin_family = he->h_addrtype;
119: addr.sin_port = htons(80);
120: memcpy(&addr.sin_addr, he->h_addr, he->h_length);
121:
122: if (connect(sock, (struct sockaddr *)&addr, sizeof addr) == -1) {
123: perror("connect");
124: goto die;
125: }
126: printf("Connected to %s.\n", hostname);
127:
128: printf("Retrieving using: %s", req);
129: for (bufp = req, c = strlen(bufp); c > 0; c -= d, bufp += d) {
130: if ((d = write(sock, bufp, c)) <= 0)
131: break;
132: }
133: if (d == -1) {
134: perror("sending command");
135: goto die;
136: }
137:
138: file = open(basename, O_CREAT|O_WRONLY|O_TRUNC, 0666);
139: if (!file) {
140: perror("fopen");
141: goto die;
142: }
143:
144: bytes = 0;
145: while ((c = read(sock, buf, sizeof (buf))) > 0) {
146: bytes += c;
147: for (bufp = buf; c > 0; c -= d, bufp += d)
148: if ((d = write(file, bufp, c)) <= 0)
149: break;
150: }
151: if (d == -1) {
152: perror("failed to receive correctly");
153: goto die;
154: }
155: printf("Success, closing connection.\n");
156: ret = 0;
157: die:
158: if (sock != -1)
159: close(sock);
160: if (file != -1)
161: close(file);
162: if (req)
163: free(req);
164: return (ret);
165: }