• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDECore

kmountpoint.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *  This file is part of the KDE libraries
00004  *  Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
00005  *
00006  * $Id: kmountpoint.cpp 526329 2006-04-04 13:44:00Z hasso $
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License version 2 as published by the Free Software Foundation.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  *  Boston, MA 02110-1301, USA.
00021  **/
00022 
00023 #include <config.h>
00024 #include <stdlib.h>
00025 
00026 #include <qfile.h>
00027 
00028 #include "kstandarddirs.h"
00029 
00030 #include "kmountpoint.h"
00031 
00032 #ifdef HAVE_VOLMGT
00033 #include <volmgt.h>
00034 #endif
00035 #ifdef HAVE_SYS_MNTTAB_H
00036 #include <sys/mnttab.h>
00037 #endif
00038 #ifdef HAVE_MNTENT_H
00039 #include <mntent.h>
00040 #elif defined(HAVE_SYS_MNTENT_H)
00041 #include <sys/mntent.h>
00042 #endif
00043 
00044 // This is the *BSD branch
00045 #ifdef HAVE_SYS_MOUNT_H
00046 #ifdef HAVE_SYS_TYPES_H
00047 #include <sys/types.h>
00048 #endif
00049 #ifdef HAVE_SYS_PARAM_H
00050 #include <sys/param.h>
00051 #endif
00052 #include <sys/mount.h>
00053 #endif
00054 
00055 #ifdef HAVE_FSTAB_H
00056 #include <fstab.h>
00057 #endif
00058 #if defined(_AIX)
00059 #include <sys/mntctl.h>
00060 #include <sys/vmount.h>
00061 #include <sys/vfs.h>
00062 /* AIX does not prototype mntctl anywhere that I can find */
00063 #ifndef mntctl
00064 extern "C" {
00065 int mntctl(int command, int size, void* buffer);
00066 }
00067 #endif
00068 extern "C" struct vfs_ent *getvfsbytype(int vfsType);
00069 extern "C" void endvfsent( );
00070 #endif
00071 
00072 
00073 #ifndef HAVE_GETMNTINFO
00074 # ifdef _PATH_MOUNTED
00075 // On some Linux, MNTTAB points to /etc/fstab !
00076 #  undef MNTTAB
00077 #  define MNTTAB _PATH_MOUNTED
00078 # else
00079 #  ifndef MNTTAB
00080 #   ifdef MTAB_FILE
00081 #    define MNTTAB MTAB_FILE
00082 #   else
00083 #    define MNTTAB "/etc/mnttab"
00084 #   endif
00085 #  endif
00086 # endif
00087 #endif
00088 
00089 
00090 
00091 #ifdef _OS_SOLARIS_
00092 #define FSTAB "/etc/vfstab"
00093 #else
00094 #define FSTAB "/etc/fstab"
00095 #endif
00096 
00097 
00098 
00099 KMountPoint::KMountPoint()
00100 {
00101 }
00102 
00103 KMountPoint::~KMountPoint()
00104 {
00105 }
00106 
00107 #ifdef HAVE_SETMNTENT
00108 #define SETMNTENT setmntent
00109 #define ENDMNTENT endmntent
00110 #define STRUCT_MNTENT struct mntent *
00111 #define STRUCT_SETMNTENT FILE *
00112 #define GETMNTENT(file, var) ((var = getmntent(file)) != 0)
00113 #define MOUNTPOINT(var) var->mnt_dir
00114 #define MOUNTTYPE(var) var->mnt_type
00115 #define MOUNTOPTIONS(var) var->mnt_opts
00116 #define FSNAME(var) var->mnt_fsname
00117 #else
00118 #define SETMNTENT fopen
00119 #define ENDMNTENT fclose
00120 #define STRUCT_MNTENT struct mnttab
00121 #define STRUCT_SETMNTENT FILE *
00122 #define GETMNTENT(file, var) (getmntent(file, &var) == 0)
00123 #define MOUNTPOINT(var) var.mnt_mountp
00124 #define MOUNTTYPE(var) var.mnt_fstype
00125 #define MOUNTOPTIONS(var) var.mnt_mntopts
00126 #define FSNAME(var) var.mnt_special
00127 #endif
00128 
00129 KMountPoint::List KMountPoint::possibleMountPoints(int infoNeeded)
00130 {
00131   KMountPoint::List result;
00132   
00133 #ifdef HAVE_SETMNTENT
00134    STRUCT_SETMNTENT fstab;
00135    if ((fstab = SETMNTENT(FSTAB, "r")) == 0)
00136       return result;
00137 
00138    STRUCT_MNTENT fe;
00139    while (GETMNTENT(fstab, fe))
00140    {
00141       KMountPoint *mp = new KMountPoint();
00142       mp->m_mountedFrom = QFile::decodeName(FSNAME(fe));
00143          
00144       mp->m_mountPoint = QFile::decodeName(MOUNTPOINT(fe));
00145       mp->m_mountType = QFile::decodeName(MOUNTTYPE(fe));
00146 
00147       //Devices using supermount have their device names in the mount options
00148       //instead of the device field. That's why we need to read the mount options
00149       if (infoNeeded & NeedMountOptions || (mp->m_mountType == "supermount"))
00150       {
00151          QString options = QFile::decodeName(MOUNTOPTIONS(fe));
00152          mp->m_mountOptions = QStringList::split(',', options);
00153       }
00154 
00155       if(mp->m_mountType == "supermount")
00156          mp->m_mountedFrom = devNameFromOptions(mp->m_mountOptions);
00157  
00158       if (infoNeeded & NeedRealDeviceName)
00159       {
00160          if (mp->m_mountedFrom.startsWith("/"))
00161             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00162       }
00163       // TODO: Strip trailing '/' ?
00164       result.append(mp);
00165    }
00166    ENDMNTENT(fstab);
00167 #else
00168    QFile f(FSTAB);
00169    if ( !f.open(IO_ReadOnly) )
00170       return result;
00171      
00172    QTextStream t (&f);
00173    QString s;
00174 
00175    while (! t.eof()) 
00176    {
00177       s=t.readLine().simplifyWhiteSpace();
00178       if ( s.isEmpty() || (s[0] == '#'))
00179           continue;
00180 
00181       // not empty or commented out by '#'
00182       QStringList item = QStringList::split(' ', s);
00183         
00184 #ifdef _OS_SOLARIS_
00185       if (item.count() < 5)
00186          continue;
00187 #else
00188       if (item.count() < 4)
00189          continue;
00190 #endif
00191 
00192       KMountPoint *mp = new KMountPoint();
00193 
00194       int i = 0;
00195       mp->m_mountedFrom = item[i++];
00196 #ifdef _OS_SOLARIS_
00197       //device to fsck
00198       i++;
00199 #endif
00200       mp->m_mountPoint = item[i++];
00201       mp->m_mountType = item[i++];
00202       QString options = item[i++];
00203 
00204       if (infoNeeded & NeedMountOptions)
00205       {
00206          mp->m_mountOptions = QStringList::split(',', options);
00207       }
00208 
00209       if (infoNeeded & NeedRealDeviceName)
00210       {
00211          if (mp->m_mountedFrom.startsWith("/"))
00212             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00213       }
00214       // TODO: Strip trailing '/' ?
00215       result.append(mp);
00216    } //while
00217 
00218    f.close();
00219 #endif
00220    return result;
00221 }
00222 
00223 KMountPoint::List KMountPoint::currentMountPoints(int infoNeeded)
00224 {
00225   KMountPoint::List result;
00226 
00227 #ifdef HAVE_GETMNTINFO
00228 
00229 #ifdef GETMNTINFO_USES_STATVFS
00230     struct statvfs *mounted;
00231 #else
00232     struct statfs *mounted;
00233 #endif
00234 
00235     int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
00236 
00237     for (int i=0;i<num_fs;i++) 
00238     {
00239       KMountPoint *mp = new KMountPoint();
00240       mp->m_mountedFrom = QFile::decodeName(mounted[i].f_mntfromname);
00241       mp->m_mountPoint = QFile::decodeName(mounted[i].f_mntonname);
00242 
00243 #ifdef __osf__
00244       mp->m_mountType = QFile::decodeName(mnt_names[mounted[i].f_type]);
00245 #else
00246       mp->m_mountType = QFile::decodeName(mounted[i].f_fstypename);
00247 #endif      
00248 
00249       if (infoNeeded & NeedMountOptions)
00250       {
00251          struct fstab *ft = getfsfile(mounted[i].f_mntonname);
00252          QString options = QFile::decodeName(ft->fs_mntops);
00253          mp->m_mountOptions = QStringList::split(',', options);
00254       }
00255 
00256       if (infoNeeded & NeedRealDeviceName)
00257       {
00258          if (mp->m_mountedFrom.startsWith("/"))
00259             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00260       }
00261       // TODO: Strip trailing '/' ?
00262       result.append(mp);
00263    }
00264 
00265 #elif defined(_AIX)
00266 
00267     struct vmount *mntctl_buffer;
00268     struct vmount *vm;
00269     char *mountedfrom;
00270     char *mountedto;
00271     int fsname_len, num;
00272     int buf_sz = 4096;
00273 
00274     mntctl_buffer = (struct vmount*)malloc(buf_sz);
00275     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
00276     if (num == 0)
00277     {
00278     buf_sz = *(int*)mntctl_buffer;
00279     free(mntctl_buffer);
00280     mntctl_buffer = (struct vmount*)malloc(buf_sz);
00281     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
00282     }
00283 
00284     if (num > 0)
00285     {
00286         /* iterate through items in the vmount structure: */
00287         vm = (struct vmount *)mntctl_buffer;
00288         for ( ; num > 0; num-- )
00289         {
00290             /* get the name of the mounted file systems: */
00291             fsname_len = vmt2datasize(vm, VMT_STUB);
00292             mountedto     = (char*)malloc(fsname_len + 1);
00293         mountedto[fsname_len] = '\0';
00294             strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len);
00295 
00296             fsname_len = vmt2datasize(vm, VMT_OBJECT);
00297             mountedfrom     = (char*)malloc(fsname_len + 1);
00298         mountedfrom[fsname_len] = '\0';
00299             strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len);
00300 
00301         /* Look up the string for the file system type,
00302              * as listed in /etc/vfs.
00303              * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs
00304              */
00305             struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype);
00306 
00307             KMountPoint *mp = new KMountPoint();
00308             mp->m_mountedFrom = QFile::decodeName(mountedfrom);
00309             mp->m_mountPoint = QFile::decodeName(mountedto);
00310             mp->m_mountType = QFile::decodeName(ent->vfsent_name);
00311 
00312             free(mountedfrom);
00313             free(mountedto);
00314 
00315             if (infoNeeded & NeedMountOptions)
00316             {
00317               // TODO
00318             }
00319 
00320             if (infoNeeded & NeedRealDeviceName)
00321             {
00322                if (mp->m_mountedFrom.startsWith("/"))
00323                   mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00324             }
00325             
00326             result.append(mp);
00327 
00328             /* goto the next vmount structure: */
00329             vm = (struct vmount *)((char *)vm + vm->vmt_length);
00330         }
00331 
00332     endvfsent( );
00333     }
00334 
00335     free( mntctl_buffer );
00336 #elif defined(Q_WS_WIN)
00337     //TODO?
00338 #else
00339    STRUCT_SETMNTENT mnttab;
00340    if ((mnttab = SETMNTENT(MNTTAB, "r")) == 0)
00341       return result;
00342 
00343    STRUCT_MNTENT fe;
00344    while (GETMNTENT(mnttab, fe))
00345    {
00346       KMountPoint *mp = new KMountPoint();
00347       mp->m_mountedFrom = QFile::decodeName(FSNAME(fe));
00348          
00349       mp->m_mountPoint = QFile::decodeName(MOUNTPOINT(fe));
00350       mp->m_mountType = QFile::decodeName(MOUNTTYPE(fe));
00351       
00352       //Devices using supermount have their device names in the mount options
00353       //instead of the device field. That's why we need to read the mount options 
00354       if (infoNeeded & NeedMountOptions || (mp->m_mountType == "supermount"))
00355       {
00356          QString options = QFile::decodeName(MOUNTOPTIONS(fe));
00357          mp->m_mountOptions = QStringList::split(',', options);
00358       }
00359 
00360       if (mp->m_mountType == "supermount")
00361          mp->m_mountedFrom = devNameFromOptions(mp->m_mountOptions);
00362 
00363       if (infoNeeded & NeedRealDeviceName)
00364       {
00365          if (mp->m_mountedFrom.startsWith("/"))
00366             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00367       }
00368       // TODO: Strip trailing '/' ?
00369       result.append(mp);
00370    }
00371    ENDMNTENT(mnttab);
00372 #endif
00373    return result;
00374 }
00375 
00376 QString KMountPoint::devNameFromOptions(const QStringList &options)
00377 {
00378    // Search options to find the device name
00379    for ( QStringList::ConstIterator it = options.begin(); it != options.end(); ++it)
00380    {
00381       if( (*it).startsWith("dev="))
00382          return QString(*it).remove("dev=");
00383    } 
00384    return QString("none");
00385 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal