# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# global.cpp

    00001 /* This file is part of the KDE libraries
    00002    Copyright (C) 2000 David Faure <faure@kde.org>
    00003
    00004    This library is free software; you can redistribute it and/or
    00005    modify it under the terms of the GNU Library General Public
    00006    License version 2 as published by the Free Software Foundation.
    00007
    00008    This library is distributed in the hope that it will be useful,
    00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00011    Library General Public License for more details.
    00012
    00013    You should have received a copy of the GNU Library General Public License
    00014    along with this library; see the file COPYING.LIB.  If not, write to
    00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00016    Boston, MA 02111-1307, USA.
    00017 */
    00018
    00019 #include <config.h>
    00020
    00021 #include <sys/types.h>
    00022 #include <sys/wait.h>
    00023 #include <sys/uio.h>
    00024
    00025 #include <assert.h>
    00026 #include <signal.h>
    00027 #include <stdlib.h>
    00028 #include <string.h>
    00029 #include <unistd.h>
    00030 #include <stdio.h>
    00031
    00032 #include "kio/global.h"
    00033 #include "kio/job.h"
    00034
    00035 #include <kdebug.h>
    00036 #include <klocale.h>
    00037 #include <kglobal.h>
    00038 #include <kprotocolmanager.h>
    00039 #include <kde_file.h>
    00040
    00041 #ifdef HAVE_VOLMGT
    00042 #include <volmgt.h>
    00043 #endif
    00044
    00045 KIO_EXPORT QString KIO::convertSize( KIO::filesize_t size )
    00046 {
    00047     double fsize = size;
    00048     QString s;
    00049     // Giga-byte
    00050     if ( size >= 1073741824 )
    00051     {
    00052         fsize /= 1073741824.0;
    00053         if ( fsize > 1024 ) // Tera-byte
    00054             s = i18n( "%1 TB" ).arg( KGlobal::locale()->formatNumber(fsize / 1024.0, 1));
    00055         else
    00056             s = i18n( "%1 GB" ).arg( KGlobal::locale()->formatNumber(fsize, 1));
    00057     }
    00058     // Mega-byte
    00059     else if ( size >= 1048576 )
    00060     {
    00061         fsize /= 1048576.0;
    00062         s = i18n( "%1 MB" ).arg( KGlobal::locale()->formatNumber(fsize, 1));
    00063     }
    00064     // Kilo-byte
    00065     else if ( size >= 1024 )
    00066     {
    00067         fsize /= 1024.0;
    00068         s = i18n( "%1 KB" ).arg( KGlobal::locale()->formatNumber(fsize, 1));
    00069     }
    00070     // Just byte
    00071     else
    00072     {
    00073         s = i18n( "%1 B" ).arg( KGlobal::locale()->formatNumber(fsize, 0));
    00074     }
    00075     return s;
    00076 }
    00077
    00078 KIO_EXPORT QString KIO::convertSizeFromKB( KIO::filesize_t kbSize )
    00079 {
    00080     return convertSize(kbSize * 1024);
    00081 }
    00082
    00083 KIO_EXPORT QString KIO::number( KIO::filesize_t size )
    00084 {
    00085     char charbuf[256];
    00086     sprintf(charbuf, "%lld", size);
    00087     return QString::fromLatin1(charbuf);
    00088 }
    00089
    00090 KIO_EXPORT unsigned int KIO::calculateRemainingSeconds( KIO::filesize_t totalSize,
    00091                                                         KIO::filesize_t processedSize, KIO::filesize_t speed )
    00092 {
    00093   if ( (speed != 0) && (totalSize != 0) )
    00094     return ( totalSize - processedSize ) / speed;
    00095   else
    00096     return 0;
    00097 }
    00098
    00099 KIO_EXPORT QString KIO::convertSeconds( unsigned int seconds )
    00100 {
    00101   unsigned int days  = seconds / 86400;
    00102   unsigned int hours = (seconds - (days * 86400)) / 3600;
    00103   unsigned int mins  = (seconds - (days * 86400) - (hours * 3600)) / 60;
    00104   seconds            = (seconds - (days * 86400) - (hours * 3600) - (mins * 60));
    00105
    00106   const QTime time(hours, mins, seconds);
    00107   const QString timeStr( KGlobal::locale()->formatTime(time, true /*with seconds*/, true /*duration*/) );
    00108   if ( days > 0 )
    00109     return i18n("1 day %1", "%n days %1", days).arg(timeStr);
    00110   else
    00111     return timeStr;
    00112 }
    00113
    00114 KIO_EXPORT QTime KIO::calculateRemaining( KIO::filesize_t totalSize, KIO::filesize_t processedSize, KIO::filesize_t speed )
    00115 {
    00116   QTime remainingTime;
    00117
    00118   if ( speed != 0 ) {
    00119     KIO::filesize_t secs;
    00120     if ( totalSize == 0 ) {
    00121       secs = 0;
    00122     } else {
    00123       secs = ( totalSize - processedSize ) / speed;
    00124     }
    00125     if (secs >= (24*60*60)) // Limit to 23:59:59
    00126        secs = (24*60*60)-1;
    00127     int hr = secs / ( 60 * 60 );
    00128     int mn = ( secs - hr * 60 * 60 ) / 60;
    00129     int sc = ( secs - hr * 60 * 60 - mn * 60 );
    00130
    00131     remainingTime.setHMS( hr, mn, sc );
    00132   }
    00133
    00134   return remainingTime;
    00135 }
    00136
    00137 KIO_EXPORT QString KIO::itemsSummaryString(uint items, uint files, uint dirs, KIO::filesize_t size, bool showSize)
    00138 {
    00139     QString text = items == 0 ? i18n( "No Items" ) : i18n( "One Item", "%n Items", items );
    00140     text += " - ";
    00141     text += files == 0 ? i18n( "No Files" ) : i18n( "One File", "%n Files", files );
    00142     if ( showSize && files > 0 )
    00143     {
    00144         text += " ";
    00145         text += i18n("(%1 Total)").arg(KIO::convertSize( size ) );
    00146     }
    00147     text += " - ";
    00148     text += dirs == 0 ? i18n( "No Folders" ) : i18n("One Folder", "%n Folders", dirs);
    00149     return text;
    00150 }
    00151
    00152 KIO_EXPORT QString KIO::encodeFileName( const QString & _str )
    00153 {
    00154   QString str( _str );
    00155
    00156   int i = 0;
    00157   while ( ( i = str.find( "%", i ) ) != -1 )
    00158   {
    00159     str.replace( i, 1, "%%");
    00160     i += 2;
    00161   }
    00162   while ( ( i = str.find( "/" ) ) != -1 )
    00163       str.replace( i, 1, "%2f");
    00164   return str;
    00165 }
    00166
    00167 KIO_EXPORT QString KIO::decodeFileName( const QString & _str )
    00168 {
    00169   QString str;
    00170
    00171   unsigned int i = 0;
    00172   for ( ; i < _str.length() ; ++i )
    00173   {
    00174     if ( _str[i]=='%' )
    00175     {
    00176       if ( _str[i+1]=='%' ) // %% -> %
    00177       {
    00178         str.append('%');
    00179         ++i;
    00180       }
    00181       else if ( _str[i+1]=='2' && (i+2<_str.length()) && _str[i+2].lower()=='f' ) // %2f -> /
    00182       {
    00183         str.append('/');
    00184         i += 2;
    00185       }
    00186       else
    00187         str.append('%');
    00188     } else
    00189       str.append(_str[i]);
    00190   }
    00191
    00192   return str;
    00193 }
    00194
    00195 KIO_EXPORT QString KIO::Job::errorString() const
    00196 {
    00197   return KIO::buildErrorString(m_error, m_errorText);
    00198 }
    00199
    00200 KIO_EXPORT QString KIO::buildErrorString(int errorCode, const QString &errorText)
    00201 {
    00202   QString result;
    00203
    00204   switch( errorCode )
    00205     {
    00206     case  KIO::ERR_CANNOT_OPEN_FOR_READING:
    00207       result = i18n( "Could not read %1." ).arg( errorText );
    00208       break;
    00209     case  KIO::ERR_CANNOT_OPEN_FOR_WRITING:
    00210       result = i18n( "Could not write to %1." ).arg( errorText );
    00211       break;
    00212     case  KIO::ERR_CANNOT_LAUNCH_PROCESS:
    00213       result = i18n( "Could not start process %1." ).arg( errorText );
    00214       break;
    00215     case  KIO::ERR_INTERNAL:
    00216       result = i18n( "Internal Error\nPlease send a full bug report at http://bugs.kde.org\n%1" ).arg( errorText );
    00217       break;
    00218     case  KIO::ERR_MALFORMED_URL:
    00219       result = i18n( "Malformed URL %1." ).arg( errorText );
    00220       break;
    00221     case  KIO::ERR_UNSUPPORTED_PROTOCOL:
    00222       result = i18n( "The protocol %1 is not supported." ).arg( errorText );
    00223       break;
    00224     case  KIO::ERR_NO_SOURCE_PROTOCOL:
    00225       result = i18n( "The protocol %1 is only a filter protocol.").arg( errorText );
    00226       break;
    00227     case  KIO::ERR_UNSUPPORTED_ACTION:
    00228       result = errorText;
    00229 //       result = i18n( "Unsupported action %1" ).arg( errorText );
    00230       break;
    00231     case  KIO::ERR_IS_DIRECTORY:
    00232       result = i18n( "%1 is a folder, but a file was expected." ).arg( errorText );
    00233       break;
    00234     case  KIO::ERR_IS_FILE:
    00235       result = i18n( "%1 is a file, but a folder was expected." ).arg( errorText );
    00236       break;
    00237     case  KIO::ERR_DOES_NOT_EXIST:
    00238       result = i18n( "The file or folder %1 does not exist." ).arg( errorText );
    00239       break;
    00240     case  KIO::ERR_FILE_ALREADY_EXIST:
    00241       result = i18n( "A file named %1 already exists." ).arg( errorText );
    00242       break;
    00243     case  KIO::ERR_DIR_ALREADY_EXIST:
    00244       result = i18n( "A folder named %1 already exists." ).arg( errorText );
    00245       break;
    00246     case  KIO::ERR_UNKNOWN_HOST:
    00247       result = errorText.isEmpty() ? i18n( "No hostname specified." ) : i18n( "Unknown host %1" ).arg( errorText );
    00248       break;
    00249     case  KIO::ERR_ACCESS_DENIED:
    00250       result = i18n( "Access denied to %1." ).arg( errorText );
    00251       break;
    00252     case  KIO::ERR_WRITE_ACCESS_DENIED:
    00253       result = i18n( "Access denied.\nCould not write to %1." ).arg( errorText );
    00254       break;
    00255     case  KIO::ERR_CANNOT_ENTER_DIRECTORY:
    00256       result = i18n( "Could not enter folder %1." ).arg( errorText );
    00257       break;
    00258     case  KIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM:
    00259       result = i18n( "The protocol %1 does not implement a folder service." ).arg( errorText );
    00260       break;
    00261     case  KIO::ERR_CYCLIC_LINK:
    00262       result = i18n( "Found a cyclic link in %1." ).arg( errorText );
    00263       break;
    00264     case  KIO::ERR_USER_CANCELED:
    00265       // Do nothing in this case. The user doesn't need to be told what he just did.
    00266       break;
    00267     case  KIO::ERR_CYCLIC_COPY:
    00268       result = i18n( "Found a cyclic link while copying %1." ).arg( errorText );
    00269       break;
    00270     case  KIO::ERR_COULD_NOT_CREATE_SOCKET:
    00271       result = i18n( "Could not create socket for accessing %1." ).arg( errorText );
    00272       break;
    00273     case  KIO::ERR_COULD_NOT_CONNECT:
    00274       result = i18n( "Could not connect to host %1." ).arg( errorText.isEmpty() ? QString::fromLatin1("localhost") : errorText );
    00275       break;
    00276     case  KIO::ERR_CONNECTION_BROKEN:
    00277       result = i18n( "Connection to host %1 is broken." ).arg( errorText );
    00278       break;
    00279     case  KIO::ERR_NOT_FILTER_PROTOCOL:
    00280       result = i18n( "The protocol %1 is not a filter protocol." ).arg( errorText );
    00281       break;
    00282     case  KIO::ERR_COULD_NOT_MOUNT:
    00283       result = i18n( "Could not mount device.\nThe reported error was:\n%1" ).arg( errorText );
    00284       break;
    00285     case  KIO::ERR_COULD_NOT_UNMOUNT:
    00286       result = i18n( "Could not unmount device.\nThe reported error was:\n%1" ).arg( errorText );
    00287       break;
    00288     case  KIO::ERR_COULD_NOT_READ:
    00289       result = i18n( "Could not read file %1." ).arg( errorText );
    00290       break;
    00291     case  KIO::ERR_COULD_NOT_WRITE:
    00292       result = i18n( "Could not write to file %1." ).arg( errorText );
    00293       break;
    00294     case  KIO::ERR_COULD_NOT_BIND:
    00295       result = i18n( "Could not bind %1." ).arg( errorText );
    00296       break;
    00297     case  KIO::ERR_COULD_NOT_LISTEN:
    00298       result = i18n( "Could not listen %1." ).arg( errorText );
    00299       break;
    00300     case  KIO::ERR_COULD_NOT_ACCEPT:
    00301       result = i18n( "Could not accept %1." ).arg( errorText );
    00302       break;
    00303     case  KIO::ERR_COULD_NOT_LOGIN:
    00304       result = errorText;
    00305       break;
    00306     case  KIO::ERR_COULD_NOT_STAT:
    00307       result = i18n( "Could not access %1." ).arg( errorText );
    00308       break;
    00309     case  KIO::ERR_COULD_NOT_CLOSEDIR:
    00310       result = i18n( "Could not terminate listing %1." ).arg( errorText );
    00311       break;
    00312     case  KIO::ERR_COULD_NOT_MKDIR:
    00313       result = i18n( "Could not make folder %1." ).arg( errorText );
    00314       break;
    00315     case  KIO::ERR_COULD_NOT_RMDIR:
    00316       result = i18n( "Could not remove folder %1." ).arg( errorText );
    00317       break;
    00318     case  KIO::ERR_CANNOT_RESUME:
    00319       result = i18n( "Could not resume file %1." ).arg( errorText );
    00320       break;
    00321     case  KIO::ERR_CANNOT_RENAME:
    00322       result = i18n( "Could not rename file %1." ).arg( errorText );
    00323       break;
    00324     case  KIO::ERR_CANNOT_CHMOD:
    00325       result = i18n( "Could not change permissions for %1." ).arg( errorText );
    00326       break;
    00327     case  KIO::ERR_CANNOT_DELETE:
    00328       result = i18n( "Could not delete file %1." ).arg( errorText );
    00329       break;
    00330     case  KIO::ERR_SLAVE_DIED:
    00331       result = i18n( "The process for the %1 protocol died unexpectedly." ).arg( errorText );
    00332       break;
    00333     case  KIO::ERR_OUT_OF_MEMORY:
    00334       result = i18n( "Error. Out of memory.\n%1" ).arg( errorText );
    00335       break;
    00336     case  KIO::ERR_UNKNOWN_PROXY_HOST:
    00337       result = i18n( "Unknown proxy host\n%1" ).arg( errorText );
    00338       break;
    00339     case  KIO::ERR_COULD_NOT_AUTHENTICATE:
    00340       result = i18n( "Authorization failed, %1 authentication not supported" ).arg( errorText );
    00341       break;
    00342     case  KIO::ERR_ABORTED:
    00343       result = i18n( "User canceled action\n%1" ).arg( errorText );
    00344       break;
    00345     case  KIO::ERR_INTERNAL_SERVER:
    00346       result = i18n( "Internal error in server\n%1" ).arg( errorText );
    00347       break;
    00348     case  KIO::ERR_SERVER_TIMEOUT:
    00349       result = i18n( "Timeout on server\n%1" ).arg( errorText );
    00350       break;
    00351     case  KIO::ERR_UNKNOWN:
    00352       result = i18n( "Unknown error\n%1" ).arg( errorText );
    00353       break;
    00354     case  KIO::ERR_UNKNOWN_INTERRUPT:
    00355       result = i18n( "Unknown interrupt\n%1" ).arg( errorText );
    00356       break;
    00357 /*
    00358     case  KIO::ERR_CHECKSUM_MISMATCH:
    00359       if (errorText)
    00360         result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg(errorText);
    00361       else
    00362         result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg("document");
    00363       break;
    00364 */
    00365     case KIO::ERR_CANNOT_DELETE_ORIGINAL:
    00366       result = i18n( "Could not delete original file %1.\nPlease check permissions." ).arg( errorText );
    00367       break;
    00368     case KIO::ERR_CANNOT_DELETE_PARTIAL:
    00369       result = i18n( "Could not delete partial file %1.\nPlease check permissions." ).arg( errorText );
    00370       break;
    00371     case KIO::ERR_CANNOT_RENAME_ORIGINAL:
    00372       result = i18n( "Could not rename original file %1.\nPlease check permissions." ).arg( errorText );
    00373       break;
    00374     case KIO::ERR_CANNOT_RENAME_PARTIAL:
    00375       result = i18n( "Could not rename partial file %1.\nPlease check permissions." ).arg( errorText );
    00376       break;
    00377     case KIO::ERR_CANNOT_SYMLINK:
    00378       result = i18n( "Could not create symlink %1.\nPlease check permissions." ).arg( errorText );
    00379       break;
    00380     case KIO::ERR_NO_CONTENT:
    00381       result = errorText;
    00382       break;
    00383     case KIO::ERR_DISK_FULL:
    00384       result = i18n( "Could not write file %1.\nDisk full." ).arg( errorText );
    00385       break;
    00386     case KIO::ERR_IDENTICAL_FILES:
    00387       result = i18n( "The source and destination are the same file.\n%1" ).arg( errorText );
    00388       break;
    00389     case KIO::ERR_SLAVE_DEFINED:
    00390       result = errorText;
    00391       break;
    00392     case KIO::ERR_UPGRADE_REQUIRED:
    00393       result = i18n( "%1 is required by the server, but is not available." ).arg(errorText);
    00394       break;
    00395     case KIO::ERR_POST_DENIED:
    00396       result = i18n( "Access to restricted port in POST denied.");
    00397       break;
    00398     default:
    00399       result = i18n( "Unknown error code %1\n%2\nPlease send a full bug report at http://bugs.kde.org." ).arg( errorCode ).arg( errorText );
    00400       break;
    00401     }
    00402
    00403   return result;
    00404 }
    00405
    00406 KIO_EXPORT QString KIO::unsupportedActionErrorString(const QString &protocol, int cmd) {
    00407   switch (cmd) {
    00408     case CMD_CONNECT:
    00409       return i18n("Opening connections is not supported with the protocol %1." ).arg(protocol);
    00410     case CMD_DISCONNECT:
    00411       return i18n("Closing connections is not supported with the protocol %1." ).arg(protocol);
    00412     case CMD_STAT:
    00413       return i18n("Accessing files is not supported with the protocol %1.").arg(protocol);
    00414     case CMD_PUT:
    00415       return i18n("Writing to %1 is not supported.").arg(protocol);
    00416     case CMD_SPECIAL:
    00417       return i18n("There are no special actions available for protocol %1.").arg(protocol);
    00418     case CMD_LISTDIR:
    00419       return i18n("Listing folders is not supported for protocol %1.").arg(protocol);
    00420     case CMD_GET:
    00421       return i18n("Retrieving data from %1 is not supported.").arg(protocol);
    00422     case CMD_MIMETYPE:
    00423       return i18n("Retrieving mime type information from %1 is not supported.").arg(protocol);
    00424     case CMD_RENAME:
    00425       return i18n("Renaming or moving files within %1 is not supported.").arg(protocol);
    00426     case CMD_SYMLINK:
    00427       return i18n("Creating symlinks is not supported with protocol %1.").arg(protocol);
    00428     case CMD_COPY:
    00429       return i18n("Copying files within %1 is not supported.").arg(protocol);
    00430     case CMD_DEL:
    00431       return i18n("Deleting files from %1 is not supported.").arg(protocol);
    00432     case CMD_MKDIR:
    00433       return i18n("Creating folders is not supported with protocol %1.").arg(protocol);
    00434     case CMD_CHMOD:
    00435       return i18n("Changing the attributes of files is not supported with protocol %1.").arg(protocol);
    00436     case CMD_SUBURL:
    00437       return i18n("Using sub-URLs with %1 is not supported.").arg(protocol);
    00438     case CMD_MULTI_GET:
    00439       return i18n("Multiple get is not supported with protocol %1.").arg(protocol);
    00440     default:
    00441       return i18n("Protocol %1 does not support action %2.").arg(protocol).arg(cmd);
    00442   }/*end switch*/
    00443 }
    00444
    00445 KIO_EXPORT QStringList KIO::Job::detailedErrorStrings( const KURL *reqUrl /*= 0L*/,
    00446                                             int method /*= -1*/ ) const
    00447 {
    00448   QString errorName, techName, description, ret2;
    00449   QStringList causes, solutions, ret;
    00450
    00451   QByteArray raw = rawErrorDetail( m_error, m_errorText, reqUrl, method );
    00452   QDataStream stream(raw, IO_ReadOnly);
    00453
    00454   stream >> errorName >> techName >> description >> causes >> solutions;
    00455
    00456   QString url, protocol, datetime;
    00457   if ( reqUrl ) {
    00458     url = reqUrl->htmlURL();
    00459     protocol = reqUrl->protocol();
    00460   } else {
    00461     url = i18n( "(unknown)" );
    00462   }
    00463
    00464   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
    00465                                                 false );
    00466
    00467   ret << errorName;
    00468   ret << QString::fromLatin1( "<qt><p><b>" ) + errorName +
    00469          QString::fromLatin1( "</b></p><p>" ) + description +
    00470          QString::fromLatin1( "</p>" );
    00471   ret2 = QString::fromLatin1( "<qt><p>" );
    00472   if ( !techName.isNull() )
    00473     ret2 += i18n( "<b>Technical reason</b>: " ) + techName + QString::fromLatin1( "</p>" );
    00474   ret2 += i18n( "</p><p><b>Details of the request</b>:" );
    00475   ret2 += i18n( "</p><ul><li>URL: %1</li>" ).arg( url );
    00476   if ( !protocol.isNull() ) {
    00477     ret2 += i18n( "<li>Protocol: %1</li>" ).arg( protocol );
    00478   }
    00479   ret2 += i18n( "<li>Date and time: %1</li>" ).arg( datetime );
    00480   ret2 += i18n( "<li>Additional information: %1</li></ul>" ).arg( m_errorText );
    00481   if ( causes.count() ) {
    00482     ret2 += i18n( "<p><b>Possible causes</b>:</p><ul><li>" );
    00483     ret2 += causes.join( "</li><li>" );
    00484     ret2 += QString::fromLatin1( "</li></ul>" );
    00485   }
    00486   if ( solutions.count() ) {
    00487     ret2 += i18n( "<p><b>Possible solutions</b>:</p><ul><li>" );
    00488     ret2 += solutions.join( "</li><li>" );
    00489     ret2 += QString::fromLatin1( "</li></ul>" );
    00490   }
    00491   ret << ret2;
    00492   return ret;
    00493 }
    00494
    00495 KIO_EXPORT QByteArray KIO::rawErrorDetail(int errorCode, const QString &errorText,
    00496                                const KURL *reqUrl /*= 0L*/, int /*method = -1*/ )
    00497 {
    00498   QString url, host, protocol, datetime, domain, path, dir, filename;
    00499   bool isSlaveNetwork = false;
    00500   if ( reqUrl ) {
    00501     url = reqUrl->prettyURL();
    00502     host = reqUrl->host();
    00503     protocol = reqUrl->protocol();
    00504
    00505     if ( host.left(4) == "www." )
    00506       domain = host.mid(4);
    00507     else
    00508       domain = host;
    00509
    00510     path = reqUrl->path(1);
    00511     filename = reqUrl->fileName();
    00512     dir =  path + filename;
    00513
    00514     // detect if protocol is a network protocol...
    00515     // add your hacks here...
    00516     if ( protocol == "http" ||
    00517          protocol == "https" ||
    00518          protocol == "ftp" ||
    00519          protocol == "sftp" ||
    00520          protocol == "webdav" ||
    00521          protocol == "webdavs" ||
    00522          protocol == "finger" ||
    00523          protocol == "fish" ||
    00524          protocol == "gopher" ||
    00525          protocol == "imap" ||
    00526          protocol == "imaps" ||
    00527          protocol == "lan" ||
    00528          protocol == "ldap" ||
    00529          protocol == "mailto" ||
    00530          protocol == "news" ||
    00531          protocol == "nntp" ||
    00532          protocol == "pop3" ||
    00533          protocol == "pop3s" ||
    00534          protocol == "smtp" ||
    00535          protocol == "smtps" ||
    00536          protocol == "telnet"
    00537         ) {
    00538       isSlaveNetwork = false;
    00539     }
    00540   } else {
    00541     // assume that the errorText has the location we are interested in
    00542     url = host = domain = path = filename = dir = errorText;
    00543     protocol = i18n( "(unknown)" );
    00544   }
    00545
    00546   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
    00547                                                 false );
    00548
    00549   QString errorName, techName, description;
    00550   QStringList causes, solutions;
    00551
    00552   // c == cause, s == solution
    00553   QString sSysadmin = i18n( "Contact your appropriate computer support system, "
    00554     "whether the system administrator, or technical support group for further "
    00555     "assistance." );
    00556   QString sServeradmin = i18n( "Contact the administrator of the server "
    00557     "for further assistance." );
    00558   // FIXME active link to permissions dialog
    00559   QString sAccess = i18n( "Check your access permissions on this resource." );
    00560   QString cAccess = i18n( "Your access permissions may be inadequate to "
    00561     "perform the requested operation on this resource." );
    00562   QString cLocked = i18n( "The file may be in use (and thus locked) by "
    00563     "another user or application." );
    00564   QString sQuerylock = i18n( "Check to make sure that no other "
    00565     "application or user is using the file or has locked the file." );
    00566   QString cHardware = i18n( "Although unlikely, a hardware error may have "
    00567     "occurred." );
    00568   QString cBug = i18n( "You may have encountered a bug in the program." );
    00569   QString cBuglikely = i18n( "This is most likely to be caused by a bug in the "
    00570     "program. Please consider submitting a full bug report as detailed below." );
    00571   QString sUpdate = i18n( "Update your software to the latest version. "
    00572     "Your distribution should provide tools to update your software." );
    00573   QString sBugreport = i18n( "When all else fails, please consider helping the "
    00574     "KDE team or the third party maintainer of this software by submitting a "
    00575     "high quality bug report. If the software is provided by a third party, "
    00576     "please contact them directly. Otherwise, first look to see if "
    00577     "the same bug has been submitted by someone else by searching at the "
    00578     "<a href=\"http://bugs.kde.org/\">KDE bug reporting website</a>. If not, take "
    00579     "note of the details given above, and include them in your bug report, along "
    00580     "with as many other details as you think might help." );
    00581   QString cNetwork = i18n( "There may have been a problem with your network "
    00582     "connection." );
    00583   // FIXME netconf kcontrol link
    00584   QString cNetconf = i18n( "There may have been a problem with your network "
    00585     "configuration. If you have been accessing the Internet with no problems "
    00586     "recently, this is unlikely." );
    00587   QString cNetpath = i18n( "There may have been a problem at some point along "
    00588     "the network path between the server and this computer." );
    00589   QString sTryagain = i18n( "Try again, either now or at a later time." );
    00590   QString cProtocol = i18n( "A protocol error or incompatibility may have occurred." );
    00591   QString sExists = i18n( "Ensure that the resource exists, and try again." );
    00592   QString cExists = i18n( "The specified resource may not exist." );
    00593   QString cTypo = i18n( "You may have incorrectly typed the location." );
    00594   QString sTypo = i18n( "Double-check that you have entered the correct location "
    00595     "and try again." );
    00596   QString sNetwork = i18n( "Check your network connection status." );
    00597
    00598   switch( errorCode ) {
    00599     case  KIO::ERR_CANNOT_OPEN_FOR_READING:
    00600       errorName = i18n( "Cannot Open Resource For Reading" );
    00601       description = i18n( "This means that the contents of the requested file "
    00602         "or folder <strong>%1</strong> could not be retrieved, as read "
    00603         "access could not be obtained." ).arg( dir );
    00604       causes << i18n( "You may not have permissions to read the file or open "
    00605         "the folder.") << cLocked << cHardware;
    00606       solutions << sAccess << sQuerylock << sSysadmin;
    00607       break;
    00608
    00609     case  KIO::ERR_CANNOT_OPEN_FOR_WRITING:
    00610       errorName = i18n( "Cannot Open Resource For Writing" );
    00611       description = i18n( "This means that the file, <strong>%1</strong>, could "
    00612         "not be written to as requested, because access with permission to "
    00613         "write could not be obtained." ).arg( filename );
    00614       causes << cAccess << cLocked << cHardware;
    00615       solutions << sAccess << sQuerylock << sSysadmin;
    00616       break;
    00617
    00618     case  KIO::ERR_CANNOT_LAUNCH_PROCESS:
    00619       errorName = i18n( "Cannot Initiate the %1 Protocol" ).arg( protocol );
    00620       techName = i18n( "Unable to Launch Process" );
    00621       description = i18n( "The program on your computer which provides access "
    00622         "to the <strong>%1</strong> protocol could not be started. This is "
    00623         "usually due to technical reasons." ).arg( protocol );
    00624       causes << i18n( "The program which provides compatibility with this "
    00625         "protocol may not have been updated with your last update of KDE. "
    00626         "This can cause the program to be incompatible with the current version "
    00627         "and thus not start." ) << cBug;
    00628       solutions << sUpdate << sSysadmin;
    00629       break;
    00630
    00631     case  KIO::ERR_INTERNAL:
    00632       errorName = i18n( "Internal Error" );
    00633       description = i18n( "The program on your computer which provides access "
    00634         "to the <strong>%1</strong> protocol has reported an internal error." )
    00635         .arg( protocol );
    00636       causes << cBuglikely;
    00637       solutions << sUpdate << sBugreport;
    00638       break;
    00639
    00640     case  KIO::ERR_MALFORMED_URL:
    00641       errorName = i18n( "Improperly Formatted URL" );
    00642       description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource "
    00643         "<strong>L</strong>ocator (URL) that you entered was not properly "
    00644         "formatted. The format of a URL is generally as follows:"
    00645         "<blockquote><strong>protocol://user:password@www.example.org:port/folder/"
    00646         "filename.extension?query=value</strong></blockquote>" );
    00647       solutions << sTypo;
    00648       break;
    00649
    00650     case  KIO::ERR_UNSUPPORTED_PROTOCOL:
    00651       errorName = i18n( "Unsupported Protocol %1" ).arg( protocol );
    00652       description = i18n( "The protocol <strong>%1</strong> is not supported "
    00653         "by the KDE programs currently installed on this computer." )
    00654         .arg( protocol );
    00655       causes << i18n( "The requested protocol may not be supported." )
    00656         << i18n( "The versions of the %1 protocol supported by this computer and "
    00657         "the server may be incompatible." ).arg( protocol );
    00658       solutions << i18n( "You may perform a search on the Internet for a KDE "
    00659         "program (called a kioslave or ioslave) which supports this protocol. "
    00660         "Places to search include <a href=\"http://kde-apps.org/\">"
    00661         "http://kde-apps.org/</a> and <a href=\"http://freshmeat.net/\">"
    00662         "http://freshmeat.net/</a>." )
    00663         << sUpdate << sSysadmin;
    00664       break;
    00665
    00666     case  KIO::ERR_NO_SOURCE_PROTOCOL:
    00667       errorName = i18n( "URL Does Not Refer to a Resource." );
    00668       techName = i18n( "Protocol is a Filter Protocol" );
    00669       description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource "
    00670         "<strong>L</strong>ocator (URL) that you entered did not refer to a "
    00671         "specific resource." );
    00672       causes << i18n( "KDE is able to communicate through a protocol within a "
    00673         "protocol; the protocol specified is only for use in such situations, "
    00674         "however this is not one of these situations. This is a rare event, and "
    00675         "is likely to indicate a programming error." );
    00676       solutions << sTypo;
    00677       break;
    00678
    00679     case  KIO::ERR_UNSUPPORTED_ACTION:
    00680       errorName = i18n( "Unsupported Action: %1" ).arg( errorText );
    00681       description = i18n( "The requested action is not supported by the KDE "
    00682         "program which is implementing the <strong>%1</strong> protocol." )
    00683         .arg( protocol );
    00684       causes << i18n( "This error is very much dependent on the KDE program. The "
    00685         "additional information should give you more information than is available "
    00686         "to the KDE input/output architecture." );
    00687       solutions << i18n( "Attempt to find another way to accomplish the same "
    00688         "outcome." );
    00689       break;
    00690
    00691     case  KIO::ERR_IS_DIRECTORY:
    00692       errorName = i18n( "File Expected" );
    00693       description = i18n( "The request expected a file, however the "
    00694         "folder <strong>%1</strong> was found instead." ).arg( dir );
    00695       causes << i18n( "This may be an error on the server side." ) << cBug;
    00696       solutions << sUpdate << sSysadmin;
    00697       break;
    00698
    00699     case  KIO::ERR_IS_FILE:
    00700       errorName = i18n( "Folder Expected" );
    00701       description = i18n( "The request expected a folder, however "
    00702         "the file <strong>%1</strong> was found instead." ).arg( filename );
    00703       causes << cBug;
    00704       solutions << sUpdate << sSysadmin;
    00705       break;
    00706
    00707     case  KIO::ERR_DOES_NOT_EXIST:
    00708       errorName = i18n( "File or Folder Does Not Exist" );
    00709       description = i18n( "The specified file or folder <strong>%1</strong> "
    00710         "does not exist." ).arg( dir );
    00711       causes << cBug;
    00712       solutions << sUpdate << sSysadmin;
    00713       break;
    00714
    00715     case  KIO::ERR_FILE_ALREADY_EXIST:
    00716       errorName = i18n( "File Already Exists" );
    00717       description = i18n( "The requested file could not be created because a "
    00718         "file with the same name already exists." );
    00719       solutions << i18n ( "Try moving the current file out of the way first, "
    00720         "and then try again." )
    00721         << i18n ( "Delete the current file and try again." )
    00722         << i18n( "Choose an alternate filename for the new file." );
    00723       break;
    00724
    00725     case  KIO::ERR_DIR_ALREADY_EXIST:
    00726       errorName = i18n( "Folder Already Exists" );
    00727       description = i18n( "The requested folder could not be created because "
    00728         "a folder with the same name already exists." );
    00729       solutions << i18n( "Try moving the current folder out of the way first, "
    00730         "and then try again." )
    00731         << i18n( "Delete the current folder and try again." )
    00732         << i18n( "Choose an alternate name for the new folder." );
    00733       break;
    00734
    00735     case  KIO::ERR_UNKNOWN_HOST:
    00736       errorName = i18n( "Unknown Host" );
    00737       description = i18n( "An unknown host error indicates that the server with "
    00738         "the requested name, <strong>%1</strong>, could not be "
    00739         "located on the Internet." ).arg( host );
    00740       causes << i18n( "The name that you typed, %1, may not exist: it may be "
    00741         "incorrectly typed." ).arg( host )
    00742         << cNetwork << cNetconf;
    00743       solutions << sNetwork << sSysadmin;
    00744       break;
    00745
    00746     case  KIO::ERR_ACCESS_DENIED:
    00747       errorName = i18n( "Access Denied" );
    00748       description = i18n( "Access was denied to the specified resource, "
    00749         "<strong>%1</strong>." ).arg( url );
    00750       causes << i18n( "You may have supplied incorrect authentication details or "
    00751         "none at all." )
    00752         << i18n( "Your account may not have permission to access the "
    00753         "specified resource." );
    00754       solutions << i18n( "Retry the request and ensure your authentication details "
    00755         "are entered correctly." ) << sSysadmin;
    00756       if ( !isSlaveNetwork ) solutions << sServeradmin;
    00757       break;
    00758
    00759     case  KIO::ERR_WRITE_ACCESS_DENIED:
    00760       errorName = i18n( "Write Access Denied" );
    00761       description = i18n( "This means that an attempt to write to the file "
    00762         "<strong>%1</strong> was rejected." ).arg( filename );
    00763       causes << cAccess << cLocked << cHardware;
    00764       solutions << sAccess << sQuerylock << sSysadmin;
    00765       break;
    00766
    00767     case  KIO::ERR_CANNOT_ENTER_DIRECTORY:
    00768       errorName = i18n( "Unable to Enter Folder" );
    00769       description = i18n( "This means that an attempt to enter (in other words, "
    00770         "to open) the requested folder <strong>%1</strong> was rejected." )
    00771         .arg( dir );
    00772       causes << cAccess << cLocked;
    00773       solutions << sAccess << sQuerylock << sSysadmin;
    00774       break;
    00775
    00776     case  KIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM:
    00777       errorName = i18n( "Folder Listing Unavailable" );
    00778       techName = i18n( "Protocol %1 is not a Filesystem" ).arg( protocol );
    00779       description = i18n( "This means that a request was made which requires "
    00780         "determining the contents of the folder, and the KDE program supporting "
    00781         "this protocol is unable to do so." );
    00782       causes << cBug;
    00783       solutions << sUpdate << sBugreport;
    00784       break;
    00785
    00786     case  KIO::ERR_CYCLIC_LINK:
    00787       errorName = i18n( "Cyclic Link Detected" );
    00788       description = i18n( "UNIX environments are commonly able to link a file or "
    00789         "folder to a separate name and/or location. KDE detected a link or "
    00790         "series of links that results in an infinite loop - i.e. the file was "
    00791         "(perhaps in a roundabout way) linked to itself." );
    00792       solutions << i18n( "Delete one part of the loop in order that it does not "
    00793         "cause an infinite loop, and try again." ) << sSysadmin;
    00794       break;
    00795
    00796     case  KIO::ERR_USER_CANCELED:
    00797       // Do nothing in this case. The user doesn't need to be told what he just did.
    00798       // rodda: However, if we have been called, an application is about to display
    00799       // this information anyway. If we don't return sensible information, the
    00800       // user sees a blank dialog (I have seen this myself)
    00801       errorName = i18n( "Request Aborted By User" );
    00802       description = i18n( "The request was not completed because it was "
    00803         "aborted." );
    00804       solutions << i18n( "Retry the request." );
    00805       break;
    00806
    00807     case  KIO::ERR_CYCLIC_COPY:
    00808       errorName = i18n( "Cyclic Link Detected During Copy" );
    00809       description = i18n( "UNIX environments are commonly able to link a file or "
    00810         "folder to a separate name and/or location. During the requested copy "
    00811         "operation, KDE detected a link or series of links that results in an "
    00812         "infinite loop - i.e. the file was (perhaps in a roundabout way) linked "
    00813         "to itself." );
    00814       solutions << i18n( "Delete one part of the loop in order that it does not "
    00815         "cause an infinite loop, and try again." ) << sSysadmin;
    00816       break;
    00817
    00818     case  KIO::ERR_COULD_NOT_CREATE_SOCKET:
    00819       errorName = i18n( "Could Not Create Network Connection" );
    00820       techName = i18n( "Could Not Create Socket" );
    00821       description = i18n( "This is a fairly technical error in which a required "
    00822         "device for network communications (a socket) could not be created." );
    00823       causes << i18n( "The network connection may be incorrectly configured, or "
    00824         "the network interface may not be enabled." );
    00825       solutions << sNetwork << sSysadmin;
    00826       break;
    00827
    00828     case  KIO::ERR_COULD_NOT_CONNECT:
    00829       errorName = i18n( "Connection to Server Refused" );
    00830       description = i18n( "The server <strong>%1</strong> refused to allow this "
    00831         "computer to make a connection." ).arg( host );
    00832       causes << i18n( "The server, while currently connected to the Internet, "
    00833         "may not be configured to allow requests." )
    00834         << i18n( "The server, while currently connected to the Internet, "
    00835         "may not be running the requested service (%1)." ).arg( protocol )
    00836         << i18n( "A network firewall (a device which restricts Internet "
    00837         "requests), either protecting your network or the network of the server, "
    00838         "may have intervened, preventing this request." );
    00839       solutions << sTryagain << sServeradmin << sSysadmin;
    00840       break;
    00841
    00842     case  KIO::ERR_CONNECTION_BROKEN:
    00843       errorName = i18n( "Connection to Server Closed Unexpectedly" );
    00844       description = i18n( "Although a connection was established to "
    00845         "<strong>%1</strong>, the connection was closed at an unexpected point "
    00846         "in the communication." ).arg( host );
    00847       causes << cNetwork << cNetpath << i18n( "A protocol error may have occurred, "
    00848         "causing the server to close the connection as a response to the error." );
    00849       solutions << sTryagain << sServeradmin << sSysadmin;
    00850       break;
    00851
    00852     case  KIO::ERR_NOT_FILTER_PROTOCOL:
    00853       errorName = i18n( "URL Resource Invalid" );
    00854       techName = i18n( "Protocol %1 is not a Filter Protocol" ).arg( protocol );
    00855       description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource "
    00856         "<strong>L</strong>ocator (URL) that you entered did not refer to "
    00857         "a valid mechanism of accessing the specific resource, "
    00858         "<strong>%1%2</strong>." )
    00859         .arg( !host.isNull() ? host + '/' : QString::null ).arg( dir );
    00860       causes << i18n( "KDE is able to communicate through a protocol within a "
    00861         "protocol. This request specified a protocol be used as such, however "
    00862         "this protocol is not capable of such an action. This is a rare event, "
    00863         "and is likely to indicate a programming error." );
    00864       solutions << sTypo << sSysadmin;
    00865       break;
    00866
    00867     case  KIO::ERR_COULD_NOT_MOUNT:
    00868       errorName = i18n( "Unable to Initialize Input/Output Device" );
    00869       techName = i18n( "Could Not Mount Device" );
    00870       description = i18n( "The requested device could not be initialized "
    00871         "(\"mounted\"). The reported error was: <strong>%1</strong>" )
    00872         .arg( errorText );
    00873       causes << i18n( "The device may not be ready, for example there may be "
    00874         "no media in a removable media device (i.e. no CD-ROM in a CD drive), "
    00875         "or in the case of a peripheral/portable device, the device may not "
    00876         "be correctly connected." )
    00877         << i18n( "You may not have permissions to initialize (\"mount\") the "
    00878         "device. On UNIX systems, often system administrator privileges are "
    00879         "required to initialize a device." )
    00880         << cHardware;
    00881       solutions << i18n( "Check that the device is ready; removable drives "
    00882         "must contain media, and portable devices must be connected and powered "
    00883         "on.; and try again." ) << sAccess << sSysadmin;
    00884       break;
    00885
    00886     case  KIO::ERR_COULD_NOT_UNMOUNT:
    00887       errorName = i18n( "Unable to Uninitialize Input/Output Device" );
    00888       techName = i18n( "Could Not Unmount Device" );
    00889       description = i18n( "The requested device could not be uninitialized "
    00890         "(\"unmounted\"). The reported error was: <strong>%1</strong>" )
    00891         .arg( errorText );
    00892       causes << i18n( "The device may be busy, that is, still in use by "
    00893         "another application or user. Even such things as having an open "
    00894         "browser window on a location on this device may cause the device to "
    00895         "remain in use." )
    00896         << i18n( "You may not have permissions to uninitialize (\"unmount\") "
    00897         "the device. On UNIX systems, system administrator privileges are "
    00898         "often required to uninitialize a device." )
    00899         << cHardware;
    00900       solutions << i18n( "Check that no applications are accessing the device, "
    00901         "and try again." ) << sAccess << sSysadmin;
    00902       break;
    00903
    00904     case  KIO::ERR_COULD_NOT_READ:
    00905       errorName = i18n( "Cannot Read From Resource" );
    00906       description = i18n( "This means that although the resource, "
    00907         "<strong>%1</strong>, was able to be opened, an error occurred while "
    00908         "reading the contents of the resource." ).arg( url );
    00909       causes << i18n( "You may not have permissions to read from the resource." );
    00910       if ( !isSlaveNetwork ) causes << cNetwork;
    00911       causes << cHardware;
    00912       solutions << sAccess;
    00913       if ( !isSlaveNetwork ) solutions << sNetwork;
    00914       solutions << sSysadmin;
    00915       break;
    00916
    00917     case  KIO::ERR_COULD_NOT_WRITE:
    00918       errorName = i18n( "Cannot Write to Resource" );
    00919       description = i18n( "This means that although the resource, <strong>%1</strong>"
    00920         ", was able to be opened, an error occurred while writing to the resource." )
    00921         .arg( url );
    00922       causes << i18n( "You may not have permissions to write to the resource." );
    00923       if ( !isSlaveNetwork ) causes << cNetwork;
    00924       causes << cHardware;
    00925       solutions << sAccess;
    00926       if ( !isSlaveNetwork ) solutions << sNetwork;
    00927       solutions << sSysadmin;
    00928       break;
    00929
    00930     case  KIO::ERR_COULD_NOT_BIND:
    00931       errorName = i18n( "Could Not Listen for Network Connections" );
    00932       techName = i18n( "Could Not Bind" );
    00933       description = i18n( "This is a fairly technical error in which a required "
    00934         "device for network communications (a socket) could not be established "
    00935         "to listen for incoming network connections." );
    00936       causes << i18n( "The network connection may be incorrectly configured, or "
    00937         "the network interface may not be enabled." );
    00938       solutions << sNetwork << sSysadmin;
    00939       break;
    00940
    00941     case  KIO::ERR_COULD_NOT_LISTEN:
    00942       errorName = i18n( "Could Not Listen for Network Connections" );
    00943       techName = i18n( "Could Not Listen" );
    00944       description = i18n( "This is a fairly technical error in which a required "
    00945         "device for network communications (a socket) could not be established "
    00946         "to listen for incoming network connections." );
    00947       causes << i18n( "The network connection may be incorrectly configured, or "
    00948         "the network interface may not be enabled." );
    00949       solutions << sNetwork << sSysadmin;
    00950       break;
    00951
    00952     case  KIO::ERR_COULD_NOT_ACCEPT:
    00953       errorName = i18n( "Could Not Accept Network Connection" );
    00954       description = i18n( "This is a fairly technical error in which an error "
    00955         "occurred while attempting to accept an incoming network connection." );
    00956       causes << i18n( "The network connection may be incorrectly configured, or "
    00957         "the network interface may not be enabled." )
    00958         << i18n( "You may not have permissions to accept the connection." );
    00959       solutions << sNetwork << sSysadmin;
    00960       break;
    00961
    00962     case  KIO::ERR_COULD_NOT_LOGIN:
    00963       errorName = i18n( "Could Not Login: %1" ).arg( errorText );
    00964       description = i18n( "An attempt to login to perform the requested "
    00965         "operation was unsuccessful." );
    00966       causes << i18n( "You may have supplied incorrect authentication details or "
    00967         "none at all." )
    00968         << i18n( "Your account may not have permission to access the "
    00969         "specified resource." ) << cProtocol;
    00970       solutions << i18n( "Retry the request and ensure your authentication details "
    00971         "are entered correctly." ) << sServeradmin << sSysadmin;
    00972       break;
    00973
    00974     case  KIO::ERR_COULD_NOT_STAT:
    00975       errorName = i18n( "Could Not Determine Resource Status" );
    00976       techName = i18n( "Could Not Stat Resource" );
    00977       description = i18n( "An attempt to determine information about the status "
    00978         "of the resource <strong>%1</strong>, such as the resource name, type, "
    00979         "size, etc., was unsuccessful." ).arg( url );
    00980       causes << i18n( "The specified resource may not have existed or may "
    00981         "not be accessible." ) << cProtocol << cHardware;
    00982       solutions << i18n( "Retry the request and ensure your authentication details "
    00983         "are entered correctly." ) << sSysadmin;
    00984       break;
    00985
    00986     case  KIO::ERR_COULD_NOT_CLOSEDIR:
    00987       //result = i18n( "Could not terminate listing %1" ).arg( errorText );
    00988       errorName = i18n( "Could Not Cancel Listing" );
    00989       techName = i18n( "FIXME: Document this" );
    00990       break;
    00991
    00992     case  KIO::ERR_COULD_NOT_MKDIR:
    00993       errorName = i18n( "Could Not Create Folder" );
    00994       description = i18n( "An attempt to create the requested folder failed." );
    00995       causes << cAccess << i18n( "The location where the folder was to be created "
    00996         "may not exist." );
    00997       if ( !isSlaveNetwork ) causes << cProtocol;
    00998       solutions << i18n( "Retry the request." ) << sAccess;
    00999       break;
    01000
    01001     case  KIO::ERR_COULD_NOT_RMDIR:
    01002       errorName = i18n( "Could Not Remove Folder" );
    01003       description = i18n( "An attempt to remove the specified folder, "
    01004         "<strong>%1</strong>, failed." ).arg( dir );
    01005       causes << i18n( "The specified folder may not exist." )
    01006         << i18n( "The specified folder may not be empty." )
    01007         << cAccess;
    01008       if ( !isSlaveNetwork ) causes << cProtocol;
    01009       solutions << i18n( "Ensure that the folder exists and is empty, and try "
    01010         "again." ) << sAccess;
    01011       break;
    01012
    01013     case  KIO::ERR_CANNOT_RESUME:
    01014       errorName = i18n( "Could Not Resume File Transfer" );
    01015       description = i18n( "The specified request asked that the transfer of "
    01016         "file <strong>%1</strong> be resumed at a certain point of the "
    01017         "transfer. This was not possible." ).arg( filename );
    01018       causes << i18n( "The protocol, or the server, may not support file "
    01019         "resuming." );
    01020       solutions << i18n( "Retry the request without attempting to resume "
    01021         "transfer." );
    01022       break;
    01023
    01024     case  KIO::ERR_CANNOT_RENAME:
    01025       errorName = i18n( "Could Not Rename Resource" );
    01026       description = i18n( "An attempt to rename the specified resource "
    01027         "<strong>%1</strong> failed." ).arg( url );
    01028       causes << cAccess << cExists;
    01029       if ( !isSlaveNetwork ) causes << cProtocol;
    01030       solutions << sAccess << sExists;
    01031       break;
    01032
    01033     case  KIO::ERR_CANNOT_CHMOD:
    01034       errorName = i18n( "Could Not Alter Permissions of Resource" );
    01035       description = i18n( "An attempt to alter the permissions on the specified "
    01036         "resource <strong>%1</strong> failed." ).arg( url );
    01037       causes << cAccess << cExists;
    01038       solutions << sAccess << sExists;
    01039       break;
    01040
    01041     case  KIO::ERR_CANNOT_DELETE:
    01042       errorName = i18n( "Could Not Delete Resource" );
    01043       description = i18n( "An attempt to delete the specified resource "
    01044         "<strong>%1</strong> failed." ).arg( url );
    01045       causes << cAccess << cExists;
    01046       solutions << sAccess << sExists;
    01047       break;
    01048
    01049     case  KIO::ERR_SLAVE_DIED:
    01050       errorName = i18n( "Unexpected Program Termination" );
    01051       description = i18n( "The program on your computer which provides access "
    01052         "to the <strong>%1</strong> protocol has unexpectedly terminated." )
    01053         .arg( url );
    01054       causes << cBuglikely;
    01055       solutions << sUpdate << sBugreport;
    01056       break;
    01057
    01058     case  KIO::ERR_OUT_OF_MEMORY:
    01059       errorName = i18n( "Out of Memory" );
    01060       description = i18n( "The program on your computer which provides access "
    01061         "to the <strong>%1</strong> protocol could not obtain the memory "
    01062         "required to continue." ).arg( protocol );
    01063       causes << cBuglikely;
    01064       solutions << sUpdate << sBugreport;
    01065       break;
    01066
    01067     case  KIO::ERR_UNKNOWN_PROXY_HOST:
    01068       errorName = i18n( "Unknown Proxy Host" );
    01069       description = i18n( "While retrieving information about the specified "
    01070         "proxy host, <strong>%1</strong>, an Unknown Host error was encountered. "
    01071         "An unknown host error indicates that the requested name could not be "
    01072         "located on the Internet." ).arg( errorText );
    01073       causes << i18n( "There may have been a problem with your network "
    01074         "configuration, specifically your proxy's hostname. If you have been "
    01075         "accessing the Internet with no problems recently, this is unlikely." )
    01076         << cNetwork;
    01077       solutions << i18n( "Double-check your proxy settings and try again." )
    01078         << sSysadmin;
    01079       break;
    01080
    01081     case  KIO::ERR_COULD_NOT_AUTHENTICATE:
    01082       errorName = i18n( "Authentication Failed: Method %1 Not Supported" )
    01083          .arg( errorText );
    01084       description = i18n( "Although you may have supplied the correct "
    01085         "authentication details, the authentication failed because the "
    01086         "method that the server is using is not supported by the KDE "
    01087         "program implementing the protocol %1." ).arg( protocol );
    01088       solutions << i18n( "Please file a bug at <a href=\"http://bugs.kde.org/\">"
    01089         "http://bugs.kde.org/</a> to inform the KDE team of the unsupported "
    01090         "authentication method." ) << sSysadmin;
    01091       break;
    01092
    01093     case  KIO::ERR_ABORTED:
    01094       errorName = i18n( "Request Aborted" );
    01095       description = i18n( "The request was not completed because it was "
    01096         "aborted." );
    01097       solutions << i18n( "Retry the request." );
    01098       break;
    01099
    01100     case  KIO::ERR_INTERNAL_SERVER:
    01101       errorName = i18n( "Internal Error in Server" );
    01102       description = i18n( "The program on the server which provides access "
    01103         "to the <strong>%1</strong> protocol has reported an internal error: "
    01104         "%0." ).arg( protocol );
    01105       causes << i18n( "This is most likely to be caused by a bug in the "
    01106         "server program. Please consider submitting a full bug report as "
    01107         "detailed below." );
    01108       solutions << i18n( "Contact the administrator of the server "
    01109         "to advise them of the problem." )
    01110         << i18n( "If you know who the authors of the server software are, "
    01111         "submit the bug report directly to them." );
    01112       break;
    01113
    01114     case  KIO::ERR_SERVER_TIMEOUT:
    01115       errorName = i18n( "Timeout Error" );
    01116       description = i18n( "Although contact was made with the server, a "
    01117         "response was not received within the amount of time allocated for "
    01118         "the request as follows:<ul>"
    01119         "<li>Timeout for establishing a connection: %1 seconds</li>"
    01120         "<li>Timeout for receiving a response: %2 seconds</li>"
    01121         "<li>Timeout for accessing proxy servers: %3 seconds</li></ul>"
    01122         "Please note that you can alter these timeout settings in the KDE "
    01123         "Control Center, by selecting Network -> Preferences." )
    01124         .arg( KProtocolManager::connectTimeout() )
    01125         .arg( KProtocolManager::responseTimeout() )
    01126         .arg( KProtocolManager::proxyConnectTimeout() );
    01127       causes << cNetpath << i18n( "The server was too busy responding to other "
    01128         "requests to respond." );
    01129       solutions << sTryagain << sServeradmin;
    01130       break;
    01131
    01132     case  KIO::ERR_UNKNOWN:
    01133       errorName = i18n( "Unknown Error" );
    01134       description = i18n( "The program on your computer which provides access "
    01135         "to the <strong>%1</strong> protocol has reported an unknown error: "
    01136         "%2." ).arg( protocol ).arg( errorText );
    01137       causes << cBug;
    01138       solutions << sUpdate << sBugreport;
    01139       break;
    01140
    01141     case  KIO::ERR_UNKNOWN_INTERRUPT:
    01142       errorName = i18n( "Unknown Interruption" );
    01143       description = i18n( "The program on your computer which provides access "
    01144         "to the <strong>%1</strong> protocol has reported an interruption of "
    01145         "an unknown type: %2." ).arg( protocol ).arg( errorText );
    01146       causes << cBug;
    01147       solutions << sUpdate << sBugreport;
    01148       break;
    01149
    01150     case KIO::ERR_CANNOT_DELETE_ORIGINAL:
    01151       errorName = i18n( "Could Not Delete Original File" );
    01152       description = i18n( "The requested operation required the deleting of "
    01153         "the original file, most likely at the end of a file move operation. "
    01154         "The original file <strong>%1</strong> could not be deleted." )
    01155         .arg( errorText );
    01156       causes << cAccess;
    01157       solutions << sAccess;
    01158       break;
    01159
    01160     case KIO::ERR_CANNOT_DELETE_PARTIAL:
    01161       errorName = i18n( "Could Not Delete Temporary File" );
    01162       description = i18n( "The requested operation required the creation of "
    01163         "a temporary file in which to save the new file while being "
    01164         "downloaded. This temporary file <strong>%1</strong> could not be "
    01165         "deleted." ).arg( errorText );
    01166       causes << cAccess;
    01167       solutions << sAccess;
    01168       break;
    01169
    01170     case KIO::ERR_CANNOT_RENAME_ORIGINAL:
    01171       errorName = i18n( "Could Not Rename Original File" );
    01172       description = i18n( "The requested operation required the renaming of "
    01173         "the original file <strong>%1</strong>, however it could not be "
    01174         "renamed." ).arg( errorText );
    01175       causes << cAccess;
    01176       solutions << sAccess;
    01177       break;
    01178
    01179     case KIO::ERR_CANNOT_RENAME_PARTIAL:
    01180       errorName = i18n( "Could Not Rename Temporary File" );
    01181       description = i18n( "The requested operation required the creation of "
    01182         "a temporary file <strong>%1</strong>, however it could not be "
    01183         "created." ).arg( errorText );
    01184       causes << cAccess;
    01185       solutions << sAccess;
    01186       break;
    01187
    01188     case KIO::ERR_CANNOT_SYMLINK:
    01189       errorName = i18n( "Could Not Create Link" );
    01190       techName = i18n( "Could Not Create Symbolic Link" );
    01191       description = i18n( "The requested symbolic link %1 could not be created." )
    01192         .arg( errorText );
    01193       causes << cAccess;
    01194       solutions << sAccess;
    01195       break;
    01196
    01197     case KIO::ERR_NO_CONTENT:
    01198       errorName = i18n( "No Content" );
    01199       description = errorText;
    01200       break;
    01201
    01202     case KIO::ERR_DISK_FULL:
    01203       errorName = i18n( "Disk Full" );
    01204       description = i18n( "The requested file <strong>%1</strong> could not be "
    01205         "written to as there is inadequate disk space." ).arg( errorText );
    01206       solutions << i18n( "Free up enough disk space by 1) deleting unwanted and "
    01207         "temporary files; 2) archiving files to removable media storage such as "
    01208         "CD-Recordable discs; or 3) obtain more storage capacity." )
    01209         << sSysadmin;
    01210       break;
    01211
    01212     case KIO::ERR_IDENTICAL_FILES:
    01213       errorName = i18n( "Source and Destination Files Identical" );
    01214       description = i18n( "The operation could not be completed because the "
    01215         "source and destination files are the same file." );
    01216       solutions << i18n( "Choose a different filename for the destination file." );
    01217       break;
    01218
    01219     // We assume that the slave has all the details
    01220     case KIO::ERR_SLAVE_DEFINED:
    01221       errorName = QString::null;
    01222       description = errorText;
    01223       break;
    01224
    01225     default:
    01226       // fall back to the plain error...
    01227       errorName = i18n( "Undocumented Error" );
    01228       description = buildErrorString( errorCode, errorText );
    01229   }
    01230
    01231   QByteArray ret;
    01232   QDataStream stream(ret, IO_WriteOnly);
    01233   stream << errorName << techName << description << causes << solutions;
    01234   return ret;
    01235 }
    01236
    01237 #ifdef Q_OS_UNIX
    01238
    01239 #include <limits.h>
    01240 #include <stdlib.h>
    01241 #include <stdio.h>
    01242 #include <qfile.h>
    01243
    01244 #include <config.h>
    01245
    01246 #ifdef HAVE_PATHS_H
    01247 #include <paths.h>
    01248 #endif
    01249 #ifdef HAVE_SYS_STAT_H
    01250 #include <sys/stat.h>
    01251 #endif
    01252 #include <sys/param.h>
    01253 #ifdef HAVE_LIMITS_H
    01254 #include <limits.h>
    01255 #endif
    01256 #ifdef HAVE_SYS_MNTTAB_H
    01257 #include <sys/mnttab.h>
    01258 #endif
    01259 #ifdef HAVE_MNTENT_H
    01260 #include <mntent.h>
    01261 #elif defined(HAVE_SYS_MNTENT_H)
    01262 #include <sys/mntent.h>
    01263 #endif
    01264 #ifdef HAVE_SYS_UCRED_H
    01265 #include <sys/ucred.h>
    01266 #endif
    01267 #ifdef HAVE_SYS_MOUNT_H
    01268 #include <sys/mount.h>
    01269 #endif
    01270 #ifdef HAVE_FSTAB_H
    01271 #include <fstab.h>
    01272 #endif
    01273 #if defined(_AIX)
    01274 #include <sys/mntctl.h>
    01275 #include <sys/vmount.h>
    01276 #include <sys/vfs.h>
    01277
    01278 /* AIX does not prototype mntctl anywhere that I can find */
    01279 #ifndef mntctl
    01280 extern "C" {
    01281 int mntctl(int command, int size, void* buffer);
    01282 }
    01283 #endif
    01284 extern "C" struct vfs_ent *getvfsbytype(int vfsType);
    01285 extern "C" void endvfsent( );
    01286 #endif
    01287
    01288 /***************************************************************
    01289  *
    01290  * Utility functions
    01291  *
    01292  ***************************************************************/
    01293
    01294 #ifndef HAVE_GETMNTINFO
    01295
    01296 #ifdef _PATH_MOUNTED
    01297 // On some Linux, MNTTAB points to /etc/fstab !
    01298 # undef MNTTAB
    01299 # define MNTTAB _PATH_MOUNTED
    01300 #else
    01301 # ifndef MNTTAB
    01302 #  ifdef MTAB_FILE
    01303 #   define MNTTAB MTAB_FILE
    01304 #  else
    01305 #   define MNTTAB "/etc/mnttab"
    01306 #  endif
    01307 # endif
    01308 #endif
    01309
    01310 #ifndef FSTAB
    01311 # ifdef _PATH_FSTAB
    01312 #  define FSTAB _PATH_FSTAB
    01313 # else
    01314 #  define FSTAB "/etc/fstab"
    01315 # endif
    01316 #endif
    01317
    01318 // There are (at least) four kind of APIs:
    01319 // setmntent + getmntent + struct mntent (linux...)
    01320 //             getmntent + struct mnttab
    01321 // mntctl                + struct vmount (AIX)
    01322 // getmntinfo + struct statfs&flags (BSD 4.4 and friends)
    01323 // getfsent + char* (BSD 4.3 and friends)
    01324
    01325 #ifdef HAVE_SETMNTENT
    01326 #define SETMNTENT setmntent
    01327 #define ENDMNTENT endmntent
    01328 #define STRUCT_MNTENT struct mntent *
    01329 #define STRUCT_SETMNTENT FILE *
    01330 #define GETMNTENT(file, var) ((var = getmntent(file)) != 0)
    01331 #define MOUNTPOINT(var) var->mnt_dir
    01332 #define MOUNTTYPE(var) var->mnt_type
    01333 #define HASMNTOPT(var, opt) hasmntopt(var, opt)
    01334 #define FSNAME(var) var->mnt_fsname
    01335 #elif defined(_AIX)
    01336 /* we don't need this stuff */
    01337 #else
    01338 #define SETMNTENT fopen
    01339 #define ENDMNTENT fclose
    01340 #define STRUCT_MNTENT struct mnttab
    01341 #define STRUCT_SETMNTENT FILE *
    01342 #define GETMNTENT(file, var) (getmntent(file, &var) == 0)
    01343 #define MOUNTPOINT(var) var.mnt_mountp
    01344 #define MOUNTTYPE(var) var.mnt_fstype
    01345 #define HASMNTOPT(var, opt) hasmntopt(&var, opt)
    01346 #define FSNAME(var) var.mnt_special
    01347 #endif
    01348
    01349 #endif /* HAVE_GETMNTINFO */
    01350
    01351 QString KIO::findDeviceMountPoint( const QString& filename )
    01352 {
    01353     QString result;
    01354
    01355 #ifdef HAVE_VOLMGT
    01356     /*
    01357      *  support for Solaris volume management
    01358      */
    01359     const char *volpath;
    01360     FILE *mnttab;
    01361     struct mnttab mnt;
    01362     int len;
    01363     QCString devname;
    01364
    01365     if( (volpath = volmgt_root()) == NULL ) {
    01366         kdDebug( 7007 ) << "findDeviceMountPoint: "
    01367             << "VOLMGT: can't find volmgt root dir" << endl;
    01368         return QString::null;
    01369     }
    01370
    01371     if( (mnttab = fopen( MNTTAB, "r" )) == NULL ) {
    01372         kdDebug( 7007 ) << "findDeviceMountPoint: "
    01373             << "VOLMGT: can't open mnttab" << endl;
    01374         return QString::null;
    01375     }
    01376
    01377     devname = volpath;
    01378     devname += QFile::encodeName( filename );
    01379     devname += '/';
    01380     len = devname.length();
    01381 //  kdDebug( 7007 ) << "findDeviceMountPoint: "
    01382 //      << "VOLMGT: searching mountpoint for \"" << devname << "\""
    01383 //      << endl;
    01384
    01385     /*
    01386      *  find the mountpoint
    01387      *  floppies:
    01388      *  /dev/disketteN    => <volpath>/dev/disketteN
    01389      *  CDROM, ZIP, and other media:
    01390      *  /dev/dsk/cXtYdZs2 => <volpath>/dev/dsk/cXtYdZ  (without slice#)
    01391      */
    01392     rewind( mnttab );
    01393     result = QString::null;
    01394     while( getmntent( mnttab, &mnt ) == 0 ) {
    01395         /*
    01396          *  either match the exact device name (floppies),
    01397          *  or the device name without the slice#
    01398          */
    01399         if( strncmp( devname.data(), mnt.mnt_special, len ) == 0
    01400             || (strncmp( devname.data(), mnt.mnt_special, len - 3 ) == 0
    01401                 && mnt.mnt_special[len - 3] == '/' )
    01402             || (strcmp(QFile::encodeName(filename).data()
    01403                     , mnt.mnt_special)==0)) {
    01404             result = mnt.mnt_mountp;
    01405             break;
    01406         }
    01407     }
    01408     fclose( mnttab );
    01409 #else
    01410
    01411     char    realpath_buffer[MAXPATHLEN];
    01412     QCString realname;
    01413
    01414     realname = QFile::encodeName(filename);
    01415     /* If the path contains symlinks, get the real name */
    01416     if (realpath(realname, realpath_buffer) != 0)
    01417       // succes, use result from realpath
    01418       realname = realpath_buffer;
    01419
    01420     //kdDebug(7007) << "findDeviceMountPoint realname=" << realname << endl;
    01421
    01422 #ifdef HAVE_GETMNTINFO
    01423
    01424     struct statfs *mounted;
    01425
    01426     int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
    01427
    01428     for (int i=0;i<num_fs;i++) {
    01429
    01430         QCString device_name = mounted[i].f_mntfromname;
    01431
    01432         // If the path contains symlinks, get
    01433         // the real name
    01434         if (realpath(device_name, realpath_buffer) != 0)
    01435             // succes, use result from realpath
    01436             device_name = realpath_buffer;
    01437
    01438         if (realname == device_name) {
    01439             result = mounted[i].f_mntonname;
    01440             break;
    01441         }
    01442     }
    01443
    01444 #elif defined(_AIX)
    01445
    01446     struct vmount *mntctl_buffer;
    01447     struct vmount *vm;
    01448     char *mountedfrom;
    01449     char *mountedto;
    01450     int fsname_len, num;
    01451     int buf_sz = 4096;
    01452
    01453     /* mntctl can be used to query mounted file systems.
    01454      * mntctl takes only the command MCTL_QUERY so far.
    01455      * The buffer is filled with an array of vmount structures, but these
    01456      * vmount structures have variable size.
    01457      * mntctl return values:
    01458      * -1 error
    01459      *  0 look in first word of buffer for required bytes, 4096 may be
    01460      *    a good starting size, but if tables grow too large, look here.
    01461      * >0 number of vmount structures
    01462      */
    01463     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    01464     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    01465     if (num == 0)
    01466     {
    01467     buf_sz = *(int*)mntctl_buffer;
    01468     free(mntctl_buffer);
    01469     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    01470     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    01471     }
    01472
    01473     if (num > 0)
    01474     {
    01475         /* iterate through items in the vmount structure: */
    01476         vm = mntctl_buffer;
    01477         for ( ; num > 0; num-- )
    01478         {
    01479             /* get the name of the mounted file systems: */
    01480             fsname_len = vmt2datasize(vm, VMT_STUB);
    01481             mountedto     = (char*)malloc(fsname_len + 1);
    01482         mountedto[fsname_len] = '\0';
    01483             strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len);
    01484
    01485             /* get the mount-from information: */
    01486             fsname_len = vmt2datasize(vm, VMT_OBJECT);
    01487             mountedfrom     = (char*)malloc(fsname_len + 1);
    01488         mountedfrom[fsname_len] = '\0';
    01489             strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len);
    01490
    01491             QCString device_name = mountedfrom;
    01492
    01493             if (realpath(device_name, realpath_buffer) != 0)
    01494                 // success, use result from realpath
    01495                 device_name = realpath_buffer;
    01496
    01497             free(mountedfrom);
    01498
    01499             if (realname == device_name) {
    01500                 result = mountedto;
    01501                 free(mountedto);
    01502                 break;
    01503             }
    01504
    01505             free(mountedto);
    01506
    01507             /* goto the next vmount structure: */
    01508             vm = (struct vmount *)((char *)vm + vm->vmt_length);
    01509         }
    01510     }
    01511
    01512     free( mntctl_buffer );
    01513
    01514 #else
    01515
    01516     STRUCT_SETMNTENT mtab;
    01517
    01518     /* Get the list of mounted file systems */
    01519
    01520     if ((mtab = SETMNTENT(MNTTAB, "r")) == 0) {
    01521         perror("setmntent");
    01522         return QString::null;
    01523     }
    01524
    01525     /* Loop over all file systems and see if we can find our
    01526      * mount point.
    01527      * Note that this is the mount point with the longest match.
    01528      * XXX: Fails if me->mnt_dir is not a realpath but goes
    01529      * through a symlink, e.g. /foo/bar where /foo is a symlink
    01530      * pointing to /local/foo.
    01531      *
    01532      * How kinky can you get with a filesystem?
    01533      */
    01534
    01535     STRUCT_MNTENT me;
    01536
    01537     while (GETMNTENT(mtab, me))
    01538     {
    01539       // There may be symbolic links into the /etc/mnttab
    01540       // So we have to find the real device name here as well!
    01541       QCString device_name = FSNAME(me);
    01542       if (device_name.isEmpty() || (device_name == "none"))
    01543          continue;
    01544
    01545       //kdDebug( 7007 ) << "device_name=" << device_name << endl;
    01546
    01547       // If the path contains symlinks, get
    01548       // the real name
    01549       if (realpath(device_name, realpath_buffer) != 0)
    01550           // succes, use result from realpath
    01551          device_name = realpath_buffer;
    01552
    01553       //kdDebug( 7007 ) << "device_name after realpath =" << device_name << endl;
    01554
    01555       if (realname == device_name)
    01556       {
    01557           result = MOUNTPOINT(me);
    01558           break;
    01559       }
    01560     }
    01561
    01562     ENDMNTENT(mtab);
    01563
    01564 #endif /* GET_MNTINFO */
    01565 #endif /* HAVE_VOLMGT */
    01566
    01567     //kdDebug( 7007 ) << "Returning result " << result << endl;
    01568     return result;
    01569 }
    01570
    01571 // Don't just trust the return value, keep iterating to check for a better match (bigger max)
    01572 static bool is_my_mountpoint( const char *mountpoint, const char *realname, int &max )
    01573 {
    01574     int length = strlen(mountpoint);
    01575
    01576     if (!strncmp(mountpoint, realname, length)
    01577         && length > max) {
    01578         max = length;
    01579         if (length == 1 || realname[length] == '/' || realname[length] == '\0')
    01580             return true;
    01581     }
    01582     return false;
    01583 }
    01584
    01585 typedef enum { Unseen, Right, Wrong } MountState;
    01586
    01590 static void check_mount_point(const char *mounttype,
    01591                               const char *fsname,
    01592                               MountState &isslow, MountState &isautofs)
    01593 {
    01594     bool nfs = !strcmp(mounttype, "nfs");
    01595     bool autofs = !strcmp(mounttype, "autofs") || !strcmp(mounttype,"subfs");
    01596     bool pid = (strstr(fsname, ":(pid") != 0);
    01597
    01598     if (nfs && !pid)
    01599         isslow = Right;
    01600     else if (isslow == Right)
    01601         isslow = Wrong;
    01602
    01603     /* Does this look like automounted? */
    01604     if (autofs || (nfs && pid)) {
    01605         isautofs = Right;
    01606         isslow = Right;
    01607     }
    01608 }
    01609
    01610 // returns the mount point, checks the mount state.
    01611 // if ismanual == Wrong this function does not check the manual mount state
    01612 static QString get_mount_info(const QString& filename,
    01613     MountState& isautofs, MountState& isslow, MountState& ismanual,
    01614     QString& fstype)
    01615 {
    01616     static bool gotRoot = false;
    01617     static dev_t rootDevice;
    01618
    01619     struct cachedDevice_t
    01620     {
    01621        dev_t device;
    01622        QString mountPoint;
    01623        MountState isautofs;
    01624        MountState isslow;
    01625        MountState ismanual;
    01626        QString fstype;
    01627     };
    01628     static struct cachedDevice_t *cachedDevice = 0;
    01629
    01630     if (!gotRoot)
    01631     {
    01632        KDE_struct_stat stat_buf;
    01633        KDE_stat("/", &stat_buf);
    01634        gotRoot = true;
    01635        rootDevice = stat_buf.st_dev;
    01636     }
    01637
    01638     bool gotDevice = false;
    01639     KDE_struct_stat stat_buf;
    01640     if (KDE_stat(QFile::encodeName(filename), &stat_buf) == 0)
    01641     {
    01642        gotDevice = true;
    01643        if (stat_buf.st_dev == rootDevice)
    01644        {
    01645           static const QString &root = KGlobal::staticQString("/");
    01646           isautofs = Wrong;
    01647           isslow = Wrong;
    01648           ismanual = Wrong;
    01649           fstype = QString::null; // ### do we need it?
    01650           return root;
    01651        }
    01652        if (cachedDevice && (stat_buf.st_dev == cachedDevice->device))
    01653        {
    01654           bool interestedInIsManual = ismanual != Wrong;
    01655           isautofs = cachedDevice->isautofs;
    01656           isslow = cachedDevice->isslow;
    01657           ismanual = cachedDevice->ismanual;
    01658           fstype = cachedDevice->fstype;
    01659           // Don't use the cache if it doesn't have the information we're looking for
    01660           if ( !interestedInIsManual || ismanual != Unseen )
    01661               return cachedDevice->mountPoint;
    01662        }
    01663     }
    01664
    01665     char realname[MAXPATHLEN];
    01666
    01667     memset(realname, 0, MAXPATHLEN);
    01668
    01669     /* If the path contains symlinks, get the real name */
    01670     if (realpath(QFile::encodeName(filename), realname) == 0) {
    01671         if( strlcpy(realname, QFile::encodeName(filename), MAXPATHLEN)>=MAXPATHLEN)
    01672             return QString::null;
    01673     }
    01674
    01675     int max = 0;
    01676     QString mountPoint;
    01677
    01678     /* Loop over all file systems and see if we can find our
    01679      * mount point.
    01680      * Note that this is the mount point with the longest match.
    01681      * XXX: Fails if me->mnt_dir is not a realpath but goes
    01682      * through a symlink, e.g. /foo/bar where /foo is a symlink
    01683      * pointing to /local/foo.
    01684      *
    01685      * How kinky can you get with a filesystem?
    01686      */
    01687
    01688 #ifdef HAVE_GETMNTINFO
    01689
    01690     struct statfs *mounted;
    01691     char    realpath_buffer[MAXPATHLEN];
    01692
    01693     int num_fs = getmntinfo(&mounted, MNT_NOWAIT);
    01694
    01695     for (int i=0;i<num_fs;i++) {
    01696
    01697         QCString device_name = mounted[i].f_mntfromname;
    01698
    01699         // If the path contains symlinks, get
    01700         // the real name
    01701         if (realpath(device_name, realpath_buffer) != 0)
    01702             // succes, use result from realpath
    01703             device_name = realpath_buffer;
    01704 #ifdef __osf__
    01705         char * mounttype = mnt_names[mounted[i].f_type];
    01706 #else
    01707         char * mounttype = mounted[i].f_fstypename;
    01708 #endif
    01709         if ( is_my_mountpoint( mounted[i].f_mntonname, realname, max ) )
    01710         {
    01711             mountPoint = QFile::decodeName(mounted[i].f_mntonname);
    01712             fstype = QString::fromLatin1(mounttype);
    01713             check_mount_point( mounttype, mounted[i].f_mntfromname,
    01714                                isautofs, isslow );
    01715             // keep going, looking for a potentially better one
    01716
    01717             if (ismanual == Unseen)
    01718             {
    01719                 struct fstab *ft = getfsfile(mounted[i].f_mntonname);
    01720                 if (!ft || strstr(ft->fs_mntops, "noauto"))
    01721                   ismanual = Right;
    01722             }
    01723         }
    01724     }
    01725
    01726 #elif defined(_AIX)
    01727
    01728     struct vmount *mntctl_buffer;
    01729     struct vmount *vm;
    01730     char *mountedfrom;
    01731     char *mountedto;
    01732     int fsname_len, num;
    01733     char realpath_buffer[MAXPATHLEN];
    01734     int buf_sz = 4096;
    01735
    01736     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    01737     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    01738     if (num == 0)
    01739     {
    01740     buf_sz = *(int*)mntctl_buffer;
    01741     free(mntctl_buffer);
    01742     mntctl_buffer = (struct vmount*)malloc(buf_sz);
    01743     num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer);
    01744     }
    01745
    01746     if (num > 0)
    01747     {
    01748         /* iterate through items in the vmount structure: */
    01749         vm = (struct vmount *)mntctl_buffer;
    01750         for ( ; num > 0; num-- )
    01751         {
    01752             /* get the name of the mounted file systems: */
    01753             fsname_len = vmt2datasize(vm, VMT_STUB);
    01754             mountedto     = (char*)malloc(fsname_len + 1);
    01755         mountedto[fsname_len] = '\0';
    01756             strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len);
    01757
    01758             fsname_len = vmt2datasize(vm, VMT_OBJECT);
    01759             mountedfrom     = (char*)malloc(fsname_len + 1);
    01760         mountedfrom[fsname_len] = '\0';
    01761             strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len);
    01762
    01763             /* get the mount-from information: */
    01764             QCString device_name = mountedfrom;
    01765
    01766             if (realpath(device_name, realpath_buffer) != 0)
    01767                 // success, use result from realpath
    01768                 device_name = realpath_buffer;
    01769
    01770         /* Look up the string for the file system type,
    01771              * as listed in /etc/vfs.
    01772              * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs
    01773              */
    01774             struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype);
    01775
    01776             if ( is_my_mountpoint( mountedto, realname, max ) )
    01777             {
    01778                 mountPoint = QFile::decodeName(mountedto);
    01779                 fstype = QString::fromLatin1(ent->vfsent_name);
    01780                 check_mount_point(ent->vfsent_name, device_name, isautofs, isslow);
    01781
    01782                 if (ismanual == Unseen)
    01783                 {
    01784                     // TODO: add check for ismanual, I couldn't find any way
    01785                     // how to get the mount attribute from /etc/filesystems
    01786                     ismanual == Wrong;
    01787                 }
    01788             }
    01789
    01790             free(mountedfrom);
    01791             free(mountedto);
    01792
    01793             /* goto the next vmount structure: */
    01794             vm = (struct vmount *)((char *)vm + vm->vmt_length);
    01795         }
    01796
    01797     endvfsent( );
    01798     }
    01799
    01800     free( mntctl_buffer );
    01801
    01802 #else
    01803
    01804     STRUCT_SETMNTENT mtab;
    01805     /* Get the list of mounted file systems */
    01806
    01807     if ((mtab = SETMNTENT(MNTTAB, "r")) == 0) {
    01808         perror("setmntent");
    01809         return QString::null;
    01810     }
    01811
    01812     STRUCT_MNTENT me;
    01813
    01814     while (true) {
    01815         if (!GETMNTENT(mtab, me))
    01816             break;
    01817
    01818         if ( is_my_mountpoint( MOUNTPOINT(me), realname, max ) )
    01819         {
    01820             mountPoint = QFile::decodeName( MOUNTPOINT(me) );
    01821             fstype = MOUNTTYPE(me);
    01822             check_mount_point(MOUNTTYPE(me), FSNAME(me), isautofs, isslow);
    01823             // we don't check if ismanual is Right, if /a/b is manually
    01824             // mounted /a/b/c can't be automounted. At least IMO.
    01825             if (ismanual == Unseen)
    01826             {
    01827                 // The next GETMNTENT call may destroy 'me'
    01828                 // Copy out the info that we need
    01829                 QCString fsname_me = FSNAME(me);
    01830                 QCString mounttype_me = MOUNTTYPE(me);
    01831
    01832                 STRUCT_SETMNTENT fstab;
    01833                 if ((fstab = SETMNTENT(FSTAB, "r")) == 0) {
    01834                     continue;
    01835                 }
    01836
    01837                 bool found = false;
    01838                 STRUCT_MNTENT fe;
    01839                 while (GETMNTENT(fstab, fe))
    01840                 {
    01841                     if (fsname_me == FSNAME(fe))
    01842                     {
    01843                         found = true;
    01844                         if (HASMNTOPT(fe, "noauto") ||
    01845                             !strcmp(MOUNTTYPE(fe), "supermount"))
    01846                             ismanual = Right;
    01847                         break;
    01848                     }
    01849                 }
    01850                 if (!found || (mounttype_me == "supermount"))
    01851                   ismanual = Right;
    01852
    01853                 ENDMNTENT(fstab);
    01854             }
    01855         }
    01856     }
    01857
    01858     ENDMNTENT(mtab);
    01859
    01860 #endif
    01861
    01862     if (isautofs == Right && isslow == Unseen)
    01863         isslow = Right;
    01864
    01865     if (gotDevice)
    01866     {
    01867        if (!cachedDevice)
    01868           cachedDevice = new cachedDevice_t;
    01869
    01870        cachedDevice->device = stat_buf.st_dev;
    01871        cachedDevice->mountPoint = mountPoint;
    01872        cachedDevice->isautofs = isautofs;
    01873        cachedDevice->isslow = isslow;
    01874        cachedDevice->ismanual = ismanual;
    01875        cachedDevice->fstype = fstype;
    01876     }
    01877
    01878     return mountPoint;
    01879 }
    01880
    01881 #else
    01882 //dummy
    01883 QString KIO::findDeviceMountPoint( const QString& filename )
    01884 {
    01885     return QString::null;
    01886 }
    01887 #endif
    01888
    01889 QString KIO::findPathMountPoint(const QString& filename)
    01890 {
    01891 #ifdef Q_OS_UNIX
    01892   MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong;
    01893   QString fstype;
    01894   return get_mount_info(filename, isautofs, isslow, ismanual, fstype);
    01895 #else
    01896   return QString::null;
    01897 #endif
    01898 }
    01899
    01900 bool KIO::manually_mounted(const QString& filename)
    01901 {
    01902 #ifdef Q_OS_UNIX
    01903   MountState isautofs = Unseen, isslow = Unseen, ismanual = Unseen;
    01904   QString fstype;
    01905   QString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype);
    01906   return !mountPoint.isNull() && (ismanual == Right);
    01907 #else
    01908   return false;
    01909 #endif
    01910 }
    01911
    01912 bool KIO::probably_slow_mounted(const QString& filename)
    01913 {
    01914 #ifdef Q_OS_UNIX
    01915   MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong;
    01916   QString fstype;
    01917   QString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype);
    01918   return !mountPoint.isNull() && (isslow == Right);
    01919 #else
    01920   return false;
    01921 #endif
    01922 }
    01923
    01924 bool KIO::testFileSystemFlag(const QString& filename, FileSystemFlag flag)
    01925 {
    01926 #ifdef Q_OS_UNIX
    01927   MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong;
    01928   QString fstype;
    01929   QString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype);
    01930     kdDebug() << "testFileSystemFlag: fstype=" << fstype << endl;
    01931   if (mountPoint.isNull())
    01932       return false;
    01933   bool isMsDos = ( fstype == "msdos" || fstype == "fat" || fstype == "vfat" );
    01934   switch (flag)  {
    01935   case SupportsChmod:
    01936   case SupportsChown:
    01937   case SupportsUTime:
    01938   case SupportsSymlinks:
    01939       return !isMsDos; // it's amazing the number of things FAT doesn't support :)
    01940   case CaseInsensitive:
    01941       return isMsDos;
    01942   }
    01943 #endif
    01944   return false;
    01945 }
    01946
    01947 KIO::CacheControl KIO::parseCacheControl(const QString &cacheControl)
    01948 {
    01949   QString tmp = cacheControl.lower();
    01950
    01951   if (tmp == "cacheonly")
    01952      return KIO::CC_CacheOnly;
    01953   if (tmp == "cache")
    01954      return KIO::CC_Cache;
    01955   if (tmp == "verify")
    01956      return KIO::CC_Verify;
    01957   if (tmp == "refresh")
    01958      return KIO::CC_Refresh;
    01959   if (tmp == "reload")
    01960      return KIO::CC_Reload;
    01961
    01962   kdDebug() << "unrecognized Cache control option:"<<cacheControl<<endl;
    01963   return KIO::CC_Verify;
    01964 }
    01965
    01966 QString KIO::getCacheControlString(KIO::CacheControl cacheControl)
    01967 {
    01968     if (cacheControl == KIO::CC_CacheOnly)
    01969     return "CacheOnly";
    01970     if (cacheControl == KIO::CC_Cache)
    01971     return "Cache";
    01972     if (cacheControl == KIO::CC_Verify)
    01973     return "Verify";
    01974     if (cacheControl == KIO::CC_Refresh)
    01975     return "Refresh";
    01976     if (cacheControl == KIO::CC_Reload)
    01977     return "Reload";
    01978     kdDebug() << "unrecognized Cache control enum value:"<<cacheControl<<endl;
    01979     return QString::null;
    01980 }

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