lib/download.c: add xbps_fetch_file{_dest,}_digest

This commit is contained in:
Duncaen 2019-07-07 14:07:59 +02:00 committed by Juan RP
parent 699b2bdd3b
commit d2bdd9574e
2 changed files with 66 additions and 4 deletions

View File

@ -50,7 +50,7 @@
* *
* This header documents the full API for the XBPS Library. * This header documents the full API for the XBPS Library.
*/ */
#define XBPS_API_VERSION "20190621" #define XBPS_API_VERSION "20190707"
#ifndef XBPS_VERSION #ifndef XBPS_VERSION
#define XBPS_VERSION "UNSET" #define XBPS_VERSION "UNSET"
@ -734,6 +734,20 @@ int xbps_configure_packages(struct xbps_handle *xhp, xbps_array_t ignpkgs);
int xbps_fetch_file(struct xbps_handle *xhp, const char *uri, int xbps_fetch_file(struct xbps_handle *xhp, const char *uri,
const char *flags); const char *flags);
/**
* Download and digest a file from a remote URL to current working directory.
*
* @param[in] xhp Pointer to an xbps_handle struct.
* @param[in] uri Remote URI string.
* @param[in] flags Flags passed to libfetch's fetchXget().
* @param[out] digestp Checksum of the downloaded file.
*
* @return -1 on error, 0 if not downloaded (because local/remote size/mtime
* do not match) and 1 if downloaded successfully.
**/
int xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
const char *flags, unsigned char **digestp);
/** /**
* Download a file from a remote URL to current working directory, * Download a file from a remote URL to current working directory,
* and writing file to \a filename. * and writing file to \a filename.
@ -749,6 +763,22 @@ int xbps_fetch_file(struct xbps_handle *xhp, const char *uri,
int xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri, int xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri,
const char *filename, const char *flags); const char *filename, const char *flags);
/**
* Download and digest a file from a remote URL to current working directory,
* and writing file to \a filename.
*
* @param[in] xhp Pointer to an xbps_handle struct.
* @param[in] uri Remote URI string.
* @param[in] filename Local filename to safe the file
* @param[in] flags Flags passed to libfetch's fetchXget().
* @param[out] digest Checksum of the downloaded file.
*
* @return -1 on error, 0 if not downloaded (because local/remote size/mtime
* do not match) and 1 if downloaded successfully.
**/
int xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri,
const char *filename, const char *flags, unsigned char **digestp);
/** /**
* Returns last error string reported by xbps_fetch_file(). * Returns last error string reported by xbps_fetch_file().
* *

View File

@ -42,6 +42,8 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <libgen.h> #include <libgen.h>
#include <openssl/sha.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "fetch.h" #include "fetch.h"
#include "compat.h" #include "compat.h"
@ -91,7 +93,7 @@ xbps_fetch_error_string(void)
} }
int int
xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags) xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags, unsigned char **digestp)
{ {
struct stat st, st_tmpfile, *stp; struct stat st, st_tmpfile, *stp;
struct url *url = NULL; struct url *url = NULL;
@ -104,10 +106,19 @@ xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri, const char *filen
char fetch_flags[8]; char fetch_flags[8];
int fd = -1, rv = 0; int fd = -1, rv = 0;
bool refetch = false, restart = false; bool refetch = false, restart = false;
unsigned char *digest = NULL;
SHA256_CTX sha256;
assert(xhp); assert(xhp);
assert(uri); assert(uri);
if (digestp) {
digest = malloc(SHA256_DIGEST_LENGTH);
if (!digest)
return -1;
SHA256_Init(&sha256);
}
/* Extern vars declared in libfetch */ /* Extern vars declared in libfetch */
fetchLastErrCode = 0; fetchLastErrCode = 0;
@ -223,6 +234,8 @@ xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri, const char *filen
* Start fetching requested file. * Start fetching requested file.
*/ */
while ((bytes_read = fetchIO_read(fio, buf, sizeof(buf))) > 0) { while ((bytes_read = fetchIO_read(fio, buf, sizeof(buf))) > 0) {
if (digest)
SHA256_Update(&sha256, buf, bytes_read);
bytes_written = write(fd, buf, (size_t)bytes_read); bytes_written = write(fd, buf, (size_t)bytes_read);
if (bytes_written != bytes_read) { if (bytes_written != bytes_read) {
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
@ -283,6 +296,11 @@ rename_file:
} }
rv = 1; rv = 1;
if (digest) {
SHA256_Final(digest, &sha256);
*digestp = digest;
}
fetch_file_out: fetch_file_out:
if (fio != NULL) if (fio != NULL)
fetchIO_close(fio); fetchIO_close(fio);
@ -297,7 +315,15 @@ fetch_file_out:
} }
int int
xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags) xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri,
const char *filename, const char *flags)
{
return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, NULL);
}
int
xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
const char *flags, unsigned char **digestp)
{ {
const char *filename; const char *filename;
/* /*
@ -307,5 +333,11 @@ xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
return -1; return -1;
filename++; filename++;
return xbps_fetch_file_dest(xhp, uri, filename, flags); return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, digestp);
}
int
xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
{
return xbps_fetch_file_digest(xhp, uri, flags, NULL);
} }