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

kio

global.cpp

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

kio

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

API Reference

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