00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "RioApacheModule.h"
00020 #include "RioModuleTypes.h"
00021 #include "RioModule.h"
00022 #include "RioServersFile.h"
00023 #include "RioError.h"
00024 #include "UserLogs.h"
00025 #include "ServerInterface.h"
00026
00027
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <errno.h>
00032 #include <execinfo.h>
00033 #include <pwd.h>
00034 #include <unistd.h>
00035
00036
00037 #include <apr_strings.h>
00038 #include <ap_compat.h>
00039 #include <http_request.h>
00040 #include <apr_shm.h>
00041
00042
00043 #include <sys/syscall.h>
00044
00045
00046
00047
00048 void show_stackframe()
00049 {
00050 void *trace[16];
00051 char **messages = (char **)NULL;
00052 int i, trace_size = 0;
00053
00054 trace_size = backtrace( trace, 16 );
00055 messages = backtrace_symbols( trace, trace_size );
00056 RioErr << "[bt] Execution path:" << endl;
00057 for( i = 0; i < trace_size; ++i )
00058 RioErr << "[bt(" << i << "/" << trace_size << ")] " << messages[i]
00059 << endl;
00060 }
00061
00062 void SignalHandler( int sig )
00063 {
00064 if( sig == SIGILL )
00065 RioErr << "[RioApacheModule] ILLEGAL INSTRUCTION!. Thread id = "
00066 << syscall( SYS_gettid ) << endl;
00067 else
00068 RioErr << "[RioApacheModule] SEGMENTATION FAULT!. Thread id = "
00069 << syscall( SYS_gettid ) << endl;
00070
00071 show_stackframe();
00072
00073 _exit( 1 );
00074 }
00075
00076 #ifdef RIO_DEBUG2
00077
00078 int PrintHeadersIn( void *req, const char *key, const char *value )
00079 {
00080 request_rec *r = ( request_rec * ) req;
00081
00082 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, " %s: %s", key, value );
00083
00084 return 1;
00085 }
00086 #endif
00087
00088
00089
00090
00091
00092
00093 apr_status_t ProcessParams( request_rec *Request, apr_table_t** ParamTable )
00094 {
00095
00096
00097
00098 char *ParamList;
00099
00100 char *NextParam;
00101
00102
00103 char *StartParamValue;
00104
00105 char *AprStrTokVar;
00106
00107
00108 *ParamTable = NULL;
00109
00110
00111 if( Request->args == NULL )
00112 {
00113 #ifdef RIO_DEBUG2
00114 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00115 "Warning: Request does not have arguments." );
00116 #endif
00117 return APR_SUCCESS;
00118 }
00119
00120
00121 *ParamTable = apr_table_make( Request->pool, 0 );
00122 if( *ParamTable == NULL )
00123 {
00124 #ifdef RIO_DEBUG2
00125 ap_log_rerror( APLOG_MARK, APLOG_ERR, APR_ENOMEM, Request,
00126 "Insufficient memory to allocate param table" );
00127 #endif
00128 return APR_ENOMEM;
00129 }
00130
00131
00132 ParamList = apr_pstrdup( Request->pool, Request->args );
00133 if( ParamList == NULL )
00134 {
00135 #ifdef RIO_DEBUG2
00136 ap_log_rerror( APLOG_MARK, APLOG_ERR, APR_ENOMEM, Request,
00137 "Insufficient memory to duplicate args string" );
00138 #endif
00139 return APR_ENOMEM;
00140 }
00141
00142 #ifdef RIO_DEBUG2
00143 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00144 "Original ParamList string: %s", ParamList );
00145 #endif
00146
00147
00148 if( ap_unescape_url( ParamList ) != 0 )
00149 {
00150 #ifdef RIO_DEBUG2
00151 ap_log_rerror( APLOG_MARK, APLOG_ERR, APR_ENOMEM, Request,
00152 "Error converting ParamList string" );
00153 #endif
00154 return APR_EGENERAL;
00155 }
00156
00157 #ifdef RIO_DEBUG2
00158 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00159 "Converted ParamList string: %s!", ParamList );
00160 #endif
00161
00162
00163
00164 NextParam = apr_strtok( ParamList, "&?", &AprStrTokVar );
00165 while( NextParam != NULL )
00166 {
00167
00168
00169 StartParamValue = strchr( NextParam, '=' );
00170 if( StartParamValue == NULL )
00171 {
00172 #ifdef RIO_DEBUG2
00173 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00174 "Warning: invalid param %s", NextParam );
00175 #endif
00176 }
00177 else
00178 {
00179
00180
00181 *StartParamValue = 0;
00182 StartParamValue++;
00183 #ifdef RIO_DEBUG2
00184 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00185 "Found a param with name %s and with value %s",
00186 NextParam, StartParamValue );
00187 #endif
00188
00189 apr_table_add( *ParamTable, NextParam, StartParamValue );
00190
00191 }
00192
00193 NextParam = apr_strtok( NULL, "&?", &AprStrTokVar );
00194 }
00195
00196 return APR_SUCCESS;
00197 }
00198
00199
00200
00201 apr_status_t SendError( request_rec *Request, apr_status_t ApacheError,
00202 int SystemError, RioResult RioError )
00203 {
00204 char ApacheStrError[ MAXAPACHESTRERRORSIZE ];
00205
00206
00207 apr_strerror( ApacheError, ApacheStrError, MAXAPACHESTRERRORSIZE );
00208
00209 #ifdef RIO_DEBUG2
00210 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00211 "Errors when processing request: ApacheError = %u (%s), "
00212 "SystemError = %u (%s), RioError = %08X (%s)", ApacheError,
00213 ApacheStrError, SystemError, strerror( SystemError ),
00214 RioError, GetErrorDescription( RioError ).c_str() );
00215 #endif
00216
00217 if( ( ApacheError != APR_SUCCESS ) || ( SystemError != 0 ) ||
00218 ( RioError != S_OK ) )
00219 {
00220 #ifdef RIO_DEBUG2
00221 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00222 "Sending these errors to the client" );
00223 #endif
00224
00225 ap_set_content_type( Request, RIOMODULE_MIME_ERROR );
00226 apr_table_set( Request->headers_out, RIOMODULE_HTTP_FILENAME,
00227 "inline; filename=error.html" );
00228
00229 ap_rprintf( Request, "<HTML>\n");
00230 ap_rprintf( Request,
00231 "<HEAD><TITLE>RioApacheModule Error report</TITLE></HEAD>\n" );
00232 ap_rprintf( Request, "<BODY>\n");
00233 if( ApacheError != APR_SUCCESS )
00234 ap_rprintf( Request, "<B>Apache Error:</B> %u (%s)<BR>\n", ApacheError,
00235 ApacheStrError );
00236 if( SystemError != 0 )
00237 ap_rprintf( Request, "<B>System Error:</B> %u (%s)<BR>\n", SystemError,
00238 strerror( SystemError ) );
00239 if( RioError != S_OK )
00240 ap_rprintf( Request, "<B>Rio Error:</B> %8X (%s)<BR>\n", RioError,
00241 GetErrorDescription( RioError ).c_str() );
00242 ap_rprintf( Request, "</BODY>\n");
00243 ap_rprintf( Request, "</HTML>\n");
00244 }
00245
00246 return APR_SUCCESS;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 bool ProcessServersFile( request_rec *Request, RioModuleConfig *Config,
00262 ServerSelectionType SelectionType, char **ServerName,
00263 apr_status_t *ApacheError, int *SystemError,
00264 RioResult *RioError )
00265 {
00266
00267 RioServerInfo ServerInfo;
00268
00269 CRioServersFile *ServersFile;
00270
00271
00272
00273 apr_status_t ApacheStatus = APR_SUCCESS;
00274 int SystemStatus = 0;
00275 RioResult RioStatus = S_OK;
00276
00277
00278 *ServerName = NULL;
00279
00280
00281 ServersFile = new CRioServersFile( Request, Config->LineSize );
00282 if( ServersFile == NULL )
00283 {
00284 *SystemError = ENOMEM;
00285
00286 #ifdef RIO_DEBUG2
00287 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00288 "Cannot create servers file object: SystemError %u (%s)",
00289 *SystemError, strerror( *SystemError ) );
00290 #endif
00291
00292 return false;
00293 }
00294
00295
00296 if( !ServersFile->Open( Config->ServersFileName ) )
00297 {
00298
00299 ServersFile->GetErrors( &ApacheStatus, &SystemStatus, &RioStatus );
00300
00301 #ifdef RIO_DEBUG2
00302 ap_log_rerror( APLOG_MARK, APLOG_ERR, ApacheStatus, Request,
00303 "Errors when processing %s servers file:"
00304 "ApacheError = %u, SystemError = %u (%s) "
00305 "RioError = %u (%s)", Config->ServersFileName,
00306 ApacheStatus, SystemStatus, strerror( SystemStatus ),
00307 RioStatus, GetErrorDescription( RioStatus ).c_str()
00308 );
00309 #endif
00310
00311
00312 if( ApacheStatus != APR_SUCCESS )
00313 *ApacheError = ApacheStatus;
00314 if( SystemStatus != 0 )
00315 *SystemError = SystemStatus;
00316 if( RioStatus != S_OK )
00317 *RioError = RioStatus;
00318
00319
00320 delete ServersFile;
00321
00322 return false;
00323 }
00324
00325
00326 if( !ServersFile->ChooseServer( SelectionType, &ServerInfo ) )
00327 {
00328
00329 ServersFile->GetErrors( &ApacheStatus, &SystemStatus, &RioStatus );
00330
00331 #ifdef RIO_DEBUG2
00332 ap_log_rerror( APLOG_MARK, APLOG_ERR, ApacheStatus, Request,
00333 "Error choosing best server of file %s: "
00334 "ApacheError = %u, SystemError = %u (%s) "
00335 "RioError = %u (%s)", Config->ServersFileName,
00336 ApacheStatus, SystemStatus, strerror( SystemStatus ),
00337 RioStatus, GetErrorDescription( RioStatus ).c_str() );
00338 #endif
00339
00340
00341 if( ApacheStatus != APR_SUCCESS )
00342 *ApacheError = ApacheStatus;
00343 if( SystemStatus != 0 )
00344 *SystemError = SystemStatus;
00345 if( RioStatus != S_OK )
00346 *RioError = RioStatus;
00347
00348
00349 delete ServersFile;
00350
00351 return false;
00352 }
00353
00354 #ifdef RIO_DEBUG2
00355 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00356 "Best Server: ServerName = %s, MaxSessions = %f, "
00357 "MaxAverage = %f", ServerInfo.ServerName,
00358 ServerInfo.MaxSessions, ServerInfo.MaxAverage );
00359 #endif
00360
00361
00362 if( ServerInfo.ServerName == NULL )
00363 {
00364 *RioError = ERROR_RIOMODULE + ERROR_SERVER_NOT_DEFINED;
00365 #ifdef RIO_DEBUG2
00366 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00367 "Error choosing best server of file %s: "
00368 "RioError = %u (%s)", Config->ServersFileName, RioStatus,
00369 GetErrorDescription( RioStatus ).c_str() );
00370 #endif
00371
00372
00373 delete ServersFile;
00374
00375 return false;
00376 }
00377
00378
00379
00380 *ServerName = apr_pstrdup( Request->pool, ServerInfo.ServerName );
00381 if( *ServerName == NULL )
00382 {
00383 *SystemError = ENOMEM;
00384
00385 #ifdef RIO_DEBUG2
00386 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00387 "Error copying ServerName %s of file %s: "
00388 "SystemError = %u (%s)", ServerInfo.ServerName,
00389 Config->ServersFileName, *SystemError,
00390 strerror( *SystemError ) );
00391 #endif
00392
00393
00394 delete ServersFile;
00395
00396 return false;
00397 }
00398
00399
00400 delete ServersFile;
00401
00402 return true;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 bool TransferRioFile( request_rec *Request, RioModuleConfig *Config,
00412 char *ServerName, const char *FileName, RioAccess Access,
00413 RioObjectSize StartPosition, RioObjectSize EndPosition,
00414 bool SendHeader, apr_status_t *ApacheError,
00415 int *SystemError, RioResult *RioError )
00416 {
00417
00418
00419
00420 const char *FileExtensionPos;
00421
00422 const char *FileNamePos;
00423
00424 char *HttpFileNameContents;
00425
00426 CRioModule *Rio;
00427
00428
00429 bool HasNextBlock;
00430
00431
00432 bool UseRealTime;
00433
00434 unsigned int BlockSize;
00435
00436
00437 RioObjectSize FileSize;
00438
00439
00440 unsigned int TotalBlocks;
00441
00442
00443 char *StrValue;
00444
00445
00446
00447 apr_status_t ApacheStatus = APR_SUCCESS;
00448 int SystemStatus = 0;
00449 RioResult RioStatus = S_OK;
00450
00451 bool NoError;
00452
00453 request_rec *SubRequest;
00454
00455
00456
00457 if( Config->RealTimeExtensions != NULL )
00458 {
00459
00460
00461 FileExtensionPos = strrchr( FileName, '.' );
00462 if( FileExtensionPos == NULL )
00463 UseRealTime = false;
00464 else
00465 UseRealTime = ( strstr( Config->RealTimeExtensions,
00466 ++FileExtensionPos ) != NULL );
00467 }
00468 else
00469
00470 UseRealTime = false;
00471
00472
00473
00474
00475 Rio = new CRioModule( Request );
00476 if( Rio == NULL )
00477 {
00478 *SystemError = ENOMEM;
00479
00480 #ifdef RIO_DEBUG2
00481 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00482 "Insufficient memory to create the object module: "
00483 "SystemError = %u (%s)", *SystemError,
00484 strerror( *SystemError ) );
00485 #endif
00486
00487 return false;
00488 }
00489
00490 #ifdef RIO_DEBUG2
00491 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00492 "Configuracao para a copia: FileName = %s, ServerName = %s, "
00493 "WaitTime = %u ms, UseRealTime = %s, User = %s,"
00494 "Password = %s", FileName, ServerName, Config->WaitTime,
00495 ( UseRealTime ) ? "on" : "off", Config->User,
00496 Config->Password );
00497 #endif
00498
00499
00500
00501 apr_table_set( Request->headers_out, RIOMODULE_HTTP_RIOSERVERNAME,
00502 ServerName );
00503
00504
00505
00506 apr_table_set( Request->headers_out, RIOMODULE_HTTP_RIOOBJECTNAME,
00507 FileName );
00508
00509
00510 NoError = true;
00511
00512
00513 if( Rio->NoError() )
00514 {
00515
00516 if( Rio->Start( ServerName, Config->User, Config->Password,
00517 Config->BufferSize, Config->FragmentSize,
00518 &BlockSize ) )
00519 {
00520
00521
00522 FileNamePos = strrchr( FileName, '/' );
00523 if( FileNamePos == NULL )
00524 FileNamePos = FileName;
00525 else
00526 FileNamePos++;
00527
00528
00529
00530
00531 #ifdef RIO_DEBUG2
00532 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00533 "Creating subrequest for file %s", FileNamePos );
00534 #endif
00535
00536 SubRequest = ap_sub_req_lookup_uri( FileNamePos, Request, NULL );
00537 if( SubRequest == NULL )
00538 {
00539 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00540 "Error creating subrequest. Using default "
00541 "type %s", RIOMODULE_MIME );
00542 ap_set_content_type( Request, RIOMODULE_MIME );
00543 }
00544 else
00545 {
00546 #ifdef RIO_DEBUG2
00547 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00548 "Subrequest content-type: %s",
00549 SubRequest->content_type );
00550 #endif
00551
00552
00553
00554 if( SubRequest->content_type != NULL )
00555 ap_set_content_type( Request, SubRequest->content_type );
00556 else
00557 ap_set_content_type( Request, RIOMODULE_MIME );
00558
00559
00560
00561 ap_destroy_sub_req( SubRequest );
00562 }
00563
00564
00565 HttpFileNameContents = apr_psprintf( Request->pool,
00566 "inline; filename=%s",
00567 FileNamePos );
00568 if( HttpFileNameContents == NULL )
00569 {
00570 #ifdef RIO_DEBUG2
00571 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00572 "Memory error when creating FileName string" );
00573 #endif
00574 }
00575 else
00576 apr_table_set( Request->headers_out, RIOMODULE_HTTP_FILENAME,
00577 HttpFileNameContents );
00578
00579
00580
00581 StrValue = apr_psprintf( Request->pool, "%u", BlockSize );
00582 if( StrValue == NULL )
00583 {
00584 #ifdef RIO_DEBUG2
00585 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00586 "Memory error when creating BlockSize string" );
00587 #endif
00588 }
00589 else
00590 apr_table_set( Request->headers_out,
00591 RIOMODULE_HTTP_RIOBLOCKSIZE, StrValue );
00592
00593
00594 if( Rio->Open( FileName, Access, UseRealTime, Config->WaitTime,
00595 StartPosition, EndPosition, SendHeader, &FileSize,
00596 &TotalBlocks ) )
00597 {
00598
00599
00600 StrValue = apr_psprintf( Request->pool, "%lld", FileSize );
00601 if( StrValue == NULL )
00602 {
00603 #ifdef RIO_DEBUG2
00604 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00605 "Memory error when creating FileSize string"
00606 );
00607 #endif
00608 }
00609 else
00610 apr_table_set( Request->headers_out,
00611 RIOMODULE_HTTP_RIOOBJECTSIZE, StrValue );
00612
00613
00614
00615 StrValue = apr_psprintf( Request->pool, "%u", TotalBlocks );
00616 if( StrValue == NULL )
00617 {
00618 #ifdef RIO_DEBUG2
00619 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00620 "Memory error when creating TotalBlocks string"
00621 );
00622 #endif
00623 }
00624 else
00625 apr_table_set( Request->headers_out,
00626 RIOMODULE_HTTP_RIOOBJECTTOTALBLOCKS,
00627 StrValue );
00628
00629
00630
00631
00632 StrValue = apr_psprintf( Request->pool, "%lld", StartPosition );
00633 if( StrValue == NULL )
00634 {
00635 #ifdef RIO_DEBUG2
00636 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00637 "Memory error when creating StartPosition string"
00638 );
00639 #endif
00640 }
00641 else
00642 apr_table_set( Request->headers_out,
00643 RIOMODULE_HTTP_RIOOBJECTSTARTPOSITION,
00644 StrValue );
00645
00646
00647
00648 StrValue = apr_psprintf( Request->pool, "%lld", EndPosition );
00649 if( StrValue == NULL )
00650 {
00651 #ifdef RIO_DEBUG2
00652 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00653 "Memory error when creating EndPosition string"
00654 );
00655 #endif
00656 }
00657 else
00658 apr_table_set( Request->headers_out,
00659 RIOMODULE_HTTP_RIOOBJECTENDPOSITION,
00660 StrValue );
00661
00662
00663
00664
00665 StrValue = apr_psprintf( Request->pool, "%s",
00666 ( SendHeader ) ? "on": "off" );
00667 if( StrValue == NULL )
00668 {
00669 #ifdef RIO_DEBUG2
00670 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00671 "Memory error when creating SendHeader string"
00672 );
00673 #endif
00674 }
00675 else
00676 apr_table_set( Request->headers_out,
00677 RIOMODULE_HTTP_RIOOBJECTSENDHEADER,
00678 StrValue );
00679
00680
00681
00682 StrValue = apr_psprintf( Request->pool, "%s",
00683 ( UseRealTime ) ? "on": "off" );
00684 if( StrValue == NULL )
00685 {
00686 #ifdef RIO_DEBUG2
00687 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00688 "Memory error when creating UseRealTime string"
00689 );
00690 #endif
00691 }
00692 else
00693 apr_table_set( Request->headers_out,
00694 RIOMODULE_HTTP_RIOOBJECTUSEREALTIME,
00695 StrValue );
00696
00697
00698
00699 do
00700 {
00701
00702 NoError = Rio->ProcessNextBlock( &HasNextBlock );
00703
00704 } while( NoError && ( HasNextBlock ) );
00705
00706 #ifdef RIO_DEBUG2
00707 if( !NoError )
00708 {
00709 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00710 "Error copying file %s", FileName );
00711 }
00712 #endif
00713
00714
00715 if ( !Rio->Close() )
00716 {
00717 #ifdef RIO_DEBUG2
00718 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00719 "Error closing file %s", FileName );
00720 #endif
00721 }
00722
00723
00724 if( !Rio->Stop() )
00725 {
00726 #ifdef RIO_DEBUG2
00727 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00728 "Error closing session with server %s",
00729 ServerName );
00730 #endif
00731 }
00732
00733 }
00734 else
00735 {
00736 NoError = false;
00737
00738 #ifdef RIO_DEBUG2
00739 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00740 "Error opening file %s", FileName );
00741 #endif
00742 }
00743 }
00744 else
00745 {
00746 NoError = false;
00747
00748 #ifdef RIO_DEBUG2
00749 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00750 "Error opening session with server %s",
00751 ServerName );
00752 #endif
00753 }
00754 }
00755 else
00756 {
00757 NoError = false;
00758
00759 #ifdef RIO_DEBUG2
00760 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00761 "Error inicializing object of the server %s",
00762 ServerName );
00763 #endif
00764 }
00765
00766
00767 if( !NoError )
00768 {
00769 Rio->GetErrors( &ApacheStatus, &SystemStatus, &RioStatus );
00770
00771 #ifdef RIO_DEBUG2
00772 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00773 "Errors when transfering file %s using server %s: "
00774 "ApacheError = %u, SystemError = %u (%s), "
00775 "RioError = %08X (%s)", FileName, ServerName,
00776 ApacheStatus, SystemStatus, strerror( SystemStatus ),
00777 RioStatus, GetErrorDescription( RioStatus ).c_str() );
00778 #endif
00779
00780
00781 if( ApacheStatus != APR_SUCCESS )
00782 *ApacheError = ApacheStatus;
00783 if( SystemStatus != 0 )
00784 *SystemError = SystemStatus;
00785 if( RioStatus != S_OK )
00786 *RioError = RioStatus;
00787 }
00788 #ifdef RIO_DEBUG2
00789 else
00790 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
00791 "The file %s transfer using the server %s has completed "
00792 "successfully.", FileName, ServerName );
00793 #endif
00794
00795
00796 delete Rio;
00797
00798 return NoError;
00799 }
00800
00801
00802
00803 int ProcessFileOptions( request_rec *r, RioModuleConfig *Config,
00804 apr_table_t* ParamTable, bool UseRedirect,
00805 apr_status_t *ApacheError, int *SystemError,
00806 RioResult *RioError )
00807 {
00808
00809
00810 char *ServerName;
00811
00812 const char *FileName = NULL;
00813
00814 bool NoError = true;
00815
00816
00817
00818 const char *StrPosition;
00819
00820
00821 RioObjectSize StartPosition = 0;
00822
00823 RioObjectSize EndPosition = -1;
00824
00825
00826
00827 bool SendHeader = false;
00828
00829 char *NewURL;
00830
00831
00832
00833 ServerSelectionType SelectionType;
00834
00835
00836 int RequestResult = OK;
00837
00838
00839 const char *HttpScheme;
00840
00841
00842 *ApacheError = APR_SUCCESS;
00843 *SystemError = 0;
00844 *RioError = S_OK;
00845
00846
00847 if( Config->ServersFileName != NULL )
00848 {
00849
00850 ServerName = NULL;
00851
00852
00853
00854
00855
00856 if( UseRedirect )
00857 SelectionType = Config->SelectionType;
00858 else
00859 {
00860 SelectionType = RIO_SELECTION_FIRST;
00861
00862
00863
00864
00865 if( strcmp( Config->ServerName, DEFAULT_SERVERNAME ) != 0 )
00866 ServerName = Config->ServerName;
00867 }
00868
00869
00870
00871
00872
00873 if( ServerName == NULL )
00874 NoError = ProcessServersFile( r, Config, SelectionType, &ServerName,
00875 ApacheError, SystemError, RioError );
00876 }
00877 else
00878 {
00879
00880
00881
00882 ServerName = Config->ServerName;
00883 }
00884
00885
00886
00887 if( NoError )
00888 {
00889 if( UseRedirect )
00890 {
00891
00892
00893
00894
00895
00896
00897
00898 HttpScheme = ap_http_scheme( r );
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 NewURL = ( char * ) apr_pcalloc( r->pool, strlen( HttpScheme ) +
00911 strlen( ServerName ) +
00912 strlen( Config->TransferName ) +
00913 strlen( r->args ) + 10 );
00914 if( NewURL == NULL )
00915 {
00916 *SystemError = ENOMEM;
00917
00918 #ifdef RIO_DEBUG2
00919 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
00920 "Insufficient memory to create the redirect "
00921 "URL: SystemError = %u (%s)", *SystemError,
00922 strerror( *SystemError ) );
00923 #endif
00924 }
00925 else
00926 {
00927
00928 sprintf( NewURL, "%s://%s/%s.rio?%s", HttpScheme, ServerName,
00929 Config->TransferName, r->args );
00930
00931
00932
00933
00934
00935
00936 #ifdef RIO_DEBUG2
00937 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
00938 "Redirecionando pedido para a URI %s", NewURL );
00939 #endif
00940
00941
00942 apr_table_set( r->headers_out, "Location", NewURL );
00943
00944
00945 RequestResult = HTTP_MOVED_TEMPORARILY;
00946 }
00947 }
00948 else
00949 {
00950
00951
00952 if( ParamTable != NULL )
00953 {
00954 #ifdef RIO_DEBUG2
00955
00956 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
00957 "Entradas na tabela com os parametros" );
00958 apr_table_do( PrintHeadersIn, r, ParamTable, NULL );
00959 #endif
00960
00961
00962 StrPosition = apr_table_get( ParamTable, "start" );
00963 if( StrPosition == NULL )
00964 StartPosition = 0;
00965 else
00966 {
00967
00968 StartPosition = atoi( StrPosition );
00969
00970 SendHeader = true;
00971 }
00972
00973
00974 StrPosition = apr_table_get( ParamTable, "end" );
00975 if( StrPosition == NULL )
00976 EndPosition = -1;
00977 else
00978 EndPosition = atoi( StrPosition );
00979
00980
00981 FileName = apr_table_get( ParamTable, "file" );
00982 if( FileName == NULL )
00983 {
00984 #ifdef RIO_DEBUG2
00985 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
00986 "Error: no filename defined" );
00987 #endif
00988 NoError = false;
00989 *RioError = ERROR_RIOMODULE + ERROR_OBJECT_NOT_DEFINED;
00990 }
00991 #ifdef RIO_DEBUG2
00992 else
00993 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
00994 "File name = %s, start position = %u",
00995 FileName, ( unsigned int ) StartPosition );
00996 #endif
00997
00998
00999
01000
01001
01002
01003
01004
01005 if( NoError )
01006 NoError = TransferRioFile( r, Config, ServerName, FileName,
01007 RIO_SHARE_READ, StartPosition,
01008 EndPosition, SendHeader,
01009 ApacheError, SystemError,
01010 RioError );
01011 }
01012 else
01013 {
01014
01015
01016 *RioError = ERROR_RIOMODULE + ERROR_OBJECT_NOT_DEFINED;
01017 }
01018 }
01019 }
01020
01021
01022 return RequestResult;
01023 }
01024
01025
01026
01027 int ProcessUserLog( request_rec *r, RioModuleConfig *Config,
01028 apr_table_t* ParamTable, apr_status_t *ApacheError,
01029 int *SystemError, RioResult *RioError )
01030 {
01031
01032
01033 int RequestResult = OK;
01034
01035
01036 CClientUserLogs *ClientUserLogs;
01037
01038 const char *SAux;
01039
01040 char *LogLine;
01041
01042
01043 *ApacheError = APR_SUCCESS;
01044 *SystemError = 0;
01045 *RioError = S_OK;
01046
01047
01048 if( ParamTable != NULL )
01049 {
01050
01051
01052 SAux = apr_table_get( ParamTable, "logline" );
01053 if( ( SAux == NULL ) || ( strlen( SAux ) == 0 ) )
01054 {
01055 #ifdef RIO_DEBUG2
01056 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01057 "Error: no log line defined" );
01058 #endif
01059 *RioError = ERROR_RIOMODULE + ERROR_LOGLINE_NOT_DEFINED;
01060 }
01061 else
01062 {
01063
01064
01065
01066
01067
01068
01069 LogLine = apr_psprintf( r->pool, "%s %s", r->connection->remote_ip,
01070 SAux );
01071 if( LogLine != NULL )
01072 {
01073 #ifdef RIO_DEBUG2
01074 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01075 "LogLine passada mais o IP = %s", LogLine );
01076 #endif
01077
01078
01079
01080 for( unsigned int p = 0; p < strlen( LogLine ); p++ )
01081 if( LogLine[ p ] == '*' )
01082 LogLine[ p ] = ' ';
01083
01084 #ifdef RIO_DEBUG2
01085 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01086 "LogLine convertida = %s", LogLine );
01087 #endif
01088
01089
01090 try
01091 {
01092
01093 ClientUserLogs = new CClientUserLogs( r );
01094
01095 *RioError = ClientUserLogs->Initialize(
01096 Config->UserLogPort );
01097
01098 if( !FAILED( *RioError ) )
01099 {
01100
01101 *RioError= ClientUserLogs->NewLogLine( LogLine );
01102
01103 #if RIO_DEBUG2
01104 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01105 "Erro %8X (%s) ao tentar inserir a "
01106 "linha de log %s!", *RioError,
01107 GetErrorDescription( *RioError ).c_str(),
01108 LogLine );
01109 #endif
01110
01111 }
01112 #ifdef RIO_DEBUG2
01113 else
01114 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01115 "Erro %8X (%s) ao inicializar o objeto "
01116 "usado para enviar a linha de log %s!",
01117 *RioError,
01118 GetErrorDescription( *RioError ).c_str(),
01119 LogLine );
01120 #endif
01121
01122
01123
01124 delete ClientUserLogs;
01125
01126 }
01127 catch( bad_alloc &ba )
01128 {
01129 #ifdef RIO_DEBUG2
01130 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Erro de "
01131 "alocacao de memoria (bad_alloc, error = %s)"
01132 " ao criar o objeto para enviar a linha de "
01133 "log %s!", ba.what(), LogLine );
01134 #endif
01135
01136
01137 *SystemError = ENOMEM;
01138 }
01139
01140 }
01141 else
01142 {
01143 #ifdef RIO_DEBUG2
01144 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Erro de alocacao "
01145 "de memoria ao duplicar a string %s com a linha "
01146 "de log nao processada!", SAux );
01147 #endif
01148
01149
01150 *SystemError = ENOMEM;
01151 }
01152 }
01153 }
01154 else
01155 {
01156 #ifdef RIO_DEBUG2
01157 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Nao foi definida uma "
01158 "opcao logline com uma linha de log!" );
01159 #endif
01160
01161
01162 *RioError = ERROR_RIOMODULE + ERROR_LOGLINE_NOT_DEFINED;
01163 }
01164
01165
01166 return RequestResult;
01167 }
01168
01169 static apr_status_t RioModuleDestroyServerInterface( void *Param )
01170 {
01171
01172
01173 TRioExecInfo *RioExecInfo;
01174
01175 RioExecInfo = ( TRioExecInfo * ) Param;
01176
01177 #ifdef RIO_DEBUG2
01178 RioErr << "RioModuleDestroyServerInterface: entrei aqui!" << endl;
01179 #endif
01180
01181 if( RioExecInfo != NULL )
01182 {
01183
01184 if( RioExecInfo->ServerInterface != NULL )
01185 {
01186 #ifdef RIO_DEBUG2
01187 RioErr << "RioModuleDestroyServerInterface: parando o objeto!"
01188 << endl;
01189 #endif
01190
01191
01192 if( !RioExecInfo->ServerInterface->Stop() )
01193 {
01194 #ifdef RIO_DEBUG2
01195 RioErr << "Error when stopping CServerInstance object!" << endl;
01196 #endif
01197 }
01198
01199 #ifdef RIO_DEBUG2
01200 RioErr << "RioModuleDestroyServerInterface: deletando o objeto!"
01201 << endl;
01202 #endif
01203
01204
01205 delete RioExecInfo->ServerInterface;
01206 }
01207
01208
01209 delete RioExecInfo;
01210 }
01211
01212 return APR_SUCCESS;
01213 }
01214
01215
01216
01217 int ProcessExec( request_rec *r, RioModuleConfig *Config,
01218 apr_table_t* ParamTable, apr_status_t *ApacheError,
01219 int *SystemError, RioResult *RioError )
01220 {
01221
01222
01223
01224 TRioExecInfo *RioExecInfo;
01225
01226
01227 void *Data;
01228
01229
01230 const char *SAux;
01231
01232 char *Command;
01233
01234
01235 bool RemoveObject;
01236
01237 int HttpResult;
01238
01239
01240 const char *StartCommand, *EndCommand;
01241
01242 unsigned int CommandSize;
01243
01244 unsigned int SessionId;
01245
01246
01247
01248
01249 unsigned int *PSessionId;
01250
01251
01252 *ApacheError = APR_SUCCESS;
01253 *SystemError = 0;
01254 *RioError = S_OK;
01255
01256
01257
01258 if( ParamTable != NULL )
01259 {
01260
01261 SAux = apr_table_get( ParamTable, "sessionid" );
01262 if( ( SAux == NULL ) || ( strlen( SAux ) == 0 ) )
01263 {
01264 #ifdef RIO_DEBUG2
01265 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01266 "Warning: no sessionid defined" );
01267 #endif
01268
01269
01270
01271 PSessionId = NULL;
01272 }
01273 else
01274 {
01275
01276 SessionId = atol( SAux );
01277
01278 PSessionId = &SessionId;
01279 }
01280
01281
01282
01283 SAux = apr_table_get( ParamTable, "command" );
01284 if( ( SAux == NULL ) || ( strlen( SAux ) == 0 ) )
01285 {
01286 #ifdef RIO_DEBUG2
01287 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01288 "Error: no command defined" );
01289 #endif
01290 *RioError = ERROR_RIOMODULE + ERROR_COMMAND_NOT_DEFINED;
01291
01292
01293 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01294 *RioError );
01295
01296
01297 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01298 *SystemError, *RioError,
01299 "<command not available>",
01300 Config->ExecLogPort ); return OK;
01301 }
01302 else
01303 {
01304
01305 StartCommand = strchr( SAux, '\"');
01306 if( StartCommand == NULL )
01307 {
01308
01309
01310 StartCommand = SAux;
01311 CommandSize = strlen( SAux );
01312 }
01313 else
01314 {
01315
01316
01317
01318 EndCommand = strrchr( SAux, '\"' );
01319
01320
01321
01322 if( EndCommand == StartCommand )
01323 {
01324
01325
01326
01327 StartCommand = &StartCommand[ 1 ];
01328 CommandSize = strlen( StartCommand );
01329 }
01330 else
01331 {
01332
01333
01334
01335
01336
01337
01338 StartCommand = &StartCommand[ 1 ];
01339 CommandSize = EndCommand - StartCommand;
01340 }
01341 }
01342
01343
01344
01345 Command = ( char * ) apr_pcalloc( r->pool, CommandSize + 1 );
01346 if( Command == NULL )
01347 {
01348 *SystemError = ENOMEM;
01349
01350 #ifdef RIO_DEBUG2
01351 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01352 "Insufficient memory to create the command!" );
01353 #endif
01354
01355
01356 CServerInterface::GenerateXMLError( r, *ApacheError,
01357 *SystemError, *RioError );
01358
01359
01360 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01361 *SystemError, *RioError,
01362 "<command not available>",
01363 Config->ExecLogPort ); return OK;
01364 return OK;
01365 }
01366
01367 strncpy( Command, StartCommand, CommandSize );
01368
01369 Command[ CommandSize ] = 0;
01370 }
01371
01372 #ifdef RIO_DEBUG2
01373 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "command param = %s, "
01374 "module command = %s", SAux, Command );
01375 #endif
01376
01377 }
01378 else
01379 {
01380 #ifdef RIO_DEBUG2
01381 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Nao foi definida nenhuma "
01382 "opcao: nem a com o command com o comando a ser "
01383 "executado, e nem a com o identificador da sessao!" );
01384 #endif
01385
01386
01387 *RioError = ERROR_RIOMODULE + ERROR_COMMAND_NOT_DEFINED;
01388
01389
01390 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01391 *RioError );
01392
01393
01394 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01395 *SystemError, *RioError,
01396 "<command not available>",
01397 Config->ExecLogPort ); return OK;
01398 return OK;
01399 }
01400
01401
01402
01403 if( apr_strnatcmp( ap_http_scheme( r ), "https" ) != 0 )
01404 {
01405 #ifdef RIO_DEBUG2
01406 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01407 "Connection is not secure!" );
01408 #endif
01409
01410 *RioError = ERROR_RIOMODULE + ERROR_HTTPS_REQUIRED;
01411
01412
01413 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01414 *RioError );
01415
01416
01417 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01418 *SystemError, *RioError,
01419 Command, Config->ExecLogPort );
01420
01421 return OK;
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431 *ApacheError = apr_pool_userdata_get( &Data, SERVERINTERFACEOBJECTPOINTER,
01432 r->connection->pool );
01433 if( *ApacheError != APR_SUCCESS )
01434 {
01435 #ifdef RIO_DEBUG2
01436 ap_log_rerror( APLOG_MARK, APLOG_ERR, *ApacheError, r,
01437 "Erro ao obter o ponteiro do objeto com a possivel "
01438 "sessao ativa!");
01439 #endif
01440
01441
01442 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01443 *RioError );
01444
01445
01446 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01447 *SystemError, *RioError,
01448 Command, Config->ExecLogPort );
01449
01450 return OK;
01451 }
01452
01453
01454
01455
01456 if( Data == NULL )
01457 {
01458 #ifdef RIO_DEBUG2
01459 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01460 "Tentando criar a estutura para armazenar as "
01461 "informacoes da opcao \"%s\"!", Config->ExecName );
01462 #endif
01463
01464
01465 try
01466 {
01467 RioExecInfo = new TRioExecInfo;
01468 }
01469 catch( bad_alloc &ba )
01470 {
01471 *SystemError = ENOMEM;
01472
01473 #ifdef RIO_DEBUG2
01474 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01475 "Insufficient memory (bad_alloc, error=%s) to "
01476 "create a instance of TRioExecInfo structure!",
01477 ba.what() );
01478 #endif
01479
01480
01481 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01482 *RioError );
01483
01484
01485 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01486 *SystemError, *RioError,
01487 Command,
01488 Config->ExecLogPort );
01489
01490 return OK;
01491 }
01492
01493
01494 RioExecInfo->ServerInterface = NULL;
01495 RioExecInfo->LocalPort = r->connection->local_addr->port;
01496 RioExecInfo->LocalIP = r->connection->local_addr->
01497 sa.sin.sin_addr.s_addr;
01498 RioExecInfo->RemotePort = r->connection->remote_addr->port;
01499 RioExecInfo->RemoteIP = r->connection->remote_addr->
01500 sa.sin.sin_addr.s_addr;
01501
01502 #ifdef RIO_DEBUG2
01503 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01504 "Tentando criar a chave %s com a estrutura com as "
01505 "informacoes da opcao \"%s\"!",
01506 SERVERINTERFACEOBJECTPOINTER, Config->ExecName );
01507 #endif
01508
01509 *ApacheError = apr_pool_userdata_set( ( const void * ) RioExecInfo,
01510 SERVERINTERFACEOBJECTPOINTER,
01511 RioModuleDestroyServerInterface,
01512 r->connection->pool );
01513 if( *ApacheError != APR_SUCCESS )
01514 {
01515 #ifdef RIO_DEBUG2
01516 ap_log_rerror( APLOG_MARK, APLOG_ERR, *ApacheError, r,
01517 "Erro ao salvar o ponteiro da estrutura com as "
01518 "informacoes da opcao \"%s\"!", Config->ExecName );
01519 #endif
01520
01521
01522 delete RioExecInfo;
01523
01524 #ifdef RIO_DEBUG2
01525 ap_log_rerror( APLOG_MARK, APLOG_ERR, *ApacheError, r,
01526 "Error when creating object pointer key!" );
01527 #endif
01528
01529
01530 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01531 *RioError );
01532
01533
01534 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01535 *SystemError, *RioError,
01536 Command,
01537 Config->ExecLogPort );
01538
01539 return OK;
01540 }
01541 }
01542 else
01543 {
01544
01545 RioExecInfo = ( TRioExecInfo * ) Data;
01546
01547
01548
01549
01550
01551
01552 if( RioExecInfo->LocalPort != r->connection->local_addr->port )
01553 {
01554 #ifdef RIO_DEBUG2
01555 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01556 "Incorret local port %u found! Port must be %u!",
01557 r->connection->local_addr->port,
01558 RioExecInfo->LocalPort );
01559 #endif
01560
01561
01562
01563
01564
01565
01566 *RioError = ERROR_RIOMODULE + ERROR_INVALID_HOST;
01567 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01568 *RioError );
01569
01570
01571 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01572 *SystemError, *RioError,
01573 Command,
01574 Config->ExecLogPort );
01575
01576 }
01577
01578
01579 if( RioExecInfo->LocalIP !=
01580 r->connection->local_addr->sa.sin.sin_addr.s_addr )
01581 {
01582 #ifdef RIO_DEBUG2
01583 in_addr IP;
01584 IP.s_addr = RioExecInfo->LocalIP;
01585 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01586 "Incorret local IP %s found! IP must be %s!",
01587 inet_ntoa( r->connection->local_addr->
01588 sa.sin.sin_addr ),
01589 inet_ntoa( IP ) );
01590 #endif
01591
01592
01593
01594
01595
01596
01597 *RioError = ERROR_RIOMODULE + ERROR_INVALID_HOST;
01598 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01599 *RioError );
01600
01601
01602 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01603 *SystemError, *RioError,
01604 Command,
01605 Config->ExecLogPort );
01606
01607 }
01608
01609
01610 if( RioExecInfo->RemotePort != r->connection->remote_addr->port )
01611 {
01612 #ifdef RIO_DEBUG2
01613 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01614 "Incorret remote port %u found! Port must be %u!",
01615 r->connection->remote_addr->port,
01616 RioExecInfo->RemotePort );
01617 #endif
01618
01619
01620
01621
01622
01623
01624 *RioError = ERROR_RIOMODULE + ERROR_INVALID_HOST;
01625 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01626 *RioError );
01627
01628
01629 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01630 *SystemError, *RioError,
01631 Command,
01632 Config->ExecLogPort );
01633
01634 }
01635
01636
01637 if( RioExecInfo->RemoteIP !=
01638 r->connection->remote_addr->sa.sin.sin_addr.s_addr )
01639 {
01640 #ifdef RIO_DEBUG2
01641 in_addr IP;
01642 IP.s_addr = RioExecInfo->RemoteIP;
01643 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01644 "Incorret remote IP %s found! IP must be %s!",
01645 inet_ntoa( r->connection->remote_addr->
01646 sa.sin.sin_addr ) ,
01647 inet_ntoa( IP ) );
01648 #endif
01649
01650
01651
01652
01653
01654
01655 *RioError = ERROR_RIOMODULE + ERROR_INVALID_HOST;
01656 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01657 *RioError );
01658
01659
01660 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01661 *SystemError, *RioError,
01662 Command,
01663 Config->ExecLogPort );
01664
01665 }
01666
01667 #ifdef RIO_DEBUG2
01668 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01669 "Corret port %u found! Executing command %s!",
01670 RioExecInfo->LocalPort, Command );
01671 #endif
01672 }
01673
01674
01675
01676
01677
01678
01679
01680 if( RioExecInfo->ServerInterface == NULL )
01681 {
01682 #ifdef RIO_DEBUG2
01683 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01684 "Tentando criar o objeto que executara os comandos "
01685 "similares ao do riosh!");
01686 #endif
01687
01688
01689 try
01690 {
01691 RioExecInfo->ServerInterface = new CServerInterface( r->server );
01692 }
01693 catch( bad_alloc &ba )
01694 {
01695 *SystemError = ENOMEM;
01696
01697
01698 RioExecInfo->ServerInterface = NULL;
01699
01700 #ifdef RIO_DEBUG2
01701 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01702 "Insufficient memory (bad_alloc, error=%s) to "
01703 "create a instance of CServerInterface class!",
01704 ba.what() );
01705 #endif
01706
01707
01708 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01709 *RioError );
01710
01711
01712 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01713 *SystemError, *RioError,
01714 Command,
01715 Config->ExecLogPort );
01716
01717 return OK;
01718 }
01719
01720
01721
01722 #ifdef RIO_DEBUG2
01723 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01724 "Tentando inicializar o objeto que executara os comandos "
01725 "similares ao do riosh!");
01726 #endif
01727
01728
01729 if( !RioExecInfo->ServerInterface->Start( Config->ServerName,
01730 Config->BufferSize,
01731 Config->FragmentSize,
01732 Config->ExecSessionId,
01733 Config->ExecLogPort ) )
01734 {
01735
01736 RioExecInfo->ServerInterface->GetErrors( ApacheError, SystemError,
01737 RioError );
01738
01739
01740 CServerInterface::GenerateXMLError( r, *ApacheError, *SystemError,
01741 *RioError );
01742
01743
01744 CServerInterface::SaveExecLogLineError( r, *ApacheError,
01745 *SystemError, *RioError,
01746 Command,
01747 Config->ExecLogPort );
01748
01749
01750 delete RioExecInfo->ServerInterface;
01751 RioExecInfo->ServerInterface = NULL;
01752
01753 #ifdef RIO_DEBUG2
01754 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01755 "Error when starting CServerInstance object!" );
01756 #endif
01757
01758 return OK;
01759 }
01760 }
01761 else
01762 {
01763 #ifdef RIO_DEBUG2
01764 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01765 "Sessao ativa achada! Usando esta sessao para executar "
01766 "o comando %s", Command );
01767 #endif
01768 }
01769
01770 #ifdef RIO_DEBUG2
01771 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01772 "Tentando executar o comando %s!", Command );
01773 #endif
01774
01775
01776
01777 HttpResult = RioExecInfo->ServerInterface->ExecuteCommands( r, Command,
01778 &RemoveObject,
01779 PSessionId );
01780
01781
01782 RioExecInfo->ServerInterface->GetErrors( ApacheError, SystemError,
01783 RioError );
01784
01785
01786 if( RemoveObject )
01787 {
01788
01789 if( !RioExecInfo->ServerInterface->Stop() )
01790 {
01791
01792 RioExecInfo->ServerInterface->GetErrors( ApacheError, SystemError,
01793 RioError );
01794
01795 #ifdef RIO_DEBUG2
01796 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01797 "Error when stopping CServerInstance object!" );
01798 #endif
01799 }
01800
01801
01802 delete RioExecInfo->ServerInterface;
01803 RioExecInfo->ServerInterface = NULL;
01804 }
01805
01806
01807 return HttpResult;
01808 }
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822 static int RioModuleRequestHandler( request_rec *r )
01823 {
01824
01825 bool NoError;
01826
01827
01828 bool UseRedirect;
01829
01830
01831
01832 apr_status_t ApacheError = APR_SUCCESS, status;
01833 int SystemError = 0;
01834 RioResult RioError = S_OK;
01835
01836 apr_table_t* ParamTable;
01837
01838
01839 int RequestResult = OK;
01840
01841
01842 char *ModulePolicy;
01843
01844 char *FinalModulePolicy;
01845
01846 #ifdef RIO_DEBUG2
01847 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "MAINTHREADID %lu",
01848 syscall( SYS_gettid ) );
01849 #endif
01850
01851 signal( SIGSEGV, SignalHandler );
01852 signal( SIGILL, SignalHandler );
01853
01854
01855 RioModuleConfig *Config = ( RioModuleConfig * ) ap_get_module_config(
01856 r->server->module_config, &RioModule );
01857
01858
01859
01860 if( strncmp( r->handler, RIOMODULE_MIME, RIOMODULE_MIME_SIZE ) != 0 )
01861 {
01862 #ifdef RIO_DEBUG2
01863 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "O arquivo %s nao esta "
01864 "relacionado ao modulo! Declinando o pedido!",
01865 r->filename );
01866 #endif
01867
01868 return DECLINED;
01869 }
01870
01871
01872 if( r->args == NULL )
01873 {
01874 #ifdef RIO_DEBUG2
01875 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Requisicao invalida! Nao "
01876 "foram passadas opcoes para o arquivo %s!",
01877 r->filename );
01878 #endif
01879
01880 return HTTP_BAD_REQUEST;
01881 }
01882
01883 #ifdef RIO_DEBUG2
01884
01885 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01886 "Cabecalhos (r->headers_in)" );
01887 apr_table_do( PrintHeadersIn, r, r->headers_in, NULL );
01888 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Campos request_rec (r): "
01889 "r->handler = %s, r->method = %s, r->filename = %s, "
01890 "r->uri = %s, r->args = %s, r->unparsed_uri = %s, "
01891 "r->connection->id = %ld, r->connection->remote_ip = %s, "
01892 "r->connection->local_ip = %s, "
01893 "r->connection->remote_addr->sin.sin_addr = %s, "
01894 "r->connection->remote_addr->sin.sin_port = %u, "
01895 "r->connection->remote_addr->port = %u, "
01896 "r->connection->local_addr->sin = %s, "
01897 "r->connection->local_addr->sin.sin_port = %u, "
01898 "r->connection->local_addr->port = %u, "
01899 "r->connection->keepalive = %u, "
01900 "ap_http_scheme( r ) = %s",
01901 r->handler, r->method, r->filename, r->uri, r->args,
01902 r->unparsed_uri, r->connection->id,
01903 r->connection->remote_ip, r->connection->local_ip,
01904 inet_ntoa( r->connection->remote_addr->sa.sin.sin_addr ),
01905 ntohs( r->connection->remote_addr->sa.sin.sin_port ),
01906 r->connection->remote_addr->port,
01907 inet_ntoa( r->connection->local_addr->sa.sin.sin_addr ),
01908 ntohs( r->connection->local_addr->sa.sin.sin_port ),
01909 r->connection->local_addr->port,
01910 r->connection->keepalive,
01911 ap_http_scheme( r ) );
01912 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Configuracao do modulo: "
01913 "Descricao = %s, ServerName = %s, RealTimeExtensions = %s, "
01914 "WaitTime = %u ms, BufferSize = %u, LineSize = %u, "
01915 "SelectionType = %u, FragmentSize = %u, User = %s, "
01916 "Password = %s, ServersFileName = %s, RedirectName = %s, "
01917 "TransferName = %s, MaxLogFileSize = %u, "
01918 "MaxCombinedLogFilesSize = %llu, UserLogsPrefixPath = %s, "
01919 "UserLogName = %s, UserLogPort = %u, ExecSessionId = %u, "
01920 "process pid = %u",
01921 Config->Description, Config->ServerName,
01922 ( Config->RealTimeExtensions == NULL) ? "<not defined>" :
01923 Config->RealTimeExtensions, Config->WaitTime,
01924 Config->BufferSize, Config->LineSize, Config->SelectionType,
01925 Config->FragmentSize, Config->User, Config->Password,
01926 ( Config->ServersFileName == NULL ) ? "<not defined>" :
01927 Config->ServersFileName, Config->RedirectName,
01928 Config->TransferName, Config->MaxLogFileSize,
01929 Config->MaxCombinedLogFilesSize, Config->UserLogsPrefixPath,
01930 Config->UserLogName, Config->UserLogPort,
01931 Config->ExecSessionId, getpid() );
01932 #endif
01933
01934 NoError = true;
01935
01936
01937 ApacheError = ProcessParams( r, &ParamTable );
01938 if( ApacheError != APR_SUCCESS )
01939 {
01940 #ifdef RIO_DEBUG2
01941 ap_log_rerror( APLOG_MARK, APLOG_ERR, ApacheError, r,
01942 "Error when reading module params" );
01943 #endif
01944 }
01945
01946
01947 FinalModulePolicy = strchr( &r->uri[ 1 ], '.' );
01948 if( FinalModulePolicy == NULL )
01949 {
01950
01951 return DECLINED;
01952 }
01953
01954
01955 *FinalModulePolicy = 0;
01956
01957
01958 ModulePolicy = apr_pstrcat( r->pool, &r->uri[ 1 ], NULL );
01959
01960
01961 *FinalModulePolicy = '.';
01962
01963
01964 if( ModulePolicy == NULL )
01965 {
01966 #ifdef RIO_DEBUG2
01967 ap_log_rerror( APLOG_MARK, APLOG_ERR, ApacheError, r,
01968 "Memory Error when creating module policy." );
01969 #endif
01970
01971 SystemError = ENOMEM;
01972
01973 }
01974 else
01975 {
01976
01977
01978
01979 if( ( strcmp( ModulePolicy, Config->RedirectName ) == 0 ) ||
01980 ( strcmp( ModulePolicy, Config->TransferName ) == 0 ) )
01981 {
01982
01983 if( strcmp( r->method, "GET" ) != 0 )
01984 return HTTP_METHOD_NOT_ALLOWED;
01985
01986
01987
01988
01989
01990 if( strcmp( ModulePolicy, Config->RedirectName ) == 0 )
01991 {
01992
01993
01994 UseRedirect = true;
01995
01996 #ifdef RIO_DEBUG2
01997 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
01998 "Redirecionando a requicao do arquivo" );
01999 #endif
02000 }
02001 else
02002 {
02003
02004
02005 UseRedirect = false;
02006
02007 #ifdef RIO_DEBUG2
02008 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
02009 "Enviando o arquivo " );
02010 #endif
02011 }
02012
02013
02014 RequestResult = ProcessFileOptions( r, Config, ParamTable,
02015 UseRedirect, &ApacheError,
02016 &SystemError, &RioError );
02017
02018 status = SendError( r, ApacheError, SystemError, RioError );
02019
02020 #ifdef RIO_DEBUG2
02021 if( status != APR_SUCCESS )
02022 ap_log_rerror( APLOG_MARK, APLOG_ERR, status, r,
02023 "error sending erro information" );
02024 #endif
02025 }
02026 else if( strcmp( ModulePolicy, Config->UserLogName ) == 0 )
02027 {
02028
02029 if( strcmp( r->method, "GET" ) != 0 )
02030 return HTTP_METHOD_NOT_ALLOWED;
02031
02032
02033
02034
02035 RequestResult = ProcessUserLog( r, Config, ParamTable, &ApacheError,
02036 &SystemError, &RioError );
02037 }
02038 else if( strcmp( ModulePolicy, Config->ExecName ) == 0 )
02039 {
02040
02041 RequestResult = ProcessExec( r, Config, ParamTable, &ApacheError,
02042 &SystemError, &RioError );
02043 }
02044 else
02045 {
02046
02047
02048 RioError = ERROR_RIOMODULE + ERROR_INVALID_MODULE_POLICY;
02049
02050 #ifdef RIO_DEBUG2
02051 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r,
02052 "Invalid policy name %s", ModulePolicy );
02053 #endif
02054 }
02055 }
02056
02057 #ifdef RIO_DEBUG2
02058 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, r, "Codigo http do resultado do "
02059 "tratamento da requisicao = %u", RequestResult );
02060 #endif
02061
02062 return RequestResult;
02063 }
02064
02065
02066
02067 static apr_status_t RioModuleTerminateServerUserLogs( void *Param )
02068 {
02069
02070 TFinalizeLogsInfo *LogsInfo;
02071
02072 RioResult RioStatus;
02073
02074 CClientUserLogs FinalizeMsg( NULL );
02075
02076 int ExitProcess;
02077
02078 apr_exit_why_e ProcessStatus;
02079
02080 apr_status_t ApacheStatus;
02081
02082 char ApacheStrError[ MAXAPACHESTRERRORSIZE ];
02083
02084
02085 #ifdef RIO_DEBUG2
02086 RioErr << "RioModuleTerminateServerUserLogs: entrei aqui!" << endl;
02087 #endif
02088
02089
02090
02091 LogsInfo = ( TFinalizeLogsInfo* ) Param;
02092
02093
02094 ApacheStatus = APR_SUCCESS;
02095
02096
02097
02098 RioStatus = FinalizeMsg.Initialize( LogsInfo->LogsServerPort );
02099 if( FAILED( RioStatus ) )
02100 {
02101 #ifdef RIO_DEBUG2
02102 RioErr << "RioModuleTerminateServerUserLogs 0x" << hex << RioStatus
02103 << dec << " (" << GetErrorDescription( RioStatus ) << ") when "
02104 << "initializing object! Process will be killed!" << endl;
02105 #endif
02106
02107
02108 kill( LogsInfo->LogsServerPort, SIGKILL );
02109 }
02110 else
02111 {
02112 RioStatus = FinalizeMsg.NewLogLine( NULL );
02113 if( FAILED( RioStatus ) )
02114 {
02115 #ifdef RIO_DEBUG2
02116 RioErr << "RioModuleTerminateServerUserLogs Erro 0x" << hex
02117 << RioStatus << dec << " ("
02118 << GetErrorDescription( RioStatus )
02119 << ") when sendling finalization message! Process will be "
02120 << "killed!" << endl;
02121 #endif
02122
02123
02124 kill( LogsInfo->LogsServerPort, SIGKILL );
02125 }
02126
02127
02128 ApacheStatus = apr_proc_wait( LogsInfo->ProcessInfo, &ExitProcess,
02129 &ProcessStatus, APR_WAIT );
02130
02131
02132 apr_strerror( ProcessStatus, ApacheStrError,
02133 MAXAPACHESTRERRORSIZE );
02134
02135 #ifdef RIO_DEBUG2
02136 RioErr << "RioModuleTerminateServerUserLogs processo terminou com o "
02137 << "codigo de saida " << ExitProcess << " e codigo de status "
02138 << ProcessStatus << " (" << ApacheStrError << ")." << endl;
02139 #endif
02140 }
02141
02142 return ApacheStatus;
02143 }
02144
02145
02146
02147
02148 int CreateServerLogsProcess( apr_pool_t *pconf, server_rec *s,
02149 RioModuleConfig *Config, char *LogsPrefixPath,
02150 unsigned int LogPort )
02151 {
02152
02153 apr_status_t ApacheStatus;
02154
02155 apr_proc_t *LogsProcessInfo;
02156
02157 RioResult RioStatus;
02158
02159 apr_file_t *InPipe, *OutPipe;
02160
02161 apr_size_t TotalBytes;
02162
02163 TFinalizeLogsInfo *LogsInfo;
02164
02165
02166 LogsProcessInfo = ( apr_proc_t * ) apr_palloc( pconf, sizeof( apr_proc_t ) );
02167 if( LogsProcessInfo == NULL )
02168 {
02169 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02170 "Error when creating process structure!" );
02171
02172 return 1;
02173 }
02174
02175
02176
02177
02178 ApacheStatus = apr_file_pipe_create( &InPipe, &OutPipe, pconf );
02179 if( ApacheStatus != APR_SUCCESS )
02180 {
02181 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02182 "Error when creating pipe!" );
02183
02184 return 1;
02185 }
02186
02187
02188 LogsInfo = ( TFinalizeLogsInfo * ) apr_palloc( pconf,
02189 sizeof( TFinalizeLogsInfo ) );
02190 if( LogsInfo == NULL )
02191 {
02192 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02193 "Error when allocating memory for user logs "
02194 "finalization structure!" );
02195
02196 return 1;
02197
02198 }
02199
02200
02201 ApacheStatus = apr_proc_fork( LogsProcessInfo, pconf );
02202 if( ( ApacheStatus != APR_INCHILD ) && ( ApacheStatus != APR_INPARENT ) )
02203 {
02204
02205 ApacheStatus = apr_file_close( InPipe );
02206
02207 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02208 "Error when creating userlogs process!" );
02209
02210 #ifdef RIO_DEBUG2
02211 if( ApacheStatus != APR_SUCCESS )
02212 {
02213 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02214 "Error closing in file of pipe!" );
02215 }
02216 #endif
02217
02218 ApacheStatus = apr_file_close( OutPipe );
02219
02220 #ifdef RIO_DEBUG2
02221 if( ApacheStatus != APR_SUCCESS )
02222 {
02223 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02224 "Error closing out file of pipe!" );
02225 }
02226 #endif
02227
02228 return 1;
02229 }
02230
02231
02232
02233
02234
02235 if( ApacheStatus == APR_INPARENT )
02236 {
02237
02238
02239
02240
02241 #ifdef RIO_DEBUG2
02242 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02243 "Executing parent process. PID = %u (apache pid = %u)",
02244 getpid(), LogsProcessInfo->pid );
02245 #endif
02246
02247
02248 ApacheStatus = apr_file_close( OutPipe );
02249
02250 if( ApacheStatus != APR_SUCCESS )
02251 {
02252 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02253 "Error closing out file of pipe!" );
02254
02255 return 1;
02256 }
02257
02258 sleep( 3 );
02259
02260
02261
02262 ApacheStatus = apr_file_read_full( InPipe, ( void * ) &RioStatus,
02263 sizeof( RioResult ), &TotalBytes );
02264 if( ( ApacheStatus != APR_SUCCESS ) ||
02265 ( TotalBytes != sizeof( RioResult ) ) )
02266 {
02267 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02268 "Error when reading stdout chid process!" );
02269
02270
02271 ApacheStatus = apr_file_close( InPipe );
02272
02273 #ifdef RIO_DEBUG2
02274 if( ApacheStatus != APR_SUCCESS )
02275 {
02276 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02277 "Error closing in file of pipe!" );
02278 }
02279 #endif
02280
02281
02282 kill( LogsProcessInfo->pid, SIGKILL );
02283
02284 return 1;
02285
02286 }
02287
02288
02289
02290 ApacheStatus = apr_file_close( InPipe );
02291
02292 #ifdef RIO_DEBUG2
02293 if( ApacheStatus != APR_SUCCESS )
02294 {
02295 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02296 "Error closing in file of pipe!" );
02297 }
02298
02299 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02300 "Recebido o codigo de erro %8X (%s) do processo filho!",
02301 RioStatus, GetErrorDescription( RioStatus ).c_str() );
02302 #endif
02303
02304 if( FAILED( RioStatus ) )
02305 {
02306 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02307 "Error %8X (%s) when creating user logs object!",
02308 RioStatus, GetErrorDescription( RioStatus ).c_str() );
02309
02310 return 1;
02311 }
02312 else
02313 {
02314
02315 LogsInfo->LogsServerPort = LogPort;
02316 LogsInfo->ProcessInfo = LogsProcessInfo;
02317 apr_pool_cleanup_register( pconf, ( void * ) LogsInfo,
02318 RioModuleTerminateServerUserLogs,
02319 apr_pool_cleanup_null );
02320 }
02321 }
02322 else
02323 {
02324
02325
02326
02327
02328
02329 CServerUserLogs *ServerUserLogs;
02330
02331 #ifdef RIO_DEBUG2
02332 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02333 "Executing child process. PID = %u (apache pid = %u)",
02334 getpid(), LogsProcessInfo->pid );
02335 #endif
02336
02337
02338 signal( SIGTERM, SIG_IGN );
02339
02340
02341 ApacheStatus = apr_file_close( InPipe );
02342
02343 if( ApacheStatus != APR_SUCCESS )
02344 {
02345 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02346 "Error closing in file of pipe!" );
02347 }
02348
02349
02350 RioStatus = S_OK;
02351
02352
02353 ServerUserLogs = NULL;
02354
02355
02356 try
02357 {
02358
02359 ServerUserLogs = new CServerUserLogs( s );
02360
02361 #ifdef RIO_DEBUG2
02362 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s, "Objeto criado com "
02363 "sucesso! Tentando inicializar o objeto!" );
02364
02365 #endif
02366
02367
02368 RioStatus = ServerUserLogs->Initialize( LogsPrefixPath,
02369 Config->MaxLogFileSize,
02370 Config->MaxCombinedLogFilesSize,
02371 LogPort );
02372 if( FAILED( RioStatus ) )
02373 {
02374 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02375 "Error %8X (%s) when initializing "
02376 "CServerUserLogs object!", RioStatus,
02377 GetErrorDescription( RioStatus ).c_str() );
02378 delete ServerUserLogs;
02379 }
02380 else
02381 {
02382 #ifdef RIO_DEBUG2
02383 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02384 "Objeto inicializado com sucesso! Tentando "
02385 "obter o IP associado ao socket UDP!" );
02386 #endif
02387 }
02388
02389 }
02390 catch( bad_alloc &ba )
02391 {
02392
02393 RioStatus = ERROR_RIOMODULE + ERROR_MEMORY;
02394
02395 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02396 "Error bad_alloc (%s) when creating CServerUserLogs "
02397 "object!", ba.what() );
02398 }
02399
02400
02401
02402
02403 ApacheStatus = apr_file_write_full( OutPipe, ( void * ) &RioStatus,
02404 sizeof( RioResult ), &TotalBytes );
02405 if( ( ApacheStatus != APR_SUCCESS ) ||
02406 ( TotalBytes != sizeof( RioResult ) ) )
02407 {
02408
02409 if( ServerUserLogs != NULL )
02410 delete ServerUserLogs;
02411
02412
02413 ApacheStatus = apr_file_close( OutPipe );
02414
02415 #ifdef RIO_DEBUG2
02416 if( ApacheStatus != APR_SUCCESS )
02417 {
02418 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02419 "Error closing out file of pipe!" );
02420 }
02421 #endif
02422
02423 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02424 "Error when reading stdout child process!" );
02425
02426 exit( -1 );
02427 }
02428
02429
02430 ApacheStatus = apr_file_flush( OutPipe );
02431 if( ApacheStatus != APR_SUCCESS )
02432 {
02433 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02434 "Error when flushing out chid process!" );
02435
02436
02437 if( ServerUserLogs != NULL )
02438 delete ServerUserLogs;
02439
02440
02441 ApacheStatus = apr_file_close( OutPipe );
02442
02443 #ifdef RIO_DEBUG2
02444 if( ApacheStatus != APR_SUCCESS )
02445 {
02446 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02447 "Error closing out file of pipe!" );
02448 }
02449 #endif
02450
02451 exit( -1 );
02452 }
02453
02454
02455
02456 ApacheStatus = apr_file_close( OutPipe );
02457
02458 #ifdef RIO_DEBUG2
02459 if( ApacheStatus != APR_SUCCESS )
02460 {
02461 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, s,
02462 "Error closing out file of pipe!" );
02463 }
02464 #endif
02465
02466
02467 ServerUserLogs->JoinThread();
02468
02469
02470 exit( 0 );
02471 }
02472
02473 return 0;
02474 }
02475
02476
02477
02478
02479 static int RioModulePostConfigHandler( apr_pool_t *pconf, apr_pool_t *plog,
02480 apr_pool_t *ptemp, server_rec *s )
02481 {
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495 int Result;
02496
02497
02498 RioModuleConfig *Config = ( RioModuleConfig * ) ap_get_module_config(
02499 s->module_config, &RioModule );
02500
02501
02502
02503 Result = CreateServerLogsProcess( pconf, s, Config,
02504 Config->UserLogsPrefixPath,
02505 Config->UserLogPort );
02506 if( Result != 0 )
02507 {
02508 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02509 "Error when creating process for userlog command!" );
02510
02511 return 1;
02512
02513 }
02514
02515
02516
02517 Result = CreateServerLogsProcess( pconf, s, Config,
02518 Config->ExecLogsPrefixPath,
02519 Config->ExecLogPort );
02520 if( Result != 0 )
02521 {
02522 ap_log_error( APLOG_MARK, APLOG_ERR, 0, s,
02523 "Error when creating process for exec command!" );
02524
02525 return 1;
02526
02527 }
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839 return 0;
02840 }
02841
02842 static void RioModuleChildInitHandler( apr_pool_t *p, server_rec *s )
02843 {
02844
02845
02846 srandom( ( unsigned int ) ( time( NULL ) ) ^
02847 ( unsigned int ) ( getpid() ) );
02848 }
02849
02850
02851
02852
02853
02854
02855
02856 static void RioModuleRegisterHooks( apr_pool_t *p )
02857 {
02858
02859
02860 ap_hook_handler( RioModuleRequestHandler, NULL, NULL, APR_HOOK_LAST );
02861
02862 ap_hook_post_config( RioModulePostConfigHandler, NULL, NULL,
02863 APR_HOOK_LAST );
02864
02865
02866
02867
02868 ap_hook_child_init( RioModuleChildInitHandler, NULL, NULL, APR_HOOK_LAST );
02869 }
02870
02871
02872 static const char *setServerName( cmd_parms *parms, void *mconfig,
02873 const char *arg )
02874 {
02875
02876 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02877 parms->server->module_config, &RioModule );
02878
02879
02880 config->ServerName = apr_pstrdup( parms->pool, arg );
02881
02882
02883 return NULL;
02884 }
02885
02886
02887
02888 static const char *setRealTimeExtensions( cmd_parms *parms, void *mconfig,
02889 const char *arg )
02890 {
02891
02892 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02893 parms->server->module_config, &RioModule );
02894
02895
02896
02897 config->RealTimeExtensions = apr_pstrdup( parms->pool, arg );
02898
02899
02900 return NULL;
02901 }
02902
02903
02904 static const char *setWaitTime( cmd_parms *parms, void *mconfig,
02905 const char *arg )
02906 {
02907
02908 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02909 parms->server->module_config, &RioModule );
02910
02911
02912
02913 config->WaitTime = atoi( arg );
02914
02915
02916 return NULL;
02917 }
02918
02919
02920
02921 static const char *setBufferSize( cmd_parms *parms, void *mconfig,
02922 const char *arg )
02923 {
02924
02925 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02926 parms->server->module_config, &RioModule );
02927
02928
02929 config->BufferSize = atoi( arg );
02930
02931
02932 return NULL;
02933 }
02934
02935
02936
02937 static const char *setLineSize( cmd_parms *parms, void *mconfig,
02938 const char *arg )
02939 {
02940
02941 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02942 parms->server->module_config, &RioModule );
02943
02944
02945 config->LineSize = atoi( arg );
02946
02947
02948 return NULL;
02949 }
02950
02951
02952
02953 static const char *setSelectionType( cmd_parms *parms, void *mconfig,
02954 const char *arg )
02955 {
02956
02957 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02958 parms->server->module_config, &RioModule );
02959
02960
02961 if( strcasecmp( arg, "Random" ) == 0 )
02962 config->SelectionType = RIO_SELECTION_RANDOM;
02963 else if ( strcasecmp( arg, "Lload" ) == 0 )
02964 config->SelectionType = RIO_SELECTION_L_LOAD;
02965 else if ( strcasecmp( arg, "Mvavg" ) == 0 )
02966 config->SelectionType = RIO_SELECTION_MV_AVG;
02967 else
02968 {
02969
02970 config->SelectionType = RIO_SELECTION_RANDOM;
02971 }
02972
02973
02974 return NULL;
02975 }
02976
02977
02978
02979 static const char *setFragmentSize( cmd_parms *parms, void *mconfig,
02980 const char *arg )
02981 {
02982
02983 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02984 parms->server->module_config, &RioModule );
02985
02986
02987 config->FragmentSize = atoi( arg );
02988
02989
02990 return NULL;
02991 }
02992
02993
02994 static const char *setRIOUser( cmd_parms *parms, void *mconfig,
02995 const char *arg1, const char *arg2 )
02996 {
02997
02998 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
02999 parms->server->module_config, &RioModule );
03000
03001
03002 config->User = apr_pstrdup( parms->pool, arg1 );
03003 if( arg2 != NULL )
03004 config->Password = apr_pstrdup( parms->pool, arg2 );
03005
03006
03007 return NULL;
03008 }
03009
03010
03011 static const char *setServersFileName( cmd_parms *parms, void *mconfig,
03012 const char *arg )
03013 {
03014
03015 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03016 parms->server->module_config, &RioModule );
03017
03018
03019 config->ServersFileName = apr_pstrdup( parms->pool, arg );
03020
03021
03022 return NULL;
03023 }
03024
03025
03026
03027
03028 static const char *setRedirectName( cmd_parms *parms, void *mconfig,
03029 const char *arg )
03030 {
03031
03032 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03033 parms->server->module_config, &RioModule );
03034
03035
03036 config->RedirectName = apr_pstrdup( parms->pool, arg );
03037
03038
03039 return NULL;
03040 }
03041
03042
03043
03044 static const char *setTransferName( cmd_parms *parms, void *mconfig,
03045 const char *arg )
03046 {
03047
03048 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03049 parms->server->module_config, &RioModule );
03050
03051
03052 config->TransferName = apr_pstrdup( parms->pool, arg );
03053
03054
03055 return NULL;
03056 }
03057
03058
03059
03060 static const char *setMaxLogFileSize( cmd_parms *parms, void *mconfig,
03061 const char *arg )
03062 {
03063
03064 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03065 parms->server->module_config, &RioModule );
03066
03067
03068 config->MaxLogFileSize = atoi( arg ) * 1024;
03069
03070
03071 return NULL;
03072 }
03073
03074
03075
03076 static const char *setMaxCombinedLogFilesSize( cmd_parms *parms, void *mconfig,
03077 const char *arg )
03078 {
03079
03080 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03081 parms->server->module_config, &RioModule );
03082
03083
03084 config->MaxCombinedLogFilesSize = atoll( arg ) * 1024ull;
03085
03086
03087 return NULL;
03088 }
03089
03090
03091
03092
03093 static const char *setUserLogsPrefixPath( cmd_parms *parms, void *mconfig,
03094 const char *arg )
03095 {
03096
03097 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03098 parms->server->module_config, &RioModule );
03099
03100
03101 config->UserLogsPrefixPath = apr_pstrdup( parms->pool, arg );
03102
03103
03104 return NULL;
03105 }
03106
03107
03108
03109
03110 static const char *setUserLogName( cmd_parms *parms, void *mconfig,
03111 const char *arg )
03112 {
03113
03114 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03115 parms->server->module_config, &RioModule );
03116
03117
03118 config->UserLogName = apr_pstrdup( parms->pool, arg );
03119
03120
03121 return NULL;
03122 }
03123
03124
03125
03126 static const char *setExecName( cmd_parms *parms, void *mconfig,
03127 const char *arg )
03128 {
03129
03130 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03131 parms->server->module_config, &RioModule );
03132
03133
03134 config->ExecName = apr_pstrdup( parms->pool, arg );
03135
03136
03137 return NULL;
03138 }
03139
03140
03141
03142 static const char *setUserLogPort( cmd_parms *parms, void *mconfig,
03143 const char *arg )
03144 {
03145
03146 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03147 parms->server->module_config, &RioModule );
03148
03149
03150
03151 config->UserLogPort = atoi( arg );
03152
03153
03154 return NULL;
03155 }
03156
03157
03158
03159
03160 static const char *setExecSessionId( cmd_parms *parms, void *mconfig,
03161 const char *arg )
03162 {
03163
03164 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03165 parms->server->module_config, &RioModule );
03166
03167
03168
03169 config->ExecSessionId = atoi( arg );
03170
03171
03172 return NULL;
03173 }
03174
03175
03176
03177
03178 static const char *setExecLogsPrefixPath( cmd_parms *parms, void *mconfig,
03179 const char *arg )
03180 {
03181
03182 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03183 parms->server->module_config, &RioModule );
03184
03185
03186 config->ExecLogsPrefixPath = apr_pstrdup( parms->pool, arg );
03187
03188
03189 return NULL;
03190 }
03191
03192
03193
03194 static const char *setExecLogPort( cmd_parms *parms, void *mconfig,
03195 const char *arg )
03196 {
03197
03198 RioModuleConfig *config = ( RioModuleConfig * ) ap_get_module_config(
03199 parms->server->module_config, &RioModule );
03200
03201
03202
03203 config->ExecLogPort = atoi( arg );
03204
03205
03206 return NULL;
03207 }
03208
03209
03210
03211
03212 static void *CreateRioModuleConfig( apr_pool_t *p, server_rec *s )
03213 {
03214 RioModuleConfig *config;
03215
03216
03217
03218 config = (RioModuleConfig *) apr_pcalloc( p, sizeof( RioModuleConfig ) );
03219
03220
03221 config->Description = apr_pstrdup( p, MODULE_DESCRIPTION );
03222 config->ServerName = apr_pstrdup( p, DEFAULT_SERVERNAME );
03223 config->RealTimeExtensions = NULL;
03224 config->WaitTime = DEFAULT_WAITTIME;
03225 config->BufferSize = DEFAULT_BUFFERSIZE;
03226 config->LineSize = DEFAULT_LINESIZE;
03227 config->SelectionType = DEFAULT_SERVERSELECTION;
03228 config->FragmentSize = DEFAULT_FRAGMENTSIZE;
03229 config->User = apr_pstrdup( p, DEFAULT_USER );
03230 config->Password = apr_pstrdup( p, DEFAULT_USERPASSWORD );
03231 config->ServersFileName = NULL;
03232 config->RedirectName = apr_pstrdup( p, DEFAULT_REDIRECTNAME );
03233 config->TransferName = apr_pstrdup( p, DEFAULT_TRANSFERNAME );
03234 config->MaxLogFileSize = DEFAULT_MAXLOGFILESIZE * 1024;
03235 config->MaxCombinedLogFilesSize = DEFAULT_MAXCOMBINEDLOGFILESSIZE * 1024ull;
03236 config->UserLogName = apr_pstrdup( p, DEFAULT_USERLOGNAME );
03237 config->UserLogsPrefixPath = apr_pstrdup( p, DEFAULT_USERLOGSPREFIXPATH );
03238 config->ExecName = apr_pstrdup( p, DEFAULT_EXECNAME );
03239 config->UserLogPort = DEFAULT_USERLOGPORT;
03240 config->ExecSessionId = DEFAULT_EXECSESSIONID;
03241 config->ExecLogsPrefixPath = apr_pstrdup( p, DEFAULT_EXECLOGSPREFIXPATH );
03242 config->ExecLogPort = DEFAULT_EXECLOGPORT;
03243
03244 return ( void * ) config;
03245 }
03246