| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kmountpoint.cpp

    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 354801 2004-10-15 17:50:40Z boiko $
    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., 59 Temple Place - Suite 330,
    00020  *  Boston, MA 02111-1307, 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     struct statfs *mounted;
    00230
    00231     int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
    00232
    00233     for (int i=0;i<num_fs;i++)
    00234     {
    00235       KMountPoint *mp = new KMountPoint();
    00236       mp->m_mountedFrom = QFile::decodeName(mounted[i].f_mntfromname);
    00237       mp->m_mountPoint = QFile::decodeName(mounted[i].f_mntonname);
    00238
    00239 #ifdef __osf__
    00240       mp->m_mountType = QFile::decodeName(mnt_names[mounted[i].f_type]);
    00241 #else
    00242       mp->m_mountType = QFile::decodeName(mounted[i].f_fstypename);
    00243 #endif
    00244
    00245       if (infoNeeded & NeedMountOptions)
    00246       {
    00247          struct fstab *ft = getfsfile(mounted[i].f_mntonname);
    00248          QString options = QFile::decodeName(ft->fs_mntops);
    00249          mp->m_mountOptions = QStringList::split(',', options);
    00250       }
    00251
    00252       if (infoNeeded & NeedRealDeviceName)
    00253       {
    00254          if (mp->m_mountedFrom.startsWith("/"))
    00255             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
    00256       }
    00257       // TODO: Strip trailing '/' ?
    00258       result.append(mp);
    00259    }
    00260
    00261 #elif defined(_AIX)
    00262
    00263     struct vmount *mntctl_buffer;
    00264     struct vmount *vm;
    00265     char *mountedfrom;
    00266     char *mountedto;
    00267     int fsname_len, num;
    00268     int buf_sz = 4096;
    00269
    00270     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    00271     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    00272     if (num == 0)
    00273     {
    00274     buf_sz = *(int*)mntctl_buffer;
    00275     free(mntctl_buffer);
    00276     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    00277     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    00278     }
    00279
    00280     if (num > 0)
    00281     {
    00282         /* iterate through items in the vmount structure: */
    00283         vm = (struct vmount *)mntctl_buffer;
    00284         for ( ; num > 0; num-- )
    00285         {
    00286             /* get the name of the mounted file systems: */
    00287             fsname_len = vmt2datasize(vm, VMT_STUB);
    00288             mountedto     = (char*)malloc(fsname_len + 1);
    00289         mountedto[fsname_len] = '\0';
    00290             strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len);
    00291
    00292             fsname_len = vmt2datasize(vm, VMT_OBJECT);
    00293             mountedfrom     = (char*)malloc(fsname_len + 1);
    00294         mountedfrom[fsname_len] = '\0';
    00295             strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len);
    00296
    00297         /* Look up the string for the file system type,
    00298              * as listed in /etc/vfs.
    00299              * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs
    00300              */
    00301             struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype);
    00302
    00303             KMountPoint *mp = new KMountPoint();
    00304             mp->m_mountedFrom = QFile::decodeName(mountedfrom);
    00305             mp->m_mountPoint = QFile::decodeName(mountedto);
    00306             mp->m_mountType = QFile::decodeName(ent->vfsent_name);
    00307
    00308             free(mountedfrom);
    00309             free(mountedto);
    00310
    00311             if (infoNeeded & NeedMountOptions)
    00312             {
    00313               // TODO
    00314             }
    00315
    00316             if (infoNeeded & NeedRealDeviceName)
    00317             {
    00318                if (mp->m_mountedFrom.startsWith("/"))
    00319                   mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
    00320             }
    00321
    00322             result.append(mp);
    00323
    00324             /* goto the next vmount structure: */
    00325             vm = (struct vmount *)((char *)vm + vm->vmt_length);
    00326         }
    00327
    00328     endvfsent( );
    00329     }
    00330
    00331     free( mntctl_buffer );
    00332 #elif defined(Q_WS_WIN)
    00333     //TODO?
    00334 #else
    00335    STRUCT_SETMNTENT mnttab;
    00336    if ((mnttab = SETMNTENT(MNTTAB, "r")) == 0)
    00337       return result;
    00338
    00339    STRUCT_MNTENT fe;
    00340    while (GETMNTENT(mnttab, fe))
    00341    {
    00342       KMountPoint *mp = new KMountPoint();
    00343       mp->m_mountedFrom = QFile::decodeName(FSNAME(fe));
    00344
    00345       mp->m_mountPoint = QFile::decodeName(MOUNTPOINT(fe));
    00346       mp->m_mountType = QFile::decodeName(MOUNTTYPE(fe));
    00347
    00348       //Devices using supermount have their device names in the mount options
    00349       //instead of the device field. That's why we need to read the mount options
    00350       if (infoNeeded & NeedMountOptions || (mp->m_mountType == "supermount"))
    00351       {
    00352          QString options = QFile::decodeName(MOUNTOPTIONS(fe));
    00353          mp->m_mountOptions = QStringList::split(',', options);
    00354       }
    00355
    00356       if (mp->m_mountType == "supermount")
    00357          mp->m_mountedFrom = devNameFromOptions(mp->m_mountOptions);
    00358
    00359       if (infoNeeded & NeedRealDeviceName)
    00360       {
    00361          if (mp->m_mountedFrom.startsWith("/"))
    00362             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
    00363       }
    00364       // TODO: Strip trailing '/' ?
    00365       result.append(mp);
    00366    }
    00367    ENDMNTENT(mnttab);
    00368 #endif
    00369    return result;
    00370 }
    00371
    00372 QString KMountPoint::devNameFromOptions(const QStringList &options)
    00373 {
    00374    // Search options to find the device name
    00375    for ( QStringList::ConstIterator it = options.begin(); it != options.end(); ++it)
    00376    {
    00377       if( (*it).startsWith("dev="))
    00378          return QString(*it).remove("dev=");
    00379    }
    00380    return QString("none");
    00381 }

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:09 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003