/* * * This file is part of the KDE libraries * Copyright (c) 2003 Waldo Bastian * * $Id$ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. **/ #include #include #include #include "kstandarddirs.h" #include "kmountpoint.h" #ifdef HAVE_VOLMGT #include #endif #ifdef HAVE_SYS_MNTTAB_H #include #include #endif #ifdef HAVE_MNTENT_H #include #elif defined(HAVE_SYS_MNTENT_H) #include #endif // This is the *BSD branch #ifdef HAVE_SYS_MOUNT_H #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #include #endif #ifdef HAVE_FSTAB_H #include #endif #if defined(_AIX) #include #include #include /* AIX does not prototype mntctl anywhere that I can find */ #ifndef mntctl extern "C" { int mntctl(int command, int size, void* buffer); } #endif extern "C" struct vfs_ent *getvfsbytype(int vfsType); extern "C" void endvfsent( ); #endif #ifndef HAVE_GETMNTINFO # ifdef _PATH_MOUNTED // On some Linux, MNTTAB points to /etc/fstab ! # undef MNTTAB # define MNTTAB _PATH_MOUNTED # else # ifndef MNTTAB # ifdef MTAB_FILE # define MNTTAB MTAB_FILE # else # define MNTTAB "/etc/mnttab" # endif # endif # endif #endif #ifdef _OS_SOLARIS_ #define FSTAB "/etc/vfstab" #else #define FSTAB "/etc/fstab" #endif KMountPoint::KMountPoint() { } KMountPoint::~KMountPoint() { } #ifdef HAVE_SETMNTENT #define SETMNTENT setmntent #define ENDMNTENT endmntent #define STRUCT_MNTENT struct mntent * #define STRUCT_SETMNTENT FILE * #define GETMNTENT(file, var) ((var = getmntent(file)) != 0) #define MOUNTPOINT(var) var->mnt_dir #define MOUNTTYPE(var) var->mnt_type #define MOUNTOPTIONS(var) var->mnt_opts #define FSNAME(var) var->mnt_fsname #else #define SETMNTENT fopen #define ENDMNTENT fclose #define STRUCT_MNTENT struct mnttab #define STRUCT_SETMNTENT FILE * #define GETMNTENT(file, var) (getmntent(file, &var) == 0) #define MOUNTPOINT(var) var.mnt_mountp #define MOUNTTYPE(var) var.mnt_fstype #define MOUNTOPTIONS(var) var.mnt_mntopts #define FSNAME(var) var.mnt_special #endif KMountPoint::List KMountPoint::possibleMountPoints(int infoNeeded) { KMountPoint::List result; #ifdef HAVE_SETMNTENT STRUCT_SETMNTENT fstab; if ((fstab = SETMNTENT(FSTAB, "r")) == 0) return result; STRUCT_MNTENT fe; while (GETMNTENT(fstab, fe)) { KMountPoint *mp = new KMountPoint(); mp->m_mountedFrom = TQFile::decodeName(FSNAME(fe)); mp->m_mountPoint = TQFile::decodeName(MOUNTPOINT(fe)); mp->m_mountType = TQFile::decodeName(MOUNTTYPE(fe)); //Devices using supermount have their device names in the mount options //instead of the device field. That's why we need to read the mount options if (infoNeeded & NeedMountOptions || (mp->m_mountType == "supermount")) { TQString options = TQFile::decodeName(MOUNTOPTIONS(fe)); mp->m_mountOptions = TQStringList::split(',', options); } if(mp->m_mountType == "supermount") mp->m_mountedFrom = devNameFromOptions(mp->m_mountOptions); if (infoNeeded & NeedRealDeviceName) { if (mp->m_mountedFrom.startsWith("/")) mp->m_device = TDEStandardDirs::realPath(mp->m_mountedFrom); } // TODO: Strip trailing '/' ? result.append(mp); } ENDMNTENT(fstab); #else TQFile f(FSTAB); if ( !f.open(IO_ReadOnly) ) return result; TQTextStream t (&f); TQString s; while (! t.eof()) { s=t.readLine().simplifyWhiteSpace(); if ( s.isEmpty() || (s[0] == '#')) continue; // not empty or commented out by '#' TQStringList item = TQStringList::split(' ', s); #ifdef _OS_SOLARIS_ if (item.count() < 5) continue; #else if (item.count() < 4) continue; #endif KMountPoint *mp = new KMountPoint(); int i = 0; mp->m_mountedFrom = item[i++]; #ifdef _OS_SOLARIS_ //device to fsck i++; #endif mp->m_mountPoint = item[i++]; mp->m_mountType = item[i++]; TQString options = item[i++]; if (infoNeeded & NeedMountOptions) { mp->m_mountOptions = TQStringList::split(',', options); } if (infoNeeded & NeedRealDeviceName) { if (mp->m_mountedFrom.startsWith("/")) mp->m_device = TDEStandardDirs::realPath(mp->m_mountedFrom); } // TODO: Strip trailing '/' ? result.append(mp); } //while f.close(); #endif return result; } KMountPoint::List KMountPoint::currentMountPoints(int infoNeeded) { KMountPoint::List result; #ifdef HAVE_GETMNTINFO #ifdef GETMNTINFO_USES_STATVFS struct statvfs *mounted; #else struct statfs *mounted; #endif int num_fs = getmntinfo(&mounted, MNT_NOWAIT); for (int i=0;im_mountedFrom = TQFile::decodeName(mounted[i].f_mntfromname); mp->m_mountPoint = TQFile::decodeName(mounted[i].f_mntonname); #ifdef __osf__ mp->m_mountType = TQFile::decodeName(mnt_names[mounted[i].f_type]); #else mp->m_mountType = TQFile::decodeName(mounted[i].f_fstypename); #endif if (infoNeeded & NeedMountOptions) { struct fstab *ft = getfsfile(mounted[i].f_mntonname); TQString options = TQFile::decodeName(ft->fs_mntops); mp->m_mountOptions = TQStringList::split(',', options); } if (infoNeeded & NeedRealDeviceName) { if (mp->m_mountedFrom.startsWith("/")) mp->m_device = TDEStandardDirs::realPath(mp->m_mountedFrom); } // TODO: Strip trailing '/' ? result.append(mp); } #elif defined(_AIX) struct vmount *mntctl_buffer; struct vmount *vm; char *mountedfrom; char *mountedto; int fsname_len, num; int buf_sz = 4096; mntctl_buffer = (struct vmount*)malloc(buf_sz); num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); if (num == 0) { buf_sz = *(int*)mntctl_buffer; free(mntctl_buffer); mntctl_buffer = (struct vmount*)malloc(buf_sz); num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); } if (num > 0) { /* iterate through items in the vmount structure: */ vm = (struct vmount *)mntctl_buffer; for ( ; num > 0; num-- ) { /* get the name of the mounted file systems: */ fsname_len = vmt2datasize(vm, VMT_STUB); mountedto = (char*)malloc(fsname_len + 1); mountedto[fsname_len] = '\0'; strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len); fsname_len = vmt2datasize(vm, VMT_OBJECT); mountedfrom = (char*)malloc(fsname_len + 1); mountedfrom[fsname_len] = '\0'; strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len); /* Look up the string for the file system type, * as listed in /etc/vfs. * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs */ struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype); KMountPoint *mp = new KMountPoint(); mp->m_mountedFrom = TQFile::decodeName(mountedfrom); mp->m_mountPoint = TQFile::decodeName(mountedto); mp->m_mountType = TQFile::decodeName(ent->vfsent_name); free(mountedfrom); free(mountedto); if (infoNeeded & NeedMountOptions) { // TODO } if (infoNeeded & NeedRealDeviceName) { if (mp->m_mountedFrom.startsWith("/")) mp->m_device = TDEStandardDirs::realPath(mp->m_mountedFrom); } result.append(mp); /* goto the next vmount structure: */ vm = (struct vmount *)((char *)vm + vm->vmt_length); } endvfsent( ); } free( mntctl_buffer ); #elif defined(TQ_WS_WIN) //TODO? #else STRUCT_SETMNTENT mnttab; if ((mnttab = SETMNTENT(MNTTAB, "r")) == 0) return result; STRUCT_MNTENT fe; while (GETMNTENT(mnttab, fe)) { KMountPoint *mp = new KMountPoint(); mp->m_mountedFrom = TQFile::decodeName(FSNAME(fe)); mp->m_mountPoint = TQFile::decodeName(MOUNTPOINT(fe)); mp->m_mountType = TQFile::decodeName(MOUNTTYPE(fe)); //Devices using supermount have their device names in the mount options //instead of the device field. That's why we need to read the mount options if (infoNeeded & NeedMountOptions || (mp->m_mountType == "supermount")) { TQString options = TQFile::decodeName(MOUNTOPTIONS(fe)); mp->m_mountOptions = TQStringList::split(',', options); } if (mp->m_mountType == "supermount") mp->m_mountedFrom = devNameFromOptions(mp->m_mountOptions); if (infoNeeded & NeedRealDeviceName) { if (mp->m_mountedFrom.startsWith("/")) mp->m_device = TDEStandardDirs::realPath(mp->m_mountedFrom); } // TODO: Strip trailing '/' ? result.append(mp); } ENDMNTENT(mnttab); #endif return result; } TQString KMountPoint::devNameFromOptions(const TQStringList &options) { // Search options to find the device name for ( TQStringList::ConstIterator it = options.begin(); it != options.end(); ++it) { if( (*it).startsWith("dev=")) return TQString(*it).remove("dev="); } return TQString("none"); }