/* Delete a particular public key from the archive. 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 "Parsed_Name.hpp" #include "../../config.h" #include "Spawn.hpp" #include "gvfs.hpp" #include "Temp_File.hpp" #include "get_gpg_name.hpp" #include "tempdir.hpp" using namespace std; using namespace boost; namespace fs=boost::filesystem; using fs::path; void delete_key_from_archive(const Parsed_Name &name, const string &key) { list gpg=get_gpg_name(); if(!gpg.empty()) { /* Get the old keyring */ gvfs::Init(); gvfs::uri public_keys(name.archive_location() / ",meta-info/public_keys"); Temp_File new_public_keys(tempdir(),",,public_keys"); /* This is an ugly hack to delete the autmatic backup file that gpg likes to make. */ Temp_File new_public_keys_backup(path(new_public_keys.path .string() + "~")); /* And this is another ugly hack to allow you to delete signatures without deleting your secret key. */ Temp_File secret_keys(tempdir(),",,secret_keys"); if(gvfs::exists(public_keys)) gvfs::copy(public_keys,new_public_keys.path.native_file_string()); /* Delete the key */ Spawn gpg_delete; for(list::iterator i=gpg.begin(); i!=gpg.end(); ++i) gpg_delete << *i; gpg_delete << "--no-default-keyring" << "-q" << "--yes" << "--batch" << "--keyring" << system_complete(new_public_keys.path).native_file_string() << "--secret-keyring" << system_complete(secret_keys.path).native_file_string() << "--delete-key" << key; int return_status; if(!gpg_delete.execute(return_status,true) || return_status!=0) throw arx_error("Error when executing gpg to delete the key\n\t" + key); /* If there are any keys left, copy the result over, deleting any left-over new public keys */ if(!is_empty(new_public_keys.path)) { gvfs::uri new_archive_keys(public_keys.string() + "_new"); if(gvfs::exists(new_archive_keys)) gvfs::remove(new_archive_keys); gvfs::copy(gvfs::uri(new_public_keys.path.native_file_string()), new_archive_keys); gvfs::rename(new_archive_keys,public_keys); } /* Otherwise, just delete the old keys */ else { gvfs::remove(public_keys); } } else throw arx_error("ERROR: You can not delete keys from archives, because ArX has not been\ncompiled with gpg support and you did not specify a gpg program\nwith \"arx param\"."); }