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 sbuild::_;
00041 using sbuild::N_;
00042 using namespace schroot_releaselock;
00043
00044 namespace
00045 {
00046
00047 typedef std::pair<main::error_code,const char *> emap;
00048
00053 emap init_errors[] =
00054 {
00055 emap(main::DEVICE_NOTBLOCK, N_("File is not a block device")),
00056
00057 emap(main::DEVICE_OWNED, N_("Failed to release device lock (lock held by PID %4%)")),
00058 emap(main::DEVICE_RELEASE, N_("Failed to release device lock")),
00059 emap(main::DEVICE_STAT, N_("Failed to stat device"))
00060 };
00061
00062 }
00063
00064 template<>
00065 sbuild::error<main::error_code>::map_type
00066 sbuild::error<main::error_code>::error_strings
00067 (init_errors,
00068 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00069
00070 main::main (options::ptr& options):
00071 schroot_base::main("schroot-releaselock",
00072
00073
00074 _("[OPTION...] - release a device lock"),
00075 options,
00076 false),
00077 opts(options)
00078 {
00079 }
00080
00081 main::~main ()
00082 {
00083 }
00084
00085 void
00086 main::action_releaselock ()
00087 {
00088 if (this->opts->pid == 0)
00089 {
00090 sbuild::log_warning() << _("No PID specified; forcing release of lock")
00091 << endl;
00092 }
00093
00094 struct stat statbuf;
00095
00096 if (stat(this->opts->device.c_str(), &statbuf) == -1)
00097 throw error(this->opts->device, DEVICE_STAT, strerror(errno));
00098
00099 if (!S_ISBLK(statbuf.st_mode))
00100 throw error(this->opts->device, DEVICE_NOTBLOCK);
00101
00102 pid_t status = dev_unlock(this->opts->device.c_str(), this->opts->pid);
00103 if (status < 0)
00104 throw error(this->opts->device, DEVICE_RELEASE);
00105 else if (status > 0)
00106 throw error(this->opts->device, DEVICE_OWNED, status);
00107 }
00108
00109 int
00110 main::run_impl ()
00111 {
00112 if (this->opts->action == options::ACTION_HELP)
00113 action_help(std::cerr);
00114 else if (this->opts->action == options::ACTION_VERSION)
00115 action_version(std::cerr);
00116 else if (this->opts->action == options::ACTION_RELEASELOCK)
00117 action_releaselock();
00118 else
00119 assert(0);
00120
00121 return EXIT_SUCCESS;
00122 }