00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "RioExplorer.h"
00018
00019 #include <sys/stat.h>
00020 #include <pwd.h>
00021 #include <grp.h>
00022 #include <fcntl.h>
00023 #include <errno.h>
00024 #include <stdarg.h>
00025 #include <stdlib.h>
00026 #include <regex.h>
00027 #include <unistd.h>
00028
00029
00030 #include <fcntl.h>
00031 #include <limits.h>
00032 #include <sys/mman.h>
00033 #include <openssl/md5.h>
00034
00035 #include <iostream>
00036 #include <algorithm>
00037
00038 #include "RioInterface.h"
00039 #include "RioError.h"
00040 #include "RioSemaphore.h"
00041 #include "FileObject.h"
00042
00043 CSemaphore Semaphore( 0, RioExplorer::MaxRequests );
00044
00045 RioExplorer::RioExplorer()
00046 {
00047 MD5CACHEFILE = "/.md5cache.xml";
00048 session = NULL;
00049 RioError = S_OK;
00050 SystemError = 0;
00051 }
00052
00053 RioExplorer::~RioExplorer()
00054 {
00055
00056 if( session != NULL )
00057 {
00058 if( session->isConnected() )
00059 session->Disconnect();
00060 delete session;
00061 }
00062 }
00063
00064
00065
00066
00067 CRioSession *RioExplorer::createSession( char * MachineName, char * UserName,
00068 char * Password )
00069 {
00070 CRioSession *session = NULL;
00071 RioResult hResult;
00072 struct timeval RTT_average;
00073 bool status = true;
00074 unsigned int BlockSize;
00075 string message;
00076
00077 session = new CRioSession();
00078 hResult = session->Connect( MachineName, UserName, Password, 1 );
00079
00080 if( FAILED( hResult ) )
00081 {
00082
00083
00084
00085
00086
00087
00088
00089
00090 if( (unsigned int) hResult == ERROR_RIOSESSION + ERROR_NO_MAPPING )
00091 {
00092 message = "Não foi possivel obter os mapeamentos pelo servidor RIO localizado na máquina \"" + string( MachineName )
00093 + "\". \nO cliente náo funcionará se estiver atrás de NAT.";
00094 showMessage( INFO_MSG, message );
00095 } else {
00096 message = "Não conseguiu conexão com o servidor RIO localizado na máquina \""
00097 + string( MachineName ) + "\"";
00098
00099 switch( hResult & 0xff )
00100 {
00101 case ERROR_INVALID_VERSION:
00102 message += ": Versão inválida.\n";
00103 break;
00104
00105 case ERROR_INVALID_USER:
00106 message += ": Nome do usuário \"";
00107 message += UserName;
00108 message += "\" inválido.\n";
00109 break;
00110
00111 case ERROR_SOCKET_CONNECT:
00112 message += ": Servidor não está respondendo.\n";
00113 break;
00114
00115 case ERROR_MAX_SESSIONS:
00116 message += ": Número máximo de sessões já abertas.\n";
00117 break;
00118
00119 default:
00120 message += ": Erro inesperado.\n(";
00121 message += GetErrorDescription( hResult );
00122 message += ").\n";
00123 break;
00124 }
00125 showMessage( ERROR_MSG, message );
00126 status = false;
00127 }
00128 }
00129 else
00130 {
00131 session->GetAverageRTT( &RTT_average );
00132 hResult = session->GetBlockSize( &BlockSize );
00133 if( FAILED( hResult ) )
00134 {
00135 message = "Não conseguiu pegar tamanho do bloco utilizado pelo servidor.\n(";
00136 message += GetErrorDescription( hResult );
00137 message += ")\n";
00138 showMessage( ERROR_MSG, message );
00139 status = false;
00140 }
00141 }
00142
00143 if( status )
00144 return session;
00145 else
00146 return NULL;
00147 }
00148
00149
00150
00151
00152
00153 bool RioExplorer::checkSession( void )
00154 {
00155 string message;
00156 bool isValid;
00157
00158
00159 isValid = !session || session->isConnected();
00160 return isValid;
00161 }
00162
00163 bool RioExplorer::checkSession( CRioSession *session )
00164 {
00165 string message;
00166 bool isValid;
00167
00168
00169 isValid = !session || session->isConnected();
00170 return isValid;
00171 }
00172
00173
00174
00175
00176 CRioStream *RioExplorer::createNRTStream( CRioSession *cpsession )
00177 {
00178 CRioStream *stream = NULL;
00179 RioResult hResult;
00180 unsigned int BlockSize;
00181 string message;
00182
00183 if( cpsession != NULL )
00184 {
00185 getBlockSize( &BlockSize, cpsession );
00186
00187 RioStreamTraffic *traffic = new RioStreamTraffic();
00188 traffic->Type = RIO_TRAFFIC_NRT;
00189 traffic->Direction = RioStreamDirectionReadWrite;
00190 traffic->LogicalBlockSize = BlockSize;
00191 traffic->MaxRequests = MaxRequests;
00192 traffic->TrafficNRT.Reserved = 0;
00193
00194 stream = new CRioStream();
00195 hResult = stream->Open( traffic, cpsession );
00196 if( FAILED( hResult ) )
00197 {
00198 message = "Não conseguiu abrir uma stream.\n(";
00199 message += GetErrorDescription( hResult );
00200 message += ")\n";
00201 showMessage( ERROR_MSG, message );
00202
00203 delete stream;
00204 stream = NULL;
00205 }
00206 }
00207 else
00208 showMessage( ERROR_MSG, "Sessão nula! Impossível criar stream.\n" );
00209
00210 return stream;
00211 }
00212
00213
00214
00215
00216 string RioExplorer::formatSize( RioObjectSize size )
00217 {
00218 int units;
00219 int Kilo = 0;
00220 int Mega = 0;
00221 int Giga = 0;
00222 int Tera = 0;
00223 int Peta = 0;
00224 int Exa = 0;
00225 int Zetta = 0;
00226 int Yotta = 0;
00227 int mag;
00228
00229 float sizefloat;
00230 char aux[255];
00231
00232 string fmt_size;
00233
00234 units = size % 1024;
00235 mag = 0;
00236 size = size / 1024;
00237 if( size > 0 )
00238 {
00239 Kilo = size % 1024;
00240 size = size / 1024;
00241 mag = 1;
00242 if( size > 0 )
00243 {
00244 Mega = size % 1024;
00245 size = size / 1024;
00246 mag = 2;
00247 if( size > 0 )
00248 {
00249 Giga = size % 1024;
00250 size = size / 1024;
00251 mag = 3;
00252 if( size > 0 )
00253 {
00254 Tera = size % 1024;
00255 size = size / 1024;
00256 mag = 4;
00257 if( size > 0 )
00258 {
00259 Peta = size % 1024;
00260 size = size / 1024;
00261 mag = 5;
00262 if( size > 0 )
00263 {
00264 Exa = size % 1024;
00265 size = size / 1024;
00266 mag = 6;
00267 if( size > 0 )
00268 {
00269 Zetta = size % 1024;
00270 size = size / 1024;
00271 mag = 7;
00272 if( size > 0 )
00273 {
00274 Yotta = size % 1024;
00275 mag = 8;
00276 }
00277 }
00278 }
00279 }
00280 }
00281 }
00282 }
00283 }
00284
00285 switch( mag )
00286 {
00287 case 0:
00288 sprintf( aux, "%5dB", units );
00289 break;
00290
00291 case 1:
00292 sizefloat = Kilo + ( float )( units / 1024.0 );
00293 sprintf( aux, "%5.1fKB", sizefloat );
00294 break;
00295
00296 case 2:
00297 sizefloat = Mega + ( float )( Kilo / 1024.0 );
00298 sprintf( aux, "%5.1fMB", sizefloat );
00299 break;
00300
00301 case 3:
00302 sizefloat = Giga + ( float )( Mega / 1024.0 );
00303 sprintf( aux, "%5.1fGB", sizefloat );
00304 break;
00305
00306 case 4:
00307 sizefloat = Tera + ( float )( Giga / 1024.0 );
00308 sprintf( aux, "%5.1fTB", sizefloat );
00309 break;
00310
00311 case 5:
00312 sizefloat = Peta + ( float )( Tera / 1024.0 );
00313 sprintf( aux, "%5.1fPB", sizefloat );
00314 break;
00315
00316 case 6:
00317 sizefloat = Exa + ( float )( Peta / 1024.0 );
00318 sprintf( aux, "%5.1fEB", sizefloat );
00319 break;
00320
00321 case 7:
00322 sizefloat = Zetta + ( float )( Exa / 1024.0 );
00323 sprintf( aux, "%5.1fZB", sizefloat );
00324 break;
00325
00326 case 8:
00327 sizefloat = Yotta + ( float )( Zetta / 1024.0 );
00328 sprintf( aux, "%5.1fYB", sizefloat );
00329 break;
00330
00331
00332 default:
00333 aux[0] = '\0';
00334 }
00335
00336 fmt_size = aux;
00337
00338 return fmt_size;
00339 }
00340
00341
00342
00343
00344 RioObjectSize RioExplorer::rGetSize( vector<DuInfo> *data, char *Name,
00345 CRioSession *session, bool showallfiles )
00346 {
00347 CRioDirectory *Directory ;
00348 RioResult hResult;
00349 int IsDirectory;
00350 const int ObjectNameSize = MAXNAMELEN;
00351 char ObjectName[ObjectNameSize];
00352 char DirectoryName[MAXNAMELEN];
00353 RioObjectSize size;
00354 RioObjectSize objsize;
00355 unsigned int nBlocks;
00356 unsigned int BlockSize;
00357 string message;
00358
00359 getBlockSize( &BlockSize, session );
00360
00361 size = 0;
00362
00363 if( session != NULL )
00364 {
00365 Directory = new CRioDirectory;
00366
00367 strcpy( DirectoryName, Name );
00368 hResult = Directory->FirstObject( DirectoryName, ObjectNameSize,
00369 ObjectName, &IsDirectory, session );
00370
00371 if( FAILED( hResult ) )
00372 {
00373 if( ( hResult & 0xff ) == (unsigned) ERROR_NO_MORE_OBJECTS )
00374 {
00375 DuInfo duInfo;
00376 duInfo.size = 0;
00377 duInfo.nBlocks = 0;
00378 duInfo.object_name = DirectoryName;
00379
00380 data->push_back( duInfo );
00381
00382 Directory->Close();
00383 delete Directory;
00384 return size;
00385 }
00386 else
00387 {
00388 delete Directory;
00389 return size;
00390 }
00391 }
00392
00393 while( !FAILED( hResult ) )
00394 {
00395 char s[128];
00396 strcpy( s, Name );
00397 strcat( s,"/" );
00398 strcat( s, ObjectName );
00399 strcpy( ObjectName, s );
00400 ObjectInfo objectInfo;
00401
00402 if( !getObjectInfo( ObjectName, session, &objectInfo ) )
00403 continue;
00404
00405 if( objectInfo.isDir() )
00406 size += rGetSize( data, ObjectName, session, showallfiles );
00407 else if( ( objectInfo.getType() == ObjectInfo::FILE_TYPE_DATA ) ||
00408 ( objectInfo.getType() == ObjectInfo::FILE_TYPE_DATA_LINK )
00409 )
00410 {
00411 nBlocks = ( objectInfo.getSize() + BlockSize - 1 ) / BlockSize;
00412 objsize = nBlocks * BlockSize;
00413 size += objsize;
00414 if( showallfiles )
00415 {
00416 DuInfo duInfo;
00417 duInfo.size = objsize;
00418 duInfo.nBlocks = nBlocks;
00419 duInfo.object_name = ObjectName;
00420
00421 data->push_back( duInfo );
00422 }
00423 }
00424 else
00425 {
00426 message = "du: Não conseguiu pegar informações do objeto \"";
00427 message += ObjectName;
00428 message += "\".\n(";
00429 message += GetErrorDescription( hResult );
00430 message += ")\n";
00431 showMessage( ERROR_MSG, message );
00432 continue;
00433 }
00434
00435 hResult = Directory->NextObject( ObjectNameSize,
00436 ObjectName,
00437 &IsDirectory );
00438 }
00439
00440 if( ( hResult & 0xff ) == (unsigned) ERROR_NO_MORE_OBJECTS )
00441 {
00442 nBlocks = ( size + BlockSize - 1 ) / BlockSize;
00443 objsize = ( RioObjectSize ) nBlocks * ( RioObjectSize ) BlockSize ;
00444
00445 DuInfo duInfo;
00446 duInfo.size = objsize;
00447 duInfo.nBlocks = nBlocks;
00448 duInfo.object_name = DirectoryName;
00449
00450 data->push_back( duInfo );
00451 }
00452
00453 Directory->Close();
00454 delete Directory;
00455 }
00456 else
00457 {
00458 strcpy( DirectoryName, Name );
00459 DIR *currentdir = opendir( DirectoryName );
00460
00461 if( ( currentdir == NULL ) && ( errno == EACCES ) )
00462 {
00463 message = "du: Não conseguiu pegar informações do objeto \"";
00464 message += DirectoryName;
00465 message += "\".\n(";
00466 message += "Permissão negada";
00467 message += ")\n";
00468 showMessage( QUESTION_MSG, message );
00469
00470 return size;
00471 }
00472
00473 struct dirent *direntry = readdir( currentdir );
00474 if( direntry == NULL )
00475 {
00476 if( errno == EBADF )
00477 {
00478 closedir( currentdir );
00479 return size;
00480 }
00481 else
00482 {
00483 DuInfo duInfo;
00484 duInfo.size = 0;
00485 duInfo.nBlocks = 0;
00486 duInfo.object_name = DirectoryName;
00487
00488 data->push_back( duInfo );
00489 closedir( currentdir );
00490 return size;
00491 }
00492 }
00493
00494 for( ; direntry != NULL; direntry = readdir( currentdir ) )
00495 {
00496 if( ( strcmp( direntry->d_name, "." ) == 0 ) ||
00497 ( strcmp( direntry->d_name, ".." ) == 0 )
00498 )
00499 continue;
00500
00501 char s[128];
00502 strcpy( s, Name );
00503 strcat( s,"/" );
00504 strcat( s, direntry->d_name );
00505 strcpy( ObjectName, s );
00506 ObjectInfo objectInfo;
00507
00508 if( !getObjectInfo( ObjectName, session, &objectInfo ) )
00509 continue;
00510
00511 if( objectInfo.isDir() )
00512 size += rGetSize( data, ObjectName, session, showallfiles );
00513 else if( ( objectInfo.getType() == ObjectInfo::FILE_TYPE_DATA ) ||
00514 ( objectInfo.getType() == ObjectInfo::FILE_TYPE_DATA_LINK )
00515 )
00516 {
00517 nBlocks = ( objectInfo.getSize() + BlockSize - 1 ) / BlockSize;
00518 objsize = nBlocks * BlockSize;
00519 size += objsize;
00520 if( showallfiles )
00521 {
00522 DuInfo duInfo;
00523 duInfo.size = objsize;
00524 duInfo.nBlocks = nBlocks;
00525 duInfo.object_name = ObjectName;
00526
00527 data->push_back( duInfo );
00528 }
00529 }
00530 else
00531 {
00532 message = "du: Não conseguiu pegar informações do objeto \"";
00533 message += ObjectName;
00534 message += "\".\n";
00535 showMessage( ERROR_MSG, message );
00536 continue;
00537 }
00538 }
00539
00540 if( errno != EBADF )
00541 {
00542 nBlocks = ( size + BlockSize - 1 ) / BlockSize;
00543 objsize = ( RioObjectSize ) nBlocks * ( RioObjectSize ) BlockSize ;
00544
00545 DuInfo duInfo;
00546 duInfo.size = objsize;
00547 duInfo.nBlocks = nBlocks;
00548 duInfo.object_name = DirectoryName;
00549
00550 data->push_back( duInfo );
00551 }
00552
00553 closedir( currentdir );
00554 }
00555 return size;
00556 }
00557
00558
00559
00560
00561 void CallBack( RioRequest *Request )
00562 {
00563 Semaphore.V();
00564 }
00565
00566
00567
00568
00569 bool RioExplorer::getNextLocalFileName( DIR *o_dir, char *curDir,
00570 ObjectInfo *objectInfo )
00571 {
00572 struct dirent *dp;
00573 string message;
00574 char Object[MAXNAMELEN];
00575 bool status = true;
00576
00577 dp = readdir( o_dir );
00578 if( dp == NULL )
00579 status = false;
00580
00581 if( status )
00582 {
00583 strcpy( Object, curDir );
00584 strcat( Object, "/" );
00585 strcat( Object, dp->d_name );
00586
00587 status = getObjectInfo( Object, NULL, objectInfo );
00588 objectInfo->setNames( dp->d_name, curDir );
00589 }
00590
00591 return status;
00592 }
00593
00594
00595
00596
00597 bool RioExplorer::getNextRioFileName( CRioDirectory *Directory,
00598 CRioSession *session,
00599 char *curDir,
00600 ObjectInfo *objectInfo,
00601 bool isFirstFile )
00602 {
00603 RioResult hResult;
00604 int IsDirectory;
00605 string message;
00606 char Object[MAXNAMELEN];
00607 char ObjectName[MAXNAMELEN];
00608 bool status = true;
00609
00610 if( isFirstFile )
00611 hResult = Directory->FirstObject( curDir, MAXNAMELEN, ObjectName,
00612 &IsDirectory, session );
00613 else
00614 hResult = Directory->NextObject( MAXNAMELEN, ObjectName,
00615 &IsDirectory );
00616
00617 if( FAILED( hResult ) )
00618 {
00619 if( ( hResult & 0xff ) != (signed) ERROR_NO_MORE_OBJECTS )
00620 {
00621 message = "ls: Não conseguiu pegar informações do objeto \"";
00622 message += curDir;
00623 message += "\".\n(";
00624 message += GetErrorDescription( hResult );
00625 message += ")\n";
00626 showMessage( ERROR_MSG, message );
00627 }
00628
00629 status = false;
00630 }
00631
00632 if( status )
00633 {
00634 strcpy( Object, curDir );
00635 strcat( Object, "/" );
00636 strcat( Object, ObjectName );
00637
00638 status = getObjectInfo( Object, session, objectInfo );
00639 objectInfo->setNames( ObjectName, curDir );
00640 }
00641
00642 return status;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 bool RioExplorer::getLocalObjectInfo( const char *fileName,
00654 ObjectInfo *Objectinfo )
00655 {
00656 struct stat64 mystat;
00657 struct tm mytime;
00658 struct passwd *pw;
00659 struct group *gr;
00660 string message;
00661 bool status = true;
00662
00663 if( lstat64( fileName, &mystat ) )
00664 {
00665 SystemError = errno;
00666 message = "getLocalObjectInfo: Unable to get stat information!\n";
00667 showMessage( ERROR_MSG, message );
00668 status = false;
00669 }
00670
00671 if( status )
00672 {
00673 if( S_ISREG( mystat.st_mode ) )
00674 Objectinfo->setType( ObjectInfo::FILE_TYPE_DATA );
00675 else if( S_ISDIR( mystat.st_mode ) )
00676 Objectinfo->setType( ObjectInfo::FILE_TYPE_DIRECTORY );
00677 else if( S_ISLNK( mystat.st_mode ) )
00678 {
00679 struct stat lnkstat;
00680 if( stat( fileName, &lnkstat ) )
00681 Objectinfo->setType( ObjectInfo::FILE_TYPE_BROKEN_LINK );
00682 else
00683 {
00684 if( S_ISREG( lnkstat.st_mode ) )
00685 Objectinfo->setType( ObjectInfo::FILE_TYPE_DATA_LINK );
00686 else if( S_ISDIR( lnkstat.st_mode ) )
00687 Objectinfo->setType( ObjectInfo::FILE_TYPE_DIR_LINK );
00688 mystat.st_size = lnkstat.st_size;
00689 }
00690 }
00691 else
00692 Objectinfo->setType( ObjectInfo::FILE_TYPE_INVALID );
00693
00694 gmtime_r( &(mystat.st_mtime), &mytime );
00695 pw = getpwuid( mystat.st_uid );
00696 gr = getgrgid( mystat.st_gid);
00697
00698 Objectinfo->setPermission( (short) mystat.st_mode );
00699 Objectinfo->setSize( (RioObjectSize) mystat.st_size );
00700
00701 AccessTime LastModificationTime;
00702 LastModificationTime.Year = (short) mytime.tm_year + 1900;
00703 LastModificationTime.Month = (short) mytime.tm_mon + 1;
00704 LastModificationTime.DayOfWeek = (short) mytime.tm_wday;
00705 LastModificationTime.Day = (short) mytime.tm_mday;
00706 LastModificationTime.Hour = (short) mytime.tm_hour;
00707 LastModificationTime.Minute = (short) mytime.tm_min;
00708
00709 Objectinfo->setTime( LastModificationTime );
00710
00711 if( pw != NULL )
00712 Objectinfo->setOwner( pw->pw_name );
00713 else
00714 Objectinfo->setOwner( "unknown" );
00715
00716 if( gr != NULL )
00717 Objectinfo->setGroup( gr->gr_name );
00718 else
00719 Objectinfo->setGroup( "unknown" );
00720
00721
00722
00723 Objectinfo->setVideoRate( 0 );
00724
00725 }
00726 return status;
00727 }
00728
00729 bool RioExplorer::display( DisplayInfo * info, char * ObjectName,
00730 int start, int size,
00731 bool showhexadecimal )
00732 {
00733 RioResult hResult;
00734 CRioStream *Stream;
00735 RioStreamTraffic Traffic;
00736 RioAccess Access;
00737 CRioObject* Object;
00738 bool status = true;
00739 unsigned int BlockSize;
00740 string message;
00741
00742 status = checkSession();
00743
00744 if( status )
00745 {
00746 Stream = new CRioStream();
00747
00748 getBlockSize( &BlockSize, session );
00749
00750 Traffic.Type = RIO_TRAFFIC_NRT;
00751 Traffic.Direction = RioStreamDirectionRead;
00752 Traffic.LogicalBlockSize = BlockSize;
00753 Traffic.MaxRequests = MaxRequests;
00754 Traffic.TrafficNRT.Reserved = 0;
00755 hResult = Stream->Open( &Traffic, session );
00756 if( FAILED( hResult ) )
00757 {
00758 message = "cat: Não conseguiu abrir stream.\n(";
00759 message += GetErrorDescription( hResult );
00760 message += ")\n";
00761 showMessage( ERROR_MSG, message );
00762 delete Stream;
00763 status = false;
00764 }
00765 else
00766 {
00767 Object = new CRioObject();
00768 Access = RIO_READ_ACCESS | RIO_SHARE_READ;
00769 hResult = Object->Open( ObjectName, Access,Stream );
00770 if( FAILED( hResult ) )
00771 {
00772 message = "cat: Não conseguiu abrir o objeto \"";
00773 message += ObjectName;
00774 message += "\".\n(";
00775 message += GetErrorDescription( hResult );
00776 message += ")\n";
00777 showMessage( ERROR_MSG, message );
00778
00779 Stream->Close();
00780
00781 status = false;
00782 }
00783 else
00784 {
00785 char* data ;
00786 data = new char[BlockSize];
00787 RioObjectSize ObjSize;
00788
00789 Object->GetSize( &ObjSize );
00790 if( ObjSize >= 0xffffffff )
00791 {
00792 message = "cat: Tamanho do objeto muito grande. Não pode ";
00793 message += "mostrar objeto \"";
00794 message += ObjectName;
00795 message += "\".\n";
00796 showMessage( ERROR_MSG, message );
00797
00798 Stream->Close();
00799 status = false;
00800 }
00801 else
00802 {
00803 unsigned int usize;
00804 RioRequest Request;
00805 usize = (unsigned int) ObjSize;
00806 Request.Size = BlockSize;
00807 Request.Buffer = data;
00808 Request.CallBackFunction = CallBack;
00809 Request.User = NULL;
00810
00811 unsigned int done;
00812 unsigned int bytes;
00813 unsigned int nwrite;
00814 RioBlock Block;
00815 done = 0;
00816 bytes = 0;
00817 nwrite = 0;
00818 Block = 0;
00819
00820 if( (unsigned)size+start > usize )
00821 {
00822 Object->Close();
00823 Stream->Close();
00824
00825 status = false;
00826 }
00827 else
00828 {
00829 if( size == 0 )
00830 size = usize - ( start - start % BlockSize );
00831 else
00832 size = size + start % BlockSize;
00833
00834 Block = start / BlockSize;
00835
00836 while( done < (unsigned) size )
00837 {
00838 Request.Block = Block;
00839 Request.Result = S_OK;
00840 Request.Status = RIO_REQUEST_FREE;
00841
00842 bytes = size - done;
00843 if( bytes>BlockSize )
00844 bytes = BlockSize;
00845
00846 hResult = Object->StreamRead( &Request );
00847 Semaphore.P();
00848
00849 if( showhexadecimal )
00850 {
00851 for( int i = 0; (unsigned) i < bytes; i++ )
00852 {
00853 if( i + done >= start % BlockSize )
00854 {
00855 char aux[256];
00856 unsigned char ch = data[i];
00857
00858 sprintf( aux, "%.2x", ch );
00859 info->data += aux;
00860
00861 if( i % 2 == 1 )
00862 info->data += " ";
00863 if( i % 16 == 15 )
00864 {
00865 info->data += "\n";
00866 if( i + 1 + done < (unsigned) size )
00867 {
00868 sprintf( aux, "%08x: ",
00869 i + 1 +
00870 ( Block * BlockSize ) );
00871 info->data += aux;
00872 }
00873 }
00874 }
00875 }
00876 }
00877 else
00878 info->data += data;
00879
00880 Block++;
00881 done += bytes;
00882 }
00883
00884 Object->Close();
00885 Stream->Close();
00886 }
00887 }
00888 }
00889 delete Object;
00890 delete Stream;
00891 }
00892 }
00893
00894 return status;
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 bool RioExplorer::copyFile( CRioStream *stream_src, CRioStream *stream_dest,
00907 char *src, char *dst,
00908 bool askuser, bool *can_continue,
00909 RioObjectSize *current_file_completed,
00910 RioObjectSize *total_completed, RioMd5 *calculator )
00911 {
00912 bool status = true;
00913 string message;
00914 char source[MAXNAMELEN];
00915 char dest[MAXNAMELEN];
00916 FileObject *sourceFile = NULL;
00917 FileObject *destFile = NULL;
00918
00919 strcpy( source, src );
00920 strcpy( dest, dst );
00921
00922 if( current_file_completed )
00923 *current_file_completed = 0;
00924
00925
00926 if( stream_src == NULL )
00927 {
00928 sourceFile = new LocalFileObject( source );
00929 if( !sourceFile->Open( O_RDONLY ) )
00930 {
00931 status = false;
00932 }
00933 }
00934 else
00935 {
00936 sourceFile = new RioFileObject( stream_src, source );
00937 if( !sourceFile->Open( RIO_READ_ACCESS | RIO_SHARE_READ ) )
00938 {
00939 status = false;
00940 }
00941 }
00942
00943 if( status )
00944 {
00945
00946 ObjectInfo destInfo;
00947 CRioSession *sessionDest;
00948 if( stream_dest != NULL )
00949 sessionDest = stream_dest->GetRioSession();
00950 else
00951 sessionDest = NULL;
00952
00953 bool replaceFile = true;
00954 if( askuser && getObjectInfo( dest, sessionDest, &destInfo, false ) )
00955
00956 {
00957 message = "\nSobrescrever arquivo \"";
00958 message += dest;
00959 message += "\". Continuar?";
00960
00961 replaceFile = showMessage( QUESTION_MSG, message );
00962 }
00963
00964 if( replaceFile )
00965 {
00966 updateCopyProgress();
00967
00968 char *md5 = new char[MD5SIZE];
00969
00970
00971 if( stream_dest == NULL )
00972 {
00973 destFile = new LocalFileObject( dest );
00974 if( !destFile->Open( O_WRONLY | O_CREAT | O_TRUNC ) )
00975 {
00976 message = "\ncp: Erro tentando abrir arquivo de destino \"";
00977 message += dest;
00978 message += "\".\n";
00979 showMessage( ERROR_MSG, message );
00980
00981 status = false;
00982 }
00983 }
00984 else
00985 {
00986 CRioSession *sessionSrc;
00987
00988 if( stream_src != NULL )
00989 sessionSrc = stream_src->GetRioSession();
00990 else
00991 sessionSrc = NULL;
00992
00993 if( calculator != NULL )
00994 calculator->getMd5Sum( source, md5 );
00995 else
00996 getObjectMd5Sum( source, sessionSrc, md5 );
00997
00998 destFile = new RioFileObject( stream_dest, dest );
00999 if( !destFile->Open( RIO_RW_ACCESS, md5 ) )
01000 {
01001 message = "\ncp: Erro tentando abrir arquivo de destino \"";
01002 message += dest;
01003 message += "\".\n";
01004 showMessage( ERROR_MSG, message );
01005
01006 status = false;
01007 }
01008 }
01009
01010 if( status )
01011 {
01012 char *buffer = new char[BUFFERSIZE];
01013 int readBytes = 0;
01014 int writeBytes = 0;
01015
01016
01017
01018
01019 unsigned int VideoRate;
01020
01021 if( sourceFile->getVideoRate( &VideoRate ) )
01022 destFile->setVideoRate( VideoRate );
01023
01024 while( status &&
01025 ( ( readBytes = sourceFile->Read( buffer, BUFFERSIZE ) ) > 0 ) )
01026 {
01027 if( !( *can_continue ) )
01028 {
01029 showMessage( INFO_MSG, "\nCópia cancelada.\n" );
01030 status = false;
01031 break;
01032 }
01033
01034 pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL );
01035
01036 writeBytes = destFile->Write( buffer, readBytes, md5 );
01037
01038
01039 pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
01040
01041 if( writeBytes != readBytes )
01042 {
01043 showMessage( ERROR_MSG, "cp: Erro durante a cópia.\n" );
01044
01045 status = false;
01046 break;
01047 }
01048
01049 if( total_completed )
01050 *total_completed += readBytes;
01051
01052 if( current_file_completed )
01053 *current_file_completed += readBytes;
01054
01055 if( total_completed || current_file_completed )
01056 updateCopyProgress();
01057
01058 if( readBytes != BUFFERSIZE )
01059 break;
01060 }
01061
01062
01063 if( readBytes < 0 )
01064 {
01065 showMessage( ERROR_MSG, "cp: Erro durante a cópia.\n" );
01066 status = false;
01067 }
01068 destFile->Close();
01069 delete destFile;
01070 delete[] buffer;
01071 }
01072 delete [] md5;
01073 }
01074 sourceFile->Close();
01075 }
01076
01077 delete sourceFile;
01078 return status;
01079 }
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097 bool RioExplorer::ls( ObjectInfo *src, vector<ObjectInfo> *fileList,
01098 CRioSession *session, bool allFiles,
01099 bool recursive, char *searchPoint, int reclevel )
01100 {
01101 string message;
01102 bool status = true;
01103 string newSrc;
01104 vector<ObjectInfo> recSrc;
01105 vector<ObjectInfo> recList;
01106 char newSearchPoint[ MAXNAMELEN ];
01107 RioResult hResult;
01108 bool removeSearchPoint = false;
01109
01110 status = checkSession( session );
01111
01112 if( status )
01113 {
01114 if( src == NULL )
01115 {
01116 status = resolveRegExp( &recSrc, session, "*" );
01117
01118 for( unsigned int i = 0; status && ( i < recSrc.size() ); i++ )
01119 {
01120 if( recursive )
01121 {
01122 recList.clear();
01123
01124 if( !recSrc[i].isHidden() || allFiles )
01125 status = ls( &recSrc[i], &recList, session, allFiles,
01126 recursive, NULL, reclevel+1 );
01127
01128 for( unsigned int j = 0;
01129 status && ( j < recList.size() );
01130 j++
01131 )
01132 {
01133 if( recSrc[i].isDir() )
01134 {
01135 string newPath = recList[j].getPath();
01136 newPath.insert( 0,"/" );
01137 newPath.insert( 0,
01138 recSrc[i].getFullName().c_str() );
01139 recList[j].setPath( newPath );
01140 }
01141
01142 if( !recList[j].isHidden() || allFiles )
01143 fileList->insert( fileList->end(), recList[j] );
01144 }
01145 }
01146 else
01147 {
01148 if( !recSrc[i].isHidden() || allFiles )
01149 fileList->insert( fileList->end(), recSrc[i] );
01150 }
01151 }
01152 }
01153 else if( src->getFullName().length() == 0 )
01154 {
01155
01156 RioError = ERROR_RIOSESSION + ERROR_INVALID_PARAM;
01157
01158 message = "ls: Parâmetro source vazio.\n";
01159 message += "A listagem não será feita.\n";
01160 showMessage( ERROR_MSG, message );
01161 status = false;
01162 }
01163 else if( ( src->getType() == ObjectInfo::FILE_TYPE_DATA ) ||
01164 ( src->getType() == ObjectInfo::FILE_TYPE_DATA_LINK ) ||
01165 ( src->getType() == ObjectInfo::FILE_TYPE_BROKEN_LINK )
01166 )
01167 {
01168 if( !src->isHidden() || allFiles )
01169 fileList->insert( fileList->end(), *src );
01170 }
01171 else if( src->isDir() )
01172 {
01173 if( reclevel > 0 )
01174 fileList->insert( fileList->end(), *src );
01175
01176 if( recursive || ( reclevel == 0 ) )
01177 {
01178 if( searchPoint == NULL )
01179 {
01180 searchPoint = (char *)malloc( MAXNAMELEN * sizeof( char ) );
01181 if( searchPoint == NULL )
01182 {
01183 SystemError = ENOMEM;
01184 message = "ls: memoria insuficiente.\n";
01185 showMessage( ERROR_MSG, message );
01186 return false;
01187
01188
01189
01190 }
01191
01192 removeSearchPoint = true;
01193
01194 if( session != NULL )
01195 {
01196 hResult = session->GetCurrentDir( searchPoint,
01197 MAXNAMELEN );
01198 if( FAILED( hResult ) )
01199 {
01200 RioError = hResult;
01201 message = "ls: error when obtaining current ";
01202 message += "directory!\n";
01203 showMessage( ERROR_MSG, message );
01204 free( searchPoint );
01205 return false;
01206 }
01207 }
01208 else
01209 {
01210 if( getcwd( searchPoint, (size_t) MAXNAMELEN ) == NULL )
01211 {
01212 SystemError = errno;
01213 message = "ls: Unable to get working directory";
01214 message += ".\n";
01215 showMessage( ERROR_MSG, message );
01216 return false;
01217
01218
01219 }
01220 }
01221 }
01222
01223 if( src->getFullName().at( 0 ) == '/' )
01224 {
01225 strcpy( newSearchPoint, (char*)src->getFullName().c_str() );
01226 }
01227 else
01228 {
01229 strcpy( newSearchPoint, searchPoint );
01230
01231 if( strcmp( searchPoint, "/" ) )
01232 strcat( newSearchPoint, "/" );
01233
01234 strcat( newSearchPoint, (char*)src->getFullName().c_str() );
01235 }
01236
01237 recSrc.clear();
01238 status = resolveRegExp( &recSrc, session, "*", newSearchPoint );
01239
01240 for( unsigned int i = 0; status && ( i < recSrc.size() ); i++ )
01241 {
01242 recList.clear();
01243
01244 if( !recSrc[i].isHidden() || allFiles )
01245 status = ls( &recSrc[i], &recList, session, allFiles,
01246 recursive, newSearchPoint, reclevel+1 );
01247
01248 for( unsigned int j = 0; status && ( j < recList.size() );
01249 j++ )
01250 {
01251 string newPath = recList[j].getPath();
01252
01253 if( reclevel > 0 )
01254 {
01255 newPath.insert( 0,"/" );
01256 newPath.insert( 0, src->getFullName() );
01257 }
01258 recList[j].setPath( newPath );
01259
01260 if( !recList[j].isHidden() || allFiles )
01261 fileList->insert( fileList->end(), recList[j] );
01262 }
01263 }
01264 }
01265 }
01266 }
01267
01268 sort(fileList->begin(),fileList->end());
01269
01270 if( removeSearchPoint )
01271 free( searchPoint );
01272 return status;
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 bool RioExplorer::strMatch( char *src_string, char *src_regexp )
01285 {
01286 regex_t comp_regexp;
01287 int ecode;
01288 bool status = true;
01289 char regexp[ MAXNAMELEN + 1 ];
01290
01291 regexp[0] = '^';
01292 strcpy( ( regexp + 1 ), src_regexp );
01293 strcpy( ( regexp + strlen( regexp) ), "$" );
01294
01295 if( ( ecode = regcomp( &comp_regexp , regexp, REG_EXTENDED|REG_NOSUB ) ) != 0 )
01296 {
01297 size_t length;
01298 char *buffer = NULL;
01299
01300 length = regerror( ecode, &comp_regexp, NULL, 0 );
01301
01302 if( ( buffer = (char *)malloc(length) ) != NULL )
01303 {
01304 regerror( ecode, &comp_regexp, buffer, length );
01305 free( buffer );
01306 }
01307 else
01308 {
01309 string message = "error: malloc buffer\n";
01310 showMessage( ERROR_MSG, message );
01311 }
01312
01313 status = false;
01314 }
01315
01316 if( status )
01317 if( ( regexec( &comp_regexp, src_string, 0, (regmatch_t *)NULL, 0 ) ) != 0 )
01318 status = false;
01319
01320 return status;
01321 }
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335 char *RioExplorer::convertPath( const char *path )
01336 {
01337
01338 int length = strlen( path );
01339
01340
01341 char *return_path = (char *)malloc( MAXNAMELEN * sizeof( char ) );
01342
01343
01344
01345
01346
01347 for( int i = 0, j = 0; i <= length; i++ )
01348 {
01349 switch( path[i] )
01350 {
01351 case '/':
01352
01353 if( i > 0 )
01354 {
01355
01356 if( i < length - 1 )
01357 {
01358
01359 if( path[ i + 1 ] != '/' )
01360 {
01361 return_path[j++] = path[i];
01362 }
01363 }
01364
01365 else
01366 {
01367
01368 return_path[j++] = '\0';
01369 }
01370 }
01371 else
01372 return_path[j++] = path[i];
01373 break;
01374
01375 case '?':
01376 return_path[j++] = '.';
01377 break;
01378
01379 case '*':
01380 return_path[j++] = '.';
01381 return_path[j++] = '*';
01382 break;
01383
01384 case '.':
01385
01386 if( ( path[ i + 1 ] == '/' ) && ( path[ i - 1 ] == '/' ) )
01387 {
01388 i++;
01389 }
01390 else
01391 {
01392 return_path[j++] = '\\';
01393 return_path[j++] = '.';
01394 }
01395 break;
01396
01397 case '+':
01398 return_path[j++] = '\\';
01399 return_path[j++] = '+';
01400 break;
01401
01402 case '\\':
01403 return_path[j++] = '\\';
01404 return_path[j++] = '\\';
01405 break;
01406
01407 default:
01408 return_path[j++] = path[i];
01409 }
01410 }
01411
01412 return return_path;
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 bool RioExplorer::mkdir( char *DirectoryName, CRioSession *session, bool notifyExistsError )
01427 {
01428 RioResult hResult;
01429 bool status = true;
01430 string message;
01431 ObjectInfo fileInfo;
01432
01433 status = checkSession( session );
01434
01435 if( status )
01436 {
01437 if( getObjectInfo( DirectoryName, session, &fileInfo, false ) )
01438 {
01439 if( !fileInfo.isDir() && notifyExistsError )
01440 {
01441 RioError = ERROR_RIOSESSION + ERROR_OBJECT_EXISTS;
01442 message = "mkdir: \"";
01443 message += fileInfo.getFullName();
01444 message += "\" existe mas não é um diretório.\n";
01445
01446 showMessage( ERROR_MSG, message );
01447 }
01448
01449 status = false;
01450
01451 }
01452 else
01453 {
01454 if( session != NULL )
01455 {
01456 hResult = session->CreateObject(
01457 DirectoryName,
01458 ObjectInfo::FILE_TYPE_DIRECTORY,
01459 NULL );
01460
01461 if( FAILED( hResult ) )
01462 {
01463 RioError = hResult;
01464 message = "mkdir: Erro ao tentar criar diretório \"";
01465 message += DirectoryName;
01466 message += "\".\n(";
01467 message += GetErrorDescription( hResult );
01468 message += ")\n";
01469 showMessage( ERROR_MSG, message );
01470
01471 status = false;
01472 }
01473 }
01474 else if( ::mkdir( DirectoryName, 0700 ) )
01475 {
01476 SystemError = errno;
01477 message = "mkdir: Erro ao tentar criar diretório \"";
01478 message += DirectoryName;
01479 message += "\".\n(";
01480 message += strerror( errno );
01481 message += ")\n";
01482 showMessage( ERROR_MSG, message );
01483
01484 status = false;
01485 }
01486 }
01487 }
01488
01489 return status;
01490 }
01491
01492
01493
01494
01495
01496
01497
01498
01499 bool RioExplorer::rm( ObjectInfo *src, CRioSession *session, bool askuser, bool recursive )
01500 {
01501 bool status = true;
01502 bool canRemove;
01503 string message;
01504 RioResult hResult = 0;
01505 vector<ObjectInfo> rmFiles;
01506
01507 status = checkSession( session );
01508
01509 if( status )
01510 {
01511 if( src != NULL )
01512 {
01513 if( ( src->getType() == ObjectInfo::FILE_TYPE_DATA ) ||
01514 ( src->getType() == ObjectInfo::FILE_TYPE_DATA_LINK ) ||
01515 ( src->getType() == ObjectInfo::FILE_TYPE_BROKEN_LINK )
01516 )
01517 {
01518 #ifdef RIO_DEBUG2
01519 RioErr << "Tentando remover o arquivo " << src->getFullName()
01520 << ": askuser = " << askuser << ", recursive = "
01521 << recursive << endl;
01522 #endif
01523
01524 if( askuser )
01525 {
01526 message = "\nRemover arquivo \"";
01527 message += src->getFullName();
01528 message += "\"?";
01529 canRemove = showMessage( QUESTION_MSG, message );
01530 }
01531 else
01532 canRemove = true;
01533
01534 if( canRemove )
01535 {
01536 if( session != NULL )
01537 {
01538 hResult = session->DeleteObject( src->getFullPath().c_str() );
01539 if( FAILED( hResult ) )
01540 {
01541 status = false;
01542 RioError = hResult;
01543 message = "Error when removing file ";
01544 message += src->getFullPath();
01545 showMessage( ERROR_MSG, message );
01546 }
01547 }
01548 else
01549 {
01550 if( remove( src->getFullPath().c_str() ) )
01551 {
01552 SystemError = errno;
01553 message = "Error when removing file ";
01554 message += src->getFullPath();
01555 showMessage( ERROR_MSG, message );
01556 status = false;
01557 }
01558 }
01559
01560 if( status == false )
01561 {
01562 message = "rm: Não conseguiu apagar o arquivo \"";
01563 message += src->getFullName();
01564 message += "\".\n(";
01565
01566 if( session != NULL )
01567 message += GetErrorDescription( hResult );
01568 else
01569 message += strerror( errno );
01570
01571 message += ")\n";
01572
01573 showMessage( ERROR_MSG, message );
01574 }
01575 }
01576 }
01577 else if( src->isDir() )
01578 {
01579 #ifdef RIO_DEBUG2
01580 RioErr << "Tentando remover o diretorio " << src->getFullName()
01581 << ": askuser = " << askuser << ", recursive = "
01582 << recursive << endl;
01583 #endif
01584
01585 if( ( recursive ) &&
01586 ( strcmp( src->getFullPath().c_str(), "/" ) != 0 ) )
01587 {
01588 if( askuser )
01589 {
01590 message = "\nExaminar diretório \"";
01591 message += src->getFullName();
01592 message += "\"?";
01593 canRemove = showMessage( QUESTION_MSG, message );
01594 }
01595 else
01596 canRemove = true;
01597
01598 if( canRemove )
01599 {
01600 string rmExp;
01601 rmExp = src->getFullPath();
01602 rmExp += "/*";
01603
01604 if( resolveRegExp( &rmFiles, session, (char*)rmExp.c_str() ) == false )
01605 {
01606 message = "rm: impossível obter lista de arquivos de \"";
01607 message += src->getFullPath();
01608 message += "\".\nO diretório não será removido.\n";
01609 showMessage( ERROR_MSG, message );
01610
01611 RioError = ERROR_CLIENT + ERROR_INVALID_PARAM;
01612
01613 status = false;
01614 return status;
01615 }
01616
01617 #ifdef RIO_DEBUG2
01618 RioErr << "Lista de arquivos para o diretorio "
01619 << src->getFullPath() << ":";
01620 for( unsigned int i = 0;
01621 i < (unsigned int)rmFiles.size(); i++ )
01622 RioErr << " " << rmFiles[i].getFullName();
01623
01624 RioErr << endl;
01625 #endif
01626
01627 for( unsigned int i = 0; status && ( i < (unsigned int)rmFiles.size() ) ; i++ )
01628 status = rm( &rmFiles[i], session, askuser, recursive );
01629
01630
01631 rmFiles.clear();
01632 resolveRegExp( &rmFiles, session, (char*)rmExp.c_str() );
01633 if( rmFiles.size() == 0 )
01634 {
01635 if( askuser )
01636 {
01637 message = "\nRemover diretório \"";
01638 message += src->getFullName();
01639 message += "\"?";
01640 canRemove = showMessage( QUESTION_MSG, message );
01641 }
01642 else
01643 canRemove = true;
01644
01645 if( canRemove )
01646 {
01647 if( session != NULL )
01648 {
01649 hResult = session->DeleteObject( src->getFullPath().c_str() );
01650 if( FAILED( hResult ) )
01651 {
01652 RioError = hResult;
01653 message = "Error when removing file ";
01654 message += src->getFullPath();
01655 showMessage( ERROR_MSG, message );
01656 status = false;
01657 }
01658 }
01659 else
01660 {
01661 if( remove( src->getFullPath().c_str() ) )
01662 {
01663 SystemError = errno;
01664 message = "Error when removing file ";
01665 message += src->getFullPath();
01666 showMessage( ERROR_MSG, message );
01667 status = false;
01668 }
01669 }
01670
01671 if( status == false )
01672 {
01673 message = "rm: Não conseguiu remover o diretório \"";
01674 message += src->getFullName();
01675 message += "\".\n(";
01676
01677 if( session != NULL )
01678 message += GetErrorDescription( hResult );
01679 else
01680 message += strerror( errno );
01681
01682 message += ")\n";
01683
01684 showMessage( ERROR_MSG, message );
01685 }
01686 }
01687 }
01688 }
01689 }
01690 else
01691 {
01692 message = "rm: Não foi possível remover o diretório \"";
01693 message += src->getFullName();
01694 message += "\": é um diretório.\n";
01695 showMessage( ERROR_MSG, message );
01696
01697 RioError = ERROR_CLIENT + ERROR_PERMISSION_DENIED;
01698
01699 status = false;
01700 return status;
01701 }
01702 }
01703 else
01704 {
01705 #ifdef RIO_DEBUG2
01706 RioErr << "Tentando remover objeto invalido "
01707 << src->getFullName()
01708 << ": askuser = " << askuser << ", recursive = "
01709 << recursive << endl;
01710 #endif
01711
01712 message = "rm: Não foi possível remover o objeto \"";
01713 message += src->getFullName();
01714 message += "\": tipo desconhecido!\n";
01715 showMessage( ERROR_MSG, message );
01716
01717 RioError = ERROR_CLIENT + ERROR_INVALID_OBJECT_TYPE;
01718
01719 status = false;
01720 return status;
01721 }
01722 }
01723 else
01724 {
01725 showMessage( ERROR_MSG, "rm: Erro: parâmetro não fornecido.\n" );
01726 }
01727 }
01728 return status;
01729 }
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749 bool RioExplorer::cp( CRioSession *session_src ,
01750 CRioSession *session_dest ,
01751 ObjectInfo *src ,
01752 char *dest ,
01753 bool askuser ,
01754 bool recursive ,
01755 bool *can_continue ,
01756 string *current_file ,
01757 RioObjectSize *current_file_completed,
01758 RioObjectSize *current_file_size ,
01759 RioObjectSize *total_completed ,
01760 CRioStream *stream_src ,
01761 CRioStream *stream_dest ,
01762 RioMd5 *calculator )
01763 {
01764 string newDest;
01765 string newSrc;
01766 bool closeSrcStream = false;
01767 bool closeDestStream = false;
01768 bool destExists;
01769 string message;
01770 vector<ObjectInfo> srcFiles;
01771 vector<ObjectInfo> recSrc;
01772 ObjectInfo destInfo;
01773 bool status = true;
01774
01775
01776
01777
01778 status = checkSession( session_src ) && checkSession( session_dest );
01779
01780 if( status )
01781 {
01782 if( session_src != NULL )
01783 {
01784 if( stream_src == NULL )
01785 {
01786 if( ( stream_src = createNRTStream( session_src ) ) == NULL )
01787 status = false;
01788 else
01789 closeSrcStream = true;
01790 }
01791 }
01792 }
01793
01794 if( status )
01795 {
01796 if( session_dest != NULL )
01797 {
01798 if( stream_dest == NULL )
01799 {
01800 if( ( stream_dest = createNRTStream( session_dest ) ) == NULL )
01801 status = false;
01802 else
01803 closeDestStream = true;
01804 }
01805 }
01806 }
01807
01808 if( status )
01809 {
01810 destExists = getObjectInfo( dest, session_dest, &destInfo, false );
01811 if( destExists )
01812 {
01813 if( destInfo.isDir() )
01814
01815 newDest = destInfo.getFullPath() + "/" + src->getName();
01816 else
01817 newDest = dest;
01818 }
01819 else
01820 {
01821 if( src->isDir() )
01822 {
01823 char curDir[MAXNAMELEN];
01824 if( session_dest != NULL )
01825 session_dest->GetCurrentDir( curDir, MAXNAMELEN );
01826 else
01827 {
01828 if( getcwd( curDir, (size_t) MAXNAMELEN ) == NULL )
01829 {
01830 RioErr << "RioExplorer::cp Unable to get working "
01831 << "directory " << endl;
01832 }
01833 }
01834
01835 newDest = string( curDir ) + "/" + dest;
01836 }
01837 else
01838 newDest = dest;
01839 }
01840
01841 if( ( src->getType() == ObjectInfo::FILE_TYPE_DATA ) ||
01842 ( src->getType() == ObjectInfo::FILE_TYPE_DATA_LINK ) )
01843 {
01844 if( current_file )
01845 *current_file = src->getFullName();
01846
01847 if( current_file_size )
01848 *current_file_size = src->getSize();
01849
01850 if( current_file_completed )
01851 *current_file_completed = 0;
01852
01853 newSrc = src->getFullPath();
01854 status = copyFile( stream_src, stream_dest, (char *)newSrc.c_str(),
01855 (char* )newDest.c_str(), askuser, can_continue,
01856 current_file_completed, total_completed, calculator );
01857 }
01858 else if( src->isDir() )
01859 {
01860 if( recursive )
01861 {
01862 newSrc = src->getFullPath() + "/*";
01863 if( mkdir( (char *)newDest.c_str(), session_dest, false ) )
01864 {
01865 if( !resolveRegExp( &srcFiles, session_src,
01866 (char*)newSrc.c_str() ) )
01867 {
01868 message = "cp: impossível obter lista de arquivos de origem.";
01869 message += " A cópia não será feita.\n";
01870 showMessage( ERROR_MSG, message );
01871
01872 status = false;
01873 }
01874
01875 for( unsigned int i = 0;
01876 status && ( i < (unsigned int)srcFiles.size() );
01877 i++ )
01878 {
01879 status = cp( session_src, session_dest, &srcFiles[i],
01880 strdup( (char *)newDest.c_str() ),
01881 askuser, recursive, can_continue,
01882 current_file, current_file_completed,
01883 current_file_size, total_completed,
01884 stream_src, stream_dest, calculator );
01885 }
01886 }
01887 else
01888 {
01889 message = "\ncp: Erro criando diretório de destino \"";
01890 message += newDest;
01891 message += "\".\nA cópia não será feita.\n";
01892 showMessage( ERROR_MSG, message );
01893 status = false;
01894 }
01895 }
01896 else
01897 {
01898 message = "cp: omitting directory `";
01899 message += src->getName();
01900 message += "'.\n";
01901 showMessage( ERROR_MSG, message );
01902 }
01903 }
01904 else
01905 {
01906 message = "cp: invalid source object \"";
01907 message += src->getName();
01908
01909 if( src->getType() == ObjectInfo::FILE_TYPE_BROKEN_LINK )
01910 message += "\": Broken link.\n";
01911 else
01912 message += "\": Invalid type.\n";
01913
01914 showMessage( ERROR_MSG, message );
01915 }
01916 }
01917 if( closeSrcStream )
01918 {
01919 stream_src->Close();
01920 delete stream_src;
01921 }
01922 if( closeDestStream )
01923 {
01924 stream_dest->Close();
01925 delete stream_dest;
01926 }
01927 return status;
01928 }
01929
01930
01931
01932
01933 bool RioExplorer::cd( char *DirectoryName, CRioSession *cdSession )
01934 {
01935 string message;
01936 bool status = true;
01937
01938 status = checkSession( cdSession );
01939
01940 if( status )
01941 {
01942 if( cdSession != NULL )
01943 {
01944 RioResult hResult;
01945 hResult = cdSession->ChangeDir( DirectoryName );
01946 if( FAILED( hResult ) )
01947 {
01948 RioError = hResult;
01949 message = "cd: \"" + string( DirectoryName ) + "\"";
01950 switch( hResult & 0xff )
01951 {
01952 case (signed) ERROR_INVALID_OBJECTNAME:
01953 message += ": Diretório não existe.\n";
01954 break;
01955 case (signed) ERROR_PERMISSION_DENIED:
01956 message += ": Permissão negada.\n";
01957 break;
01958 default:
01959 message += ": erro inesperado.\n(";
01960 message += GetErrorDescription( hResult );
01961 message += ")\nTente 'cd --ajuda' para maiores informações.\n";
01962 }
01963
01964 showMessage( ERROR_MSG, message );
01965 status = false;
01966 }
01967 }
01968 else
01969 {
01970 if( chdir( DirectoryName ) != 0 )
01971 {
01972 SystemError = errno;
01973 message = "cd: \"" + string( DirectoryName ) + "\": ";
01974 message += strerror( errno );
01975 message += ".\nTente 'cd --ajuda' para maiores informações.\n";
01976 showMessage( ERROR_MSG, message );
01977
01978 status = false;
01979 }
01980 }
01981 }
01982
01983 return status;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002 bool RioExplorer::sync( QString masterPath ,
02003 CRioSession *masterSession ,
02004 QString slavePath ,
02005 CRioSession *slaveSession ,
02006 string *current_file ,
02007 RioObjectSize *current_file_completed,
02008 RioObjectSize *current_file_size )
02009 {
02010 vector<ObjectInfo> objectsInfomaster;
02011 vector<ObjectInfo>::iterator masterIterator;
02012 vector<ObjectInfo> objectsInfoslave;
02013 vector<ObjectInfo>::iterator slaveIterator;
02014 ObjectInfo fileInfomaster;
02015 ObjectInfo fileInfoslave;
02016 RioMd5 *masterCache = NULL;
02017 RioMd5 *slaveCache = NULL;
02018
02019 QString eraseDir;
02020 QString comparaDir;
02021 string message;
02022
02023 char *destPath;
02024 char *makeDir;
02025
02026 bool status = true;
02027 bool compareMd5;
02028 bool toCopy;
02029
02030 if( masterPath.endsWith("/") )
02031 masterPath.remove( masterPath.length() - 1, 1 );
02032 if( slavePath.endsWith("/") )
02033 slavePath.remove( slavePath.length() - 1, 1 );
02034
02035 if( !getObjectInfo( (char*)masterPath.latin1(), masterSession,
02036 &fileInfomaster ) ||
02037 !ls( &fileInfomaster, &objectsInfomaster, masterSession, true, true )
02038 )
02039 {
02040 message = "sync: Impossível obter lista do objeto de origem.\n";
02041 showMessage( ERROR_MSG, message );
02042 status = false;
02043 }
02044
02045
02046 if( !getObjectInfo( (char*)slavePath.latin1(), slaveSession,
02047 &fileInfoslave, false ) )
02048 {
02049 if( !mkdir( (char*)slavePath.latin1(), slaveSession, false ) )
02050 {
02051 message = "sync: Erro criando diretório \"";
02052 message += masterIterator->getFullName();
02053 message = "\" \n";
02054 showMessage( ERROR_MSG, message );
02055 status = false;
02056 }
02057 }
02058
02059 if( !ls( &fileInfoslave, &objectsInfoslave, slaveSession, true, true ) )
02060 {
02061 message = "sync: Impossível obter lista do objeto de destino.\n";
02062 showMessage( ERROR_MSG, message );
02063 status = false;
02064 }
02065
02066
02067
02068 if( status )
02069 {
02070 QString insideDir;
02071 char masterMd5[MD5SIZE];
02072 memset( masterMd5, 0, sizeof( masterMd5 ) );
02073 char slaveMd5[MD5SIZE];
02074 memset( slaveMd5, 0, sizeof( slaveMd5 ) );
02075
02076
02077
02078 if( masterSession == NULL )
02079 masterCache = new RioMd5( this, masterSession,
02080 (char *)fileInfomaster.getFullPath().c_str() );
02081 else
02082 masterCache = new RioMd5( this, masterSession );
02083
02084 if( slaveSession == NULL )
02085 slaveCache = new RioMd5( this, slaveSession,
02086 (char *)fileInfoslave.getFullPath().c_str() );
02087 else
02088 slaveCache = new RioMd5( this, slaveSession );
02089
02090
02091
02092
02093
02094
02095 for( masterIterator = objectsInfomaster.begin();
02096 masterIterator != objectsInfomaster.end(); )
02097 {
02098 compareMd5 = false;
02099 toCopy = false;
02100
02101
02102
02103 for( slaveIterator = objectsInfoslave.begin();
02104 ( slaveIterator != objectsInfoslave.end() ) &&
02105 ( masterIterator->getFullName() != slaveIterator->getFullName() );
02106 slaveIterator++
02107 )
02108 {
02109 }
02110
02111 if( slaveIterator != objectsInfoslave.end() )
02112 compareMd5 = true;
02113 else
02114 toCopy = true;
02115
02116 if( compareMd5 )
02117 {
02118 if( masterIterator->getName() != md5CacheFile() )
02119 {
02120 memset( masterMd5, 0, sizeof( masterMd5 ) );
02121 memset( slaveMd5, 0, sizeof( slaveMd5 ) );
02122 setSyncCheck( (char *)masterIterator->getName().c_str(),
02123 false );
02124 masterCache->getMd5Sum(
02125 (char *)masterIterator->getFullPath().c_str(),
02126 masterMd5 );
02127 slaveCache->getMd5Sum(
02128 (char *)slaveIterator->getFullPath().c_str(),
02129 slaveMd5 );
02130 setSyncCheck( (char *)masterIterator->getName().c_str(),
02131 false );
02132
02133 if( ( strcmp( masterMd5, slaveMd5 ) != 0 ) ||
02134 ( ( masterIterator->getSize() != slaveIterator->getSize() ) &&
02135 ( !masterIterator->isDir() ) ) )
02136 {
02137
02138
02139
02140 objectsInfoslave.erase( slaveIterator );
02141 toCopy = true;
02142 }
02143 }
02144
02145
02146 if( !toCopy )
02147 {
02148 objectsInfomaster.erase( masterIterator );
02149
02150
02151
02152 if( slaveIterator->getName() != md5CacheFile() )
02153 objectsInfoslave.erase( slaveIterator );
02154 }
02155 }
02156
02157 if( toCopy )
02158 {
02159 bool copy_allowed = true;
02160
02161
02162 insideDir = masterIterator->getPath();
02163
02164
02165 if( insideDir.contains( "/" ) )
02166 {
02167 int index = insideDir.findRev( '/' );
02168 insideDir = "/" + insideDir.left( index );
02169 }
02170
02171
02172
02173 destPath = strdup( (slavePath + insideDir ).ascii() );
02174
02175 if( masterIterator->isDir() )
02176 {
02177 makeDir = strdup( (slavePath + "/" +
02178 masterIterator->getFullName() ).ascii() );
02179 if( !mkdir( makeDir, slaveSession, false ) )
02180 {
02181 message = "sync: Erro criando diretório \"";
02182 message += masterIterator->getFullName();
02183 message += "\" \n";
02184 RioErr << message << endl;
02185 showMessage( ERROR_MSG, message );
02186 status = false;
02187
02188 objectsInfomaster.erase( masterIterator );
02189 }
02190 else
02191 objectsInfomaster.erase( masterIterator );
02192 }
02193 else
02194 {
02195 if( masterIterator->getName() != md5CacheFile() )
02196 {
02197 if( !cp( masterSession, slaveSession,
02198 &objectsInfomaster[0], destPath, false,
02199 false, ©_allowed, current_file,
02200 current_file_completed, current_file_size,
02201 NULL, NULL, NULL, masterCache ) )
02202 {
02203 message = "sync: Erro copiando arquivo \"";
02204 message += masterIterator->getFullName();
02205 message = "\" \n";
02206 showMessage( ERROR_MSG, message );
02207 status = false;
02208
02209 objectsInfomaster.erase( masterIterator );
02210 }
02211 else
02212 objectsInfomaster.erase( masterIterator );
02213 }
02214
02215
02216
02217 else objectsInfomaster.erase( masterIterator );
02218 }
02219 }
02220 }
02221 }
02222
02223
02224 if( status )
02225 {
02226 for( slaveIterator = objectsInfoslave.begin() ;
02227 slaveIterator != objectsInfoslave.end(); )
02228 {
02229 if( slaveIterator->isDir() )
02230 {
02231 eraseDir = ( slaveIterator->getName() + "/" );
02232
02233 if( !rm( &objectsInfoslave[0], slaveSession, false, true ) )
02234 {
02235 message = "sync: Erro removendo diretório \"";
02236 message += slaveIterator->getFullName();
02237 message = "\" \n";
02238 showMessage( ERROR_MSG, message );
02239 status = false;
02240
02241 objectsInfoslave.erase( slaveIterator );
02242 }
02243 else
02244 objectsInfoslave.erase( slaveIterator );
02245
02246 comparaDir = slaveIterator->getPath();
02247
02248 while( ( comparaDir.startsWith( eraseDir ) ) &&
02249 ( slaveIterator != objectsInfoslave.end() ) )
02250 {
02251 objectsInfoslave.erase( slaveIterator );
02252
02253 if( slaveIterator != objectsInfoslave.end() )
02254 {
02255 comparaDir = slaveIterator->getPath();
02256 }
02257 }
02258 }
02259 else
02260 {
02261 if( slaveIterator->getName() != md5CacheFile() )
02262 {
02263 if( !rm( &objectsInfoslave[0], slaveSession, false, false ) )
02264 {
02265 message = "sync: Erro removendo arquivo \"";
02266 message += slaveIterator->getFullName();
02267 message = "\" \n";
02268 showMessage( ERROR_MSG, message );
02269 status = false;
02270 }
02271 objectsInfoslave.erase( slaveIterator );
02272 }
02273 else
02274 {
02275
02276
02277 if( slaveSession != NULL )
02278 {
02279 if( !rm( &objectsInfoslave[0], slaveSession, false, false ) )
02280 {
02281 message = "sync: Erro removendo arquivo \"";
02282 message += slaveIterator->getFullName();
02283 message = "\" \n";
02284 showMessage( ERROR_MSG, message );
02285 status = false;
02286 }
02287 }
02288
02289 objectsInfoslave.erase( slaveIterator );
02290 }
02291 }
02292 }
02293 }
02294
02295 if( masterCache )
02296 masterCache->updateCache();
02297 if( slaveCache )
02298 {
02299 if( slaveSession == NULL )
02300 {
02301 if( masterSession == NULL)
02302 slaveCache->copyCache( masterCache );
02303 else
02304 slaveCache->importData( masterPath, masterSession );
02305 }
02306 slaveCache->updateCache();
02307 }
02308
02309
02310 delete masterCache;
02311 delete slaveCache;
02312
02313 return status;
02314 }
02315
02316
02317
02318
02319 bool RioExplorer::createObject( char *ObjectName, unsigned int ObjectSize )
02320 {
02321 RioResult hResult;
02322 CRioStream *Stream;
02323 RioStreamTraffic Traffic;
02324 RioAccess Access;
02325 CRioObject *Object;
02326 RioObjectSize Size;
02327 bool status = true;
02328 unsigned int BlockSize;
02329 string message;
02330
02331 status = checkSession();
02332
02333 if( status )
02334 {
02335 getBlockSize( &BlockSize, session );
02336
02337 char* md5 = strdup( "0123456789abcdef0123456789abcdef" );
02338 hResult = session->CreateObject( ObjectName, ObjectInfo::FILE_TYPE_DATA,
02339 NULL );
02340
02341 if( FAILED( hResult ) )
02342 {
02343 message = "create: Não conseguiu criar o objeto \"";
02344 message += ObjectName;
02345 message += "\".\n(";
02346 message += GetErrorDescription( hResult );
02347 message += "\")\n";
02348 showMessage( ERROR_MSG, message );
02349
02350 status = false;
02351 }
02352 else
02353 {
02354 Stream = new CRioStream;
02355 Traffic.Type = RIO_TRAFFIC_NRT;
02356 Traffic.Direction = RioStreamDirectionReadWrite;
02357 Traffic.LogicalBlockSize = BlockSize;
02358 Traffic.MaxRequests = MaxRequests;
02359 Traffic.TrafficNRT.Reserved = 0;
02360 hResult = Stream->Open( &Traffic,session );
02361 if( FAILED( hResult ) )
02362 {
02363 message = "create: Não conseguiu abrir stream.\n(";
02364 message += GetErrorDescription( hResult );
02365 message += ")\n";
02366 showMessage( ERROR_MSG, message );
02367
02368 delete Stream;
02369 session->DeleteObject( ObjectName );
02370
02371 status = false;
02372 }
02373 else
02374 {
02375 Object = new CRioObject;
02376 Access = RIO_RW_ACCESS;
02377 hResult = Object->Open( ObjectName,Access,Stream );
02378 if( FAILED( hResult ) )
02379 {
02380 message = "create: Não conseguiu abrir o objeto \"";
02381 message += ObjectName;
02382 message += "\".\n(";
02383 message += GetErrorDescription( hResult );
02384 message += ")\n";
02385
02386 Stream->Close();
02387 delete Object;
02388 delete Stream;
02389 session->DeleteObject( ObjectName );
02390
02391 showMessage( ERROR_MSG, message );
02392 status = false;
02393 }
02394 else
02395 {
02396 Size = ( (RioObjectSize)ObjectSize )*BlockSize;
02397 hResult = Object->SetSize( Size, md5 );
02398
02399 Object->Close();
02400 Stream->Close();
02401 delete Object;
02402 delete Stream;
02403
02404 if( FAILED( hResult ) )
02405 {
02406 message = "create: Não conseguiu alocar espaço para o";
02407 message += " objeto \"";
02408 message += ObjectName;
02409 message += "\".\n(";
02410 message += GetErrorDescription( hResult );
02411 message += ")\n";
02412 showMessage( ERROR_MSG, message );
02413
02414 session->DeleteObject( ObjectName );
02415 status = false;
02416 }
02417 }
02418 }
02419 }
02420 free( md5 );
02421 }
02422
02423 return status;
02424 }
02425
02426
02427
02428
02429 bool RioExplorer::df( vector<DfInfo> *data )
02430 {
02431 RioResult hResult;
02432 unsigned int freeblocksOfAllDisks = 0;
02433 unsigned int TotalblocksOfAllDisks = 0;
02434 unsigned int usedblocksOfAllDisks = 0;
02435 unsigned int NumberOfStorageNodes;
02436 unsigned int i;
02437 RioStorageNodeInfo StorageNodeInfo;
02438 bool status = true;
02439 unsigned int BlockSize;
02440 string message;
02441
02442 status = checkSession();
02443
02444 if( status )
02445 {
02446 getBlockSize( &BlockSize, session );
02447
02448 hResult = session->GetNumberOfStorageNodes( &NumberOfStorageNodes );
02449 if( FAILED( hResult ) )
02450 {
02451 message = "df: Não conseguiu pegar número de storages do sistema";
02452 message += " RIO.\n(";
02453 message += GetErrorDescription( hResult );
02454 message += ")\n";
02455 showMessage( ERROR_MSG, message );
02456
02457 status = false;
02458 }
02459 else
02460 {
02461 RioObjectSize usedsize, freesize;
02462 unsigned int Totalblocks, usedblocks;
02463
02464 for( i = 0; i < NumberOfStorageNodes; i++ )
02465 {
02466 DfInfo df_info;
02467
02468 hResult = session->GetStorageNodeInfo( &StorageNodeInfo, i );
02469
02470 if( FAILED( hResult ) )
02471 {
02472 message = "df: Não conseguiu pegar informações do ";
02473 message += "storage.\n(";
02474 message += GetErrorDescription( hResult );
02475 message += ")\n";
02476 showMessage( ERROR_MSG, message );
02477 status = false;
02478 }
02479 else
02480 {
02481 vector<StorageDfInfo> storage_node;
02482 for( short j = 0; j < StorageNodeInfo.NumberOfDisks; j++ )
02483 {
02484 StorageDfInfo storage_df_info;
02485
02486 Totalblocks = StorageNodeInfo.Disks[j].Size / BlockSize;
02487 TotalblocksOfAllDisks += Totalblocks;
02488 usedblocks = Totalblocks -
02489 StorageNodeInfo.Disks[j].NumberOfFreeBlocks;
02490 usedblocksOfAllDisks += usedblocks;
02491
02492 usedsize = ( RioObjectSize) usedblocks *
02493 (RioObjectSize) BlockSize;
02494 freesize = (RioObjectSize)
02495 StorageNodeInfo.Disks[j].NumberOfFreeBlocks *
02496 (RioObjectSize) BlockSize;
02497 freeblocksOfAllDisks +=
02498 StorageNodeInfo.Disks[j].NumberOfFreeBlocks;
02499
02500 StorageNodeInfo.Hostname[14] = '\0';
02501 StorageNodeInfo.Disks[j].DiskName[19] = '\0';
02502
02503 storage_df_info.hostname = StorageNodeInfo.Hostname;
02504 storage_df_info.diskname =
02505 StorageNodeInfo.Disks[j].DiskName;
02506 storage_df_info.size = StorageNodeInfo.Disks[j].Size;
02507 storage_df_info.used_size = usedsize;
02508 storage_df_info.free_size = freesize;
02509 storage_df_info.total_blocks = Totalblocks;
02510 storage_df_info.used_blocks = usedblocks;
02511 storage_df_info.free_blocks =
02512 StorageNodeInfo.Disks[j].NumberOfFreeBlocks;
02513
02514 storage_node.push_back( storage_df_info );
02515 }
02516 df_info.storage_df_info = storage_node;
02517 }
02518
02519 usedsize = (RioObjectSize) usedblocksOfAllDisks *
02520 (RioObjectSize) BlockSize;
02521 freesize = (RioObjectSize) freeblocksOfAllDisks *
02522 (RioObjectSize) BlockSize;
02523
02524 df_info.used_size = usedsize;
02525 df_info.free_size = freesize;
02526 df_info.free_blocks_of_all_disks = freeblocksOfAllDisks;
02527 df_info.total_blocks_of_all_disks = TotalblocksOfAllDisks;
02528 df_info.used_blocks_of_all_disks = usedblocksOfAllDisks;
02529
02530 data->push_back( df_info );
02531 }
02532 }
02533 }
02534
02535 return status;
02536 }
02537
02538
02539
02540
02541 bool RioExplorer::du( vector<DuInfo> *data, char * ObjectName,
02542 CRioSession *session, bool showallfiles )
02543 {
02544 RioObjectSize Size;
02545 bool status = true;
02546 unsigned int BlockSize;
02547 string message;
02548
02549 status = ( checkSession( session ) );
02550
02551 if( status )
02552 {
02553 getBlockSize( &BlockSize, session );
02554 if( strcmp( ObjectName, "" ) != 0 )
02555 {
02556 ObjectInfo Objectinfo;
02557 if( !getObjectInfo( ObjectName, session, &Objectinfo ) )
02558 status = false;
02559 else
02560 {
02561 if( !Objectinfo.isDir() )
02562 {
02563 Size = Objectinfo.getSize();
02564 unsigned int nBlocks;
02565
02566
02567
02568 nBlocks = ( Size + BlockSize - 1 ) / BlockSize;
02569
02570 DuInfo duInfo;
02571 duInfo.size = Size;
02572 duInfo.nBlocks = nBlocks;
02573 duInfo.object_name = ObjectName;
02574
02575 data->push_back( duInfo );
02576 }
02577 else
02578 rGetSize( data, ObjectName, session, showallfiles ) ;
02579 }
02580 }
02581 }
02582 return status;
02583 }
02584
02585
02586
02587
02588 bool RioExplorer::sessions( SessionsInfo * info )
02589 {
02590 RioResult hResult;
02591 unsigned int NumberOfActiveSessions;
02592 unsigned int NumberOfMaxSessions;
02593 bool status = true;
02594 string message;
02595
02596 status = checkSession();
02597
02598 if( status )
02599 {
02600 hResult = session->GetNumberOfActiveAndMaxSessions(
02601 &NumberOfActiveSessions,
02602 &NumberOfMaxSessions );
02603 if( FAILED( hResult ) )
02604 {
02605
02606 RioError = hResult;
02607
02608 message = "sessions: Não conseguiu pegar número de sessões do ";
02609 message += "RIO.\n(";
02610 message += GetErrorDescription( hResult );
02611 message += ")\n";
02612 showMessage( ERROR_MSG, message );
02613
02614 status = false;
02615 }
02616 else
02617 {
02618 info->number_of_max_sessions = NumberOfMaxSessions;
02619 info->number_of_active_sessions = NumberOfActiveSessions;
02620 }
02621 }
02622 else
02623 if( session == NULL )
02624 RioError = ERROR_RIOSESSION + ERROR_NOT_INITIALIZED;
02625 else
02626 RioError = ERROR_RIOSESSION + ERROR_SESSION_NOT_OPENED;
02627
02628 return status;
02629 }
02630
02631
02632
02633
02634 bool RioExplorer::measures( void )
02635 {
02636 RioResult hResult;
02637 bool status = true;
02638 string message;
02639
02640 status = checkSession();
02641
02642 if( status )
02643 {
02644 hResult = session->SaveMeasures();
02645
02646 if( FAILED( hResult ) )
02647 {
02648 message = "salvarmedidas: O servidor não está coletando medidas ";
02649 message += "no momento.\n(";
02650 message += GetErrorDescription( hResult );
02651 message += ")\n";
02652 showMessage( ERROR_MSG, message );
02653 status = false;
02654 }
02655 else
02656 {
02657 message = "salvarmedidas: As medidas coletadas até o momento";
02658 message += "foram gravadas em arquivos.\n";
02659 showMessage( INFO_MSG, message );
02660 }
02661 }
02662
02663 return status;
02664 }
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674 bool RioExplorer::mv( char *CurrentName, char *NewName, CRioSession *session,
02675 bool askuser )
02676 {
02677 bool status = true;
02678 string message;
02679 ObjectInfo destInfo;
02680
02681 status = checkSession( session );
02682
02683 if( status )
02684 {
02685 if( getObjectInfo( NewName, session, &destInfo, false ) )
02686 {
02687
02688 if( destInfo.isDir() )
02689 {
02690 char *lastName;
02691 lastName = strrchr( CurrentName, '/' );
02692 if( lastName != NULL )
02693 {
02694 strcat( NewName, lastName );
02695 }
02696 else
02697 {
02698 strcat( NewName, "/" );
02699 strcat( NewName, CurrentName );
02700 }
02701
02702 if( getObjectInfo( NewName, session, &destInfo, false ) )
02703 {
02704 if( destInfo.isDir() )
02705 {
02706 message = "mv: Não foi possível sobrescrever ";
02707 message += "diretório \"";
02708 message += NewName;
02709 message += "\".\n";
02710 showMessage( ERROR_MSG, message );
02711 status = false;
02712 }
02713 else if( askuser )
02714 {
02715 message = "Objeto ";
02716 message += NewName;
02717 message += " já existe. Sobrescrever?";
02718 status = showMessage( QUESTION_MSG, message );
02719 }
02720 }
02721
02722 }
02723 else if( askuser )
02724 {
02725 message = "Objeto ";
02726 message += NewName;
02727 message += " já existe. Sobrescrever?";
02728 status = showMessage( QUESTION_MSG, message );
02729 }
02730 }
02731 }
02732
02733 if( status )
02734 {
02735 string errorMsg;
02736 if( session != NULL )
02737 {
02738 RioResult hResult;
02739 hResult = session->RenameObject( CurrentName, NewName );
02740 if( FAILED( hResult ) )
02741 {
02742 status = false;
02743 RioError = hResult;
02744
02745 errorMsg = GetErrorDescription( hResult );
02746 }
02747 }
02748 else
02749 {
02750 if( rename( CurrentName, NewName ) )
02751 {
02752 status = false;
02753 SystemError = errno;
02754
02755 errorMsg = strerror( errno );
02756 }
02757 }
02758
02759 if( status == false )
02760 {
02761 message = "mv: Erro tentando mover \"";
02762 message += CurrentName;
02763 message += "\".\n(";
02764 message += errorMsg;
02765 message += ")\n";
02766
02767 showMessage( ERROR_MSG, message );
02768 }
02769 }
02770
02771 return status;
02772 }
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 bool RioExplorer::resolveRegExp( vector<ObjectInfo> *matchList,
02788 CRioSession *session, const char *regExp,
02789 char *searchPoint, int reclevel )
02790 {
02791 CRioDirectory *Directory = NULL;
02792 DIR *o_dir = NULL;
02793 ObjectInfo Objectinfo;
02794 ObjectInfo fileInfo;
02795 char *DirectoryName;
02796 char newSearchPoint[MAXNAMELEN];
02797 string message;
02798 bool status = true;
02799 bool nextOk = true;
02800 bool isFirstFile = true;
02801 vector<ObjectInfo> appendData;
02802 RioResult hResult;
02803 bool removeSearchPoint = false;
02804
02805 if( reclevel == 0 )
02806 DirectoryName = convertPath( regExp );
02807 else
02808 DirectoryName = strdup( regExp );
02809
02810 if( searchPoint == NULL )
02811 {
02812 searchPoint = (char *)malloc( MAXNAMELEN * sizeof( char ) );
02813 if( searchPoint == NULL )
02814 {
02815 SystemError = ENOMEM;
02816 message = "resolveRegExp: memoria insuficiente.\n";
02817 showMessage( ERROR_MSG, message );
02818 return false;
02819
02820 }
02821
02822 removeSearchPoint = true;
02823
02824 if( session != NULL )
02825 {
02826 hResult = session->GetCurrentDir( searchPoint, MAXNAMELEN );
02827 if( FAILED( hResult ) )
02828 {
02829 RioError = hResult;
02830 message = "resolveRegExp: error when obtaining current ";
02831 message += "directory!\n";
02832 showMessage( ERROR_MSG, message );
02833 free( searchPoint );
02834 return false;
02835 }
02836 }
02837 else
02838 {
02839 if( getcwd( searchPoint, (size_t) MAXNAMELEN ) == NULL)
02840 {
02841
02842 SystemError = errno;
02843 message = "resolveRegExp: Unable to get working directory";
02844 message += ".\n";
02845 showMessage( ERROR_MSG, message );
02846 free( searchPoint );
02847 return false;
02848
02849
02850 }
02851 }
02852 }
02853
02854 if( DirectoryName[0] == '/' )
02855 {
02856 if( strcmp( DirectoryName, "/" ) == 0 )
02857 {
02858 getObjectInfo( "/", session, &fileInfo );
02859 appendData.push_back( fileInfo );
02860 }
02861 else
02862 {
02863 strcpy( newSearchPoint, "/" );
02864 status = status && resolveRegExp( &appendData, session,
02865 DirectoryName+1,
02866 newSearchPoint,
02867 reclevel + 1 );
02868 }
02869 }
02870 else
02871 {
02872 char firstDir[MAXNAMELEN];
02873 char *breakPoint;
02874
02875 strcpy( firstDir, DirectoryName );
02876 breakPoint = strchr( firstDir, '/' );
02877
02878 if( breakPoint != NULL )
02879 {
02880 *breakPoint= '\0';
02881
02882 DirectoryName = strchr( DirectoryName, '/' );
02883 DirectoryName++;
02884 }
02885 else
02886 DirectoryName[0] = '\0';
02887
02888 if( session != NULL )
02889 {
02890 try
02891 {
02892 Directory = new CRioDirectory();
02893 }
02894 catch( bad_alloc &ba )
02895 {
02896 SystemError = ENOMEM;
02897 message = "resolveRegExp: insufficient memory (bad_alloc=";
02898 message += ba.what();
02899 message += ".\n";
02900 showMessage( ERROR_MSG, message );
02901 status = false;
02902 }
02903
02904 }
02905 else
02906 {
02907 o_dir = opendir( searchPoint );
02908
02909 if( o_dir == NULL )
02910 {
02911 SystemError = errno;
02912 message = "resolveRegExp: error when executing opendir!\n";
02913 showMessage( ERROR_MSG, message );
02914 status = false;
02915 }
02916 }
02917
02918 if( status )
02919 {
02920 if( strcmp( firstDir, "\\.\\." ) == 0 )
02921 {
02922 if( strcmp( DirectoryName, "" ) == 0 )
02923
02924 {
02925 getObjectInfo( "..", session, &fileInfo );
02926 appendData.push_back( fileInfo );
02927 }
02928 else
02929 {
02930 strcpy( newSearchPoint, searchPoint );
02931 breakPoint = strrchr( newSearchPoint, '/' );
02932
02933
02934 if( breakPoint != NULL )
02935 *breakPoint= '\0';
02936
02937
02938
02939 if( ( strlen( newSearchPoint ) == 0 ) &&
02940 ( searchPoint[0] == '/' )
02941 )
02942 strcpy( newSearchPoint, "/");
02943
02944 status = status && resolveRegExp( &appendData, session,
02945 DirectoryName,
02946 newSearchPoint,
02947 reclevel + 1 );
02948
02949 for( unsigned int i = 0;
02950 status && ( i < (unsigned int)appendData.size() );
02951 i++
02952 )
02953 {
02954 string newPath = appendData[i].getPath();
02955 string::size_type loc = newPath.find( "/", 0 );
02956 if( loc != string::npos )
02957 newPath.replace( 0, loc, ".." );
02958
02959 appendData[i].setPath( newPath );
02960 }
02961 }
02962 }
02963 else
02964 {
02965 while( nextOk )
02966 {
02967 if( session != NULL )
02968 {
02969 nextOk = getNextRioFileName( Directory, session,
02970 searchPoint, &Objectinfo,
02971 isFirstFile );
02972 isFirstFile = false;
02973 }
02974 else
02975 {
02976 nextOk = getNextLocalFileName( o_dir, searchPoint,
02977 &Objectinfo );
02978
02979 if( ( Objectinfo.getName() == "." ) ||
02980 ( Objectinfo.getName() == ".." )
02981 )
02982 continue;
02983 }
02984
02985 if( status && nextOk )
02986 {
02987 if( strMatch( (char *)Objectinfo.getName().c_str(),
02988 firstDir )
02989 )
02990 {
02991
02992 if( strcmp( DirectoryName, "" ) == 0 )
02993 {
02994 appendData.push_back( Objectinfo );
02995 }
02996 else if( ( Objectinfo.getType() ==
02997 ObjectInfo::FILE_TYPE_DIRECTORY ) ||
02998 ( Objectinfo.getType() ==
02999 ObjectInfo::FILE_TYPE_DIR_LINK )
03000 )
03001 {
03002 strcpy( newSearchPoint, searchPoint );
03003 if( strcmp( searchPoint, "/" ) )
03004 strcat( newSearchPoint, "/" );
03005 strcat( newSearchPoint,
03006 (char *)Objectinfo.getName().c_str() );
03007
03008 status = status && resolveRegExp( &appendData,
03009 session,
03010 DirectoryName,
03011 newSearchPoint,
03012 reclevel + 1 );
03013 }
03014 }
03015 }
03016 else
03017 break;
03018
03019 }
03020 }
03021 }
03022
03023 if( session != NULL )
03024 {
03025 Directory->Close();
03026 delete Directory;
03027 }
03028 else
03029 {
03030 if( o_dir != NULL )
03031 closedir( o_dir );
03032 }
03033 }
03034
03035 char *lastName;
03036 lastName = strrchr( searchPoint, '/' );
03037 if( lastName != NULL )
03038 lastName++;
03039
03040 if( lastName != NULL )
03041 for( unsigned int i = 0; i < appendData.size(); i++ )
03042 {
03043 if( reclevel != 0 )
03044 {
03045 string newPath = appendData[i].getPath();
03046 newPath.insert( 0, "/" );
03047 newPath.insert( 0, lastName );
03048 appendData[i].setPath( newPath );
03049 }
03050
03051 matchList->insert( matchList->end(), appendData[i] );
03052 }
03053
03054 if( removeSearchPoint )
03055 free( searchPoint );
03056
03057 return status;
03058 }
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068 bool RioExplorer::getObjectInfo( const char *objectName, CRioSession *session,
03069 ObjectInfo *fileInfo, bool notifyError )
03070 {
03071 bool status = true;
03072 string message;
03073 char curDir[MAXNAMELEN];
03074 RioResult hResult;
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084 string::size_type pos;
03085 string s( objectName );
03086 pos = s.find( "//", 0 );
03087 while( pos != string::npos ) {
03088 s.erase( pos, 1 );
03089 pos = s.find( "//", 0 );
03090 }
03091 objectName = strdup( s.c_str() );
03092
03093 status = checkSession( session );
03094
03095 if( status )
03096 {
03097 if( objectName[0] != '/' )
03098 {
03099 if( session != NULL )
03100 {
03101 hResult = session->GetCurrentDir( curDir, MAXNAMELEN );
03102 if( FAILED( hResult ) )
03103 {
03104 RioError = hResult;
03105 message = "getObjectInfo: error when obtaining current";
03106 message += "directory!\n";
03107 showMessage( ERROR_MSG, message );
03108 return false;
03109 }
03110 }
03111 else
03112 {
03113 if( getcwd( curDir, (size_t)MAXNAMELEN ) == NULL )
03114 {
03115 SystemError = errno;
03116 message = "getObjectInfo: Unable to get working directory";
03117 message += ".\n";
03118 showMessage( ERROR_MSG, message );
03119 return false;
03120 RioErr << "RioExplorer::getObjectInfo Unable to get "
03121 << "working directory " << endl;
03122 }
03123 }
03124 }
03125 else
03126 curDir[0] = '\0';
03127 }
03128
03129 if( session == NULL )
03130 {
03131 if( getLocalObjectInfo( objectName, fileInfo ) == false )
03132 {
03133 if( notifyError )
03134 {
03135 message = "Impossível pegar informações do objeto local \"";
03136 message += objectName;
03137 message += "\".\n";
03138 showMessage( ERROR_MSG, message );
03139 }
03140
03141 status = false;
03142 }
03143 }
03144 else
03145 {
03146 hResult = session->GetObjectInfo( objectName, fileInfo );
03147 if( FAILED( hResult ) )
03148 {
03149 if( notifyError )
03150 {
03151 message = "Impossível pegar informações do objeto do RIO \"";
03152 message += objectName;
03153 message += "\".\n(";
03154 message += GetErrorDescription( hResult );
03155 message += ")\n";
03156 showMessage( ERROR_MSG, message );
03157 }
03158
03159
03160 RioError = hResult ;
03161
03162 status = false;
03163 }
03164 }
03165 fileInfo->setNames( objectName, curDir );
03166 return status;
03167 }
03168
03169
03170
03171
03172
03173
03174 bool RioExplorer::getBlockSize( unsigned int *BlockSize, CRioSession *session )
03175 {
03176 bool status = true;
03177
03178 status = checkSession( session );
03179
03180 if( status )
03181 {
03182 if( session == NULL )
03183 {
03184 struct stat mystat;
03185
03186 if( lstat( ".", &mystat ) )
03187 status = false;
03188 else
03189 *BlockSize = mystat.st_blksize;
03190 }
03191 else
03192 {
03193 if( FAILED( session->GetBlockSize( BlockSize ) ) )
03194 status = false;
03195 }
03196 }
03197
03198 return status;
03199 }
03200
03201
03202
03203
03204
03205
03206
03207 bool RioExplorer::getMonitorTable( CRioSession *session, char * UserName,
03208 vector<ClientData> *client_data,
03209 vector<StorageData> *storage_data )
03210 {
03211 bool status = true;
03212
03213 status = checkSession( session );
03214 if( status )
03215 {
03216 if( session == NULL )
03217 status = false;
03218 else
03219 {
03220 if( FAILED( session->GetMonitorTable(
03221 UserName, client_data, storage_data ) ) )
03222 {
03223 string message = "Permissão negada";
03224 showMessage( ERROR_MSG, message );
03225 status = false;
03226 }
03227 }
03228 }
03229 else
03230 status = false;
03231 return status;
03232 }
03233
03234
03235
03236 void RioExplorer::setSession( CRioSession* Session )
03237 {
03238 session = Session;
03239 }
03240
03241
03242
03243
03244 QString RioExplorer::md5CacheFile()
03245 {
03246 return MD5CACHEFILE.right( MD5CACHEFILE.length() - 1 );
03247 }
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257 bool RioExplorer::getObjectMd5Sum( char *objectName, CRioSession *session,
03258 char *md5sum, bool notifyError )
03259 {
03260 RioMd5 calculator( this, session );
03261 return calculator.getMd5Sum( objectName, md5sum, notifyError );
03262 }
03263
03264
03265 void RioExplorer::getError( RioResult *RioStatus, int *SystemStatus )
03266 {
03267
03268
03269
03270 if( ( RioError != S_OK ) && ( RioStatus != NULL ) &&
03271 ( ( *RioStatus ) == S_OK ) )
03272 *RioStatus = RioError;
03273
03274
03275
03276
03277 if( ( SystemError != 0 ) && ( SystemStatus != NULL ) &&
03278 ( ( *SystemStatus ) == 0 ) )
03279 *SystemStatus = SystemError;
03280 }
03281
03282
03283
03284
03285
03286
03287 RioMd5::RioMd5( RioExplorer *explorer, CRioSession *session )
03288 {
03289 parent = explorer;
03290 md5Session = session;
03291 }
03292
03293 RioMd5::RioMd5( RioExplorer *explorer, CRioSession *session, char *src )
03294 {
03295 parent = explorer;
03296 md5Session = session;
03297 srcDirectory = QString( src );
03298 MD5CACHEFILE = explorer->md5CacheFile();
03299 loadCache( srcDirectory , md5Cache );
03300 }
03301
03302 RioMd5::~RioMd5()
03303 {
03304 if( srcDirectory.isNull() ) return;
03305
03306 #ifdef RIO_DEBUG2
03307 RioErr << "Destroying cache for " << srcDirectory.latin1() << endl;
03308 #endif
03309
03310
03311
03312 QDomDocument doc( "document" );
03313 QDomElement root = doc.createElement( "root" );
03314 doc.appendChild( root );
03315
03316 vector<QDomElement>::iterator elemIt;
03317 for( elemIt = md5Cache.begin(); elemIt != md5Cache.end(); elemIt++ )
03318 {
03319
03320 QString dir = (*elemIt).attribute( "name" ).copy();
03321 if( dir.findRev( '/' ) == -1 )
03322 dir = "";
03323 else
03324 dir.truncate( dir.findRev( '/' ) );
03325
03326
03327 QString newName = (*elemIt).attribute( "name" );
03328 if( dir != "" )
03329 newName.remove( 0, dir.length() + 1 );
03330 (*elemIt).setAttribute( "name", newName );
03331
03332
03333 bool found = false;
03334 QDomNode node = root.firstChild();
03335 while( !node.isNull() && !found )
03336 {
03337 if( node.isElement() )
03338 {
03339 QDomElement elem = node.toElement();
03340 if( ( elem.attribute( "dir" ) == dir ) )
03341 {
03342 elem.appendChild( *elemIt );
03343 found = true;
03344 }
03345 }
03346 node = node.nextSibling();
03347 }
03348 if( !found )
03349 {
03350 QDomElement newDir = doc.createElement( "root" );
03351 newDir.setAttribute( "dir", dir );
03352 newDir.appendChild( *elemIt );
03353 root.appendChild( newDir );
03354 }
03355 }
03356
03357 QDomNode exportNode = root.firstChild();
03358 while( !exportNode.isNull() )
03359 {
03360
03361 QString fileOutput = exportNode.toElement().attribute( "dir" ).copy();
03362 if( fileOutput == "" )
03363 fileOutput = srcDirectory;
03364 else
03365 fileOutput = srcDirectory + '/' + fileOutput;
03366 fileOutput += '/';
03367 fileOutput += MD5CACHEFILE;
03368
03369 #ifdef RIO_DEBUG2
03370 RioErr << "Exporting node to file: " << fileOutput.latin1() << endl;
03371 #endif
03372
03373
03374 exportNode.toElement().removeAttribute( "dir" );
03375 QFile file( fileOutput );
03376 if( file.exists() && !file.remove() )
03377 {
03378 #ifdef RIO_DEBUG2
03379 RioErr << "Couldn't reset file " << fileOutput.latin1() << endl;
03380 #endif
03381
03382 exportNode = exportNode.nextSibling();
03383 continue;
03384 }
03385 file.open( IO_ReadWrite );
03386 QTextStream stream( &file );
03387 exportNode.save( stream, 0 );
03388
03389 exportNode = exportNode.nextSibling();
03390 }
03391 }
03392
03393
03394
03395
03396
03397 void RioMd5::loadCache( QString src, vector<QDomElement> &md5Cache )
03398 {
03399
03400 QString cacheFile = src + '/' + MD5CACHEFILE;
03401 QDomDocument doc( cacheFile );
03402 QFile file( cacheFile );
03403 #ifdef RIO_DEBUG2
03404 RioErr << "Loading cache: " << cacheFile.latin1() << endl;
03405 #endif
03406 if ( !file.open( IO_ReadWrite ) )
03407 {
03408 #ifdef RIO_DEBUG2
03409 RioErr << "Could not open/create MD5Sum cache file." << endl;
03410 #endif
03411 return;
03412 }
03413 if ( !doc.setContent( &file ) )
03414 {
03415 #ifdef RIO_DEBUG2
03416 RioErr << "Could not set content: probably a corrupted or empty MD5Sum "
03417 << "cache file."
03418 << endl;
03419 #endif
03420 file.close();
03421 return;
03422 }
03423
03424
03425
03426
03427 QDomNode node = doc.documentElement().firstChild();
03428 while( !node.isNull() )
03429 {
03430 if( node.isElement() )
03431 {
03432 QDomElement elem = node.toElement();
03433 QString path = src.copy();
03434
03435
03436 path.remove( 0, srcDirectory.length() );
03437 path.remove( 0, 1 );
03438 if( !path.isEmpty() ) path += '/';
03439 path += elem.attribute( "name" );
03440 elem.setAttribute( "name", path );
03441
03442 md5Cache.push_back( elem );
03443 if( ( elem.tagName() == "dir" ) )
03444 loadCache( src + "/" +
03445 elem.attribute( "name" ).section( '/', -1 ),
03446 md5Cache );
03447 }
03448 node = node.nextSibling();
03449 }
03450 file.close();
03451 }
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463 bool RioMd5::getMd5Sum( char *objectName, char *md5sum, bool notifyError )
03464 {
03465 bool found = false;
03466
03467 QString name( objectName );
03468
03469
03470 if( !srcDirectory.isNull() &&
03471 name.left( srcDirectory.length() ) != srcDirectory )
03472 {
03473 md5sum = NULL;
03474 return false;
03475 }
03476
03477 if( !parent->checkSession( md5Session ) )
03478 {
03479 md5sum = NULL;
03480 return false;
03481 }
03482 ObjectInfo searchInfo;
03483 if (!parent->getObjectInfo( (char *)objectName, md5Session, &searchInfo,
03484 notifyError ))
03485 {
03486 md5sum = NULL;
03487 return false;
03488 }
03489
03490 #ifdef RIO_DEBUG2
03491 RioErr << "getMd5Sum for " << objectName << endl;
03492 #endif
03493
03494 if( md5Session == NULL )
03495 {
03496 if( !srcDirectory.isEmpty() )
03497 {
03498
03499 RioObjectSize size = searchInfo.getSize();
03500 AccessTime date = searchInfo.getTime();
03501
03502 QString stringSize;
03503 stringSize += QString::number( size );
03504
03505
03506
03507
03508 QString stringDate;
03509 stringDate += QString::number( date.Year ).rightJustify( 4, '0' );
03510 stringDate += QString::number( date.Month ).rightJustify( 2, '0' );
03511 stringDate += QString::number( date.Day ).rightJustify( 2, '0' );
03512 stringDate += QString::number( date.Hour ).rightJustify( 2, '0' );
03513 stringDate += QString::number( date.Minute ).rightJustify( 2, '0' );
03514
03515
03516 QString searchName = QString( objectName );
03517 searchName.remove( 0, srcDirectory.length() );
03518 searchName.remove( 0, 1 );
03519
03520 vector<QDomElement>::iterator it;
03521 for( it = md5Cache.begin(); it != md5Cache.end() && !found; it++ )
03522 {
03523 if( (*it).attribute( "name" ) == searchName )
03524
03525 {
03526 if( searchInfo.isDir() )
03527
03528 {
03529 md5sum = NULL;
03530 return true;
03531 }
03532
03533 found = true;
03534
03535
03536 if( stringSize == (*it).attribute( "size" ) &&
03537 stringDate == (*it).attribute( "date" ) )
03538 {
03539 #ifdef RIO_DEBUG2
03540 RioErr << "CASE 1: cache updated" << endl;
03541 #endif
03542
03543 strcpy( md5sum,
03544 (char *)(*it).attribute( "md5sum" ).latin1() );
03545
03546 }
03547
03548 else
03549 {
03550 #ifdef RIO_DEBUG2
03551 RioErr << "CASE 2: cache outdated" << endl;
03552 RioErr << " file size = " << stringSize.latin1()
03553 << ", file date = " << stringDate.latin1() << endl;
03554 RioErr << "cache size = " << (*it).attribute( "size" ).latin1()
03555 << ", cache date = " << (*it).attribute( "date" ).latin1() << endl;
03556 #endif
03557
03558 (*it).setAttribute( "size", stringSize );
03559 (*it).setAttribute( "date", stringDate );
03560
03561 char buffer[MD5SIZE];
03562 parent->setMD5Calculation( objectName, false );
03563 QString md5 = calculateMD5( objectName, buffer );
03564 parent->setMD5Calculation( objectName, true );
03565 (*it).setAttribute( "md5sum", md5 );
03566 strcpy( md5sum, (char *)md5.latin1() );
03567 }
03568 return true;
03569 }
03570 }
03571
03572 if( !found )
03573 {
03574 #ifdef RIO_DEBUG2
03575 RioErr << "CASE 3: no entry on cache" << endl;
03576 #endif
03577
03578 char buffer[MD5SIZE];
03579 parent->setMD5Calculation( objectName, false );
03580 QString md5 = calculateMD5( objectName, buffer );
03581 parent->setMD5Calculation( objectName, true );
03582
03583 if( searchInfo.isDir() )
03584 {
03585 md5sum = NULL;
03586 QDomDocument doc( "document" );
03587 QDomElement newElement = doc.createElement( "dir" );
03588 newElement.setAttribute( "name", searchName );
03589 md5Cache.push_back( newElement );
03590
03591 return true;
03592 }
03593
03594 QDomDocument doc( "document" );
03595 QDomElement newElement = doc.createElement( "file" );
03596 newElement.setAttribute( "name", searchName );
03597 newElement.setAttribute( "md5sum", md5 );
03598 newElement.setAttribute( "size", stringSize );
03599 newElement.setAttribute( "date", stringDate );
03600 md5Cache.push_back( newElement );
03601
03602 strcpy( md5sum, (char *)md5.latin1() );
03603 return true;
03604 }
03605 }
03606
03607 else
03608 {
03609 #ifdef RIO_DEBUG2
03610 RioErr << "CASE 4: cache not used" << endl;
03611 #endif
03612
03613 if( searchInfo.isDir() )
03614 {
03615 md5sum = NULL;
03616 return true;
03617 }
03618 char buffer[MD5SIZE];
03619 parent->setMD5Calculation( objectName, false );
03620 QString md5 = calculateMD5( objectName, buffer );
03621 parent->setMD5Calculation( objectName, true );
03622 strcpy( md5sum, (char *)md5.latin1() );
03623 return true;
03624 }
03625 }
03626
03627 else
03628 {
03629 #ifdef RIO_DEBUG2
03630 RioErr << "CASE 5: not a local file" << endl;
03631 #endif
03632
03633 searchInfo.getMd5sum( md5sum );
03634 return true;
03635 }
03636
03637 md5sum = NULL;
03638 return false;
03639 }
03640
03641
03642
03643
03644
03645 bool RioMd5::updateCache()
03646 {
03647 #ifdef RIO_DEBUG1
03648 RioErr << "Entered updateCache" << endl;
03649 #endif
03650
03651 if( !parent->checkSession( md5Session ) )
03652 return false;
03653
03654 #ifdef RIO_DEBUG2
03655 if( !srcDirectory.isEmpty() )
03656 RioErr << "Updating cache for " << srcDirectory.latin1() << endl;
03657 #endif
03658
03659 if( !srcDirectory.isEmpty() )
03660 {
03661 ObjectInfo objInfo;
03662 vector<ObjectInfo> objectsInfo;
03663 vector<ObjectInfo>::iterator lsIterator;
03664 vector<QDomElement>::iterator cacheIterator;
03665 char md5Buffer[MD5SIZE];
03666 memset( md5Buffer, 0, sizeof( md5Buffer ) );
03667
03668 if( !parent->getObjectInfo( (char*)srcDirectory.latin1(), md5Session,
03669 &objInfo ) ||
03670 !parent->ls( &objInfo, &objectsInfo, md5Session, true, true )
03671 )
03672 {
03673 #ifdef RIO_DEBUG1
03674 RioErr << "Leaving updateCache [1]" << endl;
03675 #endif
03676 return false;
03677 }
03678
03679
03680
03681 for( lsIterator = objectsInfo.begin(); lsIterator != objectsInfo.end();
03682 lsIterator++ )
03683 {
03684 if( (char *)MD5CACHEFILE.latin1() != lsIterator->getName() )
03685 {
03686 QString fileName = srcDirectory + '/' +
03687 lsIterator->getFullName();
03688 getMd5Sum( (char *)fileName.latin1(), md5Buffer );
03689 }
03690 }
03691
03692 for( cacheIterator = md5Cache.begin();
03693 cacheIterator != md5Cache.end(); )
03694 {
03695 QString fileName = srcDirectory + '/' +
03696 cacheIterator->attribute( "name" );
03697 if( !parent->getObjectInfo( (char *)fileName.latin1(), md5Session,
03698 &objInfo ) )
03699 md5Cache.erase( cacheIterator );
03700 else
03701 cacheIterator++;
03702 }
03703 #ifdef RIO_DEBUG1
03704 RioErr << "Leaving updateCache [2]" << endl;
03705 #endif
03706 return true;
03707 }
03708 else
03709 {
03710 #ifdef RIO_DEBUG1
03711 RioErr << "Leaving updateCache [3]" << endl;
03712 #endif
03713 return true;
03714 }
03715 }
03716
03717
03718
03719
03720
03721 void RioMd5::copyCache( RioMd5 *srcMd5 )
03722 {
03723 if( !srcDirectory.isNull() )
03724 {
03725 md5Cache.clear();
03726
03727 vector<QDomElement>::iterator it;
03728 for( it = srcMd5->md5Cache.begin(); it != srcMd5->md5Cache.end(); it++ )
03729 {
03730 QDomElement newElement = it->cloneNode().toElement();
03731 md5Cache.push_back( newElement );
03732 }
03733 }
03734 }
03735
03736
03737
03738
03739
03740 bool RioMd5::importData( QString srcDirectory, CRioSession *srcSession )
03741 {
03742 #ifdef RIO_DEBUG2
03743 RioErr << "Importing MD5 data from the RIO Session" << endl;
03744 #endif
03745
03746 if( !srcDirectory.isNull() )
03747 {
03748 md5Cache.clear();
03749
03750 ObjectInfo dirInfo;
03751 vector<ObjectInfo> objInfo;
03752 vector<ObjectInfo> localObjInfo;
03753 vector<ObjectInfo>::iterator objIterator;
03754 vector<ObjectInfo>::iterator localObjIterator;
03755
03756 if( !parent->getObjectInfo( (char*)srcDirectory.latin1(), srcSession,
03757 &dirInfo, false ) )
03758 return false;
03759
03760 if( !parent->ls( &dirInfo, &objInfo, srcSession, true, true ) )
03761 return false;
03762
03763 if( !parent->getObjectInfo( this->srcDirectory.latin1(), md5Session,
03764 &dirInfo, false ) )
03765 return false;
03766
03767 if( !parent->ls( &dirInfo, &localObjInfo, md5Session, true, true ) )
03768 return false;
03769
03770 for( objIterator = objInfo.begin();
03771 objIterator != objInfo.end();
03772 objIterator++ )
03773 {
03774 char md5[MD5SIZE];
03775 QString relativePath;
03776 QString stringSize;
03777 QString stringDate;
03778 AccessTime date;
03779 RioObjectSize size;
03780
03781 if( objIterator->isDir() )
03782 {
03783 relativePath = objIterator->getFullName();
03784
03785 QDomDocument doc( "document" );
03786 QDomElement newElement = doc.createElement( "dir" );
03787 newElement.setAttribute( "name", relativePath );
03788 md5Cache.push_back( newElement );
03789 }
03790 else
03791 {
03792 relativePath = objIterator->getFullName();
03793
03794 size = objIterator->getSize();
03795 stringSize += QString::number( size );
03796
03797 objIterator->getMd5sum( md5 );
03798
03799
03800
03801
03802
03803
03804 for( localObjIterator = localObjInfo.begin();
03805 localObjIterator != localObjInfo.end();
03806 localObjIterator++ )
03807 if( localObjIterator->getFullName() == objIterator->getFullName() )
03808 break;
03809
03810 date = localObjIterator->getTime();
03811
03812
03813
03814
03815 stringDate += QString::number( date.Year ).rightJustify( 4, '0' );
03816 stringDate += QString::number( date.Month ).rightJustify( 2, '0' );
03817 stringDate += QString::number( date.Day ).rightJustify( 2, '0' );
03818 stringDate += QString::number( date.Hour ).rightJustify( 2, '0' );
03819 stringDate += QString::number( date.Minute ).rightJustify( 2, '0' );
03820
03821 QDomDocument doc( "document" );
03822 QDomElement newElement = doc.createElement( "file" );
03823 newElement.setAttribute( "name", relativePath );
03824 newElement.setAttribute( "md5sum", md5 );
03825 newElement.setAttribute( "size", stringSize );
03826 newElement.setAttribute( "date", stringDate );
03827 md5Cache.push_back( newElement );
03828 }
03829 }
03830 }
03831 return true;
03832 }
03833
03834
03835 char *RioMd5::calculateMD5( const char *filename, char *buf )
03836 {
03837 MD5_CTX state;
03838
03839
03840 unsigned int size = UINT_MAX;
03841 unsigned char digest[16];
03842 char hex[17] = "0123456789abcdef";
03843 char temp[100];
03844 char *m;
03845 int fd;
03846 int di = 0;
03847 int rc;
03848 struct stat st;
03849
03850 fd = open( filename, O_RDONLY );
03851 MD5_Init( &state );
03852
03853 if( fstat( fd, &st ) == -1 )
03854 {
03855 close( fd );
03856 if( buf )
03857 strcpy( buf, "0" );
03858 else
03859 buf = strdup( "0" );
03860 return buf;
03861 }
03862
03863 if( (unsigned int) st.st_size < size )
03864 size = st.st_size;
03865
03866 if( ( m = (char *) mmap(
03867 (void *) 0, size, PROT_READ, MAP_PRIVATE, fd, 0 ) ) != MAP_FAILED )
03868 {
03869 MD5_Update( &state, (unsigned char *) m, size );
03870 MD5_Final( digest, &state );
03871 munmap( m, size );
03872
03873 for ( di = 0, rc = 0; di < 16; ++di, rc += 2 )
03874 {
03875 temp[ rc ] = hex[ digest[di] >> 4 ];
03876 temp[ rc + 1 ] = hex[ digest[di] & 15 ];
03877 }
03878 temp[ 32 ] = 0;
03879 sprintf( temp, "%s", temp );
03880
03881 if( buf == NULL )
03882 buf = strdup( temp );
03883 else
03884 strcpy( buf, temp );
03885 }
03886 else
03887 {
03888 if( buf )
03889 strcpy( buf, "0" );
03890 else
03891 buf = strdup( "0" );
03892 return buf;
03893 }
03894 close( fd );
03895 return buf;
03896 }