kdecore Library API Documentation

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,v 1.9 2004/05/22 02:10:15 bmeyer Exp $
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 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     /*
00134       #ifdef HAVE_SETMNTENT
00135       STRUCT_SETMNTENT fstab;
00136       if ((fstab = SETMNTENT(FSTAB, "r")) == 0)
00137       return result;
00138 
00139       STRUCT_MNTENT fe;
00140       while (GETMNTENT(fstab, fe))
00141       {
00142       KMountPoint *mp = new KMountPoint();
00143       mp->m_mountedFrom = QFile::decodeName(FSNAME(fe));
00144 
00145       mp->m_mountPoint = QFile::decodeName(MOUNTPOINT(fe));
00146       mp->m_mountType = QFile::decodeName(MOUNTTYPE(fe));
00147       if (infoNeeded & NeedMountOptions)
00148       {
00149       QString options = QFile::decodeName(MOUNTOPTIONS(fe));
00150       mp->m_mountOptions = QStringList::split(',', options);
00151       }
00152 
00153       if (infoNeeded & NeedRealDeviceName)
00154       {
00155       if (mp->m_mountedFrom.startsWith("/"))
00156       mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00157       }
00158       // TODO: Strip trailing '/' ?
00159       result.append(mp);
00160       }
00161       ENDMNTENT(fstab);
00162       #else
00163     */
00164     QFile f(FSTAB);
00165     if ( !f.open(IO_ReadOnly) )
00166         return result;
00167 
00168     QTextStream t (&f);
00169     QString s;
00170 
00171     while (! t.eof())
00172     {
00173         s=t.readLine().simplifyWhiteSpace();
00174         if ( s.isEmpty() || (s[0] == '#'))
00175             continue;
00176         if( s.startsWith("none") && s.contains("supermount"))
00177         {
00178             QStringList item = QStringList::split(' ', s);
00179             if ( item.count() > 2 && item[1] != QString::fromLatin1("/proc")
00180                  && item[0] == QString::fromLatin1("none")
00181                  && item[0] != QString::fromLatin1("-") )
00182             {
00183                 KMountPoint *mp = new KMountPoint();
00184                 QString deviceStr = item[3];
00185                 QStringList lstCommat = QStringList::split( ',',deviceStr );
00186                 deviceStr =  lstCommat[0];
00187         if( s.contains("supermount"))
00188           {
00189             for ( QStringList::Iterator it = lstCommat.begin(); it != lstCommat.end(); ++it ) 
00190               {
00191             if( (*it).contains("dev="))
00192               {
00193                 QString tmp = *it;
00194                 tmp = tmp.remove("dev=");
00195                 mp->m_mountedFrom = tmp;
00196                 break;
00197               }
00198               }
00199           }
00200                 mp->m_mountPoint = item[1];
00201                 mp->m_mountType = item[2];
00202                 QString options = item[3];
00203                 if (infoNeeded & NeedMountOptions)
00204                 {
00205                     mp->m_mountOptions = QStringList::split(',', options);
00206                 }
00207 
00208                 if (infoNeeded & NeedRealDeviceName)
00209                 {
00210                     if (mp->m_mountedFrom.startsWith("/"))
00211                         mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00212                 }
00213                 // TODO: Strip trailing '/' ?
00214                 result.append(mp);
00215             }
00216         }
00217         else
00218         {
00219             // not empty or commented out by '#'
00220             QStringList item = QStringList::split(' ', s);
00221 
00222 #ifdef _OS_SOLARIS_
00223             if (item.count() < 5)
00224                 continue;
00225 #else
00226             if (item.count() < 4)
00227                 continue;
00228 #endif
00229 
00230             KMountPoint *mp = new KMountPoint();
00231 
00232             int i = 0;
00233             mp->m_mountedFrom = item[i++];
00234 #ifdef _OS_SOLARIS_
00235             //device to fsck
00236             i++;
00237 #endif
00238             mp->m_mountPoint = item[i++];
00239             mp->m_mountType = item[i++];
00240             QString options = item[i++];
00241             if (infoNeeded & NeedMountOptions)
00242             {
00243                 mp->m_mountOptions = QStringList::split(',', options);
00244             }
00245 
00246             if (infoNeeded & NeedRealDeviceName)
00247             {
00248                 if (mp->m_mountedFrom.startsWith("/"))
00249                     mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00250             }
00251             // TODO: Strip trailing '/' ?
00252             result.append(mp);
00253         }
00254     } //while
00255 
00256     f.close();
00257 //#endif
00258     return result;
00259 }
00260 
00261 
00262 KMountPoint::List KMountPoint::currentMountPoints(int infoNeeded)
00263 {
00264   KMountPoint::List result;
00265 
00266 #ifdef HAVE_GETMNTINFO
00267 
00268     struct statfs *mounted;
00269 
00270     int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
00271 
00272     for (int i=0;i<num_fs;i++)
00273     {
00274       KMountPoint *mp = new KMountPoint();
00275       mp->m_mountedFrom = QFile::decodeName(mounted[i].f_mntfromname);
00276       mp->m_mountPoint = QFile::decodeName(mounted[i].f_mntonname);
00277 
00278 #ifdef __osf__
00279       mp->m_mountType = QFile::decodeName(mnt_names[mounted[i].f_type]);
00280 #else
00281       mp->m_mountType = QFile::decodeName(mounted[i].f_fstypename);
00282 #endif
00283 
00284       if (infoNeeded & NeedMountOptions)
00285       {
00286          struct fstab *ft = getfsfile(mounted[i].f_mntonname);
00287          QString options = QFile::decodeName(ft->fs_mntops);
00288          mp->m_mountOptions = QStringList::split(',', options);
00289       }
00290 
00291       if (infoNeeded & NeedRealDeviceName)
00292       {
00293          if (mp->m_mountedFrom.startsWith("/"))
00294             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00295       }
00296       // TODO: Strip trailing '/' ?
00297       result.append(mp);
00298    }
00299 
00300 #elif defined(_AIX)
00301 
00302     struct vmount *mntctl_buffer;
00303     struct vmount *vm;
00304     char *mountedfrom;
00305     char *mountedto;
00306     int fsname_len, num;
00307     int buf_sz = 4096;
00308 
00309     mntctl_buffer = (struct vmount*)malloc(buf_sz);
00310     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
00311     if (num == 0)
00312     {
00313     buf_sz = *(int*)mntctl_buffer;
00314     free(mntctl_buffer);
00315     mntctl_buffer = (struct vmount*)malloc(buf_sz);
00316     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
00317     }
00318 
00319     if (num > 0)
00320     {
00321         /* iterate through items in the vmount structure: */
00322         vm = (struct vmount *)mntctl_buffer;
00323         for ( ; num > 0; num-- )
00324         {
00325             /* get the name of the mounted file systems: */
00326             fsname_len = vmt2datasize(vm, VMT_STUB);
00327             mountedto     = (char*)malloc(fsname_len + 1);
00328         mountedto[fsname_len] = '\0';
00329             strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len);
00330 
00331             fsname_len = vmt2datasize(vm, VMT_OBJECT);
00332             mountedfrom     = (char*)malloc(fsname_len + 1);
00333         mountedfrom[fsname_len] = '\0';
00334             strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len);
00335 
00336         /* Look up the string for the file system type,
00337              * as listed in /etc/vfs.
00338              * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs
00339              */
00340             struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype);
00341 
00342             KMountPoint *mp = new KMountPoint();
00343             mp->m_mountedFrom = QFile::decodeName(mountedfrom);
00344             mp->m_mountPoint = QFile::decodeName(mountedto);
00345             mp->m_mountType = QFile::decodeName(ent->vfsent_name);
00346 
00347             free(mountedfrom);
00348             free(mountedto);
00349 
00350             if (infoNeeded & NeedMountOptions)
00351             {
00352               // TODO
00353             }
00354 
00355             if (infoNeeded & NeedRealDeviceName)
00356             {
00357                if (mp->m_mountedFrom.startsWith("/"))
00358                   mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00359             }
00360 
00361             result.append(mp);
00362 
00363             /* goto the next vmount structure: */
00364             vm = (struct vmount *)((char *)vm + vm->vmt_length);
00365         }
00366 
00367     endvfsent( );
00368     }
00369 
00370     free( mntctl_buffer );
00371 #else
00372    STRUCT_SETMNTENT mnttab;
00373    if ((mnttab = SETMNTENT(MNTTAB, "r")) == 0)
00374       return result;
00375 
00376    STRUCT_MNTENT fe;
00377    while (GETMNTENT(mnttab, fe))
00378    {
00379       KMountPoint *mp = new KMountPoint();
00380       mp->m_mountedFrom = QFile::decodeName(FSNAME(fe));
00381 
00382       mp->m_mountPoint = QFile::decodeName(MOUNTPOINT(fe));
00383       mp->m_mountType = QFile::decodeName(MOUNTTYPE(fe));
00384       if(mp->m_mountType =="supermount" )
00385     {
00386       QString options = QFile::decodeName(MOUNTOPTIONS(fe));
00387       QStringList split = QStringList::split(',', options);   
00388       for ( QStringList::Iterator it = split.begin(); it != split.end(); ++it ) {
00389         if( (*it).contains("dev="))
00390           {
00391         QString tmp = *it;
00392         tmp = tmp.remove("dev=");
00393         mp->m_mountedFrom = tmp;
00394         break;
00395           }
00396       }
00397     }
00398 
00399       if (infoNeeded & NeedMountOptions)
00400       {
00401          QString options = QFile::decodeName(MOUNTOPTIONS(fe));
00402          mp->m_mountOptions = QStringList::split(',', options);
00403       }
00404 
00405       if (infoNeeded & NeedRealDeviceName)
00406       {
00407          if (mp->m_mountedFrom.startsWith("/"))
00408             mp->m_device = KStandardDirs::realPath(mp->m_mountedFrom);
00409       }
00410       // TODO: Strip trailing '/' ?
00411       result.append(mp);
00412    }
00413    ENDMNTENT(mnttab);
00414 #endif
00415    return result;
00416 }
00417 
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:09:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003