Skip to content

Commit cf72d9a

Browse files
Hocurihpk42Alexander Krotov
authored
Tar backup (#1749)
Fix #1729 Co-authored-by: holger krekel <[email protected]> Co-authored-by: Alexander Krotov <[email protected]>
1 parent 77c61ab commit cf72d9a

File tree

7 files changed

+293
-18
lines changed

7 files changed

+293
-18
lines changed

Cargo.lock

Lines changed: 58 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,14 @@ anyhow = "1.0.28"
5959
async-trait = "0.1.31"
6060
url = "2.1.1"
6161
async-std-resolver = "0.19.5"
62+
async-tar = "0.3.0"
6263
uuid = { version = "0.8", features = ["serde", "v4"] }
6364

6465
pretty_env_logger = { version = "0.4.0", optional = true }
6566
log = {version = "0.4.8", optional = true }
6667
rustyline = { version = "4.1.0", optional = true }
6768
ansi_term = { version = "0.12.1", optional = true }
69+
dirs = { version = "3.0.1", optional=true }
6870
toml = "0.5.6"
6971

7072

@@ -96,7 +98,7 @@ required-features = ["repl"]
9698
[features]
9799
default = []
98100
internals = []
99-
repl = ["internals", "rustyline", "log", "pretty_env_logger", "ansi_term"]
101+
repl = ["internals", "rustyline", "log", "pretty_env_logger", "ansi_term", "dirs"]
100102
vendored = ["async-native-tls/vendored", "async-smtp/native-tls-vendored"]
101103
nightly = ["pgp/nightly"]
102104

deltachat-ffi/deltachat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,8 +1773,8 @@ dc_contact_t* dc_get_contact (dc_context_t* context, uint32_t co
17731773
* - **DC_IMEX_EXPORT_BACKUP** (11) - Export a backup to the directory given as `param1`.
17741774
* The backup contains all contacts, chats, images and other data and device independent settings.
17751775
* The backup does not contain device dependent settings as ringtones or LED notification settings.
1776-
* The name of the backup is typically `delta-chat.<day>.bak`, if more than one backup is create on a day,
1777-
* the format is `delta-chat.<day>-<number>.bak`
1776+
* The name of the backup is typically `delta-chat-<day>.tar`, if more than one backup is create on a day,
1777+
* the format is `delta-chat-<day>-<number>.tar`
17781778
*
17791779
* - **DC_IMEX_IMPORT_BACKUP** (12) - `param1` is the file (not: directory) to import. The file is normally
17801780
* created by DC_IMEX_EXPORT_BACKUP and detected by dc_imex_has_backup(). Importing a backup

examples/repl/cmdline.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
extern crate dirs;
2+
13
use std::str::FromStr;
24

35
use anyhow::{bail, ensure};
@@ -442,17 +444,21 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
442444
has_backup(&context, blobdir).await?;
443445
}
444446
"export-backup" => {
445-
imex(&context, ImexMode::ExportBackup, Some(blobdir)).await?;
447+
let dir = dirs::home_dir().unwrap_or_default();
448+
imex(&context, ImexMode::ExportBackup, Some(&dir)).await?;
449+
println!("Exported to {}.", dir.to_string_lossy());
446450
}
447451
"import-backup" => {
448452
ensure!(!arg1.is_empty(), "Argument <backup-file> missing.");
449453
imex(&context, ImexMode::ImportBackup, Some(arg1)).await?;
450454
}
451455
"export-keys" => {
452-
imex(&context, ImexMode::ExportSelfKeys, Some(blobdir)).await?;
456+
let dir = dirs::home_dir().unwrap_or_default();
457+
imex(&context, ImexMode::ExportSelfKeys, Some(&dir)).await?;
458+
println!("Exported to {}.", dir.to_string_lossy());
453459
}
454460
"import-keys" => {
455-
imex(&context, ImexMode::ImportSelfKeys, Some(blobdir)).await?;
461+
imex(&context, ImexMode::ImportSelfKeys, Some(arg1)).await?;
456462
}
457463
"export-setup" => {
458464
let setup_code = create_setup_code(&context);

src/dc_tools.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ pub fn dc_open_file_std<P: AsRef<std::path::Path>>(
450450
}
451451
}
452452

453-
pub(crate) async fn dc_get_next_backup_path(
453+
pub(crate) async fn get_next_backup_path_old(
454454
folder: impl AsRef<Path>,
455455
backup_time: i64,
456456
) -> Result<PathBuf, Error> {
@@ -470,6 +470,32 @@ pub(crate) async fn dc_get_next_backup_path(
470470
bail!("could not create backup file, disk full?");
471471
}
472472

473+
/// Returns Ok((temp_path, dest_path)) on success. The backup can then be written to temp_path. If the backup succeeded,
474+
/// it can be renamed to dest_path. This guarantees that the backup is complete.
475+
pub(crate) async fn get_next_backup_path_new(
476+
folder: impl AsRef<Path>,
477+
backup_time: i64,
478+
) -> Result<(PathBuf, PathBuf), Error> {
479+
let folder = PathBuf::from(folder.as_ref());
480+
let stem = chrono::NaiveDateTime::from_timestamp(backup_time, 0)
481+
.format("delta-chat-backup-%Y-%m-%d")
482+
.to_string();
483+
484+
// 64 backup files per day should be enough for everyone
485+
for i in 0..64 {
486+
let mut tempfile = folder.clone();
487+
tempfile.push(format!("{}-{:02}.tar.part", stem, i));
488+
489+
let mut destfile = folder.clone();
490+
destfile.push(format!("{}-{:02}.tar", stem, i));
491+
492+
if !tempfile.exists().await && !destfile.exists().await {
493+
return Ok((tempfile, destfile));
494+
}
495+
}
496+
bail!("could not create backup file, disk full?");
497+
}
498+
473499
pub(crate) fn time() -> i64 {
474500
SystemTime::now()
475501
.duration_since(SystemTime::UNIX_EPOCH)

src/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub enum EventType {
127127
#[strum(props(id = "150"))]
128128
NewBlobFile(String),
129129

130-
/// Emitted when an new file in the $BLOBDIR was created
130+
/// Emitted when an file in the $BLOBDIR was deleted
131131
#[strum(props(id = "151"))]
132132
DeletedBlobFile(String),
133133

0 commit comments

Comments
 (0)