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