From acc36165b14542a51218f76e617c64b43b4b1ccd Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Thu, 28 Jun 2012 00:20:20 +0900
Subject: [PATCH] Metalink: message updates

Print "parsing (...) OK" only when no warnings are generated.  If
no file is found in Metalink, treat it FAILED.

If no digest is provided, print WARNING in parse_metalink().
Also print validating FAILED after download.

These changes make tests 2012 to 2016 pass.
---
 src/tool_metalink.c |   21 +++++++++++++++------
 src/tool_metalink.h |   10 ++++++++++
 src/tool_operate.c  |    8 ++++----
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index 8065741..c35dd79 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -330,7 +330,6 @@ static int check_hash(const char *filename,
   digest_context *dctx;
   int check_ok;
   int fd;
-  fprintf(error, "Metalink: validating (%s)...\n", filename);
   fd = open(filename, O_RDONLY);
   if(fd == -1) {
     fprintf(error, "Metalink: validating (%s) FAILED (%s)\n", filename,
@@ -374,7 +373,11 @@ int metalink_check_hash(struct Configurable *config,
                         const char *filename)
 {
   int rv;
+  fprintf(config->errors, "Metalink: validating (%s)...\n", filename);
   if(mlfile->checksum == NULL) {
+    fprintf(config->errors,
+            "Metalink: validating (%s) FAILED (digest missing)\n",
+            filename);
     return -2;
   }
   rv = check_hash(filename, mlfile->checksum->digest_def,
@@ -474,6 +477,7 @@ int parse_metalink(struct Configurable *config, struct OutStruct *outs,
   metalink_error_t r;
   metalink_t* metalink;
   metalink_file_t **files;
+  bool warnings = FALSE;
 
   /* metlaink_parse_final deletes outs->metalink_parser */
   r = metalink_parse_final(outs->metalink_parser, NULL, 0, &metalink);
@@ -482,17 +486,17 @@ int parse_metalink(struct Configurable *config, struct OutStruct *outs,
     return -1;
   }
   if(metalink->files == NULL) {
-    fprintf(config->errors, "\nMetalink: parsing (%s) WARNING "
+    fprintf(config->errors, "Metalink: parsing (%s) WARNING "
             "(missing or invalid file name)\n",
             metalink_url);
     metalink_delete(metalink);
-    return 0;
+    return -1;
   }
   for(files = metalink->files; *files; ++files) {
     struct getout *url;
     /* Skip an entry which has no resource. */
     if(!(*files)->resources) {
-      fprintf(config->errors, "\nMetalink: parsing (%s) WARNING "
+      fprintf(config->errors, "Metalink: parsing (%s) WARNING "
               "(missing or invalid resource)\n",
               metalink_url, (*files)->name);
       continue;
@@ -517,7 +521,12 @@ int parse_metalink(struct Configurable *config, struct OutStruct *outs,
     if(url) {
       metalinkfile *mlfile;
       mlfile = new_metalinkfile(*files);
-
+      if(!mlfile->checksum) {
+        warnings = TRUE;
+        fprintf(config->errors, "Metalink: parsing (%s) WARNING "
+                "(digest missing)\n",
+                metalink_url);
+      }
       /* Set name as url */
       GetStr(&url->url, mlfile->filename);
 
@@ -534,7 +543,7 @@ int parse_metalink(struct Configurable *config, struct OutStruct *outs,
     }
   }
   metalink_delete(metalink);
-  return 0;
+  return warnings == TRUE ? -2 : 0;
 }
 
 size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb,
diff --git a/src/tool_metalink.h b/src/tool_metalink.h
index a3d10a2..52a430e 100644
--- a/src/tool_metalink.h
+++ b/src/tool_metalink.h
@@ -90,6 +90,16 @@ extern const digest_params SHA256_DIGEST_PARAMS[1];
 int count_next_metalink_resource(metalinkfile *mlfile);
 void clean_metalink(struct Configurable *config);
 
+/*
+ * Performs final parse operation and extracts information from
+ * Metalink and creates metalinkfile structs.
+ *
+ * This function returns 0 if it succeeds without warnings, or one of
+ * the following negative error codes:
+ *
+ * -1: Parsing failed; or no file is found
+ * -2: Parsing succeeded with some warnings.
+ */
 int parse_metalink(struct Configurable *config, struct OutStruct *outs,
                    const char *metalink_url);
 
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 0b828de..7c0b8b5 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1621,10 +1621,10 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
 
 #ifdef USE_METALINK
         if(!metalink && config->use_metalink && res == CURLE_OK) {
-          if(parse_metalink(config, &outs, this_url) == 0)
-            fprintf(config->errors, "Metalink: parsing (%s) OK\n",
-                    this_url);
-          else
+          int rv = parse_metalink(config, &outs, this_url);
+          if(rv == 0)
+            fprintf(config->errors, "Metalink: parsing (%s) OK\n", this_url);
+          else if(rv == -1)
             fprintf(config->errors, "Metalink: parsing (%s) FAILED\n",
                     this_url);
         }
-- 
1.7.9.1

