Ticket #613: nALFS-download-md5.patch

File nALFS-download-md5.patch, 7.4 KB (added by kpfleming@…, 21 years ago)

New version of download patch, incorporating modifications from bug 619

  • src/handlers/Makefile.in

    diff -X /usr/src/dontdiff -urN nALFS-new/src/handlers/Makefile.in nALFS-new2/src/handlers/Makefile.in
    old new  
    3434SO_C_FILES := $(filter-out $(DIGEST_C_FILES), $(C_FILES))
    3535
    3636DIGEST_SO_C_FILES := $(srcdir)/new-unpack.c
     37DIGEST_SO_C_FILES += $(srcdir)/new-download.c
    3738
    3839DIGEST_SO_FILES := $(patsubst $(srcdir)/%.c,%.so, $(DIGEST_SO_C_FILES))
    3940
  • src/handlers/new-download.c

    diff -X /usr/src/dontdiff -urN nALFS-new/src/handlers/new-download.c nALFS-new2/src/handlers/new-download.c
    old new  
     1/*
     2 *  new-archive.c - Handler.
     3 *
     4 *  Copyright (C) 2003
     5 * 
     6 *  Neven Has <haski@sezampro.yu>
     7 *  Vassili Dzuba <vdzuba@nerim.net>
     8 *
     9 *  This program is free software; you can redistribute it and/or modify
     10 *  it under the terms of the GNU General Public License as published by
     11 *  the Free Software Foundation; either version 2 of the License, or
     12 *  (at your option) any later version.
     13 *
     14 *  This program is distributed in the hope that it will be useful,
     15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 *  GNU General Public License for more details.
     18 *
     19 *  You should have received a copy of the GNU General Public License
     20 *  along with this program; if not, write to the Free Software
     21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     22 */
     23
     24
     25#include <stdlib.h>
     26#include <string.h>
     27#include <unistd.h>
     28#include <errno.h>
     29#include <ctype.h>
     30#include <sys/types.h>
     31#include <sys/stat.h>
     32
     33#include "utility.h"
     34#include "win.h"
     35#include "handlers.h"
     36#include "parser.h"
     37#include "nalfs.h"
     38#include "backend.h"
     39#include "config.h"
     40#include "digest.h"
     41
     42#define El_download_file(el) alloc_trimmed_param_value("file", el)
     43#define El_download_destination(el) alloc_trimmed_param_value("destination", el)
     44#define El_download_digest(el) alloc_trimmed_param_value("digest", el)
     45
     46#ifdef HAVE_LIBCURL
     47
     48typedef struct output_file_s {
     49        const char *filename;
     50        FILE *stream;
     51} output_file_s;
     52
     53#include <curl/curl.h>
     54
     55int my_fwrite(void *buffer, size_t size, size_t nmemb, void *data)
     56{
     57        output_file_s *output = (output_file_s *)data;
     58
     59
     60        if (output->stream == NULL) { /* Open the output file. */
     61                if ((output->stream = fopen(output->filename, "wb")) == NULL) {
     62                        Nprint_err("Unable to open %s for writing.",
     63                                        output->filename);
     64                        return -1;
     65                }
     66        }
     67
     68        return fwrite(buffer, size, nmemb, output->stream);
     69}
     70
     71int load_url(const char *archive, const char *url)
     72{
     73        CURL *handle;
     74        CURLcode err;
     75        char error_buffer[CURL_ERROR_SIZE];
     76        output_file_s output = { archive, NULL };
     77        FILE *error_file = NULL;
     78
     79
     80        Nprint("Downloading with Curl:");
     81        Nprint("    %s", url);
     82
     83        if ((err = curl_global_init(CURL_GLOBAL_ALL)) != 0) {
     84                Nprint_err("Error initializing Curl (%d).", err);
     85                return -1;
     86        }
     87
     88        if ((handle = curl_easy_init()) == NULL) {
     89                Nprint_err("Error initializing easy interface.");
     90                curl_global_cleanup();
     91                return -1;
     92        }
     93
     94        /* Can't ignore CURLOPT_STDERR when CURLOPT_ERRORBUFFER is set? */
     95        error_file = fopen("/dev/null", "w");
     96        if (error_file) {
     97                curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, error_buffer);
     98                curl_easy_setopt(handle, CURLOPT_STDERR, error_file);
     99        }
     100        /* Set URL to download, callback function and the output file. */
     101        curl_easy_setopt(handle, CURLOPT_URL, url);
     102        curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_fwrite);
     103        curl_easy_setopt(handle, CURLOPT_FILE, &output);
     104        curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);
     105
     106        /* Start downloading. */
     107        err = curl_easy_perform(handle);
     108
     109        /* Cleanup. */
     110        curl_easy_cleanup(handle);
     111        curl_global_cleanup();
     112
     113        if (output.stream) { /* Close output file. */
     114                fclose(output.stream);
     115        }
     116        if (error_file) { /* Close error file. */
     117                fclose(error_file);
     118        }
     119
     120        if (err != CURLE_OK) {
     121                if (error_file) {
     122                        Nprint_err("Downloading with Curl failed:");
     123                        Nprint_err("    %s", error_buffer);
     124                } else {
     125                        Nprint_err("Downloading with Curl failed (%d).", err);
     126                }
     127
     128                return -1;
     129        }
     130
     131        Nprint("Downloading with Curl completed successfully.");
     132
     133        return 0;
     134}
     135
     136#endif
     137
     138
     139static INLINE int get_url(const char *urldir, const char *file)
     140{
     141        int status;
     142        struct stat file_stat;
     143        char *url = malloc(strlen(urldir) + strlen(file) + 1);
     144       
     145        strcpy(url, urldir);
     146        strcat(url, file);
     147
     148        /* TODO: We need to make sure that a directory for archive exists. */
     149
     150#ifdef HAVE_LIBCURL
     151        status = load_url(file, url);
     152#else
     153        status = execute_command("wget --progress=dot -O %s %s%s", file, url);
     154#endif
     155
     156        if (status) {
     157                Nprint_h_err("Getting url failed:");
     158                Nprint_h_err("    %s", url);
     159
     160                /* TODO: Should we delete the broken archive here? */
     161
     162                xfree(url);
     163                return -1;
     164        }
     165
     166        if (stat(file, &file_stat)) {
     167                Nprint_h_err("Unable to get %s from url %s:",
     168                        file, url);
     169                Nprint_h_err("    %s", strerror(errno));
     170
     171                xfree(url);
     172                return -1;
     173        }
     174
     175        xfree(url);     
     176        return 0;
     177}
     178
     179char handler_name[] = "download";
     180char handler_description[] = "Download";
     181char *handler_syntax_versions[] = { "3.1", NULL };
     182// char *handler_attributes[] = { NULL };
     183char *handler_parameters[] =
     184        { "digest", "file", "url", "destination", NULL };
     185int handler_action = 1;
     186
     187
     188int handler_main(element_s *el)
     189{
     190        int status = 0;
     191        char *file;
     192        char *destination;
     193        char *digest;
     194        struct stat file_stat;
     195
     196        /* <file> is mandatory */
     197        if ((file = El_download_file(el)) == NULL) {
     198                Nprint_h_err("File name is missing.");
     199                return -1;
     200        }
     201
     202        /* <destination> is mandatory */
     203        if ((destination = El_download_destination(el)) == NULL) {
     204                Nprint_h_err("Destination is missing.");
     205                xfree(file);
     206                return -1;
     207        }
     208       
     209        /* changing to <destination> directory */
     210        if (change_current_dir(destination)) {
     211                xfree(file);
     212                xfree(destination);
     213                return -1;
     214        }
     215
     216        /* Check if file exists. */
     217        if ((stat(file, &file_stat))) {
     218                if (errno == ENOENT && first_param("url", el) != NULL) {
     219                        int found = 0;
     220                        element_s *p;
     221
     222                        Nprint_h_warn("File %s not found.", file);
     223                        Nprint_h("Trying to fetch it from <url>...");
     224
     225                        for (p = first_param("url", el); p; p = next_param(p)) {
     226                              char *s;
     227
     228                              if ((s = alloc_trimmed_str(p->content)) == NULL) {
     229                                Nprint_h_warn("Source empty.");
     230                                continue;
     231                              }
     232
     233                              if (! get_url(s, file)) {
     234                                found = 1;
     235                                break;
     236                              }
     237
     238                              xfree(s);
     239                        }
     240
     241                        if (! found) {
     242                          Nprint_h_err("Unable to download file %s.", file);                     
     243                          xfree(file);
     244                          xfree(destination);
     245                          return -1;
     246                        }
     247
     248                } else {
     249                        Nprint_h_err("Checking for %s failed:", file);
     250                        Nprint_h_err("    %s", strerror(errno));
     251                        xfree(file);
     252                        xfree(destination);
     253                        return -1;
     254                }
     255        }
     256
     257        if ((digest = El_download_digest(el)) != NULL) {
     258                element_s *el2 = first_param("digest", el);
     259                char *type = attr_value("type", el2);
     260                char *s;
     261
     262                if (type != NULL) {
     263                        for (s = type; *s; s++) {
     264                                *s = tolower(*s);
     265                        }
     266                }
     267         
     268                if ((type == NULL) || (*type == 0)) {
     269                        type = "md5";
     270                }
     271
     272                if (verify_digest(type, digest, file)) {
     273                        Nprint_h_err("Wrong %s digest of file: %s",
     274                                type, file);
     275                        xfree(file);
     276                        xfree(destination);
     277                        return -1;
     278                }
     279        }
     280
     281        xfree(file);
     282        xfree(destination);
     283       
     284        return status;
     285}