00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include "schroot-releaselock-main.h"
00022
00023 #include <cerrno>
00024 #include <cstdlib>
00025 #include <ctime>
00026 #include <iostream>
00027 #include <locale>
00028
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <unistd.h>
00032
00033 #include <boost/format.hpp>
00034
00035 #include <lockdev.h>
00036
00037 using std::endl;
00038 using boost::format;
00039 using sbuild::_;
00040 using sbuild::N_;
00041 using namespace schroot_releaselock;
00042
00043 namespace
00044 {
00045
00046 typedef std::pair<main::error_code,const char *> emap;
00047
00052 emap init_errors[] =
00053 {
00054 emap(main::DEVICE_NOTBLOCK, N_("File is not a block device")),
00055
00056 emap(main::DEVICE_OWNED, N_("Failed to release device lock (lock held by PID %4%)")),
00057 emap(main::DEVICE_RELEASE, N_("Failed to release device lock")),
00058 emap(main::DEVICE_STAT, N_("Failed to stat device"))
00059 };
00060
00061 }
00062
00063 template<>
00064 sbuild::error<main::error_code>::map_type
00065 sbuild::error<main::error_code>::error_strings
00066 (init_errors,
00067 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00068
00069 main::main (options::ptr& options):
00070 schroot_base::main("schroot-releaselock",
00071
00072
00073 _("[OPTION...] - release a device lock"),
00074 options,
00075 false),
00076 opts(options)
00077 {
00078 }
00079
00080 main::~main ()
00081 {
00082 }
00083
00084 void
00085 main::action_releaselock ()
00086 {
00087 if (this->opts->pid == 0)
00088 {
00089 sbuild::log_warning() << _("No PID specified; forcing release of lock")
00090 << endl;
00091 }
00092
00093 struct stat statbuf;
00094
00095 if (stat(this->opts->device.c_str(), &statbuf) == -1)
00096 throw error(this->opts->device, DEVICE_STAT, strerror(errno));
00097
00098 if (!S_ISBLK(statbuf.st_mode))
00099 throw error(this->opts->device, DEVICE_NOTBLOCK);
00100
00101 pid_t status = dev_unlock(this->opts->device.c_str(), this->opts->pid);
00102 if (status < 0)
00103 throw error(this->opts->device, DEVICE_RELEASE);
00104 else if (status > 0)
00105 throw error(this->opts->device, DEVICE_OWNED, status);
00106 }
00107
00108 int
00109 main::run_impl ()
00110 {
00111 if (this->opts->action == options::ACTION_HELP)
00112 action_help(std::cerr);
00113 else if (this->opts->action == options::ACTION_VERSION)
00114 action_version(std::cerr);
00115 else if (this->opts->action == options::ACTION_RELEASELOCK)
00116 action_releaselock();
00117 else
00118 assert(0);
00119
00120 return EXIT_SUCCESS;
00121 }