/// <summary> /// Perform backup on the specified media /// </summary> public void Backup(BackupMedia media, String password = null) { // Make a determination that the user is allowed to perform this action if (AuthenticationContext.Current.Principal != AuthenticationContext.SystemPrincipal) { new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PolicyIdentifiers.ExportClinicalData).Demand(); } // Get the output medium var directoryName = this.GetBackupDirectory(media); string fileName = Path.Combine(directoryName, $"oizdc-{DateTime.Now.ToString("yyyyMMddHHmm")}.oiz.tar"); // Confirm if the user really really wants to backup if (String.IsNullOrEmpty(password) && !ApplicationContext.Current.Confirm(Strings.locale_backup_confirm)) { return; } // TODO: Audit the backup to the data to the central server AuditUtil.AuditDataExport(); // Try to backup the data try { this.m_tracer.TraceInfo("Beginning backup to {0}..", fileName); ApplicationContext.Current?.SetProgress(Strings.locale_backup, 0.25f); // Backup folders first var sourceDirectory = XamarinApplicationContext.Current.ConfigurationManager.ApplicationDataDirectory; using (var fs = File.Create(fileName)) using (var writer = new SharpCompress.Writers.Tar.TarWriter(fs, new SharpCompress.Writers.WriterOptions(SharpCompress.Common.CompressionType.None))) { this.BackupDirectory(writer, sourceDirectory, sourceDirectory); var appInfo = new ApplicationInfo(false).ToDiagnosticReport(); // Output appInfo using (var ms = new MemoryStream()) { XmlSerializer xsz = new XmlSerializer(appInfo.GetType()); xsz.Serialize(ms, appInfo); ms.Flush(); ms.Seek(0, SeekOrigin.Begin); writer.Write(".appinfo.xml", ms, DateTime.Now); } // Output declaration statement using (var ms = new MemoryStream(Encoding.UTF8.GetBytes($"User {(AuthenticationContext.Current?.Principal?.Identity?.Name ?? "SYSTEM")} created this backup on {DateTime.Now}. The end user was asked to confirm this decision to backup and acknolwedges all responsibilities for guarding this file."))) writer.Write("DISCLAIMER.TXT", ms, DateTime.Now); } this.m_tracer.TraceInfo("Beginning compression {0}..", fileName); using (var fs = File.OpenRead(fileName)) using (var gzs = new GZipStream(File.Create(fileName + ".gz"), CompressionMode.Compress)) { int br = 4096; byte[] buffer = new byte[br]; while (br == 4096) { br = fs.Read(buffer, 0, 4096); gzs.Write(buffer, 0, br); ApplicationContext.Current?.SetProgress(Strings.locale_backup_compressing, (float)fs.Position / (float)fs.Length * 0.5f + 0.5f); } } File.Delete(fileName); } catch (Exception ex) { this.m_tracer.TraceError("Error backing up to {0}: {1}", fileName, ex); throw; } }