/* Copyright © 2003,2006-2008 Roger Leigh * * schroot 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 3 of the License, or * (at your option) any later version. * * schroot 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, see * . * *********************************************************************/ #include #include "sbuild-mntstream.h" #include #include using namespace sbuild; namespace { typedef std::pair emap; /** * This is a list of the supported error codes. It's used to * construct the real error codes map. */ emap init_errors[] = { // TRANSLATORS: %1% = mount file name emap(mntstream::MNT_OPEN, N_("Failed to open mount file '%1%'")), // TRANSLATORS: %1% = mount file name emap(mntstream::MNT_READ, N_("Failed to read mount file '%1%'")) }; } template<> error::map_type error::error_strings (init_errors, init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); mntstream::mntentry::mntentry (struct mntent const& entry): filesystem_name(entry.mnt_fsname), directory(entry.mnt_dir), type(entry.mnt_type), options(entry.mnt_opts), dump_frequency(entry.mnt_freq), fsck_pass(entry.mnt_passno) { } mntstream::mntstream(std::string const& file): file(), mntfile(0), data(), error_status(true), eof_status(true) { open(file); } mntstream::~mntstream() { close(); } void mntstream::open(std::string const& file) { this->mntfile = setmntent(file.c_str(), "r"); if (this->mntfile == 0) { this->file.clear(); this->error_status = true; this->eof_status = true; throw error(file, MNT_OPEN, strerror(errno)); } this->file = file; this->error_status = false; this->eof_status = false; read(); } void mntstream::read(int quantity) { int i; if (this->mntfile == 0) return; for (i = 0; i < quantity; ++i) { struct mntent* entry; errno = 0; entry = getmntent(mntfile); if (entry == 0) // EOF or error { //std::cerr << "Mount file read error: "; if (errno) // error { this->error_status = true; throw error(this->file, MNT_READ, strerror(errno)); } return; } mntentry newentry(*entry); // make a mntentry this->data.push_back(newentry); // push onto the end of the list } } void mntstream::close() { if (this->mntfile) endmntent(this->mntfile); // don't throw an exception on failure // -- it could be called in the // destructor this->mntfile = 0; this->data.clear(); // clear all data this->file.clear(); this->error_status = true; this->eof_status = true; } bool mntstream::eof() const { return this->eof_status; } bool mntstream::bad() const { return this->error_status; } mntstream::operator bool () { return !(bad() || eof()); } bool mntstream::operator ! () { return bad() || eof(); } mntstream& sbuild::operator >> (mntstream& stream, mntstream::mntentry& entry) { stream.read(); // read a new entry if (stream && !stream.data.empty()) // not at end of file or bad. { entry = stream.data.front(); // assign next mntentry to entry stream.data.pop_front(); // remove the entry } else // blank the mntentry and set EOF status { entry = mntstream::mntentry(); stream.eof_status = true; } return stream; }