1 /*
2 FXiTe - The Free eXtensIble Text Editor
3 Copyright (c) 2009 Jeffrey Pohlmeyer <yetanothergeek@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 3 as
7 published by the Free Software Foundation.
8
9 This software is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19
20 #include <unistd.h>
21 #include <cerrno>
22 #include <fx.h>
23
24 #include "scidoc_util.h"
25 #include "compat.h"
26
27 #include "intl.h"
28 #include "backup.h"
29
30
31 #define ErrorMessage(fmt, fn) \
32 { \
33 if (mainwin->shown()) { \
34 FXMessageBox::error(mainwin, \
35 MBOX_OK, _("Autosave Error"), "%s:\n%s\n(%s)", fmt,fn.text(), lasterror.text()); \
36 } else { \
37 FXMessageBox::error(FXApp::instance(), \
38 MBOX_OK, _("Autosave Error"), "%s:\n%s\n(%s)", fmt, fn.text(), lasterror.text()); \
39 } \
40 }
41
42
43
MakePath(const FXString & path)44 bool BackupMgr::MakePath(const FXString& path)
45 {
46 lasterror="";
47 FXString parts=FXPath::absolute(path);
48 FXString dirs=FXPath::root(parts);
49 parts.append(PATHSEP);
50 FXint nseps=parts.contains(PATHSEP);
51 FXint i;
52 for (i=1;i<nseps;i++) {
53 dirs.append(parts.section(PATHSEP,i));
54 if (!(IsDir(dirs)||FXDir::create(dirs,FXIO::OwnerFull))) {
55 lasterror=SystemErrorStr();
56 ErrorMessage(_("Failed to create backup directory"), dirs);
57 return false;
58 }
59 dirs.append(PATHSEP);
60 }
61 return true;
62 }
63
64
65
BackupMgr(FXMainWindow * w,const FXString & configdir)66 BackupMgr::BackupMgr(FXMainWindow*w, const FXString &configdir)
67 {
68 mainwin=w;
69 backupdir=configdir;
70 backupdir=FXPath::directory(backupdir);
71 backupdir=FXPath::directory(backupdir);
72 backupdir.append(PATHSEP);
73 backupdir.append("backups.d");
74 MakePath(backupdir);
75 backupdir.append(PATHSEP);
76 }
77
78 #ifdef WIN32
79 # define FN_FMT "%s%d-%p"
80 #else
81 # define FN_FMT "%s%d-%lx"
82 #endif
83
84
SaveBackup(SciDoc * sci)85 bool BackupMgr::SaveBackup(SciDoc*sci)
86 {
87 FXString savename;
88 FXString untitled;
89 untitled.format(FN_FMT, backupdir.text(), abs(getpid()), SciDocUtils::ID(sci));
90 if (SciDocUtils::Filename(sci).empty()) {
91 savename=untitled;
92 } else {
93 if (FXStat::isFile(untitled)) {
94 RemoveBackup(untitled);
95 }
96 #ifdef WIN32
97 savename=SciDocUtils::Filename(sci).text();
98 savename.substitute(':', '%', true);
99 savename.prepend(backupdir.text());
100 #else
101 savename.format("%s%s", backupdir.text(), SciDocUtils::Filename(sci).text());
102 #endif
103 }
104 if (MakePath(FXPath::directory(savename))) {
105 if (SciDocUtils::SaveToFile(sci,savename.text(),false)) {
106 SciDocUtils::NeedBackup(sci, false);
107 return true;
108 } else {
109 lasterror=SciDocUtils::GetLastError(sci);
110 ErrorMessage(_("Failed to save backup"), savename);
111 return false;
112 }
113 } else {
114 return false;
115 }
116 }
117
118
119
RemoveBackup(const FXString & filename)120 void BackupMgr::RemoveBackup(const FXString&filename) {
121 if (FXFile::remove(filename)) {
122 FXString dir=filename;
123 while (1) {
124 dir=FXPath::directory(dir);
125 if ( (dir+PATHSEP) == backupdir ) { break; }
126 if (!FXDir::remove(dir)) { break; }
127 }
128 }
129 }
130
131
132
RemoveBackup(SciDoc * sci)133 void BackupMgr::RemoveBackup(SciDoc*sci)
134 {
135 FXString untitled;
136 SciDocUtils::NeedBackup(sci,false);
137 untitled.format(FN_FMT, backupdir.text(), abs(getpid()), SciDocUtils::ID(sci));
138 RemoveBackup(untitled);
139 if (!SciDocUtils::Filename(sci).empty()) {
140 FXString savename;
141 #ifdef WIN32
142 savename=SciDocUtils::Filename(sci).text();
143 savename.substitute(':', '%', true);
144 savename.prepend(backupdir.text());
145 #else
146 savename.format("%s%s", backupdir.text(), SciDocUtils::Filename(sci).text());
147 #endif
148 RemoveBackup(savename);
149 }
150 }
151
152