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