/* Set a property for a given path. Copyright (C) 2004 Walter Landry This program 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 program 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "arx_error.hpp" #include "boost/filesystem/operations.hpp" #include "boost/filesystem/fstream.hpp" #include "boost/archive/text_oarchive.hpp" #include #include "tree_root.hpp" #include "sha256.hpp" #include "file_attributes.hpp" #include "Temp_File.hpp" #include using namespace std; using namespace boost; namespace fs=boost::filesystem; using fs::path; void property_action(const path &dir, const path &file_path, const string &action, const string &key, const string &value) { const path root(tree_root(dir)); Temp_File temp_changes(root,",,changes"); if(lexists(root/"_arx/++changes")) copy_file(root/"_arx/++changes",temp_changes.path); { fs::ofstream changes(temp_changes.path,ios::app|ios::out); changes << "\n" << action << "\t"; archive::text_oarchive changes_archive(changes,archive::no_header); changes_archive << file_path.string() << key << value; } if(rename(temp_changes.path.native_file_string().c_str(), (root/"_arx/++changes").native_file_string().c_str())!=0) throw arx_error("Can't rename " + temp_changes.path.native_file_string() + " to " + (root/"_arx/++changes").native_file_string()); if(action=="set") { map stat_map; stat_map["arx:user-read"]=S_IRUSR; stat_map["arx:user-write"]=S_IWUSR; stat_map["arx:user-exec"]=S_IXUSR; stat_map["arx:group-read"]=S_IRGRP; stat_map["arx:group-write"]=S_IWGRP; stat_map["arx:group-exec"]=S_IXGRP; stat_map["arx:other-read"]=S_IROTH; stat_map["arx:other-write"]=S_IWOTH; stat_map["arx:other-exec"]=S_IXOTH; if(stat_map.find(key)!=stat_map.end()) { struct stat path_stat; if(::stat((root/file_path).native_file_string().c_str(),&path_stat)) throw arx_error("Can't stat " + (root/file_path).native_file_string()); if(value=="true") { path_stat.st_mode|=stat_map[key]; } else if(value=="false") { path_stat.st_mode&=~stat_map[key]; } else { throw arx_error("Bad property value for " + key + ". It must be either true or false\n\t" + value); } if(::chmod((root/file_path).native_file_string().c_str(), path_stat.st_mode)) throw arx_error("Can't chmod " + (root/file_path).native_file_string()); } } }