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