/* Query, add, or delete archive registrations Copyright (C) 2001, 2002 Tom Lord Copyright (C) 2002, 2003 Walter Landry and the Regents of the University of California Copyright (C) 2004, 2005 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 #include #include #include "parse_common_options.hpp" #include "parse_unknown_options.hpp" #include "check_extra_args.hpp" #include "get_option_from_file.hpp" #include "command_initializer.hpp" #include "arx_error.hpp" #include "boost/filesystem/operations.hpp" #include "boost/filesystem/exception.hpp" #include "Parsed_Name.hpp" #include "list_archive_keys.hpp" #include "gvfs.hpp" #include "create_archive_registration.hpp" #include "read_archive_locations.hpp" #include "write_archive_locations.hpp" #include "match_uri_fragment.hpp" #include "delete_archive_registration.hpp" using namespace std; using namespace boost; namespace fs=boost::filesystem; using fs::path; int archives(list &argument_list, const command &cmd); static command_initializer archives_init(command("archives", "Query, add, or delete archive registrations", "usage: archives [options] [archive]\n\ archives --add LOCATION\n\ archives --delete ARCHIVE [LOCATION]\n\ archives --make-default ARCHIVE LOCATION", " -a --add add an archive located in LOCATION\n\ -d --delete Delete ARCHIVE's registration\n\ --make-default Set LOCATION as the default for ARCHIVE\n\ --keys print public keys\n\ \n\ Query, add, or delete archive registrations. Without any options or\n\ arguments, it will print out all archive names and locations. If\n\ you specify an archive, it will only print out information about\n\ that archive.\n\ \n\ With the --add option, you must specify the location of the new archive.\n\ ArX will then automatically discover the name of the archive. With\n\ the --delete option, you must specify the archive name to delete. For\n\ example:\n\ \n\ arx archives -a http://example.org/foo-archive\n\ \n\ will add the archive at that location. If the archive is named foo-archive,\n\ then\n\ \n\ arx archives -d foo-archive\n\ \n\ will delete the registration. If you only want to delete one location for\n\ an archive, specify the location as well, as in\n\ \n\ arx archives -d foo-archive http://example.org/foo-archive\n\ \n\ If you have several locations registered for one archive (e.g. for mirrors),\n\ the first location is the one used for \"get\", \"commit\", etc. You can\n\ change the default with the --make-default option. The location can be\n\ abbreviated. See \"arx mirror --help\" for details.", archives,"Miscellaneous Advanced",true)); int archives(list &argument_list, const command &cmd) { bool print_keys(false), add(false), remove(false), make_default(false); Command_Info info(cmd); bool done=false; while(!argument_list.empty() && !done) { if(!parse_common_options(argument_list,info)) { list::iterator arg=argument_list.begin(); if(*arg=="--keys") { print_keys=true; argument_list.pop_front(); } else if(*(argument_list.begin())=="--add" || *(argument_list.begin())=="-a") { add=true; argument_list.pop_front(); } else if(*(argument_list.begin())=="--delete" || *(argument_list.begin())=="-d") { remove=true; argument_list.pop_front(); } else if(*(argument_list.begin())=="--make-default") { make_default=true; argument_list.pop_front(); } else { parse_unknown_options(argument_list); done=true; } } } if((add && (remove || make_default)) || (remove && make_default)) throw arx_error("You may only specify one of add, delete, or make-default"); string argument; if(!argument_list.empty()) { argument=*argument_list.begin(); argument_list.pop_front(); } if((add || remove) && argument.empty()) throw arx_error("Argument required for --add and --delete"); string location_fragment; if((remove || make_default) && !argument_list.empty()) { location_fragment=*argument_list.begin(); argument_list.pop_front(); } check_extra_args(argument_list,info); /* Add an archive */ if(add) { gvfs::Init(); gvfs::uri location(argument); string archive; if(gvfs::exists(location/ ",meta-info/name")) { archive=read_archive(location/ ",meta-info/name"); } else { throw arx_error("This location does not appear to have an archive there.\n\t" + archive + "\nSpecifically, there should be a file\n\t" + (location/ ",meta-info/name").string()); } create_archive_registration(archive,location); } else if(remove) { delete_archive_registration(argument,location_fragment); } /* Make a location the default */ else if(make_default) { /* Match the input */ Parsed_Name archive(argument+"/"); string default_location(match_uri_fragment(location_fragment,archive)); list locations(read_archive_locations(archive)); /* Find the match in the list, delete it, reinsert in the front, and rewrite the locations. */ list::iterator i=find(locations.begin(),locations.end(), default_location); locations.erase(i); locations.push_front(default_location); write_archive_locations(archive,locations); } /* Simply list the registrations */ else { path home(getenv("HOME")); if(lexists(home / ".arx/archives")) { for(fs::directory_iterator i(home / ".arx/archives"); i!=fs::directory_iterator(); ++i) if(argument.empty() || i->leaf()==argument) { string element; list locations; locations=read_archive_locations((*i)/"uri"); element=i->leaf(); for(list::iterator j=locations.begin(); j!=locations.end(); ++j) element+="\n\t" + *j; cout << element << endl; if(print_keys) list_archive_keys(Parsed_Name(i->leaf()+"/")); } } } return 0; }