00001 #include <arpa/inet.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <errno.h>
00006 #include <unistd.h>
00007 #include <sys/types.h>
00008 #include <sys/socket.h>
00009 #include <netinet/in.h>
00010 #include <sys/stat.h>
00011
00012
00013 #include "SearchLogs.h"
00014 #include "CommonLibraries.h"
00015 #include "RioInterfaceTypes.h"
00016 #include "RioError.h"
00017
00018
00019
00020 CSearchLogs::CSearchLogs()
00021 {
00022
00023 m_Initialized = false;
00024 m_LogRotation = NULL;
00025 m_NetMgr = NULL;
00026 m_LogsDirectory = NULL;
00027 m_SearchResultPrefix = NULL;
00028 m_BlockSize = 0;
00029 m_NetInterface = NULL;
00030 }
00031
00032
00033 CSearchLogs::~CSearchLogs()
00034 {
00035 }
00036
00037
00038 int CSearchLogs::Initialize( CLogRotation *MyLogRotation, NetMgr *MyNetMgr,
00039 const char *LogsDirectory,
00040 const char *SearchResultPrefix,
00041 unsigned int BlockSize,
00042 CNetInterface *NetInterface )
00043 {
00044
00045 if( m_Initialized )
00046 {
00047 #ifdef RIO_DEBUG2
00048 RioErr << "CSearchLogs::Initialize o objeto ja foi inicializado"
00049 << endl;
00050 #endif
00051 return ERROR_SEARCHLOGS + ERROR_INITIALIZED;
00052 }
00053 m_LogRotation = MyLogRotation;
00054 m_NetMgr = MyNetMgr;
00055 m_LogsDirectory = LogsDirectory;
00056 m_SearchResultPrefix = SearchResultPrefix;
00057 m_BlockSize = BlockSize;
00058 m_NetInterface = NetInterface;
00059 m_Initialized = true;
00060 return S_OK;
00061 }
00062
00063
00064
00065 bool CSearchLogs::GetSearchFileName( unsigned long long int SearchFileId,
00066 char *SearchFileName )
00067 {
00068
00069 bool status;
00070
00071
00072 char RandomName[ 11 ];
00073
00074 status = IdRandomName( SearchFileId, RandomName, 10 );
00075 if( status )
00076 {
00077 strcpy( SearchFileName, m_LogsDirectory );
00078 strcat( SearchFileName, SEARCHRESULTDIRECTORY );
00079 strcat( SearchFileName, m_SearchResultPrefix );
00080 strcat( SearchFileName, RandomName );
00081 }
00082 return status;
00083 }
00084
00085
00086 void CSearchLogs::SearchResutCallback( char *SearchFileName, time_t StartTime,
00087 time_t EndTime, int SearchResult,
00088 void *callbackparam )
00089 {
00090
00091 SearchCallbackData *ClientData;
00092
00093 struct stat FileInfo;
00094
00095
00096
00097
00098 char SearchInfo[ sizeof( int ) + sizeof( unsigned long long int ) ];
00099
00100
00101
00102 ClientData = ( SearchCallbackData * ) callbackparam;
00103
00104
00105 memset( ( void * ) SearchInfo, 0, sizeof( SearchInfo ) );
00106
00107
00108
00109 if( SearchResult == SEARCH_OK )
00110 {
00111
00112 if( lstat( SearchFileName, &FileInfo ) == 0 )
00113 {
00114
00115 memcpy( ( void * ) SearchInfo, ( void * ) &( FileInfo.st_size ),
00116 sizeof( int ) );
00117
00118 memcpy( ( void * ) &SearchInfo[ sizeof( int ) ],
00119 ( void * ) &( ClientData->ResultFileId ),
00120 sizeof( unsigned long long int ) );
00121 }
00122 else
00123 {
00124 remove( SearchFileName );
00125 }
00126 }
00127
00128 #ifdef RIO_DEBUG2
00129 in_addr ip;
00130 ip.s_addr = ClientData->ClientIP;
00131 RioErr << "CSearchLogs::SearchResutCallback Busca terminada para o cliente "
00132 << "com o IP " << inet_ntoa( ip ) << " e porta "
00133 << ntohs( ClientData->ClientPort ) << ": tempo inicial = "
00134 << StartTime << ", tempo final = " << EndTime << ", usando a id = "
00135 << ClientData->ReqId << ", a id do arquivo = "
00136 << ClientData->ResultFileId << ", e o nome de arquivo "
00137 << SearchFileName << endl;
00138
00139 RioErr << "CSearchLogs::ProcessSearchCmd SearchInfo = ";
00140 char Hex[ 3 ];
00141 for( unsigned int i = 0; i < sizeof( int ) + sizeof( unsigned long long int );
00142 i++ )
00143 {
00144 sprintf( Hex, "%02X", ( unsigned char ) SearchInfo[ i ] );
00145 RioErr << Hex << " ";
00146 }
00147 RioErr << ", sizeof( SearchInfo ) = " << sizeof( SearchInfo ) << endl;
00148 #endif
00149
00150
00151
00152 if( ( ClientData->SearchLogs->m_NetInterface != NULL ) &&
00153 ( ClientData->SearchLogs->m_NetInterface->FindIPAndPort(
00154 ClientData->ClientIP, ClientData->ClientPort ) ) )
00155 ClientData->SearchLogs->m_NetInterface->SendCmd( ClientData->ClientIP,
00156 ClientData->ClientPort,
00157 ClientData->ReqId, SearchInfo,
00158 sizeof( SearchInfo ),
00159 &SearchCmdCallback,
00160 ( void * ) ClientData );
00161 else
00162 ClientData->SearchLogs->m_NetMgr->SendCmd( ClientData->ClientIP,
00163 ClientData->ClientPort,
00164 ClientData->ReqId, SearchInfo,
00165 sizeof( SearchInfo ),
00166 &SearchCmdCallback,
00167 ( void * ) ClientData );
00168 }
00169
00170
00171
00172 void CSearchLogs::SearchCmdCallback( void *callbackparam, int result )
00173 {
00174
00175 SearchCallbackData *ClientData;
00176
00177
00178
00179 ClientData = ( SearchCallbackData * ) callbackparam;
00180
00181 #ifdef RIO_DEBUG2
00182 in_addr ip;
00183 ip.s_addr = ClientData->ClientIP;
00184 RioErr << "CSearchLogs::SearchCmdCallback Comando enviado para o cliente "
00185 << "com o IP " << inet_ntoa( ip ) << " e porta "
00186 << ntohs( ClientData->ClientPort ) << ", usando a id = "
00187 << ClientData->ReqId << ", e a id do arquivo = "
00188 << ClientData->ResultFileId << " terminou com o status "
00189 << result << endl;
00190 #endif
00191
00192 if( result == S_OK )
00193 {
00194 #ifdef RIO_DEBUG2
00195 RioErr << "CSearchLogs::SearchCmdCallback comando de uma solicitacao "
00196 << "de busca enviado com sucesso. Enviando a resposta ao "
00197 << "comando" << endl;
00198 #endif
00199
00200
00201 if( ( ClientData->SearchLogs->m_NetInterface != NULL ) &&
00202 ( ClientData->SearchLogs->m_NetInterface->FindIPAndPort(
00203 ClientData->ClientIP, ClientData->ClientPort ) ) )
00204 ClientData->SearchLogs->m_NetInterface->SendResult(
00205 ClientData->ClientIP,
00206 ClientData->ClientPort,
00207 ClientData->ReqId, S_OK );
00208 else
00209 ClientData->SearchLogs->m_NetMgr->SendResult( ClientData->ClientIP,
00210 ClientData->ClientPort,
00211 ClientData->ReqId, S_OK );
00212
00213 }
00214 else
00215 {
00216 #ifdef RIO_DEBUG2
00217 RioErr << "CSearchLogs::SearchCmdCallback erro " << result
00218 << " ao enviar o comando de uma solicitacao de busca." << endl;
00219 #endif
00220
00221
00222 delete ClientData;
00223 }
00224
00225 }
00226
00227
00228 void CSearchLogs::SearchCmdResultCallback( void *callbackparam, int result )
00229 {
00230
00231 SearchCallbackData *ClientData;
00232
00233
00234
00235 ClientData = ( SearchCallbackData * ) callbackparam;
00236
00237 #ifdef RIO_DEBUG2
00238 in_addr ip;
00239 ip.s_addr = ClientData->ClientIP;
00240 RioErr << "CSearchLogs::SearchCmdCallback Resposta enviada para o cliente "
00241 << "com o IP "<< inet_ntoa( ip ) << " e porta "
00242 << ntohs( ClientData->ClientPort ) << ", usando a id = "
00243 << ClientData->ReqId << ", e a id do arquivo = "
00244 << ClientData->ResultFileId << " terminou com o status "
00245 << result << endl;
00246
00247 if( result != S_OK )
00248 RioErr << "CSearchLogs::SearchCmdResultCallback erro " << result
00249 << " ao enviar a resposta de um comando de uma solicitacao de "
00250 << "busca." << endl;
00251 #endif
00252
00253
00254 delete ClientData;
00255
00256 }
00257
00258
00259
00260 void CSearchLogs::SearchBlockCallback( void *callbackparam, int result )
00261 {
00262
00263 char *BlockBuffer;
00264
00265 #ifdef RIO_DEBUG2
00266 if( result != S_OK )
00267 RioErr << "CSearchLogs::SearchBlockCallback erro " << result
00268 << " ao enviar um bloco do arquivo de busca ao cliente" << endl;
00269 else
00270 RioErr << "CSearchLogs::SearchBlockCallback bloco do arquivo de busca "
00271 << "enviado com sucesso ao cliente" << endl;
00272 #endif
00273
00274
00275
00276 BlockBuffer = ( char * ) callbackparam;
00277
00278
00279 delete[] BlockBuffer;
00280 }
00281
00282
00283
00284 int CSearchLogs::SearchLogsRequest( time_t StartTime, time_t EndTime,
00285 u32 ClientIPAddr, u16 ClientPort,
00286 u32 ReqId )
00287 {
00288
00289 char SearchResultFileName[ MaxPathSize ];
00290
00291 SearchCallbackData *SearchData;
00292
00293
00294 if( !m_Initialized )
00295 {
00296 #ifdef RIO_DEBUG2
00297 RioErr << "CSearchLogs::SearchLogsRequest o objeto nao foi "
00298 << "inicializado" << endl;
00299 #endif
00300 return ERROR_SEARCHLOGS + ERROR_NOT_INITIALIZED;
00301 }
00302
00303
00304 if( ( StartTime < 0 ) || ( EndTime < 0 ) || ( EndTime < StartTime ) )
00305 return ERROR_SEARCHLOGS + ERROR_SEARCHLOGS_TIME_INTERVAL;
00306
00307
00308
00309 SearchData = new SearchCallbackData;
00310 if( SearchData == NULL )
00311 return ERROR_SEARCHLOGS + ERROR_MEMORY;
00312
00313
00314
00315 SearchData->SearchLogs = this;
00316 SearchData->ClientIP = ClientIPAddr;
00317 SearchData->ClientPort = ClientPort;
00318 SearchData->ReqId = ReqId;
00319
00320
00321
00322
00323 strcpy( SearchResultFileName, m_LogsDirectory );
00324 strcat( SearchResultFileName, SEARCHRESULTDIRECTORY );
00325 strcat( SearchResultFileName, m_SearchResultPrefix );
00326 strcat( SearchResultFileName, "XXXXXXXXXX" );
00327
00328
00329 if( !RIOmktempAndID( SearchResultFileName, &SearchData->ResultFileId ) )
00330 {
00331
00332
00333 return ERROR_SEARCHLOGS + ERROR_CREATE_SEARCHRESULT_FILENAME;
00334 }
00335
00336
00337 if( m_LogRotation->SearchLogFiles( SearchResultFileName, StartTime, EndTime,
00338 &SearchResutCallback,
00339 ( void * ) SearchData ) != S_OK )
00340 return ERROR_SEARCHLOGS + ERROR_LOGROTATION_SEARCH_FAILED;
00341 else
00342 {
00343 #ifdef RIO_DEBUG2
00344 in_addr ip;
00345 ip.s_addr = ClientIPAddr;
00346 RioErr << "CSearchLogs::SearchLogsRequest Busca inicializada para o "
00347 << "cliente com o IP " << inet_ntoa( ip ) << " e porta "
00348 << ntohs( ClientPort ) << ": tempo inicial = "
00349 << StartTime << ", tempo final = " << EndTime
00350 << ", usando a id = " << ReqId << endl;
00351 #endif
00352
00353 return S_OK;
00354 }
00355 }
00356
00357
00358
00359 int CSearchLogs::SearchResultDataRequest( u32 ClientIPAddr, u16 ClientPort,
00360 u64 ResultFileId, u32 Block,
00361 u32 ReqId )
00362 {
00363
00364 char SearchResultFileName[ MaxPathSize ];
00365
00366 unsigned int TotalBlocks;
00367
00368
00369 unsigned int ReadSize;
00370
00371 struct stat FileInfo;
00372
00373 char *BlockBuffer;
00374
00375
00376 FILE *ResultFile;
00377
00378
00379 if( !m_Initialized )
00380 {
00381 #ifdef RIO_DEBUG2
00382 RioErr << "CSearchLogs::SearchResultDataRequest o objeto nao foi "
00383 << "inicializado" << endl;
00384 #endif
00385 return ERROR_SEARCHLOGS + ERROR_NOT_INITIALIZED;
00386 }
00387
00388 #ifdef RIO_DEBUG2
00389 in_addr ip;
00390 ip.s_addr = ClientIPAddr;
00391 RioErr << "CSearchLogs::SearchResultDataRequest Pedido do bloco " << Block
00392 << " do arquivo com o identificador " << ResultFileId
00393 << " a partir do cliente com o IP " << inet_ntoa( ip )
00394 << " e porta " << ntohs( ClientPort ) << ", usando a id "
00395 << ReqId << endl;
00396 #endif
00397
00398 BlockBuffer = new char[ m_BlockSize ];
00399 if( BlockBuffer == NULL )
00400 return ERROR_SEARCHLOGS + ERROR_MEMORY;
00401
00402
00403 if( !GetSearchFileName( ResultFileId, SearchResultFileName ) )
00404 {
00405 delete [] BlockBuffer;
00406 return ERROR_SEARCHLOGS + ERROR_INVALID_SEARCHRESULT_IDENTIFICATION;
00407 }
00408
00409 #ifdef RIO_DEBUG2
00410 RioErr << "CSearchLogs::SearchResultDataRequest Arquivo com o nome "
00411 << SearchResultFileName << " esta associado ao identificador "
00412 << ResultFileId << endl;
00413 #endif
00414
00415
00416 if( lstat( SearchResultFileName, &FileInfo ) < 0 )
00417 {
00418 delete [] BlockBuffer;
00419 return ERROR_SEARCHLOGS + ERROR_OPEN_SEARCHRESULT_FILE;
00420 }
00421
00422
00423 TotalBlocks = ( FileInfo.st_size + m_BlockSize - 1 ) / m_BlockSize;
00424 #ifdef RIO_DEBUG2
00425 RioErr << "CSearchLogs::SearchResultDataRequest tamanho do arquivo de "
00426 << "busca " << FileInfo.st_size << " bytes (ou " << TotalBlocks
00427 << " blocos)" << endl;
00428 #endif
00429
00430
00431 if( Block >= TotalBlocks )
00432 {
00433 delete [] BlockBuffer;
00434 return ERROR_SEARCHLOGS + ERROR_INVALID_BLOCK;
00435 }
00436
00437
00438 ResultFile = fopen( SearchResultFileName, "r" );
00439 if( ResultFile == NULL )
00440 {
00441 delete [] BlockBuffer;
00442 return ERROR_SEARCHLOGS + ERROR_OPEN_SEARCHRESULT_FILE;
00443 }
00444
00445
00446
00447 if( fseek( ResultFile, Block * m_BlockSize, SEEK_SET ) )
00448 {
00449 fclose( ResultFile );
00450 delete [] BlockBuffer;
00451 return ERROR_SEARCHLOGS + ERROR_READ_SEARCHRESULT_FILE;
00452 }
00453
00454 if( Block < TotalBlocks - 1 )
00455 ReadSize = m_BlockSize;
00456 else
00457 ReadSize = FileInfo.st_size - m_BlockSize * ( TotalBlocks - 1 );
00458
00459
00460 memset( BlockBuffer, 0, sizeof( BlockBuffer ) );
00461
00462
00463 if( fread( BlockBuffer, sizeof( char ), ReadSize, ResultFile ) !=
00464 ReadSize )
00465 {
00466 fclose( ResultFile );
00467 delete [] BlockBuffer;
00468 return ERROR_SEARCHLOGS + ERROR_READ_SEARCHRESULT_FILE;
00469 }
00470
00471
00472 fclose( ResultFile );
00473
00474
00475
00476
00477 if( ( m_NetInterface != NULL ) &&
00478 ( m_NetInterface->FindIPAndPort( ClientIPAddr, ClientPort ) ) )
00479 m_NetInterface->SendBlock( ClientIPAddr, ClientPort, ReqId, BlockBuffer,
00480 m_BlockSize, &SearchBlockCallback,
00481 ( void * ) BlockBuffer );
00482 else
00483 m_NetMgr->SendBlock( ClientIPAddr, ClientPort, ReqId, BlockBuffer,
00484 m_BlockSize, &SearchBlockCallback,
00485 ( void * ) BlockBuffer, RIO_TRAFFIC_NRT );
00486
00487 return S_OK;
00488
00489 }
00490
00491
00492
00493 int CSearchLogs::RemoveSearchResultFile( u64 ResultFileId )
00494 {
00495
00496
00497 char SearchResultFileName[ MaxPathSize ];
00498
00499
00500 if( !m_Initialized )
00501 {
00502 #ifdef RIO_DEBUG2
00503 RioErr << "CSearchLogs::RemoveSearchResultFile o objeto nao foi "
00504 << "inicializado" << endl;
00505 #endif
00506 return ERROR_SEARCHLOGS + ERROR_NOT_INITIALIZED;
00507 }
00508
00509 #ifdef RIO_DEBUG2
00510 RioErr << "CSearchLogs::RemoveSearchResultFile Pedido de remocao do "
00511 << " do arquivo com o identificador " << ResultFileId << endl;
00512 #endif
00513
00514 if( GetSearchFileName( ResultFileId, SearchResultFileName ) )
00515 {
00516 #ifdef RIO_DEBUG2
00517 RioErr << "CSearchLogs::RemoveSearchResultFile Removendo o arquivo "
00518 << SearchResultFileName << " associado ao identificador "
00519 << ResultFileId << endl;
00520 #endif
00521 if( remove( SearchResultFileName ) < 0 )
00522 {
00523 #ifdef RIO_DEBUG2
00524 RioErr << "CSearchLogs::RemoveSearchResultFile Nao consegui "
00525 << "remover o arquivo "<< SearchResultFileName
00526 << ": " << errno << "(" << strerror( errno ) << ")"
00527 << endl;
00528 #endif
00529 return ERROR_SEARCHLOGS + ERROR_REMOVE_SEARCHRESULT_FILE;
00530 }
00531 else
00532 return S_OK;
00533 }
00534 else
00535 return ERROR_SEARCHLOGS + ERROR_INVALID_SEARCHRESULT_IDENTIFICATION;
00536 }
00537
00538
00539
00540 void CSearchLogs::SearchLogsRequestSendError( time_t StartTime, time_t EndTime,
00541 u32 ClientIPAddr, u16 ClientPort,
00542 u32 ReqId )
00543 {
00544 int Status;
00545
00546 Status = SearchLogsRequest( StartTime, EndTime, ClientIPAddr, ClientPort,
00547 ReqId );
00548 if( Status != S_OK )
00549 {
00550 #ifdef RIO_DEBUG2
00551 RioErr << "SearchLogsRequestSendError ocorreu um erro ao executar a "
00552 << "funcao SearchLogsRequest. Enviando o codigo de erro usando "
00553 << "um comando especial a partir da funcao SendCmd da classe "
00554 << "NetMgr" << endl;
00555 #endif
00556 if( ( m_NetInterface != NULL ) &&
00557 ( m_NetInterface->FindIPAndPort( ClientIPAddr, ClientPort ) ) )
00558 m_NetInterface->SendRst( ClientIPAddr, ClientPort, ReqId, Status );
00559 else
00560 m_NetMgr->SendRst( ClientIPAddr, ClientPort, ReqId, Status );
00561 }
00562 }
00563
00564
00565
00566 void CSearchLogs::SearchResultDataRequestSendError( u32 ClientIPAddr,
00567 u16 ClientPort,
00568 u64 ResultFileId, u32 Block,
00569 u32 ReqId )
00570 {
00571 int Status;
00572
00573 Status = SearchResultDataRequest( ClientIPAddr, ClientPort, ResultFileId,
00574 Block, ReqId );
00575 if( Status != S_OK )
00576 {
00577 #ifdef RIO_DEBUG2
00578 RioErr << "SearchResultDataRequestSendError ocorreu um erro ao "
00579 << "executar a funcao SearchResultDataRequest. Enviando o "
00580 << "codigo de erro usando a funcao SendRst da classe NetMgr"
00581 << endl;
00582 #endif
00583 if( ( m_NetInterface != NULL ) &&
00584 ( m_NetInterface->FindIPAndPort( ClientIPAddr, ClientPort ) ) )
00585 m_NetInterface->SendRst( ClientIPAddr, ClientPort, ReqId, Status );
00586 else
00587 m_NetMgr->SendRst( ClientIPAddr, ClientPort, ReqId, Status );
00588 }
00589 }