mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 00:41:17 +02:00
our current experimental Neutrino branch
git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@27 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
384
src/system/fsmounter.cpp
Normal file
384
src/system/fsmounter.cpp
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
Neutrino-GUI - DBoxII-Project
|
||||
|
||||
FSMount/Umount by Zwen
|
||||
|
||||
Homepage: http://dbox.cyberphoria.org/
|
||||
|
||||
Kommentar:
|
||||
|
||||
Diese GUI wurde von Grund auf neu programmiert und sollte nun vom
|
||||
Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert
|
||||
auf der Client-Server Idee, diese GUI ist also von der direkten DBox-
|
||||
Steuerung getrennt. Diese wird dann von Daemons uebernommen.
|
||||
|
||||
|
||||
License: GPL
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <system/fsmounter.h>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <global.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_mutex_t g_mut;
|
||||
pthread_cond_t g_cond;
|
||||
pthread_t g_mnt;
|
||||
int g_mntstatus;
|
||||
|
||||
void *mount_thread(void* cmd)
|
||||
{
|
||||
int ret;
|
||||
ret=system((const char *) cmd);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
g_mntstatus=ret;
|
||||
pthread_cond_broadcast(&g_cond);
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
CFSMounter::CFSMounter()
|
||||
{
|
||||
}
|
||||
|
||||
bool in_proc_filesystems(const char * const fsname)
|
||||
{
|
||||
std::string s;
|
||||
std::string t;
|
||||
std::ifstream in("/proc/filesystems", std::ifstream::in);
|
||||
|
||||
t = fsname;
|
||||
|
||||
while (in >> s)
|
||||
{
|
||||
if (s == t)
|
||||
{
|
||||
in.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool insert_modules(const CFSMounter::FSType fstype)
|
||||
{
|
||||
if (fstype == CFSMounter::NFS)
|
||||
{
|
||||
#ifdef HAVE_MODPROBE
|
||||
return (system("modprobe nfs") == 0);
|
||||
#else
|
||||
return ((system("insmod sunrpc") == 0) && (system("insmod lockd") == 0) && (system("insmod nfs") == 0));
|
||||
#endif
|
||||
}
|
||||
else if (fstype == CFSMounter::CIFS)
|
||||
return (system("insmod cifs") == 0);
|
||||
else if (fstype == CFSMounter::LUFS)
|
||||
return (system("insmod lufs") == 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nfs_mounted_once = false;
|
||||
|
||||
bool remove_modules(const CFSMounter::FSType fstype)
|
||||
{
|
||||
if (fstype == CFSMounter::NFS)
|
||||
{
|
||||
return ((system("rmmod nfs") == 0) && (system("rmmod lockd") == 0) && (system("rmmod sunrpc") == 0));
|
||||
}
|
||||
else if (fstype == CFSMounter::CIFS)
|
||||
return (system("rmmod cifs") == 0);
|
||||
else if (fstype == CFSMounter::LUFS)
|
||||
return (system("rmmod lufs") == 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFSMounter::FS_Support CFSMounter::fsSupported(const CFSMounter::FSType fstype, const bool keep_modules)
|
||||
{
|
||||
const char * fsname = NULL;
|
||||
|
||||
if (fstype == CFSMounter::NFS)
|
||||
fsname = "nfs";
|
||||
else if (fstype == CFSMounter::CIFS)
|
||||
fsname = "cifs";
|
||||
else if (fstype == CFSMounter::LUFS)
|
||||
fsname = "lufs";
|
||||
|
||||
if (in_proc_filesystems(fsname))
|
||||
return CFSMounter::FS_READY;
|
||||
|
||||
if (insert_modules(fstype))
|
||||
{
|
||||
if (in_proc_filesystems(fsname))
|
||||
{
|
||||
if (keep_modules)
|
||||
{
|
||||
if (fstype == CFSMounter::NFS)
|
||||
nfs_mounted_once = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_modules(fstype);
|
||||
}
|
||||
|
||||
return CFSMounter::FS_NEEDS_MODULES;
|
||||
}
|
||||
}
|
||||
remove_modules(fstype);
|
||||
return CFSMounter::FS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
bool CFSMounter::isMounted(const char * const local_dir)
|
||||
{
|
||||
std::ifstream in;
|
||||
if (local_dir == NULL)
|
||||
return false;
|
||||
|
||||
// according to the man page realpath() sucks, but there's nothing better :(
|
||||
int path_max = 0;
|
||||
|
||||
#ifdef PATH_MAX
|
||||
path_max = PATH_MAX;
|
||||
#else
|
||||
path_max = 4096;
|
||||
#endif
|
||||
char mount_point[path_max];
|
||||
if (realpath(local_dir, mount_point) == NULL) {
|
||||
printf("[CFSMounter] could not resolve dir: %s: %s\n",local_dir, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
in.open("/proc/mounts", std::ifstream::in);
|
||||
while(in.good())
|
||||
{
|
||||
MountInfo mi;
|
||||
in >> mi.device >> mi.mountPoint >> mi.type;
|
||||
if (strcmp(mi.mountPoint.c_str(),mount_point) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CFSMounter::MountRes CFSMounter::mount(const char * const ip, const char * const dir, const char * const local_dir,
|
||||
const FSType fstype, const char * const username, const char * const password,
|
||||
char * options1, char * options2)
|
||||
{
|
||||
std::string cmd;
|
||||
pthread_mutex_init(&g_mut, NULL);
|
||||
pthread_cond_init(&g_cond, NULL);
|
||||
g_mntstatus=-1;
|
||||
|
||||
FS_Support sup = fsSupported(fstype, true); /* keep modules if necessary */
|
||||
|
||||
if (sup == CFSMounter::FS_UNSUPPORTED)
|
||||
{
|
||||
printf("[CFSMounter] FS type %d not supported\n", (int) fstype);
|
||||
return MRES_FS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
printf("[CFSMounter] Mount(%d) %s:%s -> %s\n", (int) fstype, ip, dir, local_dir);
|
||||
|
||||
if (isMounted(local_dir))
|
||||
{
|
||||
printf("[CFSMounter] FS mount error %s already mounted\n", local_dir);
|
||||
return MRES_FS_ALREADY_MOUNTED;
|
||||
}
|
||||
|
||||
if(options1[0] == '\0')
|
||||
{
|
||||
strcpy(options1,options2);
|
||||
options2[0] = '\0';
|
||||
}
|
||||
|
||||
if((options1[0] == '\0') && (options2[0] == '\0'))
|
||||
{
|
||||
if(fstype == NFS)
|
||||
{
|
||||
strcpy(options1,"ro,soft,udp");
|
||||
strcpy(options2,"nolock,rsize=8192,wsize=8192");
|
||||
}
|
||||
else if(fstype == CIFS)
|
||||
{
|
||||
strcpy(options1,"ro");
|
||||
strcpy(options2,"");
|
||||
}
|
||||
else if(fstype == LUFS)
|
||||
{
|
||||
strcpy(options1,"");
|
||||
strcpy(options2,"");
|
||||
}
|
||||
}
|
||||
|
||||
if(fstype == NFS)
|
||||
{
|
||||
cmd = "mount -t nfs ";
|
||||
cmd += ip;
|
||||
cmd += ':';
|
||||
cmd += dir;
|
||||
cmd += ' ';
|
||||
cmd += local_dir;
|
||||
cmd += " -o ";
|
||||
cmd += options1;
|
||||
}
|
||||
else if(fstype == CIFS)
|
||||
{
|
||||
cmd = "mount -t cifs //";
|
||||
cmd += ip;
|
||||
cmd += '/';
|
||||
cmd += dir;
|
||||
cmd += ' ';
|
||||
cmd += local_dir;
|
||||
cmd += " -o username=";
|
||||
cmd += username;
|
||||
cmd += ",password=";
|
||||
cmd += password;
|
||||
//cmd += ",unc=//"; for whats needed?
|
||||
//cmd += ip;
|
||||
//cmd += '/';
|
||||
//cmd += dir;
|
||||
//cmd += ',';
|
||||
//cmd += options1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = "lufsd none ";
|
||||
cmd += local_dir;
|
||||
cmd += " -o fs=ftpfs,username=";
|
||||
cmd += username;
|
||||
cmd += ",password=";
|
||||
cmd += password;
|
||||
cmd += ",host=";
|
||||
cmd += ip;
|
||||
cmd += ",root=/";
|
||||
cmd += dir;
|
||||
cmd += ',';
|
||||
cmd += options1;
|
||||
}
|
||||
|
||||
if (options2[0] !='\0')
|
||||
{
|
||||
cmd += ',';
|
||||
cmd += options2;
|
||||
}
|
||||
|
||||
pthread_create(&g_mnt, 0, mount_thread, (void *) cmd.c_str());
|
||||
|
||||
struct timespec timeout;
|
||||
int retcode;
|
||||
|
||||
pthread_mutex_lock(&g_mut);
|
||||
timeout.tv_sec = time(NULL) + 5;
|
||||
timeout.tv_nsec = 0;
|
||||
retcode = pthread_cond_timedwait(&g_cond, &g_mut, &timeout);
|
||||
if (retcode == ETIMEDOUT)
|
||||
{ // timeout occurred
|
||||
pthread_cancel(g_mnt);
|
||||
}
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
pthread_join(g_mnt, NULL);
|
||||
if ( g_mntstatus != 0 )
|
||||
{
|
||||
printf("[CFSMounter] FS mount error: \"%s\"\n", cmd.c_str());
|
||||
return (retcode == ETIMEDOUT) ? MRES_TIMEOUT : MRES_UNKNOWN;
|
||||
}
|
||||
return MRES_OK;
|
||||
|
||||
}
|
||||
|
||||
bool CFSMounter::automount()
|
||||
{
|
||||
bool res = true;
|
||||
for(int i = 0; i < NETWORK_NFS_NR_OF_ENTRIES; i++)
|
||||
{
|
||||
if(g_settings.network_nfs_automount[i])
|
||||
{
|
||||
res = (MRES_OK == mount(g_settings.network_nfs_ip[i].c_str(), g_settings.network_nfs_dir[i], g_settings.network_nfs_local_dir[i],
|
||||
(FSType) g_settings.network_nfs_type[i], g_settings.network_nfs_username[i],
|
||||
g_settings.network_nfs_password[i], g_settings.network_nfs_mount_options1[i],
|
||||
g_settings.network_nfs_mount_options2[i])) && res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
CFSMounter::UMountRes CFSMounter::umount(const char * const dir)
|
||||
{
|
||||
UMountRes res = UMRES_OK;
|
||||
if (dir != NULL)
|
||||
{
|
||||
if (umount2(dir, MNT_FORCE) != 0)
|
||||
{
|
||||
return UMRES_ERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MountInfo mi;
|
||||
std::ifstream in("/proc/mounts", std::ifstream::in);
|
||||
while(in.good())
|
||||
{
|
||||
in >> mi.device >> mi.mountPoint >> mi.type;
|
||||
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
|
||||
if(strcmp(mi.type.c_str(),"nfs")==0 && strcmp(mi.mountPoint.c_str(),"/")==0)
|
||||
{
|
||||
if (umount2(mi.mountPoint.c_str(),MNT_FORCE) != 0)
|
||||
{
|
||||
printf("[CFSMounter] Error umounting %s\n",mi.device.c_str());
|
||||
res = UMRES_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nfs_mounted_once)
|
||||
remove_modules(CFSMounter::NFS);
|
||||
return res;
|
||||
}
|
||||
|
||||
void CFSMounter::getMountedFS(MountInfos& info)
|
||||
{
|
||||
std::ifstream in("/proc/mounts", std::ifstream::in);
|
||||
|
||||
while(in.good())
|
||||
{
|
||||
MountInfo mi;
|
||||
in >> mi.device >> mi.mountPoint >> mi.type;
|
||||
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
if (mi.type == "nfs" ||
|
||||
mi.type == "cifs" ||
|
||||
mi.type == "lufs")
|
||||
{
|
||||
info.push_back(mi);
|
||||
printf("[CFSMounter] mounted fs: dev: %s, mp: %s, type: %s\n",
|
||||
mi.device.c_str(),mi.mountPoint.c_str(),mi.type.c_str());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user