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