summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h1
-rw-r--r--linux.c5
-rw-r--r--macos.c5
-rw-r--r--save-xml.c34
-rw-r--r--windows.c16
5 files changed, 61 insertions, 0 deletions
diff --git a/dive.h b/dive.h
index 2e0039f80..ae2645ac0 100644
--- a/dive.h
+++ b/dive.h
@@ -656,6 +656,7 @@ extern void save_dives_logic(const char *filename, bool select_only);
extern void save_dive(FILE *f, struct dive *dive);
extern void export_dives_uddf(const char *filename, const bool selected);
+extern int subsurface_rename(const char *path, const char *newpath);
extern int subsurface_open(const char *path, int oflags, mode_t mode);
extern FILE *subsurface_fopen(const char *path, const char *mode);
extern void *subsurface_opendir(const char *path);
diff --git a/linux.c b/linux.c
index 1feefd6f1..ac1174a5c 100644
--- a/linux.c
+++ b/linux.c
@@ -101,6 +101,11 @@ int enumerate_devices (device_callback_t callback, void *userdata)
}
/* NOP wrappers to comform with windows.c */
+int subsurface_rename(const char *path, const char *newpath)
+{
+ return rename(path, newpath);
+}
+
int subsurface_open(const char *path, int oflags, mode_t mode)
{
return open(path, oflags, mode);
diff --git a/macos.c b/macos.c
index ba461ee4f..aa5036ea2 100644
--- a/macos.c
+++ b/macos.c
@@ -82,6 +82,11 @@ int enumerate_devices (device_callback_t callback, void *userdata)
}
/* NOP wrappers to comform with windows.c */
+int subsurface_rename(const char *path, const char *newpath)
+{
+ return rename(path, newpath);
+}
+
int subsurface_open(const char *path, int oflags, mode_t mode)
{
return open(path, oflags, mode);
diff --git a/save-xml.c b/save-xml.c
index 7bb2642bd..a95487313 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -577,12 +577,46 @@ void save_dives_buffer(struct membuffer *b, const bool select_only)
put_format(b, "</dives>\n</divelog>\n");
}
+static void save_backup(const char *name, const char *ext, const char *new_ext)
+{
+ int len = strlen(name);
+ int a = strlen(ext), b = strlen(new_ext);
+ char *newname;
+
+ /* len up to and including the final '.' */
+ len -= a;
+ if (len <= 1)
+ return;
+ if (name[len-1] != '.')
+ return;
+ /* msvc doesn't have strncasecmp, has _strnicmp instead - crazy */
+ if (strncasecmp(name+len, ext, a))
+ return;
+
+ newname = malloc(len + b + 1);
+ if (!newname)
+ return;
+
+ memcpy(newname, name, len);
+ memcpy(newname+len, new_ext, b+1);
+
+ /*
+ * Ignore errors. Maybe we can't create the backup file,
+ * maybe no old file existed. Regardless, we'll write the
+ * new file.
+ */
+ subsurface_rename(name, newname);
+ free(newname);
+}
+
void save_dives_logic(const char *filename, const bool select_only)
{
struct membuffer buf = {0};
FILE *f;
save_dives_buffer(&buf, select_only);
+ /* Maybe we might want to make this configurable? */
+ save_backup(filename, "xml", "bak");
f = subsurface_fopen(filename, "w");
if (f) {
flush_buffer(&buf, f);
diff --git a/windows.c b/windows.c
index 7c537f6e5..042e1c619 100644
--- a/windows.c
+++ b/windows.c
@@ -111,6 +111,22 @@ static wchar_t *utf8_to_utf16_fl(const char *utf8, char *file, int line)
/* bellow we provide a set of wrappers for some I/O functions to use wchar_t.
* on win32 this solves the issue that we need paths to be utf-16 encoded.
*/
+int subsurface_rename(const char *path, const char *newpath)
+{
+ int ret = -1;
+ if (!path || !newpath)
+ return -1;
+
+ wchar_t *wpath = utf8_to_utf16(path);
+ wchar_t *wnewpath = utf8_to_utf16(newpath);
+
+ if (wpath && wnewpath)
+ ret = _wrename(wpath, wnewpath);
+ free((void *)wpath);
+ free((void *)wnewpath);
+ return ret;
+}
+
int subsurface_open(const char *path, int oflags, mode_t mode)
{
int ret = -1;