/* === S Y N F I G ========================================================= */ /*! \file cvs.cpp ** \brief Template File ** ** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as ** published by the Free Software Foundation; either version 2 of ** the License, or (at your option) any later version. ** ** This package is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** General Public License for more details. ** \endlegal */ /* ========================================================================= */ /* === H E A D E R S ======================================================= */ #ifdef USING_PCH # include "pch.h" #else #ifdef HAVE_CONFIG_H # include #endif #include "cvs.h" #include #include #include #include #include #include #include //#include #include #include "general.h" #endif /* === U S I N G =========================================================== */ using namespace std; using namespace etl; using namespace synfig; using namespace synfigapp; /* === M A C R O S ========================================================= */ #define cvs_command synfig::String("cvs -z4") #ifndef WIN32 #define HAVE_STRPTIME #endif #if defined(__APPLE__) || defined(__OpenBSD__) time_t _daylight_() { time_t t(time(0)); return localtime(&t)->tm_gmtoff; } #define daylight _daylight_() #endif /* === G L O B A L S ======================================================= */ /* === P R O C E D U R E S ================================================= */ /* === M E T H O D S ======================================================= */ CVSInfo::CVSInfo(const synfig::String& file_name) { update_available_=false; set_file_name(file_name); } CVSInfo::CVSInfo(): in_sandbox_(), in_repository_(), update_available_(false), original_timestamp_() { } CVSInfo::~CVSInfo() { } void CVSInfo::set_file_name(const synfig::String& file_name) { file_name_=file_name; std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str()); if(file) { in_sandbox_=true; calc_repository_info(); } else in_sandbox_=false; } void CVSInfo::calc_repository_info() { #ifdef _DEBUG synfig::info("in_sandbox() = %d",in_sandbox()); #endif if(!in_sandbox_) return; std::ifstream file((dirname(file_name_)+"/CVS/Entries").c_str()); while(file) { String line; getline(file,line); if(line.find(basename(file_name_))!=String::npos) { in_repository_=true; String::size_type s,f; // Grab the version s=line.find('/',1); assert(s!=String::npos); s++; f=line.find('/',s+1); assert(f!=String::npos); cvs_version_=String(line,s,f-s); // Grab the time #ifdef HAVE_STRPTIME s=f+1; f=line.find('/',s+1); assert(f!=String::npos); tm time_struct; strptime(String(line,s,f-s).c_str(),"%c",&time_struct); original_timestamp_=mktime(&time_struct); #endif if( system(strprintf( "cd '%s' && cvs status '%s' | grep -q -e 'Needs Patch'", dirname(file_name_).c_str(), basename(file_name_).c_str() ).c_str())==0 ) { synfig::info("UPDATE_AVAILABLE=TRUE"); update_available_=true; } else { system(strprintf( "cd '%s' && cvs status '%s'", dirname(file_name_).c_str(), basename(file_name_).c_str() ).c_str()); synfig::info("UPDATE_AVAILABLE=FALSE"); update_available_=false; } #ifdef _DEBUG synfig::info("in_repository() = %d",in_repository()); synfig::info("get_cvs_version() = %s",get_cvs_version().c_str()); synfig::info("get_original_timestamp() = %s",ctime(&get_original_timestamp())); time_t t(get_current_timestamp()); synfig::info("get_current_timestamp() = %s",ctime(&t)); synfig::info("get_cvs_root() = %s",get_cvs_root().c_str()); synfig::info("get_cvs_module() = %s",get_cvs_module().c_str()); #endif return; } } in_repository_=false; cvs_version_.clear(); original_timestamp_=0; #ifdef _DEBUG synfig::info("in_repository() = %d",in_repository()); #endif } bool CVSInfo::in_sandbox()const { return in_sandbox_; } bool CVSInfo::in_repository()const { if(!in_sandbox_) return false; return in_repository_; } bool CVSInfo::is_modified()const { if(!in_sandbox() || !in_repository()) return false; #ifdef _DEBUG synfig::info("%d-%d=%d",get_current_timestamp(),get_original_timestamp(),get_current_timestamp()-get_original_timestamp()); #endif return get_current_timestamp()!=get_original_timestamp() && abs(get_current_timestamp()-get_original_timestamp())!=3600; } bool CVSInfo::is_updated()const { return update_available_; } const synfig::String& CVSInfo::get_cvs_version()const { return cvs_version_; } const time_t& CVSInfo::get_original_timestamp()const { return original_timestamp_; } time_t CVSInfo::get_current_timestamp()const { struct stat st; if(stat(file_name_.c_str(),&st)<0) { synfig::error("Unable to get file stats"); return false; } time_t ret((daylight-1)*3600); //ret+=timezone; ret+=st.st_mtime; return ret; } synfig::String CVSInfo::get_cvs_root()const { if(!in_sandbox_) return synfig::String(); std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str()); if(file) { String ret; getline(file,ret); return ret; } return synfig::String(); } synfig::String CVSInfo::get_cvs_module()const { if(!in_sandbox_) return synfig::String(); std::ifstream file((dirname(file_name_)+"/CVS/Repository").c_str()); if(file) { String ret; getline(file,ret); return ret; } return synfig::String(); } // This function pre-processes the message so that we // don't get any CVS syntax errors. inline synfig::String fix_msg(const synfig::String& message) { synfig::String ret; int i; for(i=0;i<(int)message.size();i++) { if(message[i]=='\'') ret+="'\"'\"'"; else ret+=message[i]; } return ret; } void CVSInfo::cvs_add(const synfig::String& message) { if(!in_sandbox_) { synfig::error("cvs_add(): Not in a sand box"); throw int(); return; } synfig::String command(strprintf("cd '%s' && %s add -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str())); int ret(system(command.c_str())); calc_repository_info(); switch(ret) { case 0: break; default: synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str()); throw(ret); break; } } void CVSInfo::cvs_update() { if(!in_sandbox_) { synfig::error("cvs_update(): Not in a sand box"); throw int(); return; } synfig::String command(strprintf("cd '%s' && %s update '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),basename(file_name_).c_str())); int ret(system(command.c_str())); calc_repository_info(); switch(ret) { case 0: break; default: synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str()); throw(ret); break; } } void CVSInfo::cvs_commit(const synfig::String& message) { if(!in_sandbox_) { synfig::error("cvs_commit(): Not in a sand box"); throw int(); return; } synfig::String command(strprintf("cd '%s' && %s commit -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str())); int ret(system(command.c_str())); calc_repository_info(); switch(ret) { case 0: break; default: synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str()); if(is_modified()) throw(ret); break; } }