kio Library API Documentation

global.cpp

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