include_HEADERS = \
MediaException.h \
MediaAccess.h \
- MediaHandler.h
+ MediaHandler.h \
+ Mount.h
# MediaCurl.h
lib@PACKAGE@_media_la_SOURCES = \
MediaAccess.cc \
- MediaHandler.cc
+ MediaHandler.cc \
+ Mount.cc
# MediaCurl.cc
#include <iosfwd>
+#include <string>
+
#include "zypp/base/Exception.h"
///////////////////////////////////////////////////////////////////
class MediaException : public Exception
{
public:
- /** Ctor taking message. */
+ /** Ctor taking message.
+ * Use \ref ZYPP_THROW to throw exceptions.
+ */
+ MediaException()
+ : Exception( "Media Exception" )
+ {}
+ /** Ctor taking message.
+ * Use \ref ZYPP_THROW to throw exceptions.
+ */
MediaException( const std::string & msg_r )
: Exception( msg_r )
{}
+ /** Dtor. */
+ virtual ~MediaException() throw() {};
+ };
+
+ class MediaMountException : public MediaException
+ {
+ public:
+ /** Ctor taking message.
+ * Use \ref ZYPP_DOTHROW to throw exceptions.
+ */
+ MediaMountException( const std::string & msg_r,
+ const std::string & source_r,
+ const std::string & target_r )
+ : MediaException( msg_r )
+ , _source(source_r)
+ , _target(target_r)
+ {}
+ /** Dtor. */
+ virtual ~MediaMountException() throw() {};
+ std::string source() const { return _source; }
+ std::string target() const { return _target; }
+ private:
+ std::string _source;
+ std::string _target;
+ };
+
+ class MediaUnmountException : public MediaException
+ {
+ public:
+ /** Ctor taking message.
+ * Use \ref ZYPP_DOTHROW to throw exceptions.
+ */
+ MediaUnmountException( const std::string & msg_r,
+ const std::string & path_r )
+ : MediaException( msg_r )
+ , _path(path_r)
+ {}
+ /** Dtor. */
+ virtual ~MediaUnmountException() throw() {};
+ std::string path() const { return _path; }
+ private:
+ std::string _path;
};
/////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ V / _` \___ \ | | __) | |
+| | | (_| |___) || | / __/ |
+| |_|\__,_|____/ |_| |_____| |
+| |
+| core system |
+| (C) 2002 SuSE AG |
+\----------------------------------------------------------------------/
+
+ File: Mount.cc
+ Purpose: Implement interface to mount program
+ Author: Ludwig Nussel <lnussel@suse.de>
+ Maintainer: Ludwig Nussel <lnussel@suse.de>
+
+/-*/
+
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "zypp/base/ExternalDataSource.h"
+#include "zypp/base/Logger.h"
+#include "zypp/media/Mount.h"
+#include "zypp/media/MediaException.h"
+
+#ifndef N_
+#define N_(STR) STR
+#endif
+
+using namespace std;
+
+namespace zypp {
+ namespace media {
+
+Mount::Mount()
+{
+ process = 0;
+ exit_code = -1;
+}
+
+Mount::~Mount()
+{
+ MIL << "~Mount()" << endl;
+
+ if ( process )
+ delete process;
+
+ process = NULL;
+
+ MIL << "~Mount() end" << endl;
+}
+
+void Mount::mount ( const string& source,
+ const string& target,
+ const string& filesystem,
+ const string& options,
+ const Environment& environment )
+{
+ const char *const argv[] = {
+ "/bin/mount",
+ "-t", filesystem.c_str(),
+ "-o", options.c_str(),
+ source.c_str(),
+ target.c_str(),
+ NULL
+ };
+
+ std::string err;
+
+ this->run(argv, environment, ExternalProgram::Stderr_To_Stdout);
+
+ if ( process == NULL )
+ {
+ ZYPP_DOTHROW(MediaMountException(source, target, "Error::E_mount_failed"));
+ }
+
+ string value;
+ string output = process->receiveLine();
+
+ // parse error messages
+ while ( output.length() > 0)
+ {
+ string::size_type ret;
+
+ // extract \n
+ ret = output.find_first_of ( "\n" );
+ if ( ret != string::npos )
+ {
+ value.assign ( output, 0, ret );
+ }
+ else
+ {
+ value = output;
+ }
+
+ DBG << "stdout: " << value << endl;
+
+ if ( value.find ( "is already mounted on" ) != string::npos )
+ {
+ err = "Error::E_already_mounted";
+ }
+ else if ( value.find ( "ermission denied" ) != string::npos )
+ {
+ err = "Error::E_no_permission";
+ }
+ else if ( value.find ( "wrong fs type" ) != string::npos )
+ {
+ err = "Error::E_invalid_filesystem";
+ }
+
+ output = process->receiveLine();
+ }
+
+ int status = Status();
+
+ if ( status == 0 )
+ {
+ // return codes overwites parsed error message
+ err = "";
+ }
+ else if ( status != 0 && err == "" )
+ {
+ err = "Error::E_mount_failed";
+ }
+
+ if ( err != "" ) {
+ WAR << "mount " << source << " " << target << ": " << err << endl;
+ ZYPP_DOTHROW(MediaMountException(source, target, err));
+ } else {
+ MIL << "mounted " << source << " " << target << endl;
+ }
+}
+
+void Mount::umount (const string& path)
+{
+ const char *const argv[] = {
+ "/bin/umount",
+ path.c_str(),
+ NULL
+ };
+
+ std::string err;
+
+ this->run(argv, ExternalProgram::Stderr_To_Stdout);
+
+ if ( process == NULL )
+ {
+ ZYPP_DOTHROW(MediaUnmountException("E_mount_failed", path));
+ }
+
+ string value;
+ string output = process->receiveLine();
+
+ // parse error messages
+ while ( output.length() > 0)
+ {
+ string::size_type ret;
+
+ // extract \n
+ ret = output.find_first_of ( "\n" );
+ if ( ret != string::npos )
+ {
+ value.assign ( output, 0, ret );
+ }
+ else
+ {
+ value = output;
+ }
+
+ DBG << "stdout: " << value << endl;
+
+ // if ( value.find ( "not mounted" ) != string::npos )
+ // {
+ // err = Error::E_already_mounted;
+ // }
+
+ if ( value.find ( "device is busy" ) != string::npos )
+ {
+ err = "Error::E_busy";
+ }
+
+ output = process->receiveLine();
+ }
+
+ int status = Status();
+
+ if ( status == 0 )
+ {
+ // return codes overwites parsed error message
+ err = "";
+ }
+ else if ( status != 0 && err == "" )
+ {
+ err = "Error::E_umount_failed";
+ }
+
+ if ( err != "") {
+ WAR << "umount " << path << ": " << err << endl;
+ ZYPP_DOTHROW(MediaUnmountException(err, path));
+ } else {
+ MIL << "unmounted " << path << endl;
+ }
+}
+
+void Mount::run( const char *const *argv, const Environment& environment,
+ ExternalProgram::Stderr_Disposition disp )
+{
+ exit_code = -1;
+
+ if ( process != NULL )
+ {
+ delete process;
+ process = NULL;
+ }
+ // Launch the program
+
+ process = new ExternalProgram(argv, environment, disp, false, -1, true);
+}
+
+/*--------------------------------------------------------------*/
+/* Return the exit status of the Mount process, closing the */
+/* connection if not already done */
+/*--------------------------------------------------------------*/
+int Mount::Status()
+{
+ if ( process == NULL )
+ return -1;
+
+ exit_code = process->close();
+ process->kill();
+ delete process;
+ process = 0;
+
+ DBG << "exit code: " << exit_code << endl;
+
+ return exit_code;
+}
+
+/* Forcably kill the process */
+void Mount::Kill()
+{
+ if (process) process->kill();
+}
+
+ } // namespace media
+} // namespace zypp
--- /dev/null
+/*---------------------------------------------------------------------\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ V / _` \___ \ | | __) | |
+| | | (_| |___) || | / __/ |
+| |_|\__,_|____/ |_| |_____| |
+| |
+| core system |
+| (C) 2002 SuSE AG |
+\----------------------------------------------------------------------/
+
+ File: Wget.h
+ Purpose: Declare interface to mount program
+ Author: Ludwig Nussel <lnussel@suse.de>
+ Maintainer: Ludwig Nussel <lnussel@suse.de>
+
+/-*/
+
+
+// -*- C++ -*-
+
+#ifndef ZYPP_MEDIA_MOUNT_H
+#define ZYPP_MEDIA_MOUNT_H
+#include <set>
+#include <map>
+#include <string>
+
+#include "zypp/ExternalProgram.h"
+
+namespace zypp {
+ namespace media {
+
+ /**
+ * @short Interface to the mount program
+ */
+ class Mount
+ {
+ public:
+
+ /**
+ * For passing additional environment variables
+ * to mount
+ **/
+ typedef ExternalProgram::Environment Environment;
+
+ /**
+ * Mount options. 'key' or 'key=value' pairs, separated by ','
+ **/
+#warning Uncomment Options type if it is needed
+#if 0
+ typedef KVMap<_KVMap::CharSep<'=',','> > Options;
+#endif
+
+ public:
+
+ /**
+ * Create an new instance.
+ */
+ Mount();
+
+ /**
+ * Clean up.
+ */
+ ~Mount();
+
+ /**
+ * mount device
+ *
+ * @param source what to mount (e.g. /dev/hda3)
+ * @param target where to mount (e.g. /mnt)
+ * @param filesystem which filesystem to use (e.g. reiserfs) (-t parameter)
+ * @param options mount options (e.g. ro) (-o parameter)
+ * @param environment optinal environment to pass (e.g. PASSWD="sennah")
+ *
+ * \throws MediaException
+ *
+ */
+
+ void mount ( const std::string& source,
+ const std::string& target,
+ const std::string& filesystem,
+ const std::string& options,
+ const Environment& environment = Environment() );
+
+ /** umount device
+ *
+ * @param path device or mountpoint to umount
+ *
+ * \throws MediaException
+ *
+ * */
+ void umount (const std::string& path);
+
+ private:
+
+ /** The connection to the mount process.
+ * */
+ ExternalProgram *process;
+
+ /**
+ * Run mount with the specified arguments and handle stderr.
+ * @param argv Mount arguments
+ * @param environment Addittional environment to set
+ * @param stderr_disp How to handle stderr, merged with stdout by default
+ * */
+ void run( const char *const *argv, const Environment& environment,
+ ExternalProgram::Stderr_Disposition stderr_disp =
+ ExternalProgram::Stderr_To_Stdout);
+
+ void run( const char *const *argv,
+ ExternalProgram::Stderr_Disposition stderr_disp =
+ ExternalProgram::Stderr_To_Stdout) {
+ Environment notused;
+ run( argv, notused, stderr_disp );
+ }
+
+ /** Return the exit status of the process, closing the connection if
+ * not already done.
+ * */
+ int Status();
+
+ /** Forcably kill the process
+ * */
+ void Kill();
+
+
+ /** The exit code of the process, or -1 if not yet known.
+ * */
+ int exit_code;
+ };
+
+ } // namespace media
+} // namespace zypp
+
+#endif