Merge branch 'master' into sru_2_0
[yaz-moved-to-github.git] / util / yaz-url.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 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       Sets HTTP header (repeat if necessary)\n");
21     printf(" -m method           Sets HTTP method\n");
22     printf(" -O fname            Writes HTTP content to file\n");
23     printf(" -p fname            POSTs file at following url\n");
24     printf(" -R num              Set maximum number of HTTP redirects\n");
25     printf(" -u user/password    Sets Basic HTTP auth\n");
26     printf(" -x proxy            Sets HTTP proxy\n");
27     exit(1);
28 }
29
30 static char *get_file(const char *fname, size_t *len)
31 {
32     char *buf = 0;
33     FILE *inf = fopen(fname, "rb");
34     if (!inf)
35     {
36         yaz_log(YLOG_FATAL|YLOG_ERRNO, "Could not open %s", fname);
37         exit(1);
38     }
39     if (fseek(inf, 0L, SEEK_END))
40     {
41         yaz_log(YLOG_FATAL|YLOG_ERRNO, "fseek of %s failed", fname);
42         exit(1);
43     }
44     *len = ftell(inf);
45     if (*len)  /* zero length not considered an error */
46     {
47         size_t r;
48         buf = xmalloc(*len);
49         fseek(inf, 0L, SEEK_SET);
50         r = fread(buf, 1, *len, inf);
51         if (r != *len)
52         {
53             yaz_log(YLOG_FATAL|YLOG_ERRNO, "short fread of %s", fname);
54             exit(1);
55         }
56     }
57     fclose(inf);
58     return buf;
59 }
60
61 int main(int argc, char **argv)
62 {
63     int ret;
64     char *arg;
65     yaz_url_t p = yaz_url_create();
66     char *post_buf = 0;
67     size_t post_len = 0;
68     const char *method = "GET";
69     Z_HTTP_Response *http_response;
70     Z_HTTP_Header *http_headers = 0;
71     ODR odr = odr_createmem(ODR_ENCODE);
72     int exit_code = 0;
73     int no_urls = 0;
74     const char *outfname = 0;
75
76     while ((ret = options("h{help}H:m:O:p:R{max-redirs}:u:x:", argv, argc, &arg))
77            != YAZ_OPTIONS_EOF)
78     {
79         switch (ret)
80         {
81         case 'h':
82             usage();
83             break;
84         case 'H':
85             if (!strchr(arg, ':'))
86             {
87                 yaz_log(YLOG_FATAL, "bad header option (missing :) %s\n", arg);
88                 exit_code = 1;
89             }
90             else
91             {
92                 char *cp = strchr(arg, ':');
93                 char *name = odr_malloc(odr, 1 + cp - arg);
94                 char *value = cp + 1;
95                 memcpy(name, arg, cp - arg);
96                 name[cp - arg] = '\0';
97                 while (*value == ' ') /* skip space after = */
98                     value++;
99                 z_HTTP_header_add(odr, &http_headers, name, value);
100             }
101             break;
102         case 'm':
103             method = arg;
104             break;
105         case 'O':
106             outfname = arg;
107             break;
108         case 'p':
109             xfree(post_buf);
110             post_buf = get_file(arg, &post_len);
111             method = "POST";
112             break;
113         case 'R':
114             yaz_url_set_max_redirects(p, atoi(arg));
115             break;
116         case 'u':
117             if (strchr(arg, '/'))
118             {
119                 char *cp = strchr(arg, '/');
120                 char *user = odr_malloc(odr, 1 + cp - arg);
121                 char *password = cp + 1;
122                 memcpy(user, arg, cp - arg);
123                 user[cp - arg] = '\0';
124                 z_HTTP_header_add_basic_auth(odr, &http_headers, user,
125                                              password);
126             }
127             else
128                 z_HTTP_header_add_basic_auth(odr, &http_headers, arg, 0);
129             break;
130         case 'x':
131             yaz_url_set_proxy(p, arg);
132             break;
133         case 0:
134             http_response = yaz_url_exec(p, arg, method, http_headers,
135                                          post_buf, post_len);
136             if (!http_response)
137                 exit_code = 1;
138             else
139             {
140                 FILE *outf = stdout;
141                 if (outfname)
142                 {
143                     outf = fopen(outfname, "w");
144                     if (!outf)
145                     {
146                         yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", outfname);
147                         exit(1);
148                     }
149                 }
150                 fwrite(http_response->content_buf, 1,
151                        http_response->content_len, outf);
152                 if (outfname)
153                     fclose(outf);
154             }
155             no_urls++;
156             break;
157         default:
158             usage();
159         }
160     }
161     xfree(post_buf);
162     yaz_url_destroy(p);
163     odr_destroy(odr);
164     if (no_urls == 0)
165         usage();
166     exit(exit_code);
167 }
168
169 /*
170  * Local variables:
171  * c-basic-offset: 4
172  * c-file-style: "Stroustrup"
173  * indent-tabs-mode: nil
174  * End:
175  * vim: shiftwidth=4 tabstop=8 expandtab
176  */
177