1 /* === S Y N F I G ========================================================= */
2 /*! \file autorecover.cpp
3 ** \brief Template File
5 ** $Id: autorecover.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
31 #include "autorecover.h"
35 #include <synfig/savecanvas.h>
36 #include <synfig/loadcanvas.h>
41 #ifdef HAVE_SYS_STAT_H
45 #ifdef HAVE_SYS_TIME_H
49 #ifdef HAVE_SYS_WAIT_H
53 #ifdef HAVE_SYS_RESOURCE_H
54 #include <sys/resource.h>
63 /* === U S I N G =========================================================== */
67 using namespace synfig;
68 using namespace studio;
70 /* === M A C R O S ========================================================= */
73 #define mkdir(x,y) mkdir(x)
76 /* === G L O B A L S ======================================================= */
78 /* === P R O C E D U R E S ================================================= */
80 /* === M E T H O D S ======================================================= */
82 AutoRecover::AutoRecover()
85 set_timeout(3*60*1000);
87 if(mkdir(get_shadow_directory().c_str(),ACCESSPERMS)<0)
90 synfig::error("UNABLE TO CREATE \"%s\"",get_shadow_directory().c_str());
94 synfig::info("Created directory \"%s\"",get_shadow_directory().c_str());
98 AutoRecover::~AutoRecover()
103 AutoRecover::get_shadow_directory()
105 return Glib::build_filename(App::get_user_app_directory(),"tmp");
116 AutoRecover::set_timeout(int milliseconds)
118 timeout=milliseconds;
119 auto_backup_connect.disconnect();
121 auto_backup_connect=Glib::signal_timeout().connect(sigc::ptr_fun(&AutoRecover::auto_backup),timeout);
122 // auto_backup_connect=App::main.get_context()->signal_timeout().connect(sigc::mem_fun(&AutoRecover::auto_backup),timeout);
126 AutoRecover::get_shadow_file_name(const synfig::String& filename)
128 unsigned int hash1(0xdeadbeef);
129 unsigned int hash2(0x83502529);
130 char* str_hash1(reinterpret_cast<char*>(&hash1));
131 char* str_hash2(reinterpret_cast<char*>(&hash2));
133 // First we need to hash up the directory
135 String pool(dirname(filename));
139 str_hash1[0]^=pool[1];str_hash1[1]^=pool[2];str_hash1[2]^=pool[3];str_hash1[3]^=pool[0];
140 str_hash2[3]+=pool[0];str_hash2[2]+=pool[1];str_hash2[1]+=pool[2];str_hash2[0]+=pool[3];
142 pool=String(pool,4,pool.size());
146 str_hash1[0]^=pool[0];
147 str_hash1[2]^=pool[0];
148 str_hash2[1]^=pool[0];
149 str_hash2[3]^=pool[0];
151 pool=String(pool,1,pool.size());
156 return Glib::build_filename(get_shadow_directory(),strprintf("%08X-%s",hash1,basename(filename).c_str()));
158 // return dirname(filename) + ETL_DIRECTORY_SEPERATOR + ".shadow_" + basename(filename);
162 AutoRecover::cleanup_pid(int pid)
166 if(waitpid(pid,&status,WNOHANG)==-1)
168 synfig::info("PID %d isn't a zombie yet",pid);
171 if(WEXITSTATUS(status)!=0)
173 synfig::error("Autobackup seems to have failed! (PID=%d)",pid);
176 synfig::info("PID=%d has been cleaned up",pid);
182 AutoRecover::auto_backup()
192 #ifdef HAVE_SETPRIORITY
193 // make us low priority so that we don't
194 // cause the machine to slow down too much
195 setpriority(PRIO_PROCESS,0,15);
200 std::list<etl::handle<Instance> >::iterator iter;
202 std::string filename=App::get_config_file("autorecovery");
203 std::ofstream file(filename.c_str());
207 for(iter=App::instance_list.begin();iter!=App::instance_list.end();++iter)
209 // If this file hasn't even been changed
210 // since it was last saved, then don't bother
212 if((*iter)->get_action_count()==0)
215 Canvas::Handle canvas((*iter)->get_canvas());
216 file<<canvas->get_file_name()<<endl;
217 save_canvas(get_shadow_file_name(canvas->get_file_name()),canvas);
222 synfig::info("AutoRecover::auto_backup(): %d Files backed up.",savecount);
226 synfig::error("AutoRecover::auto_backup(): UNKNOWN EXCEPTION THROWN.");
227 synfig::error("AutoRecover::auto_backup(): FILES NOT BACKED UP.");
239 Glib::signal_timeout().connect(
241 sigc::ptr_fun(&AutoRecover::cleanup_pid),
248 // Also go ahead and save the settings
249 App::save_settings();
255 AutoRecover::recovery_needed()const
257 std::string filename=App::get_config_file("autorecovery");
258 std::ifstream file(filename.c_str());
264 std::string filename;
265 getline(file,filename);
266 if(!filename.empty())
274 AutoRecover::recover()
276 std::string filename=App::get_config_file("autorecovery");
277 std::ifstream file(filename.c_str());
284 std::string filename;
285 getline(file,filename);
290 if(App::open_as(get_shadow_file_name(filename),filename))
292 // Correct the file name
293 App::instance_list.back()->set_file_name(filename);
295 // This file isn't saved! mark it as such
296 App::instance_list.back()->inc_action_count();
306 AutoRecover::normal_shutdown()
308 // Turn off the timer
309 auto_backup_connect.disconnect();
311 std::string filename=App::get_config_file("autorecovery");
312 remove(filename.c_str());
316 AutoRecover::clear_backup(synfig::Canvas::Handle canvas)
319 remove(get_shadow_file_name(canvas->get_file_name()).c_str());