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