summaryrefslogtreecommitdiff
path: root/src/warc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/warc.c')
-rw-r--r--src/warc.c110
1 files changed, 91 insertions, 19 deletions
diff --git a/src/warc.c b/src/warc.c
index 5bdda1b..55884e0 100644
--- a/src/warc.c
+++ b/src/warc.c
@@ -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;
}