1 /* urlget.c Copyright 2000 by Michael Temari All Rights Reserved */
2 /* 04/05/2000 Michael Temari <Michael@TemWare.Com> */
19 _PROTOTYPE(char *unesc
, (char *s
));
20 _PROTOTYPE(void encode64
, (char **pp
, char *s
));
21 _PROTOTYPE(char *auth
, (char *user
, char *pass
));
22 _PROTOTYPE(int skipit
, (char *buf
, int len
, int *skip
));
23 _PROTOTYPE(int httpget
, (char *host
, int port
, char *user
, char *pass
, char *path
, int headers
, int discard
, int post
));
24 _PROTOTYPE(void ftppasv
, (char *reply
));
25 _PROTOTYPE(int ftpreply
, (FILE *fpr
));
26 _PROTOTYPE(int ftpcmd
, (FILE *fpw
, FILE *fpr
, char *cmd
, char *arg
));
27 _PROTOTYPE(int ftpget
, (char *host
, int port
, char *user
, char *pass
, char *path
, int type
));
28 _PROTOTYPE(int tcpget
, (char *host
, int port
, char *user
, char *pass
, char *path
));
29 _PROTOTYPE(int main
, (int argc
, char *argv
[]));
32 unsigned int ftppport
;
42 _PROTOTYPE(int strncasecmp
, (const char *s1
, const char *s2
, size_t len
));
44 strncasecmp(s1
, s2
, len
)
53 } while (c1
= toupper(*s1
++), c2
= toupper(*s2
++), c1
== c2
&& (c1
& c2
))
56 return c1
< c2
? -1 : 1;
57 return c1
? 1 : (c2
? -1 : 0);
80 if(*p
>= '0' && *p
<= '9') c
= *p
++ - '0'; else
81 if(*p
>= 'a' && *p
<= 'f') c
= *p
++ - 'a' + 10; else
82 if(*p
>= 'A' && *p
<= 'F') c
= *p
++ - 'A' + 10; else
84 if(*p
>= '0' && *p
<= '9') c
= c
<< 4 | (*p
++ - '0'); else
85 if(*p
>= 'a' && *p
<= 'f') c
= c
<< 4 | (*p
++ - 'a') + 10; else
86 if(*p
>= 'A' && *p
<= 'F') c
= c
<< 4 | (*p
++ - 'A') + 10; else
102 static char e64
[64] = {
103 'A','B','C','D','E','F','G','H','I','J','K','L','M',
104 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
105 'a','b','c','d','e','f','g','h','i','j','k','l','m',
106 'n','o','p','q','r','s','t','u','v','w','x','y','z',
107 '0','1','2','3','4','5','6','7','8','9','+','/' };
111 for(i
=0; i
< len
; i
+= 3) {
115 *p
++ = e64
[ c
[0] >> 2];
116 *p
++ = e64
[((c
[0] << 4) & 0x30) | ((c
[1] >> 4) & 0x0f)];
117 *p
++ = e64
[((c
[1] << 2) & 0x3c) | ((c
[2] >> 6) & 0x03)];
118 *p
++ = e64
[ c
[2] & 0x3f];
132 char *auth(user
, pass
)
142 sprintf(up
, "%s:%s", user
, pass
);
148 int skipit(buf
, len
, skip
)
160 if((crlf
== 0 || crlf
== 2) && *p
== '\r')
163 if((crlf
== 1 || crlf
== 3) && *p
== '\n')
171 if(crlf
== 4 || lf
== 2) {
181 int httpget(host
, port
, user
, pass
, path
, headers
, discard
, post
)
202 fd
= connect(host
, port
);
204 fprintf(stderr
, "httpget: Could not connect to %s:%d\n", host
, port
);
209 qs
= strrchr(path
, '?');
210 if(qs
!= (char *)NULL
) {
218 write(fd
, "POST ", 5);
220 write(fd
, "GET ", 4);
221 write(fd
, path
, strlen(path
));
222 write(fd
, " HTTP/1.0\r\n", 11);
223 write(fd
, "User-Agent: urlget\r\n", 20);
224 write(fd
, "Connection: Close\r\n", 19);
226 write(fd
, "Authorization: ", 15);
227 a
= auth(user
, pass
);
228 write(fd
, a
, strlen(a
));
229 write(fd
, "\r\n", 2);
231 if(post
&& len
> 0) {
232 sprintf(buffer
, "Content-Length: %u\r\n", len
);
233 write(fd
, buffer
, strlen(buffer
));
235 write(fd
, "Host: ", 6);
236 write(fd
, host
, strlen(host
));
237 write(fd
, "\r\n", 2);
238 write(fd
, "\r\n", 2);
243 while((s
= read(fd
, buffer
, sizeof(buffer
)-1)) > 0) {
246 static int firstline
= 1;
248 static char linebuf
[1000];
251 if(s
>= sizeof(linebuf
)-l
)
252 c
= sizeof(linebuf
)-1-l
;
254 memcpy(linebuf
+l
, buffer
, c
);
256 if(strchr(buffer
, '\n') || strchr(buffer
, '\r'))
258 if(sscanf(linebuf
, "HTTP/%d.%d %d ", &v1
, &v2
, &e
) == 3
260 fprintf(stderr
, "HTTP error %d\n", e
);
265 s2
= skipit(buffer
, s
, &skip
);
267 write(1, buffer
, s
- s2
);
271 if(write(1, &buffer
[s
- s2
], s2
) != s2
) {
277 fprintf(stderr
, "httpget: Read error\n");
296 while(*p
&& *p
!= '(') p
++;
304 if(p
== (char *)NULL
) return;
307 sprintf(ftpphost
, "%d.%d.%d.%d", n
[0], n
[1], n
[2], n
[3]);
308 ftppport
= n
[4] * 256 + n
[5];
315 static char reply
[256];
323 if(fgets(reply
, sizeof(reply
), fpr
) == (char *)NULL
)
327 strncpy(code
, reply
, 3);
330 } while(strncmp(reply
, code
, 3) || reply
[3] == '-');
332 } while(s
< 200 && s
!= 125 && s
!= 150);
333 if(s
== 227) ftppasv(reply
);
337 int ftpcmd(fpw
, fpr
, cmd
, arg
)
343 fprintf(fpw
, "%s%s%s\r\n", cmd
, *arg
? " " : "", arg
);
345 return(ftpreply(fpr
));
348 int ftpget(host
, port
, user
, pass
, path
, type
)
372 fd
= connect(host
, port
);
374 fprintf(stderr
, "ftpget: Could not connect to %s:%d\n", host
, port
);
377 fpr
= fdopen(fd
, "r");
378 fpw
= fdopen(fd
, "w");
381 if(s
/ 100 != 2) goto error
;
382 s
= ftpcmd(fpw
, fpr
, "USER", *user
? user
: "ftp");
384 s
= ftpcmd(fpw
, fpr
, "PASS", *pass
? pass
: "urlget@");
386 if(s
/ 100 != 2) goto error
;
390 while((p2
= strchr(p
, '/')) != (char *)NULL
) {
392 s
= ftpcmd(fpw
, fpr
, "CWD", unesc(p
));
395 sprintf(typec
, "%c", type
== 'd' ? 'A' : type
);
396 s
= ftpcmd(fpw
, fpr
, "TYPE", typec
);
397 if(s
/ 100 != 2) goto error
;
398 s
= ftpcmd(fpw
, fpr
, "PASV", "");
399 if(s
!= 227) goto error
;
400 fd2
= connect(ftpphost
, ftppport
);
401 if(fd2
< 0) goto error
;
402 s
= ftpcmd(fpw
, fpr
, type
== 'd' ? "NLST" : "RETR", unesc(p
));
403 if(s
/ 100 != 1) goto error
;
404 while((s
= read(fd2
, buffer
, sizeof(buffer
))) > 0) {
405 s2
= write(1, buffer
, s
);
408 if(s2
!= s
&& s
!= 0) s
= -1;
412 if(s
/ 100 == 2) s
= 0;
415 (void) ftpcmd(fpw
, fpr
, "QUIT", "");
421 return(s
== 0 ? 0 : -1);
424 int tcpget(host
, port
, user
, pass
, path
)
436 fprintf(stderr
, "tcpget: No port specified\n");
440 fd
= connect(host
, port
);
442 fprintf(stderr
, "httpget: Could not connect to %s:%d\n", host
, port
);
448 write(fd
, path
, strlen(path
));
450 while((s
= read(fd
, buffer
, sizeof(buffer
))) > 0) {
451 s2
= write(1, buffer
, s
);
479 prog
= strrchr(*argv
, '/');
480 if(prog
== (char *)NULL
)
485 while(argc
&& argv
[0][0] == '-') {
486 char *opt
= *argv
++ + 1;
489 if (opt
[0] == '-' && opt
[1] == 0) break;
491 while (*opt
) switch (*opt
++) {
492 case 'h': opt_h
= -1; break;
493 case 'd': opt_d
= -1; break;
494 case 'p': opt_p
= -1; break;
495 default: argc
= 0; break;
499 if(strcmp(prog
, "ftpget") == 0) {
500 if(argc
< 2 || argc
> 4) {
501 fprintf(stderr
, "Usage: %s host path [user [pass]]\n", prog
);
504 strncpy(host
, *argv
++, sizeof(host
));
508 strncpy(user
, *argv
++, sizeof(user
));
513 strncpy(pass
, *argv
++, sizeof(pass
));
517 s
= ftpget(host
, port
, user
, pass
, path
, 'i');
520 if(strcmp(prog
, "httpget") == 0) {
522 fprintf(stderr
, "Usage: %s [-h] [-d] [-p] host path\n", prog
);
525 strncpy(host
, *argv
++, sizeof(host
));
528 s
= httpget(host
, port
, user
, path
, path
, opt_h
, opt_d
, opt_p
);
534 fprintf(stderr
, "Usage: %s [-h] [-p] url\n", prog
);
541 if(strncasecmp(url
, "http://", 7) == 0) {
542 scheme
= SCHEME_HTTP
;
545 if(strncasecmp(url
, "ftp://", 6) == 0) {
549 if(strncasecmp(url
, "tcp://", 6) == 0) {
553 fprintf(stderr
, "%s: I do not handle this scheme\n", prog
);
563 while(*p
&& *p
!= '/') p
++;
568 at
= strchr(ps
, '@');
569 if(at
!= (char *)NULL
) {
572 while(*p
&& *p
!= ':') p
++;
582 while(*p
&& *p
!= '/' && *p
!= ':') p
++;
583 strncpy(host
, ps
, p
- ps
);
588 while(*p
&& *p
!= '/')
589 port
= port
* 10 + (*p
++ - '0');
595 if(scheme
== SCHEME_FTP
) {
597 while(*p
&& *p
!= ';') p
++;
600 if(strncasecmp(p
, "type=", 5) == 0) {
608 fprintf(stderr
, "Host: %s\n", host
);
609 fprintf(stderr
, "Port: %d\n", port
);
610 fprintf(stderr
, "User: %s\n", user
);
611 fprintf(stderr
, "Pass: %s\n", pass
);
612 fprintf(stderr
, "Path: %s\n", path
);
613 fprintf(stderr
, "Type: %c\n", type
);
618 s
= httpget(host
, port
, user
, pass
, path
, opt_h
, opt_d
, opt_p
);
621 s
= ftpget(host
, port
, user
, pass
, path
, type
);
624 s
= tcpget(host
, port
, user
, pass
, path
);