Add odr_setprint_noclose
[yaz-moved-to-github.git] / util / yaz-url.c
index bdc912c..7a78e67 100644 (file)
@@ -1,10 +1,10 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2011 Index Data
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
  */
 
 #if HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <string.h>
 static void usage(void)
 {
     printf("yaz-icu [options] url ..\n");
-    printf(" -H name=value       HTTP header\n");
-    printf(" -p file             POST content of file\n");
-    printf(" -u user/password    Basic HTTP auth\n");
-    printf(" -x proxy            HTTP proxy\n");
+    printf(" -H name:value       Sets HTTP header (repeat if necessary)\n");
+    printf(" -m method           Sets HTTP method\n");
+    printf(" -O fname            Writes HTTP content to file\n");
+    printf(" -p fname            POSTs file at following url\n");
+    printf(" -R num              Set maximum number of HTTP redirects\n");
+    printf(" -u user/password    Sets Basic HTTP auth\n");
+    printf(" -v                  Verbose\n");
+    printf(" -x proxy            Sets HTTP proxy\n");
     exit(1);
 }
 
@@ -39,9 +43,18 @@ static char *get_file(const char *fname, size_t *len)
         exit(1);
     }
     *len = ftell(inf);
-    buf = xmalloc(*len);
-    fseek(inf, 0L, SEEK_SET);
-    fread(buf, 1, *len, inf);
+    if (*len)  /* zero length not considered an error */
+    {
+        size_t r;
+        buf = xmalloc(*len);
+        fseek(inf, 0L, SEEK_SET);
+        r = fread(buf, 1, *len, inf);
+        if (r != *len)
+        {
+            yaz_log(YLOG_FATAL|YLOG_ERRNO, "short fread of %s", fname);
+            exit(1);
+        }
+    }
     fclose(inf);
     return buf;
 }
@@ -58,8 +71,10 @@ int main(int argc, char **argv)
     Z_HTTP_Header *http_headers = 0;
     ODR odr = odr_createmem(ODR_ENCODE);
     int exit_code = 0;
+    int no_urls = 0;
+    const char *outfname = 0;
 
-    while ((ret = options("hH:p:u:x:", argv, argc, &arg))
+    while ((ret = options("h{help}H:m:O:p:R{max-redirs}:u:vx:", argv, argc, &arg))
            != YAZ_OPTIONS_EOF)
     {
         switch (ret)
@@ -68,26 +83,37 @@ int main(int argc, char **argv)
             usage();
             break;
         case 'H':
-            if (!strchr(arg, '='))
+            if (!strchr(arg, ':'))
             {
-                yaz_log(YLOG_FATAL, "bad header option (missing =): %s\n", arg);
+                yaz_log(YLOG_FATAL, "bad header option (missing :) %s\n", arg);
                 exit_code = 1;
             }
             else
             {
-                char *cp = strchr(arg, '=');
+                char *cp = strchr(arg, ':');
                 char *name = odr_malloc(odr, 1 + cp - arg);
                 char *value = cp + 1;
                 memcpy(name, arg, cp - arg);
                 name[cp - arg] = '\0';
+                while (*value == ' ') /* skip space after = */
+                    value++;
                 z_HTTP_header_add(odr, &http_headers, name, value);
             }
             break;
+        case 'm':
+            method = arg;
+            break;
+        case 'O':
+            outfname = arg;
+            break;
         case 'p':
             xfree(post_buf);
             post_buf = get_file(arg, &post_len);
             method = "POST";
             break;
+        case 'R':
+            yaz_url_set_max_redirects(p, atoi(arg));
+            break;
         case 'u':
             if (strchr(arg, '/'))
             {
@@ -102,6 +128,9 @@ int main(int argc, char **argv)
             else
                 z_HTTP_header_add_basic_auth(odr, &http_headers, arg, 0);
             break;
+        case 'v':
+            yaz_url_set_verbose(p, 1);
+            break;
         case 'x':
             yaz_url_set_proxy(p, arg);
             break;
@@ -112,16 +141,32 @@ int main(int argc, char **argv)
                 exit_code = 1;
             else
             {
+                FILE *outf = stdout;
+                if (outfname)
+                {
+                    outf = fopen(outfname, "w");
+                    if (!outf)
+                    {
+                        yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", outfname);
+                        exit(1);
+                    }
+                }
                 fwrite(http_response->content_buf, 1,
-                       http_response->content_len, stdout);
+                       http_response->content_len, outf);
+                if (outfname)
+                    fclose(outf);
             }
+            no_urls++;
             break;
         default:
             usage();
         }
     }
+    xfree(post_buf);
     yaz_url_destroy(p);
     odr_destroy(odr);
+    if (no_urls == 0)
+        usage();
     exit(exit_code);
 }