diff options
Diffstat (limited to 'src/warc.c')
-rw-r--r-- | src/warc.c | 110 |
1 files changed, 91 insertions, 19 deletions
@@ -35,6 +35,7 @@ as that of the covered work. */ #include "hash.h" #include "utils.h" #include "version.h" +#include "dirname.h" #include <stdio.h> #include <stdlib.h> @@ -54,19 +55,22 @@ as that of the covered work. */ #include <uuid.h> #endif -#ifndef WINDOWS -#include <libgen.h> -#else -#include <fcntl.h> -#endif - #include "warc.h" #include "exits.h" +#ifdef WINDOWS +/* we need this on Windows to have O_TEMPORARY defined */ +# include <fcntl.h> +# include <rpc.h> +#endif + #ifndef O_TEMPORARY #define O_TEMPORARY 0 #endif +#include "warc.h" +#include "exits.h" + /* The log file (a temporary file that contains a copy of the wget log). */ @@ -600,27 +604,90 @@ warc_timestamp (char *timestamp, size_t timestamp_size) return timestamp; } -#if HAVE_LIBUUID || HAVE_UUID_CREATE /* Fills urn_str with a UUID in the format required for the WARC-Record-Id header. The string will be 47 characters long. */ +#if HAVE_LIBUUID void warc_uuid_str (char *urn_str) { char uuid_str[37]; + uuid_t record_id; + uuid_generate (record_id); + uuid_unparse (record_id, uuid_str); + + sprintf (urn_str, "<urn:uuid:%s>", uuid_str); +} +#elif HAVE_UUID_CREATE +void +warc_uuid_str (char *urn_str) +{ + char *uuid_str; uuid_t record_id; -#if HAVE_UUID_CREATE + uuid_create (&record_id, NULL); uuid_to_string (&record_id, &uuid_str, NULL); -#else - uuid_generate (record_id); - uuid_unparse (record_id, uuid_str); -#endif sprintf (urn_str, "<urn:uuid:%s>", uuid_str); + xfree (uuid_str); } #else +# ifdef WINDOWS + +typedef RPC_STATUS (RPC_ENTRY * UuidCreate_proc) (UUID *); +typedef RPC_STATUS (RPC_ENTRY * UuidToString_proc) (UUID *, unsigned char **); +typedef RPC_STATUS (RPC_ENTRY * RpcStringFree_proc) (unsigned char **); + +static int +windows_uuid_str (char *urn_str) +{ + static UuidCreate_proc pfn_UuidCreate = NULL; + static UuidToString_proc pfn_UuidToString = NULL; + static RpcStringFree_proc pfn_RpcStringFree = NULL; + static int rpc_uuid_avail = -1; + + /* Rpcrt4.dll is not available on older versions of Windows, so we + need to test its availability at run time. */ + if (rpc_uuid_avail == -1) + { + HMODULE hm_rpcrt4 = LoadLibrary ("Rpcrt4.dll"); + + if (hm_rpcrt4) + { + pfn_UuidCreate = + (UuidCreate_proc) GetProcAddress (hm_rpcrt4, "UuidCreate"); + pfn_UuidToString = + (UuidToString_proc) GetProcAddress (hm_rpcrt4, "UuidToStringA"); + pfn_RpcStringFree = + (RpcStringFree_proc) GetProcAddress (hm_rpcrt4, "RpcStringFreeA"); + if (pfn_UuidCreate && pfn_UuidToString && pfn_RpcStringFree) + rpc_uuid_avail = 1; + else + rpc_uuid_avail = 0; + } + else + rpc_uuid_avail = 0; + } + + if (rpc_uuid_avail) + { + BYTE *uuid_str; + UUID uuid; + + if (pfn_UuidCreate (&uuid) == RPC_S_OK) + { + if (pfn_UuidToString (&uuid, &uuid_str) == RPC_S_OK) + { + sprintf (urn_str, "<urn:uuid:%s>", uuid_str); + pfn_RpcStringFree (&uuid_str); + return 1; + } + } + } + return 0; +} +#endif /* Fills urn_str with a UUID based on random numbers in the format required for the WARC-Record-Id header. (See RFC 4122, UUID version 4.) @@ -636,6 +703,14 @@ warc_uuid_str (char *urn_str) unsigned char uuid_data[16]; int i; + +#ifdef WINDOWS + /* If the native method fails (expected on older Windows versions), + use the fallback below. */ + if (windows_uuid_str (urn_str)) + return; +#endif + for (i=0; i<16; i++) uuid_data[i] = random_number (255); @@ -663,7 +738,7 @@ warc_write_warcinfo_record (char *filename) { FILE *warc_tmp; char timestamp[22]; - char *filename_copy, *filename_basename; + char *filename_basename; /* Write warc-info record as the first record of the file. */ /* We add the record id of this info record to the other records in the @@ -673,8 +748,7 @@ warc_write_warcinfo_record (char *filename) warc_timestamp (timestamp, sizeof(timestamp)); - filename_copy = strdup (filename); - filename_basename = strdup (basename (filename_copy)); + filename_basename = base_name (filename); warc_write_start_record (); warc_write_header ("WARC-Type", "warcinfo"); @@ -683,12 +757,12 @@ warc_write_warcinfo_record (char *filename) warc_write_header ("WARC-Record-ID", warc_current_warcinfo_uuid_str); warc_write_header ("WARC-Filename", filename_basename); + xfree (filename_basename); + /* Create content. */ warc_tmp = warc_tempfile (); if (warc_tmp == NULL) { - xfree (filename_copy); - xfree (filename_basename); return false; } @@ -714,8 +788,6 @@ warc_write_warcinfo_record (char *filename) if (! warc_write_ok) logprintf (LOG_NOTQUIET, _("Error writing warcinfo record to WARC file.\n")); - xfree (filename_copy); - xfree (filename_basename); fclose (warc_tmp); return warc_write_ok; } |