-
Notifications
You must be signed in to change notification settings - Fork 1
/
plainbackup.php
159 lines (138 loc) · 4.22 KB
/
plainbackup.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php
// Include configuration
require_once('config.php');
// Include helper functions
require_once('lib/functions.php');
$shortopts = "ih";
$longopts = array(
'help',
'incremental'
);
$options = getopt($shortopts, $longopts);
if (array_key_exists('h', $options) || array_key_exists('help', $options)) {
echo "Usage: php plainbackup.php [options]
php plainbackup.php -i Run incremental backup
php plainbackup.php --incremental Run incremental backup
";
exit(0);
}
$full_backup = true;
if (array_key_exists('i', $options) || array_key_exists('incremental', $options)) {
$full_backup = false;
}
// Get us the current date
$today = date('Ymd');
// Initialize SQLite
$db = new SQLite3(DB_FILENAME);
// Create the table that holds our runtime information (more than one increment per day is supported by this table)
$db->exec("CREATE TABLE IF NOT EXISTS runinfo(
date TEXT UNIQUE NOT NULL,
value INTEGER NOT NULL
)");
// Check if there has already been a run today
$sel_stmt = $db->prepare('SELECT value FROM runinfo WHERE date = :date');
if (!$sel_stmt) {
die("Could not prepare select date runinfo\n");
}
$sel_stmt->bindValue(':date', $today);
$result = $sel_stmt->execute();
if (!$result) {
die("Could not select value FROM runinfo\n");
}
$count = 1;
if ($persitent = $result->fetchArray(SQLITE3_NUM)) {
$count = $persitent[0]+1;
}
$stmt = $db->prepare("INSERT OR REPLACE INTO runinfo (date, value) VALUES (:date, :value) ");
if (!$stmt) {
die("Could not prepare runinfo\n");
}
$stmt->bindValue(':date', $today);
$stmt->bindValue(':value', $count);
$stmt->execute();
$hostname = gethostname();
echo "plainbackup running on $hostname on ".date(DATE_RFC822)."\n";
$archive_prefix = LOCAL_TMP_PREFIX.$today.'-'.sprintf('%03d', $count);
if ($full_backup) {
$archive_prefix .= '-full';
}
$files = array();
$files = walk_dirs($files, $backup_dirs);
$db-> exec("CREATE TABLE IF NOT EXISTS file_to_hash(
file TEXT UNIQUE NOT NULL,
hash TEXT NOT NULL
)");
$filelist = fopen(BACKUP_LIST, "w") or die("Unable to open file!");
$new_files = 0;
$changed_files = 0;
$unchanged_files = 0;
foreach ($files as $f) {
$hash = md5_file($f);
if ($full_backup) {
$new_files++;
} else {
$sel_stmt = $db->prepare('SELECT hash FROM file_to_hash WHERE file = :filename');
if (!$sel_stmt) {
die("Could not prepare hash select for $f\n");
}
$sel_stmt->bindValue(':filename', $f);
$result = $sel_stmt->execute();
if (!$result) {
die("Could not select hash for $f\n");
}
if ($persitent = $result->fetchArray(SQLITE3_NUM)) {
if ($persitent[0] == $hash) {
//echo "$f not changed\n";
$unchanged_files++;
continue;
} else {
$changed_files++;
}
} else {
$new_files++;
}
}
$stmt = $db->prepare("INSERT OR REPLACE INTO file_to_hash (file, hash) VALUES (:filename, :hashvalue) ");
if (!$stmt) {
die("Could not prepare file_to_hash\n");
}
$stmt->bindValue(':filename', $f);
$stmt->bindValue(':hashvalue', $hash);
$result = $stmt->execute();
fwrite($filelist, "$f\n");
}
$targz = "$archive_prefix.tar.gz";
echo "Creating $targz\n";
exec('tar --ignore-failed-read --numeric-owner -czpf '.escapeshellarg($targz).' --files-from='.escapeshellarg(BACKUP_LIST), $output, $return_var);
if ($return_var == 0) {
echo "Files packed\n";
} else {
die("tar command failed: $return_var\n");
}
$targzgpg = "$targz.gpg";
exec('gpg --passphrase-file secret.txt --symmetric --cipher-algo AES256 -o '.escapeshellarg($targzgpg).' '.escapeshellarg($targz));
unlink($targz);
echo "Connecting to ".REMOTE_HOST."\n";
$connection = ssh2_connect(REMOTE_HOST, 22);
if (!$connection) {
die("Could not connect to ".REMOTE_HOST);
}
echo "Authenticate as user ".REMOTE_USER."\n";
if (!ssh2_auth_password($connection, REMOTE_USER, REMOTE_PASSWORD)) {
die("Could not authenticate as user ".REMOTE_USER);
}
$sftp = ssh2_sftp($connection);
$remote_path = fix_path_end(REMOTE_BASE_PATH).$hostname;
echo "Ensure remote $remote_path exists\n";
ssh2_sftp_mkdir($sftp, $remote_path, 0770, true);
$remote_file = $remote_path.'/'.$targzgpg;
if (!ssh2_scp_send($connection, $targzgpg, $remote_file)) {
die("Could not upload $targzgpg\n");
}
unlink($targzgpg);
echo "Statistic:
New files: $new_files
Changed files: $changed_files
Not modifed files: $unchanged_files
";
?>