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