1 | /* |
2 | This file is part of the KDE libraries |
3 | |
4 | SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org> |
5 | SPDX-FileCopyrightText: 2006 Allen Winter <winter@kde.org> |
6 | SPDX-FileCopyrightText: 2006 Gregory S. Hayes <syncomm@kde.org> |
7 | SPDX-FileCopyrightText: 2006 Jaison Lee <lee.jaison@gmail.com> |
8 | SPDX-FileCopyrightText: 2011 Romain Perier <bambi@ubuntu.com> |
9 | |
10 | SPDX-License-Identifier: LGPL-2.0-only |
11 | */ |
12 | |
13 | #include "kbackup.h" |
14 | |
15 | #include <QDir> |
16 | #include <QFileInfo> |
17 | |
18 | namespace KBackup |
19 | { |
20 | bool simpleBackupFile(const QString &qFilename, const QString &backupDir, const QString &backupExtension) |
21 | { |
22 | QString backupFileName = qFilename + backupExtension; |
23 | |
24 | if (!backupDir.isEmpty()) { |
25 | QFileInfo fileInfo(qFilename); |
26 | backupFileName = backupDir + QLatin1Char('/') + fileInfo.fileName() + backupExtension; |
27 | } |
28 | |
29 | // qCDebug(KCOREADDONS_DEBUG) << "KBackup copying " << qFilename << " to " << backupFileName; |
30 | QFile::remove(fileName: backupFileName); |
31 | return QFile::copy(fileName: qFilename, newName: backupFileName); |
32 | } |
33 | |
34 | bool numberedBackupFile(const QString &qFilename, const QString &backupDir, const QString &backupExtension, const uint maxBackups) |
35 | { |
36 | QFileInfo fileInfo(qFilename); |
37 | |
38 | // The backup file name template. |
39 | QString sTemplate; |
40 | if (backupDir.isEmpty()) { |
41 | sTemplate = qFilename + QLatin1String(".%1" ) + backupExtension; |
42 | } else { |
43 | sTemplate = backupDir + QLatin1Char('/') + fileInfo.fileName() + QLatin1String(".%1" ) + backupExtension; |
44 | } |
45 | |
46 | // First, search backupDir for numbered backup files to remove. |
47 | // Remove all with number 'maxBackups' and greater. |
48 | QDir d = backupDir.isEmpty() ? fileInfo.dir() : backupDir; |
49 | d.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); |
50 | const QStringList nameFilters = QStringList(fileInfo.fileName() + QLatin1String(".*" ) + backupExtension); |
51 | d.setNameFilters(nameFilters); |
52 | d.setSorting(QDir::Name); |
53 | |
54 | uint maxBackupFound = 0; |
55 | const QFileInfoList infoList = d.entryInfoList(); |
56 | for (const QFileInfo &fi : infoList) { |
57 | if (fi.fileName().endsWith(s: backupExtension)) { |
58 | // sTemp holds the file name, without the ending backupExtension |
59 | QString sTemp = fi.fileName(); |
60 | sTemp.truncate(pos: fi.fileName().length() - backupExtension.length()); |
61 | // compute the backup number |
62 | int idex = sTemp.lastIndexOf(c: QLatin1Char('.')); |
63 | if (idex > 0) { |
64 | bool ok; |
65 | const uint num = QStringView(sTemp).mid(pos: idex + 1).toUInt(ok: &ok); |
66 | if (ok) { |
67 | if (num >= maxBackups) { |
68 | QFile::remove(fileName: fi.filePath()); |
69 | } else { |
70 | maxBackupFound = qMax(a: maxBackupFound, b: num); |
71 | } |
72 | } |
73 | } |
74 | } |
75 | } |
76 | |
77 | // Next, rename max-1 to max, max-2 to max-1, etc. |
78 | QString to = sTemplate.arg(a: maxBackupFound + 1); |
79 | for (int i = maxBackupFound; i > 0; i--) { |
80 | QString from = sTemplate.arg(a: i); |
81 | // qCDebug(KCOREADDONS_DEBUG) << "KBackup renaming " << from << " to " << to; |
82 | QFile::rename(oldName: from, newName: to); |
83 | to = from; |
84 | } |
85 | |
86 | // Finally create most recent backup by copying the file to backup number 1. |
87 | // qCDebug(KCOREADDONS_DEBUG) << "KBackup copying " << qFilename << " to " << sTemplate.arg(1); |
88 | return QFile::copy(fileName: qFilename, newName: sTemplate.arg(a: 1)); |
89 | } |
90 | |
91 | } |
92 | |