9cdb388013c0c5ac26ce1c28245185ce97b3dcd1
[yaz-moved-to-github.git] / util / yaz-url.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 Index Data
3  * See the file LICENSE for details.
4  */
5
6 #if HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <yaz/url.h>
14 #include <yaz/options.h>
15 #include <yaz/log.h>
16
17 static void usage(void)
18 {
19     printf("yaz-icu [options] url ..\n");
20     printf(" -H name:value       Set HTTP header (repeat if necessary)\n");
21     printf(" -m method           HTTP method\n");
22     printf(" -p file             POSTs file at following url\n");
23     printf(" -u user/password    Basic HTTP auth\n");
24     printf(" -x proxy            HTTP proxy\n");
25     exit(1);
26 }
27
28 static char *get_file(const char *fname, size_t *len)
29 {
30     char *buf = 0;
31     FILE *inf = fopen(fname, "rb");
32     if (!inf)
33     {
34         yaz_log(YLOG_FATAL|YLOG_ERRNO, "Could not open %s", fname);
35         exit(1);
36     }
37     if (fseek(inf, 0L, SEEK_END))
38     {
39         yaz_log(YLOG_FATAL|YLOG_ERRNO, "fseek of %s failed", fname);
40         exit(1);
41     }
42     *len = ftell(inf);
43     if (*len)  /* zero length not considered an error */
44     {
45         buf = xmalloc(*len);
46         fseek(inf, 0L, SEEK_SET);
47         fread(buf, 1, *len, inf);
48     }
49     fclose(inf);
50     return buf;
51 }
52
53 int main(int argc, char **argv)
54 {
55     int ret;
56     char *arg;
57     yaz_url_t p = yaz_url_create();
58     char *post_buf = 0;
59     size_t post_len = 0;
60     const char *method = "GET";
61     Z_HTTP_Response *http_response;
62     Z_HTTP_Header *http_headers = 0;
63     ODR odr = odr_createmem(ODR_ENCODE);
64     int exit_code = 0;
65     int no_urls = 0;
66
67     while ((ret = options("hH:m:p:u:x:", argv, argc, &arg))
68            != YAZ_OPTIONS_EOF)
69     {
70         switch (ret)
71         {
72         case 'h':
73             usage();
74             break;
75         case 'H':
76             if (!strchr(arg, ':'))
77             {
78                 yaz_log(YLOG_FATAL, "bad header option (missing :) %s\n", arg);
79                 exit_code = 1;
80             }
81             else
82             {
83                 char *cp = strchr(arg, ':');
84                 char *name = odr_malloc(odr, 1 + cp - arg);
85                 char *value = cp + 1;
86                 memcpy(name, arg, cp - arg);
87                 name[cp - arg] = '\0';
88                 while (*value == ' ') /* skip space after = */
89                     value++;
90                 z_HTTP_header_add(odr, &http_headers, name, value);
91             }
92             break;
93         case 'm':
94             method = arg;
95             break;
96         case 'p':
97             xfree(post_buf);
98             post_buf = get_file(arg, &post_len);
99             method = "POST";
100             break;
101         case 'u':
102             if (strchr(arg, '/'))
103             {
104                 char *cp = strchr(arg, '/');
105                 char *user = odr_malloc(odr, 1 + cp - arg);
106                 char *password = cp + 1;
107                 memcpy(user, arg, cp - arg);
108                 user[cp - arg] = '\0';
109                 z_HTTP_header_add_basic_auth(odr, &http_headers, user,
110                                              password);
111             }
112             else
113                 z_HTTP_header_add_basic_auth(odr, &http_headers, arg, 0);
114             break;
115         case 'x':
116             yaz_url_set_proxy(p, arg);
117             break;
118         case 0:
119             http_response = yaz_url_exec(p, arg, method, http_headers,
120                                          post_buf, post_len);
121             if (!http_response)
122                 exit_code = 1;
123             else
124             {
125                 fwrite(http_response->content_buf, 1,
126                        http_response->content_len, stdout);
127             }
128             no_urls++;
129             break;
130         default:
131             usage();
132         }
133     }
134     xfree(post_buf);
135     yaz_url_destroy(p);
136     odr_destroy(odr);
137     if (no_urls == 0)
138         usage();
139     exit(exit_code);
140 }
141
142 /*
143  * Local variables:
144  * c-basic-offset: 4
145  * c-file-style: "Stroustrup"
146  * indent-tabs-mode: nil
147  * End:
148  * vim: shiftwidth=4 tabstop=8 expandtab
149  */
150