opkg: adding cache support
[oweals/opkg-lede.git] / libopkg / opkg_download.c
index 1d882a14e1852d9492fcb30aafbb23a2b65a2f80..5dabeed768cc5f10efd77fe3f9e2299206e439b7 100644 (file)
@@ -33,7 +33,8 @@
 #include "str_util.h"
 #include "opkg_defines.h"
 
-int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name, curl_progress_func cb, void *data)
+static int do_download(opkg_conf_t *conf, const char *src,
+  const char *dest_file_name, curl_progress_func cb, void *data)
 {
     int err = 0;
 
@@ -49,6 +50,7 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name
        opkg_message(conf,OPKG_INFO,"Copying %s to %s...", file_src, dest_file_name);
        ret = file_copy(src + 5, dest_file_name);
        opkg_message(conf,OPKG_INFO,"Done\n");
+        free(src_basec);
        return ret;
     }
 
@@ -58,6 +60,7 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name
        opkg_message(conf,OPKG_ERROR, "%s: ERROR: failed to unlink %s: %s\n",
                __FUNCTION__, tmp_file_location, strerror(errno));
        free(tmp_file_location);
+        free(src_basec);
        return errno;
     }
 
@@ -89,6 +92,7 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name
                curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, data);
                curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, cb);
        }
+       curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1);
        if (conf->http_proxy || conf->ftp_proxy)
        {
@@ -99,19 +103,26 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name
            free (userpwd);
        }
        res = curl_easy_perform (curl);
-       curl_easy_cleanup (curl);
        fclose (file);
        if (res)
        {
            long error_code;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &error_code);
            opkg_message(conf, OPKG_ERROR, "Failed to download %s, error %d\n", src, error_code);
+           free(tmp_file_location);
+            free(src_basec);
+           curl_easy_cleanup (curl);
            return res;
        }
+       curl_easy_cleanup (curl);
 
     }
     else
+    {
+       free(tmp_file_location);
+        free(src_basec);
        return -1;
+    }
 
     err = file_move(tmp_file_location, dest_file_name);
 
@@ -125,6 +136,43 @@ int opkg_download(opkg_conf_t *conf, const char *src, const char *dest_file_name
     return 0;
 }
 
+int opkg_download(opkg_conf_t *conf, const char *src,
+  const char *dest_file_name, curl_progress_func cb, void *data)
+{
+    char *cache_name = strdup(src);
+    char *cache_location, *p;
+    int err = 0;
+
+    if (!conf->cache || str_starts_with(src, "file:")) {
+       err = do_download(conf, src, dest_file_name, cb, data);
+       goto out1;
+    }
+
+    for (p = cache_name; *p; p++)
+       if (*p == '/')
+           *p = ',';   /* looks nicer than | or # */
+
+    sprintf_alloc(&cache_location, "%s/%s", conf->cache, cache_name);
+    if (file_exists(cache_location))
+       opkg_message(conf, OPKG_NOTICE, "Copying %s\n", cache_location);
+    else {
+       err = do_download(conf, src, cache_location, cb, data);
+       if (err) {
+           (void) unlink(cache_location);
+           goto out2;
+       }
+    }
+
+    err = file_copy(cache_location, dest_file_name);
+
+
+out2:
+    free(cache_location);
+out1:
+    free(cache_name);
+    return err;
+}
+
 int opkg_download_pkg(opkg_conf_t *conf, pkg_t *pkg, const char *dir)
 {
     int err;
@@ -145,7 +193,7 @@ int opkg_download_pkg(opkg_conf_t *conf, pkg_t *pkg, const char *dir)
     sprintf_alloc(&url, "%s/%s", pkg->src->value, pkg->filename);
 
     /* XXX: BUG: The pkg->filename might be something like
-       "../../foo.ipk". While this is correct, and exactly what we
+       "../../foo.opk". While this is correct, and exactly what we
        want to use to construct url above, here we actually need to
        use just the filename part, without any directory. */
 
@@ -193,6 +241,7 @@ int opkg_prepare_url_for_install(opkg_conf_t *conf, const char *url, char **name
          free(file_basec);
 
      } else if (strcmp(&url[strlen(url) - 4], OPKG_PKG_EXTENSION) == 0
+                || strcmp(&url[strlen(url) - 4], IPKG_PKG_EXTENSION) == 0
                || strcmp(&url[strlen(url) - 4], DPKG_PKG_EXTENSION) == 0) {
 
          err = pkg_init_from_file(pkg, url);