CServerInterface Class Reference

#include <ServerInterface.h>

Public Member Functions

 CServerInterface (server_rec *Server)
 Construtor da classe RioModule, para criar um novo objeto desta classe.
 ~CServerInterface ()
 Destrutor da classe RioModule, usado quando um objeto e removido.
bool Start (char *ServerName, unsigned int CircularBufferSize, unsigned int FragmentSize, unsigned int DefaultSessionId=0, unsigned int ExecLogPort=0)
 Funcao para inicializar o objeto da classe RioModule (ou seja, abrir a conexao e o stream).
bool Stop ()
int ExecuteCommands (request_rec *Request, char *Command, bool *RemoveObject, unsigned int *SessionId)
 Funcao para decodificar e executar todos os comandos do objeto da classe, similares aos comandos do riosh.
void GetErrors (apr_status_t *ApacheStatus, int *SystemStatus, RioResult *RioStatus)
 Funcao para retornar os codigos de erro caso alguma das funcoes acima retorne false.
bool NoError ()
 Funcao para verificar se algum erro ocorreu ao executarmos uma das funcoes da classe.
void PrintErrors ()
 Funcao para mostrar os codigos de erro no log do apache.
server_rec * GetServer ()
 Funcao para obter um ponteiro para a requisicao HTTP associada ao servidor apache2.

Static Public Member Functions

static void GenerateXMLError (request_rec *Request, apr_status_t ApacheStatus, int SystemStatus, RioResult RioStatus)
 Gera o XML com os erros passados como parametro, usando a TAG rioexec.
static void SaveExecLogLineError (request_rec *Request, apr_status_t ApacheStatus, int SystemStatus, RioResult RioStatus, const char *Command, unsigned int ExecPort)
 Gera uma linha no log da classe que executa os comandos.

Private Member Functions

bool SendBlock (request_rec *Request, const char *Data, unsigned int DataSize)
 Funcao para enviar dados ao cliente, armazenados no buffer passado no parametro Data.
bool ReceiveBlock (request_rec *Request, char *Data, unsigned int *DataSize, bool *IsEOF)
 Funcao para receber dados do cliente, os armazenando no buffer passado no parametro Data, sendo que no maximo DataSize bytes serao recebidos.
bool TerminateCopyToClient (request_rec *Request)
 Funcao para terminar o envio de dados ao client.
bool OpenRioSession (const char *ServerName, const char *UserName, const char *UserPassword)
 Funcao para abrir a sessao com o servidor RIO, com o servidor dado pelo parametro m_ServerName.
bool CloseRioSession ()
 Funcao para fechar a sessao apontada por m_Session.
bool OpenRioStream (RioStreamDirection Direction)
 Funcao para abrir um stream associado a sessao apontada pelo ponteiro m_Session.
bool CloseRioStream ()
bool OpenRioObject (const char *FileName, RioAccess Access)
bool CloseRioObject ()
bool SendSignal ()
 Funcao para gerar um sinal para a variavel de condicao m_CopyCond (esta funcao e usada pela callback chamada apos o recebimento de um bloco).
bool ReadRioObjectBlock (RioBlock Block)
bool WriteRioObjectBlock (RioBlock Block, char *Md5Sum, RioObjectSize UsedBlockSize, RioObjectSize *ActualFileSize)
void ReadRioThreadFunction ()
 Funcao usada pela thread que copia os blocos para o cliente.
void ReadApacheThreadFunction ()
 Funcao usada pela thread que copia os blocos do cliente.
bool Connect (request_rec *Request, const char *UserName, const char *UserPassword)
 Funcao para tratar da execucao do comando login (ou seja, se logar no servidor e inicializar as variaveis que dependem da conexao e criar e inicializar os objetos que tambem dependem da conexao).
bool Disconnect ()
 Funcao para fechar a sessao ativa (e o objeto e stream ativo) e remover todos as estruturas associadas a sessao atual).
void AddStatusToXML (request_rec *Request, unsigned int SessionId)
 Adiciona o estado da execucao de um comando a um xml que esta sendo gerado (o estado e composto pela id se nenhum erro ocorreu ou por uma id igual a 0 e os erros caso eles tenham ocorrido).
void GenerateXMLStatus (request_rec *Request, unsigned int CommandId, unsigned int SessionId)
 Funcao para gerar o estado da execucao dos comandos que nao retornam informacoes no XML diferente do estado (isto e, todos os comandos com excecao do sessions e do ls), usando uma TAG composta por rioexec mais, se existir, o nome do comando.
void SaveExecLogLine (request_rec *Request, const char *Command)
 Funcao para gerar uma linha no log dos comandos, usando a porta definida na classe (se o valor for 0, nenhum log sera gerado), e os erros da classe (a funcao estatica GenerateExecLogLine e usada ao gerar os logs).
bool ExecuteLoginCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando login, chamando a funcao Connect para efetuar o login no servidor e depois o XML com o resultado do comando.
bool ExecuteQuitCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando quit, usado para finalizar uma conexao ativa com o servidor RIO.
bool ExecuteSessionsCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando session, usado para mostrar as informacoes sobre as sessoes do servidor RIO.
bool ExecuteLsCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando ls, usado para mostrar as informacoes sobre um diretorio do servidor RIO.
bool ConvertPath (request_rec *Request, char *OriginalPath, char *ConvertedPath, unsigned int ConvertedPathSize)
 Funcao para converter um caminho com ".", ".." e multiplas "/" consecutivas em um caminho sem o ".", ".." e com somente uma "/" entre os componentes.
bool ExecuteRmCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando rm, usado para remover um arquivo ou um diretorio (de modo recursivo).
bool ExecuteMkdirCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando mkdir, usado para criar um diretorio.
bool FinalizeCopy (request_rec *Request)
 Funcao para cancelar uma copia em andamento.
bool Close (request_rec *Request)
 Funcao para fechar o ultimo arquivo aberto, terminando qualquer copia em andamento.
bool SendFileHeader (request_rec *Request, const char *FileName, RioObjectSize FileSize)
 Funcao para enviar um cabecalho antes dos dados do arquivo, caso o arquivo necessite do envio deste cabecalho.
int DownloadFile (request_rec *Request, const char *FileName, bool *SendXML, RioObjectSize StartPosition=0, bool SendHeader=false)
 Funcao para abrir um arquivo do servidor RIO para copiar os seus blocos para o cliente.
bool CheckDirectoryPermission (char *FileName)
 Funcao para verificar se o usuario da sessao atualmente aberta tem permissao para acessar um diretorio de um arquivo a ser lido/criado.
int ExecuteDownloadCommand (request_rec *Request, char **Params, unsigned int TotalParams)
 Funcao para efetivamente executar o comando download, usado para enviar um arquivo do servidor para o cliente.
bool ExecuteMvCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando mv, usado para criar um diretorio.
bool UploadFile (request_rec *Request, const char *FileName, char *FileMd5sum)
 Funcao para criar um arquivo no servidor RIO com os seus bytes enviados pelo cliente.
bool ExecuteUploadCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando upload, usado para enviar um arquivo do cliente para o servidor.
bool ExecuteAdduserCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando adduser, que cria um novo usuario no servidor RIO.
bool ExecuteDeluserCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando deluser, que remove um usuario do servidor RIO.
bool ExecutePasswdCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando passwd, que muda a senha de um usuario do RIO.
bool ExecuteUserListCommand (request_rec *Request, char **Params)
 Funcao para efetivamente executar o comando userlist, que retorna a lista com todos os usuarios do RIO.

Static Private Member Functions

static void ReadCallBack (RioRequest *Request)
 Funcao de callback executada apos a leitura (com sucesso ou nao) do bloco.
static void WriteCallBack (RioRequest *Request)
 Funcao de callback executada apos a escrita (com sucesso ou nao) do bloco.
static void * ReadRioThreadFunctionEp (void *Class)
 Funcao usada pela thread que copia os blocos para o cliente.
static void * ReadApacheThreadFunctionEp (void *Class)
 Funcao usada pela thread que recebe os blocos do cliente.
static void StartXML (request_rec *Request, unsigned int CommandId)
 Funcao para gerar o inicio do xml, usando uma TAG composta por rioexec mais, se existir, o nome do comando.
static void AddErrorToXML (request_rec *Request, apr_status_t ApacheStatus, int SystemStatus, RioResult RioStatus)
 Gera a parte do XML (o comando <session id="0" [erros] </session>) para os erros passados como parametros.
static void EndXML (request_rec *Request, unsigned int CommandId)
 Funcao para gerar o final do xml, usando uma TAG composta por rioexec mais, se existir, o nome do comando.
static void GenerateExecLogLine (request_rec *Request, const char *UserName, unsigned int SessionId, apr_status_t ApacheStatus, int SystemStatus, RioResult RioStatus, const char *Command, unsigned int ExecPort)
 Gera uma linha no log da classe que executa os comandos.

Private Attributes

bool m_Started
server_rec * m_Server
CRioSessionm_Session
unsigned int m_SessionId
unsigned int m_DefaultSessionId
bool m_isSessionOpen
CRioStreamm_Stream
bool m_isStreamOpen
CRioObjectm_Object
bool m_isObjectOpen
char * m_ServerName
char * m_FileName
apr_status_t m_ApacheStatus
int m_SystemStatus
RioResult m_RioStatus
CircularBufferm_CircularBuffer
unsigned int m_CircularBufferSize
char * m_RioBuffer
char * m_ApacheBuffer
RioBlock m_RioBlock
RioBlock m_SendBlock
unsigned int m_TotalBlocks
unsigned int m_BlockSize
unsigned int m_FragmentSize
bool m_isReadingRioFile
pthread_cond_t m_ReadRioStarted
pthread_cond_t m_ThreadBlocked
pthread_mutex_t m_ReadWriteMutex
pthread_cond_t m_ReadWriteCond
pthread_t m_ReadRioThread
bool m_ThreadCanceled
pthread_mutex_t m_Mutex
CModuleRioExplorerm_RioExplorer
char * m_UserName
unsigned int m_LastApacheBlockSize
bool m_IsApacheEof
request_rec * m_UploadRequest
bool m_isReadingApacheFile
pthread_cond_t m_ReadApacheStarted
pthread_t m_ReadApacheThread
unsigned int m_ExecLogPort

Detailed Description

Definition at line 109 of file ServerInterface.h.


Constructor & Destructor Documentation

CServerInterface::CServerInterface ( server_rec *  Server  ) 

Construtor da classe RioModule, para criar um novo objeto desta classe.

Parameters:
Server ponteiro para a estrutura do servidor.

Definition at line 112 of file ServerInterface.cpp.

00113 {
00114     int status;
00115     // Inicializa as variaveis da classe cujos valores sao passados ao
00116     // construtor do objeto.
00117     m_Server = Server;
00118 
00119     // Inicializa as variaveis da classe com o valor default.
00120     m_FragmentSize = 0;
00121     m_CircularBufferSize = 0;
00122     m_RioExplorer = NULL;
00123     m_Session = NULL;
00124     m_isSessionOpen = false;
00125     m_Stream = NULL;
00126     m_isStreamOpen = false;
00127     m_Object = NULL;
00128     m_isObjectOpen = false;
00129     m_CircularBuffer = NULL;
00130     m_RioBuffer = NULL;
00131     m_ApacheBuffer = NULL;
00132     m_ServerName = NULL;
00133     m_Started = false;
00134     m_ReadRioThread = 0;
00135     m_ThreadCanceled = false;
00136     m_RioBlock = 0;
00137     m_SendBlock = 0;
00138     m_TotalBlocks = 0;
00139     m_isReadingRioFile = false;
00140     m_BlockSize = 0;
00141     m_SessionId = 0;
00142     m_UserName = NULL;
00143     m_LastApacheBlockSize = 0;
00144     m_IsApacheEof = false;
00145     m_UploadRequest = NULL;
00146     m_isReadingApacheFile = false;
00147     m_ReadApacheThread = 0;
00148     m_DefaultSessionId = 0;
00149     m_ExecLogPort = 0;
00150     
00151     // Inicializa os codigos de erro.
00152     m_SystemStatus = 0;
00153     m_ApacheStatus = APR_SUCCESS;
00154     m_RioStatus = S_OK;
00155 
00156 
00157     status = pthread_mutex_init( &m_ReadWriteMutex, NULL );
00158     if( status < 0 )
00159     {
00160         m_SystemStatus = status;
00161         
00162         #ifdef RIO_DEBUG2
00163         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00164                       "Error initializing m_ReadWriteMutex: %u (%s)",
00165                       m_SystemStatus, strerror( m_SystemStatus )  );
00166         #endif               
00167 
00168         return;
00169     }
00170     
00171     status = pthread_cond_init( &m_ReadWriteCond, NULL );
00172     if( status < 0 )
00173     {
00174         m_SystemStatus = status;
00175         
00176         #ifdef RIO_DEBUG2
00177         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00178                       "Error initializing m_ReadWriteCond: %u (%s)",
00179                       m_SystemStatus, strerror( m_SystemStatus )  );
00180         #endif               
00181 
00182         return;
00183     }
00184 
00185     status = pthread_cond_init( &m_ReadRioStarted, NULL );
00186     if( status < 0 )
00187     {
00188         m_SystemStatus = status;
00189         
00190         #ifdef RIO_DEBUG2
00191         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00192                       "Error initializing m_ReadRioStarted: %u (%s)",
00193                       m_SystemStatus, strerror( m_SystemStatus )  );
00194         #endif               
00195 
00196         return;
00197     }
00198 
00199     status = pthread_cond_init( &m_ReadApacheStarted, NULL );
00200     if( status < 0 )
00201     {
00202         m_SystemStatus = status;
00203 
00204         #ifdef RIO_DEBUG2
00205         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00206                       "Error initializing m_ReadApacheStarted: %u (%s)",
00207                       m_SystemStatus, strerror( m_SystemStatus )  );
00208         #endif
00209 
00210         return;
00211     }
00212 
00213     status = pthread_cond_init( &m_ThreadBlocked, NULL );
00214     if( status < 0 )
00215     {
00216         m_SystemStatus = status;
00217         
00218         #ifdef RIO_DEBUG2
00219         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00220                       "Error initializing m_ThreadBlocked: %u (%s)",
00221                       m_SystemStatus, strerror( m_SystemStatus )  );
00222         #endif               
00223 
00224         return;
00225     }
00226 
00227     status = pthread_mutex_init( &m_Mutex, NULL ); 
00228     if( status < 0 )
00229     {
00230         m_SystemStatus = status;
00231         
00232         #ifdef RIO_DEBUG2
00233         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00234                       "Error initializing m_Mutex: %u (%s)",
00235                       m_SystemStatus, strerror( m_SystemStatus )  );
00236         #endif               
00237 
00238         return;
00239     }
00240 }

CServerInterface::~CServerInterface (  ) 

Destrutor da classe RioModule, usado quando um objeto e removido.

Definition at line 243 of file ServerInterface.cpp.

00244 {
00245     int status;
00246     // Para o objeto, se ele ja foi inicializado e nao foi parado depois
00247     // disso.
00248     if( m_Started )
00249         Stop();
00250     
00251     status = pthread_mutex_destroy( &m_ReadWriteMutex );
00252     if( status < 0 )
00253     {
00254         #ifdef RIO_DEBUG2
00255         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00256                       "Error destroying m_ReadWriteMutex: %u (%s)", status,
00257                       strerror( status )  );
00258         #endif               
00259     } 
00260 
00261     status = pthread_cond_destroy( &m_ReadWriteCond );
00262     if( status < 0 )
00263     {
00264         #ifdef RIO_DEBUG2
00265         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00266                       "Error destroying m_ReadWriteCond: %u (%s)", status,
00267                       strerror( status )  );
00268         #endif               
00269     } 
00270 
00271     status = pthread_cond_destroy( &m_ReadRioStarted );
00272     if( status  < 0 )
00273     {
00274         #ifdef RIO_DEBUG2
00275         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00276                       "Error destroying m_ReadRioStarted: %u (%s)", status,
00277                       strerror( status )  );
00278         #endif               
00279     } 
00280 
00281     status = pthread_cond_destroy( &m_ReadApacheStarted );
00282     if( status  < 0 )
00283     {
00284         #ifdef RIO_DEBUG2
00285         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00286                       "Error destroying m_ReadApacheStarted: %u (%s)", status,
00287                       strerror( status )  );
00288         #endif
00289     }
00290 
00291     status = pthread_cond_destroy( &m_ThreadBlocked ); 
00292     if( status < 0 )
00293     {
00294         #ifdef RIO_DEBUG2
00295         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00296                       "Error destroying m_ThreadBlocked: %u (%s)", status,
00297                       strerror( status )  );
00298         #endif               
00299     } 
00300 
00301     status = pthread_mutex_destroy( &m_Mutex ); 
00302     if( status < 0 )
00303     {
00304         #ifdef RIO_DEBUG2
00305         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00306                       "Error destroying m_Mutex: %u (%s)", status,
00307                        strerror( status )  );
00308         #endif               
00309     }
00310 }


Member Function Documentation

void CServerInterface::AddErrorToXML ( request_rec *  Request,
apr_status_t  ApacheStatus,
int  SystemStatus,
RioResult  RioStatus 
) [static, private]

Gera a parte do XML (o comando <session id="0" [erros] </session>) para os erros passados como parametros.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
ApacheStatus codigo de erro do Apache. Somente sera colocado no XML se for diferente de APR_SUCCESS.
SystemStatus codigo de erro do sistema. Somente sera colocado no XML se for diferente de 0.
RioStatus codigo de erro do RIO. Somente sera colocado no XML se for diferente de S_OK.

Definition at line 2376 of file ServerInterface.cpp.

02379 {
02380     // Neste caso, deveremos retornar 0 no session id e os codigos de erro
02381     // gerados (deve necessariamente existir pelo menos um codigo de erro).
02382     ap_rprintf( Request, "\t<sessionid id=\"0\">\n" );
02383 
02384     // Gera o erro do RIO, se necessario
02385     if( RioStatus != S_OK )
02386         ap_rprintf( Request, "\t\t<rioerror>%8X %s</rioerror>\n",
02387                     RioStatus, GetErrorDescription( RioStatus ).c_str() );
02388 
02389     // Gera o erro do apache (se necessario)
02390     if( ApacheStatus != APR_SUCCESS )
02391     {
02392         char ApacheStrError[ MAXAPACHESTRERRORSIZE ];
02393 
02394         // Obtem o erro do apache
02395         apr_strerror( ApacheStatus, ApacheStrError,
02396                       MAXAPACHESTRERRORSIZE );
02397 
02398         // Gera a entrada do xml com o erro
02399         ap_rprintf( Request, "\t\t<apacheerror>%u %s</apacheerror>\n",
02400                     ApacheStatus, ApacheStrError );
02401     }
02402 
02403     // Gera o erro do sistema (se necessario)
02404     if( SystemStatus != 0 )
02405         ap_rprintf( Request, "\t\t<systemerror>%u %s</systemerror>\n",
02406                     SystemStatus, strerror( SystemStatus ) );
02407 
02408     // Finaliza o comando sessionid
02409     ap_rprintf( Request, "\t</sessionid>\n" );
02410 }

void CServerInterface::AddStatusToXML ( request_rec *  Request,
unsigned int  SessionId 
) [private]

Adiciona o estado da execucao de um comando a um xml que esta sendo gerado (o estado e composto pela id se nenhum erro ocorreu ou por uma id igual a 0 e os erros caso eles tenham ocorrido).

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
SessionId identificador da sessao a ser usado caso nao exista nenhum erro reportado no objeto.

Definition at line 2413 of file ServerInterface.cpp.

02415 {
02416     if( NoError() )
02417     {
02418         // Se a execucao do comando foi correta, entao devemos somente retornar
02419         // o identificador da sessao.
02420         ap_rprintf( Request, "\t<sessionid id=\"%u\">\n", SessionId );
02421         // Finaliza o comando session
02422         ap_rprintf( Request, "\t</sessionid>\n" );
02423     }
02424     else // Chama a funcao anterior para gerar o erro.
02425         AddErrorToXML( Request, m_ApacheStatus, m_SystemStatus, m_RioStatus );
02426 }

bool CServerInterface::CheckDirectoryPermission ( char *  FileName  )  [private]

Funcao para verificar se o usuario da sessao atualmente aberta tem permissao para acessar um diretorio de um arquivo a ser lido/criado.

Parameters:
FileName ponteiro para o nome do objeto cujo caminho desejamos verificar.
Returns:
true se o arquivo pode ser acessado ou false se nao pode ser acessado ou caso algum outro erro tenha ocorrido.

Definition at line 4133 of file ServerInterface.cpp.

04134 {
04135     // Armazena um ponteiro ou para o diretorio (no caso de caminho do arquivo
04136     // ser relativo), ou para o arquivo (no caso de o caminho do arquivo ser
04137     // absoluto).
04138     char *Path;
04139     // Armazena o diretorio corrente (usado somente se o caminho for relativo).
04140     char CurrentDir[ MaxPathSize ];
04141     // Armazena o retorno de uma funcao do RIO.
04142     RioResult RioStatus;
04143 
04144     // Verifica se o nome de arquivo e absoluto. Se for relativo, devemos
04145     // obte-lo (isso e para o comando ser compativel com os outros, pois a
04146     // RioExplorer faz isso ao executar os comandos).
04147     if( FileName[ 0 ] != '/' )
04148     {
04149         // Como o caminho e relativo, precisamos tentar obter o diretorio atual.
04150         RioStatus = m_Session->GetCurrentDir( CurrentDir, MaxPathSize );
04151         if( FAILED( RioStatus ) )
04152         {
04153             m_RioStatus = RioStatus;
04154 
04155             #ifdef RIO_DEBUG2
04156             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04157                           "Erro ao obter o diretorio corrente!" );
04158             PrintErrors();
04159             #endif
04160 
04161             return false;
04162         }
04163         //return HTTP_BAD_REQUEST;
04164         Path = CurrentDir;
04165     }
04166     else
04167     {
04168         // Como temos um caminho absoluto, devemos entao usa-lo
04169         Path = FileName;
04170     }
04171 
04172     // Agora vamos verificar se o usuario pode acessar o arquivo, se o usuario
04173     // nao for o root.
04174     if( strcmp( m_UserName, "root") != 0 )
04175     {
04176         // Armazena a posicao da proxima '/'.
04177         char *PosNextBar;
04178         // Variavel que, quando true, indicara que o arquivo esta no diretorio
04179         // do usuario.
04180         bool isUserFile;
04181         // Variavel para guardar a primeira posicao da string diferente de '/'.
04182         unsigned int PosFirstComponent;
04183 
04184         // Salta as barras iniciais do caminho.
04185         PosFirstComponent = 0;
04186         while( Path[ PosFirstComponent ] == '/' )
04187             PosFirstComponent++;
04188 
04189         // Procura pela proxima barra.
04190         PosNextBar = strchr( &Path[ PosFirstComponent ], '/' );
04191 
04192         // Se o caminho for absoluto e se nao existir uma outra '/', entao o
04193         // arquivo esta na raiz, e somente o root pode acessa-lo.
04194         if( ( PosNextBar == NULL ) && ( FileName[ 0 ] != '/' ) )
04195         {
04196             #ifdef RIO_DEBUG2
04197             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04198                           "O usuario %s nao pode acessar o arquivo %s!",
04199                           m_UserName, FileName );
04200             #endif
04201 
04202             // Define o erro do RIO
04203             m_RioStatus = ERROR_SERVERINTERFACE + ERROR_OBJECT_OPEN_FAILED;
04204 
04205             return false;
04206         }
04207 
04208         // Temporariamente muda '/' para '0', para poder comparar com o nome do
04209         // usuario, se uma '/' foi encontrada.
04210         if( PosNextBar != NULL )
04211             *PosNextBar = 0;
04212 
04213         // Define se o arquivo esta ou nao no diretorio do usuario ou no var
04214         isUserFile = ( strcmp( &Path[ PosFirstComponent ], m_UserName ) == 0 );
04215 
04216         // Restaura a '/', se ela foi encontrada e mudamos antes o valor da
04217         // posicao para um '/0'.
04218         if( PosNextBar != NULL )
04219             *PosNextBar = '/';
04220 
04221         // Se o arquivo nao estiver no diretorio do usuario, retorna o erro de
04222         // permissao negada.
04223         if( !isUserFile )
04224         {
04225             #ifdef RIO_DEBUG2
04226             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04227                          "O usuario %s nao pode acessar o arquivo %s!",
04228                          m_UserName, FileName );
04229             #endif
04230 
04231             // Define o errro do RIO
04232             m_RioStatus = ERROR_SERVERINTERFACE + ERROR_OBJECT_OPEN_FAILED;
04233 
04234             return false;
04235         }
04236     }
04237 
04238     return true;
04239 }

bool CServerInterface::Close ( request_rec *  Request  )  [private]

Funcao para fechar o ultimo arquivo aberto, terminando qualquer copia em andamento.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Returns:
true se o arquivo foi fechado com sucesso ou false se algum erro ocorreu ao fecharmos o arquivo.

Definition at line 3538 of file ServerInterface.cpp.

03539 {
03540     // Tentando cancelar a copia, se ela nao foi concluida.
03541     if( !FinalizeCopy( Request ) )
03542     {
03543         #ifdef RIO_DEBUG2
03544         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03545                       "Error when executing FinalizeCopy" );
03546         #endif
03547 
03548         return false;
03549     }
03550 
03551     if( !CloseRioObject() )
03552     {
03553         #ifdef RIO_DEBUG2
03554         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03555                       "Error closing RioObject: %u (%s)", m_RioStatus,
03556                       GetErrorDescription( m_RioStatus ).c_str() );
03557         #endif
03558 
03559         return false;
03560     }
03561 
03562     if( !CloseRioStream() )
03563     {
03564         #ifdef RIO_DEBUG2
03565         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03566                       "Error closing RioStream: %u (%s)", m_RioStatus,
03567                       GetErrorDescription( m_RioStatus ).c_str() );
03568         #endif
03569 
03570         return false;
03571     }
03572 
03573     return true;
03574 }

bool CServerInterface::CloseRioObject (  )  [private]

Definition at line 1168 of file ServerInterface.cpp.

01169 {
01170     // Armazena o resultado da execucao de uma das funcoes do RIO.
01171     RioResult hResult;
01172 
01173     // Verifica se a stream e valida e se esta aberta.
01174     if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
01175     {
01176         if( m_Stream == NULL )
01177             m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
01178         else
01179             m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
01180 
01181         #ifdef RIO_DEBUG2
01182         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01183                       "Error closing object (1): %u (%s)", m_RioStatus,
01184                       GetErrorDescription( m_RioStatus ).c_str()
01185                     );
01186         #endif
01187 
01188         return false;
01189     }
01190 
01191     // Verifica se o objeto e valido e esta aberto.
01192     if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
01193     {
01194         if( m_Object == NULL )
01195             m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
01196         else
01197             m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
01198         
01199         #ifdef RIO_DEBUG2
01200         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01201                       "Error closing object (2): %u (%s)", m_RioStatus,
01202                       GetErrorDescription( m_RioStatus ).c_str() );
01203         #endif
01204         
01205         return false;
01206     }
01207 
01208     // Fecha o objeto
01209     hResult = m_Object->Close();
01210     if( FAILED( hResult ) )
01211     {
01212         m_RioStatus = hResult;
01213         
01214         #ifdef RIO_DEBUG2
01215         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01216                       "Error closing object (3): %u (%s)", m_RioStatus,
01217                       GetErrorDescription( m_RioStatus ).c_str() );
01218         #endif
01219     }
01220 
01221     // Remove o objeto com o arquivo.
01222     delete m_Object;
01223     
01224     m_isObjectOpen = false;
01225     
01226     return true;
01227 }

bool CServerInterface::CloseRioSession (  )  [private]

Funcao para fechar a sessao apontada por m_Session.

Returns:
true se a sessao foi fechada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

Definition at line 869 of file ServerInterface.cpp.

00870 {
00871     RioResult hResult;
00872 
00873     // Verifica se a sessao e valida e se esta aberta.
00874     if( ( m_Session == NULL ) || ( !m_isSessionOpen ) )
00875     {
00876         if( m_Session == NULL )
00877             m_RioStatus = ERROR_RIOSESSION + ERROR_NOT_INITIALIZED;
00878         else    
00879             m_RioStatus = ERROR_RIOSESSION + ERROR_SESSION_NOT_OPENED;
00880         
00881         #ifdef RIO_DEBUG2
00882         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00883                       "Error closing RIO session (1): %u (%s)", m_RioStatus,
00884                       GetErrorDescription( m_RioStatus ).c_str() );
00885         #endif
00886         
00887         return false;
00888     }
00889 
00890     // Tenta fechar a sessao
00891     hResult = m_Session->Disconnect();
00892     if( FAILED( hResult ) ) 
00893     {
00894         m_RioStatus = hResult;
00895 
00896         #ifdef RIO_DEBUG2
00897         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00898                       "Error closing RIO session (2): %u (%s)", m_RioStatus,
00899                       GetErrorDescription( m_RioStatus ).c_str() );
00900         #endif
00901         
00902         return false;
00903     } 
00904 
00905     // Remove o objeto com a sessao.
00906     delete m_Session;
00907     m_Session = NULL;
00908 
00909     m_isSessionOpen = false;
00910 
00911     return true;
00912 }

bool CServerInterface::CloseRioStream (  )  [private]

Definition at line 1002 of file ServerInterface.cpp.

01003 {
01004     // Armazena o resultado da execucao de uma das funcoes do RIO.
01005     RioResult hResult;
01006     // Armazena o estado de execucao de uma das funcoes da classe.
01007     bool Status;
01008 
01009     // Verifica se a stream e valida e se esta aberta.
01010     if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
01011     {
01012         if( m_Stream == NULL )
01013             m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
01014         else
01015             m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
01016         
01017         #ifdef RIO_DEBUG2
01018         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01019                       "Error closing RIO stream (1): %u (%s)",
01020                       m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
01021                     );
01022         #endif
01023         
01024         return false;
01025     }
01026     
01027     // Tenta fechar o stream.
01028     hResult = m_Stream->Close();
01029     if( FAILED( hResult ) ) 
01030     {
01031         m_RioStatus = hResult;
01032         
01033         #ifdef RIO_DEBUG2
01034         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01035                       "Error closing RIO stream (2): %u (%s)",
01036                       m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
01037                     );
01038         #endif
01039         
01040         Status = false;
01041     }
01042     else
01043         Status = true;
01044 
01045     m_isStreamOpen = false;
01046 
01047     // Remove o objeto com o stream.
01048     delete m_Stream;
01049 
01050     return Status;
01051 }

bool CServerInterface::Connect ( request_rec *  Request,
const char *  UserName,
const char *  UserPassword 
) [private]

Funcao para tratar da execucao do comando login (ou seja, se logar no servidor e inicializar as variaveis que dependem da conexao e criar e inicializar os objetos que tambem dependem da conexao).

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
UserName nome do usuario para o qual desejamos abrir uma sessao.
UserPassword senha do usuario UserName no servidor.
Returns:
true se a conexao foi aberta com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2098 of file ServerInterface.cpp.

02100 {
02101     // Armazena o codigo de erro de uma das funcoes do RIO.
02102     RioResult hResult;
02103     // Armazena o codigo de erro de uma das funcoes do sistema.
02104     int error;
02105 
02106     // Tenta abrir a sessao associada ao modulo.
02107     // Obs: devemos criar uma variavel, no modulo, indicando o usuario e a
02108     // senha, ou devemos obter isso do arquivo .rio e do arquivo de configuracao
02109     // (caso seja passado um nome a funcao)?
02110     if( !OpenRioSession( m_ServerName, UserName, UserPassword ) )
02111     {
02112         #ifdef RIO_DEBUG2
02113         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02114                        "Error creating RioSession: %u (%s)",
02115                        m_RioStatus,
02116                        GetErrorDescription( m_RioStatus ).c_str() );
02117         #endif
02118         return false;
02119     }
02120 
02121     // Obtem o tamanho do bloco.
02122     hResult = m_Session->GetBlockSize( &m_BlockSize );
02123     if( FAILED( hResult ) )
02124     {
02125         m_RioStatus = hResult;
02126 
02127         #ifdef RIO_DEBUG2
02128         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02129                        "Error getting block size: %u (%s)", m_RioStatus,
02130                        GetErrorDescription( m_RioStatus ).c_str() );
02131         #endif
02132 
02133         return false;
02134     }
02135 
02136     // Tenta criar o buffer que armazenara o ultimo bloco lido (ou escrito) no
02137     // RIO.
02138     try
02139     {
02140         m_RioBuffer = new char[ m_BlockSize ];
02141     }
02142     catch( bad_alloc &ba )
02143     {
02144         m_SystemStatus = ENOMEM;
02145 
02146         #ifdef RIO_DEBUG2
02147         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02148                        "Erro allocating (bad_alloc, error=%s) m_RioBuffer: %u "
02149                        "(%s)", ba.what(), m_SystemStatus,
02150                        strerror( m_SystemStatus ) );
02151         #endif
02152 
02153         if( !CloseRioSession() )
02154         {
02155             #ifdef RIO_DEBUG2
02156             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02157                            "Error closing RioSession: %u (%s)", m_RioStatus,
02158                            GetErrorDescription( m_RioStatus ).c_str() );
02159             #endif
02160         }
02161 
02162         return false;
02163     }
02164 
02165     // Tenta criar o buffer que armazenara o ultimo bloco enviado (ou recebido)
02166     // do cliente
02167     try
02168     {
02169         m_ApacheBuffer = new char[ m_BlockSize ];
02170     }
02171     catch( bad_alloc &ba )
02172     {
02173         m_SystemStatus = ENOMEM;
02174 
02175         #ifdef RIO_DEBUG2
02176         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02177                        "Erro allocating (bad_alloc, error=%s) block buffer: "
02178                        "%u (%s)", ba.what(), m_SystemStatus,
02179                        strerror( m_SystemStatus ) );
02180         #endif
02181 
02182         // Deleta os bufferes do bloco.
02183         delete[] m_RioBuffer;
02184         m_RioBuffer = NULL;
02185 
02186         if( !CloseRioSession() )
02187         {
02188             #ifdef RIO_DEBUG2
02189             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02190                            "Error closing RioSession: %u (%s)", m_RioStatus,
02191                            GetErrorDescription( m_RioStatus ).c_str() );
02192             #endif
02193         }
02194 
02195         return false;
02196     }
02197 
02198     // Tenta criar um objeto da classe CircularBuffer, usada para armazenar os
02199     // blocos lidos.
02200     try
02201     {
02202         m_CircularBuffer = new CircularBuffer( m_Server, m_CircularBufferSize,
02203                                                m_BlockSize );
02204     }
02205     catch( bad_alloc &ba )
02206     {
02207         m_SystemStatus = ENOMEM;
02208 
02209         #ifdef RIO_DEBUG2
02210         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02211                        "Erro allocating circular buffer (bad_alloc, error=%s): "
02212                        "%u (%s)", ba.what(),  m_SystemStatus,
02213                        strerror( m_SystemStatus ) );
02214         #endif
02215 
02216         if( !CloseRioSession() )
02217         {
02218             #ifdef RIO_DEBUG2
02219             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02220                            "Error closing RioSession: %u (%s)", m_RioStatus,
02221                            GetErrorDescription( m_RioStatus ).c_str() );
02222             #endif
02223         }
02224 
02225         // Deleta os bufferes do bloco.
02226         delete[] m_RioBuffer;
02227         m_RioBuffer = NULL;
02228         delete[] m_ApacheBuffer;
02229         m_ApacheBuffer = NULL;
02230 
02231         // Deleta o buffer circular.
02232         delete m_CircularBuffer;
02233         m_CircularBuffer = NULL;
02234 
02235         return false;
02236     }
02237 
02238     // Verifica se a classe inicializou corretamente.
02239     error = m_CircularBuffer->GetError();
02240     if( error != 0 )
02241     {
02242         m_SystemStatus = error;
02243 
02244         #ifdef RIO_DEBUG2
02245         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02246                        "Erro allocating circular buffer: %u (%s)",
02247                        m_SystemStatus, strerror( m_SystemStatus ) );
02248         #endif
02249 
02250         if( !CloseRioSession() )
02251         {
02252             #ifdef RIO_DEBUG2
02253             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02254                            "Error closing RioSession: %u (%s)", m_RioStatus,
02255                            GetErrorDescription( m_RioStatus ).c_str() );
02256             #endif
02257         }
02258 
02259         // Deleta os bufferes do bloco.
02260         delete[] m_RioBuffer;
02261         m_RioBuffer = NULL;
02262         delete[] m_ApacheBuffer;
02263         m_ApacheBuffer = NULL;
02264 
02265         // Deleta o buffer circular.
02266         delete m_CircularBuffer;
02267         m_CircularBuffer = NULL;
02268 
02269         return false;
02270     }
02271 
02272     // Escolhe aleatoriamente uma session id diferente de 0, se
02273     // m_DefaultSessionId for 0. Se for diferente de 0, sempre usaremos o valor
02274     // de m_DefaultSessionId.
02275     if( m_DefaultSessionId == 0 )
02276     {
02277         m_SessionId = 0;
02278         while( m_SessionId == 0 )
02279         {
02280             m_SessionId = random();
02281         }
02282     }
02283     else
02284         m_SessionId = m_DefaultSessionId;
02285 
02286     // Associada a sessao criada ao objeto derivado do RioExplorer.
02287     m_RioExplorer->setSession( m_Session );
02288 
02289     #ifdef RIO_DEBUG2
02290     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02291                    "Conectado com sucesso ao servidor %s, usando o usuario %s "
02292                    "e a senha %s !", m_ServerName, UserName, UserPassword );
02293     #endif
02294 
02295     return true;
02296 }

bool CServerInterface::ConvertPath ( request_rec *  Request,
char *  OriginalPath,
char *  ConvertedPath,
unsigned int  ConvertedPathSize 
) [private]

Funcao para converter um caminho com ".", ".." e multiplas "/" consecutivas em um caminho sem o ".", ".." e com somente uma "/" entre os componentes.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
OriginalPath string com o caminho a ser convertido.
ConvertedPath string que armazenara o caminho convertido.
ConvertedPathSize numero maximo de caracteres que podem existir no caminho convertido (sem contar o terminador).
Returns:
true se o caminho foi convertido com sucesso e false caso algum erro ocorreu (a variavel m_RioStatus indicara qual foi o erro).

Definition at line 3040 of file ServerInterface.cpp.

03043 {
03044     // Armazena o estado da execucao da funcao.
03045     bool Status;
03046 
03047     // Armazena as posicoes sobre o caminho original (que esta sendo
03048     // convertido)
03049     unsigned int StartComp, EndComp;
03050     // Armazena o tamnho do componente;
03051     unsigned int CompSize;
03052 
03053     // Armazena as posicoes
03054 
03055     // Inicializa as variaveis.
03056     Status = true;
03057     ConvertedPath[ 0 ] = '\0';
03058     StartComp = 0;
03059 
03060     // Processa o caminho ate atingirmos o final da string e enquanto nao
03061     // ocorrer nenhum erro.
03062     while( ( OriginalPath[ StartComp ] != '\0' ) && ( Status ) )
03063     {
03064         #ifdef RIO_DEBUG2
03065         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03066                        "Verificando a partir de %s, Novo caminho e igual a %s",
03067                        &OriginalPath[ StartComp ], ConvertedPath );
03068         #endif
03069 
03070         // Inicialmente pulamos todos os "/" duplicados.
03071         while( OriginalPath[ StartComp ] == '/' )
03072             StartComp++;
03073 
03074         // Agora vamos procurar pelo final do caminho atual, se nao chegamos ao
03075         // final da string.
03076         if( OriginalPath[ StartComp ] != '\0' )
03077         {
03078             EndComp = StartComp; // Primeiro caractere diferente de "/".
03079 
03080             // Procuramos agora pelo final da componente atual.
03081             while( ( OriginalPath[ EndComp ] != '/' ) &&
03082                    ( OriginalPath[ EndComp ] != '\0') )
03083                 EndComp++;
03084 
03085             // ao sair do while, EndComp esta no caractere '/' ou no terminador
03086             // da string. Com isso, o componente estara entre os caracteres de
03087             // StartComp ate EndComp - 1 de OriginalPath, e EndComp - StartComp
03088             // sera o numero de caracteres da componente.
03089 
03090             // Armazena o tamanho do componente
03091             CompSize = EndComp - StartComp;
03092 
03093             // O que precisamos fazer a seguir depende do componente.
03094             if( CompSize == 0 )
03095             {
03096                 // Neste caso, necessariamente deveriamos estar no final da
03097                 // string, pois o caso intermediario de "/" consecutivas e
03098                 // tratado anteriormente. Se isso nao ocorrer, entao temos
03099                 // um erro na execucao.
03100                 if( OriginalPath[ StartComp ] != '\0' )
03101                 {
03102                     #ifdef RIO_DEBUG2
03103                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03104                                    "Erro de implementacao ao converter o "
03105                                    "caminho %s!", OriginalPath );
03106                     #endif
03107 
03108                     ConvertedPath[ 0 ] = '\0';
03109                     m_RioStatus = ERROR_SERVERINTERFACE + ERROR_UNEXPECTED;
03110                     Status = false;
03111                 }
03112             }
03113             else if( ( CompSize == 1 ) && ( OriginalPath[ StartComp ] == '.' ) )
03114             {
03115                 // Neste caso, como o componente e um "." ele deve ser ignorado,
03116                 // ou seja, nao precisamos fazer nada.
03117             }
03118             else if( ( CompSize == 2 ) &&
03119                      ( OriginalPath[ StartComp ] == '.' ) &&
03120                      ( OriginalPath[ StartComp + 1 ] == '.' ) )
03121             {
03122                 // Neste caso, o componente e o "..". Precisamos entao remover,
03123                 // de AuxPath, o diretorio anteriormente copiado. Para isso,
03124                 // procuramos pelo ultimo "/" nesse caminho.
03125                 char *StartLastDir;
03126 
03127                 // Procura pela ultima '/'.
03128                 StartLastDir = strrchr( ConvertedPath, '/' );
03129 
03130                 // Se uma '/' nao existir, entao devemos remover todo o caminho.
03131                 if( StartLastDir == NULL )
03132                     StartLastDir = ConvertedPath;
03133                 else if( StartLastDir == ConvertedPath )
03134                 {
03135                     // Neste caso o caminho e absoluto porque temos pelo menos
03136                     // uma '/' no inicio, que nunca deve ser removida. Logo,
03137                     // devemos incrementar o ponteiro caso StartLastDir seja
03138                     // exatamente esta '/'.
03139                     StartLastDir++;
03140                 }
03141 
03142                 // Se a componente nao for vazia, a removemos. Em caso
03143                 // contrario, temos um erro, porque nao existe diretorio para
03144                 // voltarmos.
03145                 if( strlen( StartLastDir ) > 0 )
03146                 {
03147                     // Ignora a componente juntamente com a '/' se ela exisitir
03148                     // e nao for o unico caractere do caminho.
03149                     *StartLastDir = '\0';
03150                 }
03151                 else
03152                 {
03153                     // Nao existe mais componentes para voltar. Devemos dar
03154                     // um erro neste caso?
03155                     #ifdef RIO_DEBUG2
03156                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03157                                    "Erro de sintaxe no caminho %s!",
03158                                    OriginalPath );
03159                     #endif
03160 
03161                     ConvertedPath[ 0 ] = '\0';
03162                     m_RioStatus = ERROR_SERVERINTERFACE +
03163                                   ERROR_PATHNAME_BADSYNTAX;
03164                     Status = false;
03165                 }
03166             }
03167             else
03168             {
03169                 // Armazena o tamanho a ser adicionado ao caminho.
03170                 unsigned int ConvertedCompSize;
03171 
03172                 // Armazena o tamanho atual do caminho
03173                 unsigned int ActualConvertedPathSize;
03174 
03175                 // Temos uma componente nao vazia diferente de "." e "..". Ela
03176                 // deve ser entao copiada para o caminho final. Uma '/' deve
03177                 // ser colocada antes da componente se estivermos no meio do
03178                 // caminho ou, alternativamente, se estivermos no inicio e o
03179                 // caminho OriginalPath for absoluto.
03180 
03181                 // Inicializa o tamamnho da componente.
03182                 ConvertedCompSize = CompSize;
03183 
03184                 // Inicializa o tamanho atual do caminho convertido.
03185                 ActualConvertedPathSize = strlen( ConvertedPath );
03186 
03187                 // Se o caminho original for absoluto e estivernos na primeira
03188                 // componente ou se estivermos em uma outra componente diferente
03189                 // da primeira, devemos incrementar ConvertedCompSize em 1, para
03190                 // contar a '/' apos a componente anterior.
03191                 if( ( ActualConvertedPathSize == 0 ) ||
03192                     ( ConvertedPath[ ActualConvertedPathSize - 1 ] != '/' ) )
03193                     ConvertedCompSize++;
03194 
03195                 // Antes de adicionarmos a '/', se necessario e a componente,
03196                 // verificamos se temos espaco na string.
03197                 if( ( ActualConvertedPathSize + ConvertedCompSize ) >
03198                       ConvertedPathSize )
03199                 {
03200                     // Neste caso, nao temos espaco mais para a componente.
03201                     #ifdef RIO_DEBUG2
03202                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03203                                    "O caminho %s e muito grande!",
03204                                    OriginalPath );
03205                     #endif
03206 
03207                     ConvertedPath[ 0 ] = '\0';
03208                     m_RioStatus = ERROR_SERVERINTERFACE +
03209                                   ERROR_PATHNAME_TOOLARGE;
03210                     Status = false;
03211                 }
03212                 else
03213                 {
03214                     // Adicionamos a componente e uma '/' antes, se necessario.
03215                     if( ( ActualConvertedPathSize == 0 ) ||
03216                         ( ConvertedPath[ ActualConvertedPathSize - 1 ] != '/' )
03217                       )
03218                         strcat( ConvertedPath, "/" );
03219                     strncat( ConvertedPath, &OriginalPath[ StartComp ],
03220                              CompSize );
03221                 }
03222             }
03223 
03224             // Atualiza o ponteiro para a proxima componente.
03225             StartComp = EndComp;
03226         }
03227     }
03228 
03229     #ifdef RIO_DEBUG2
03230     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03231                    "Novo caminho final e igual a %s, Status = %u",
03232                    ConvertedPath, ( unsigned int ) Status );
03233     #endif
03234 
03235     return Status;
03236 }

bool CServerInterface::Disconnect (  )  [private]

Funcao para fechar a sessao ativa (e o objeto e stream ativo) e remover todos as estruturas associadas a sessao atual).

Returns:
true se a conexao foi fechada com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2300 of file ServerInterface.cpp.

02301 {
02302     int Status;
02303 
02304     // Define que nao existe uma sessao associada ao objeto derivado do
02305     // RioExplorer.
02306     m_RioExplorer->setSession( NULL );
02307 
02308     Status = CloseRioSession();
02309     if( !Status )
02310     {
02311         #ifdef RIO_DEBUG2
02312         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02313                       "Error closing RioSession: %u (%s)",
02314                        m_RioStatus,
02315                        GetErrorDescription( m_RioStatus ).c_str() );
02316         #endif
02317         return false;
02318     }
02319 
02320     // Deleta os bufferes do bloco.
02321     if( m_RioBuffer != NULL )
02322         delete[] m_RioBuffer;
02323     m_RioBuffer = NULL;
02324     if( m_ApacheBuffer != NULL )
02325         delete[] m_ApacheBuffer;
02326     m_ApacheBuffer = NULL;
02327 
02328     // Deleta o buffer circular.
02329     if( m_CircularBuffer != NULL )
02330         delete m_CircularBuffer;
02331     m_CircularBuffer = NULL;
02332 
02333     return true;
02334 }

int CServerInterface::DownloadFile ( request_rec *  Request,
const char *  FileName,
bool *  SendXML,
RioObjectSize  StartPosition = 0,
bool  SendHeader = false 
) [private]

Funcao para abrir um arquivo do servidor RIO para copiar os seus blocos para o cliente.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
FileName ponteiro para o nome do arquivo a ser aberto.
SendXML ponteiro para um valor booleano que, depois da execucao da funcao, sera true se um XML deve ser enviado em caso de erro ou igual a false em caso contrario.
StartPosition posicao do byte inicial do arquivo a ser copiado. Se nao for usado, a posicao inicial sera 0, o primeiro byte do arquivo
SendHeader se for igual a true, deveremos enviar um cabecalho (atualmente, somente para os arquivos .flv) se StartPosition for diferente de 0.
Returns:
OK se a copia foi executada com sucesso ou o codigo adequado do protocolo HTTP em caso contrario.

Definition at line 3624 of file ServerInterface.cpp.

03627 {
03628     RioResult hResult;
03629     int status;
03630     RioObjectSize FileSize;
03631     RioObjectSize RealFileSize;
03632     bool isFirstBlock;
03633     RioObjectSize StartFirstBlock;
03634     bool HasNextBlock;
03635     RioBlock Block;
03636     const char *FileNamePos;
03637     char *Data;
03638     unsigned int DataSize;
03639     char HeaderLine[ MaxPathSize ];
03640 
03641     // Inicializa a variavel de envio ou nao do XML. Ate comecarmos a enviar um
03642     // arquivo, o XML sempre deve ser enviado caso algum erro ocorra.
03643     *SendXML = true;
03644 
03645     // Variavel para criar uma subrequest (para descobrir o tipo do arquivo).
03646     request_rec *SubRequest;
03647 
03648     // Obtem o mutex para acessar exclusivamente as variaveis do buffer.
03649     status = pthread_mutex_lock( &m_Mutex );
03650     if( status < 0 )
03651     {
03652         m_SystemStatus = status;
03653 
03654         #ifdef RIO_DEBUG2
03655         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03656                       "Error locking m_Mutex: %u (%s)",
03657                       m_SystemStatus, strerror( m_SystemStatus )  );
03658 
03659         #endif
03660 
03661         return HTTP_INTERNAL_SERVER_ERROR;
03662     }
03663 
03664     // Verifica se uma copia esta em progresso.
03665     if( ( m_isReadingRioFile ) || ( m_SendBlock < m_TotalBlocks ) )
03666     {
03667         #ifdef RIO_DEBUG2
03668         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03669                       "A copy is already in progress" );
03670         #endif
03671 
03672         // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03673         status = pthread_mutex_unlock( &m_Mutex );
03674         if( status < 0 )
03675         {
03676             m_SystemStatus = status;
03677 
03678             #ifdef RIO_DEBUG2
03679             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03680                           "Error unlocking m_Mutex: %u (%s)",
03681                           m_SystemStatus, strerror( m_SystemStatus )  );
03682             #endif
03683         }
03684 
03685         return HTTP_INTERNAL_SERVER_ERROR;
03686     }
03687 
03688     // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03689     status = pthread_mutex_unlock( &m_Mutex );
03690     if( status < 0 )
03691     {
03692         m_SystemStatus = status;
03693 
03694         #ifdef RIO_DEBUG2
03695         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03696                       "Error unlocking m_Mutex: %u (%s)",
03697                       m_SystemStatus, strerror( m_SystemStatus )  );
03698         #endif
03699 
03700         return HTTP_INTERNAL_SERVER_ERROR;
03701     }
03702 
03703     // Abre um stream para lermos dados
03704     if( !OpenRioStream( RioStreamDirectionRead ) )
03705     {
03706         #ifdef RIO_DEBUG2
03707         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03708                       "Error creating RIO Stream: %u (%s)", m_RioStatus,
03709                       GetErrorDescription( m_RioStatus ).c_str() );
03710         #endif
03711 
03712         return HTTP_SERVICE_UNAVAILABLE;
03713     }
03714 
03715     // Tenta abrir o arquivo que desejamos ler.
03716     if( !OpenRioObject( FileName, RIO_READ_MASK ) )
03717     {
03718         #ifdef RIO_DEBUG2
03719         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03720                       "Error opening RioObject: %u (%s)", m_RioStatus,
03721                       GetErrorDescription( m_RioStatus ).c_str() );
03722         #endif
03723 
03724         if( !CloseRioStream() )
03725         {
03726             #ifdef RIO_DEBUG2
03727             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03728                           "Error closing RioStream: %u (%s)", m_RioStatus,
03729                           GetErrorDescription( m_RioStatus ).c_str() );
03730             #endif
03731         }
03732 
03733         // Verifica o erro, para retornarmos o erro correto de acordo com o erro
03734         // gerado ao tentar abrir o arquivo.
03735         if( ( m_RioStatus & 0xFF ) == ERROR_INVALID_OBJECTNAME )
03736             return HTTP_NOT_FOUND;
03737         else
03738             return HTTP_SERVICE_UNAVAILABLE;
03739     }
03740 
03741     // Tenta obter o tamanho do arquivo.
03742     hResult = m_Object->GetSize( &FileSize );
03743 
03744     if( FAILED( hResult ) )
03745     {
03746         m_RioStatus = hResult;
03747 
03748         #ifdef RIO_DEBUG2
03749         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03750                       "Error getting object size: %u (%s)", m_RioStatus,
03751                       GetErrorDescription( m_RioStatus ).c_str() );
03752         #endif
03753 
03754         return HTTP_SERVICE_UNAVAILABLE;
03755     }
03756 
03757     // Verifica se a posicao inicial e valida (se e maior do que o
03758     // tamanho do arquivo).
03759     if( ( ( StartPosition < -FileSize ) ) || ( StartPosition  >= FileSize ) )
03760     {
03761         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_INVALID_PARAM;
03762 
03763         #ifdef RIO_DEBUG2
03764         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03765                       "Invalid start position %lld >= file size %lld: "
03766                       "%u (%s)", StartPosition, FileSize, m_RioStatus,
03767                       GetErrorDescription( m_RioStatus ).c_str() );
03768         #endif
03769 
03770         return HTTP_BAD_REQUEST;
03771     }
03772 
03773     // Verifica se precisamos ajustar o valor de StartPosition. Se o valor
03774     // for negativo, o valor real que deveremos usar e
03775     // FileSize + StartPosition ("+" porque o valor e negativo), pois
03776     // neste caso estamos contando as posicoes a partir do final.
03777     if( StartPosition < 0 )
03778         StartPosition = FileSize + StartPosition;
03779 
03780     // Obtem o mutex para acessar exclusivamente as variaveis do buffer.
03781     status = pthread_mutex_lock( &m_Mutex );
03782     if( status < 0 )
03783     {
03784         m_SystemStatus = status;
03785 
03786         #ifdef RIO_DEBUG2
03787         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03788                       "Error locking m_Mutex: %u (%s)",
03789                       m_SystemStatus, strerror( m_SystemStatus )  );
03790         #endif
03791 
03792         if( !Close( Request ) )
03793         {
03794             #ifdef RIO_DEBUG2
03795             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03796                           "Error when executing Close" );
03797             #endif
03798         }
03799 
03800         return HTTP_INTERNAL_SERVER_ERROR;
03801     }
03802 
03803     // Calcula o numero de blocos.
03804     m_TotalBlocks = ( FileSize + m_BlockSize - 1 ) / m_BlockSize;
03805 
03806     // Calcula o bloco inicial do arquivo a ser enviado.
03807     m_RioBlock = StartPosition / m_BlockSize;
03808     m_SendBlock = m_RioBlock;
03809 
03810     // Calcula a posicao inicial dentro do primeiro bloco.
03811     StartFirstBlock = StartPosition % m_BlockSize;
03812 
03813     // Define que o proximo bloco sera o primeiro bloco (esta variavel se
03814     // tornara false apos este bloco ser copiado)
03815     isFirstBlock = true;
03816 
03817     // Informa que comecamos a copia do arquivo.
03818     m_isReadingRioFile = true;
03819 
03820     // Inicializa o buffer circular (caso ja tenha sido inicializado).
03821     if( !m_CircularBuffer->ReinitializeBuffer() )
03822     {
03823         m_SystemStatus = m_CircularBuffer->GetError();
03824 
03825         #ifdef RIO_DEBUG2
03826         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03827                      "Error reinitializing circular buffer: %u (%s)",
03828                       m_SystemStatus, strerror( m_SystemStatus ) );
03829         #endif
03830 
03831         // Cancela a copia atual.
03832         if( !Close( Request ) )
03833         {
03834             #ifdef RIO_DEBUG2
03835             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03836                           "Error when executing Close" );
03837             #endif
03838         }
03839 
03840         return HTTP_INTERNAL_SERVER_ERROR;
03841     }
03842 
03843     // Envia um sinal para desbloquear a thread, pois iniciamos uma copia de
03844     // dados.
03845     status = pthread_cond_signal( &m_ReadRioStarted );
03846     if( status < 0 )
03847     {
03848         m_SystemStatus = status;
03849 
03850         #ifdef RIO_DEBUG2
03851         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03852                       "Error signalling m_ReadRioStarted: %u (%s)",
03853                       m_SystemStatus, strerror( m_SystemStatus )  );
03854         #endif
03855 
03856         return false;
03857     }
03858 
03859     // Verifica se existem blocos para serem copiados.
03860     HasNextBlock = ( m_SendBlock < m_TotalBlocks );
03861 
03862     // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03863     status = pthread_mutex_unlock( &m_Mutex );
03864     if( status < 0 )
03865     {
03866         m_SystemStatus = status;
03867 
03868         #ifdef RIO_DEBUG2
03869         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03870                       "Error unlocking m_Mutex: %u (%s)",
03871                       m_SystemStatus, strerror( m_SystemStatus )  );
03872         #endif
03873 
03874         if( !Close( Request ) )
03875         {
03876             #ifdef RIO_DEBUG2
03877             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03878                           "Error when executing Close" );
03879             #endif
03880         }
03881 
03882         return HTTP_INTERNAL_SERVER_ERROR;
03883     }
03884 
03885     // Primeiramente, vamos procurar a posicao do nome do arquivo no
03886     // seu caminho.
03887     FileNamePos = strrchr( FileName, '/' );
03888     if( FileNamePos == NULL )
03889         FileNamePos = FileName;
03890     else
03891         FileNamePos++;
03892 
03893     // Define o nome do arquivo que sera mostrado ao salvar, por exemplo, o
03894     // arquivo em um browser (a mesma "dica" do XML).
03895     sprintf( HeaderLine, "inline; filename=%s", FileNamePos );
03896 
03897     // Coloca o nome do arquivo no cabecalho de saida.
03898     apr_table_set( Request->headers_out, RIOMODULE_HTTP_FILENAME,
03899                    HeaderLine );
03900 
03901     // Coloca o tipo do arquivo a ser copiado do servidor RIO.
03902     // Cria a subrequest para descobrir o tipo do arquivo.
03903     #ifdef RIO_DEBUG2
03904     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03905                   "Creating subrequest for file %s", FileNamePos );
03906     #endif
03907 
03908     // Descobre o tipo do arquivo.
03909     SubRequest = ap_sub_req_lookup_uri( FileNamePos, Request, NULL );
03910     if( SubRequest == NULL )
03911     {
03912         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03913                       "Error creating subrequest. Using default type %s",
03914                       RIOMODULE_MIME );
03915         ap_set_content_type( Request, RIOMODULE_MIME );
03916     }
03917     else
03918     {
03919         #ifdef RIO_DEBUG2
03920         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03921                       "Subrequest content-type: %s",
03922                       SubRequest->content_type );
03923         #endif
03924 
03925         // Define o tipo como o tipo do arquivo descoberto, setando para
03926         // o default se o tipo nao foi descoberto.
03927         if( SubRequest->content_type != NULL )
03928             ap_set_content_type( Request, SubRequest->content_type );
03929         else
03930             ap_set_content_type( Request, RIOMODULE_MIME );
03931 
03932         // Remove a sub-requisicao criada para descobrir o tipo do arquivo.
03933         ap_destroy_sub_req( SubRequest );
03934     }
03935 
03936     // Salva o tamanho do arquivo, que podera ser maior se o cabecalho for
03937     // colocado.
03938     RealFileSize = FileSize - StartPosition;
03939 
03940     // Verifica se devemos enviar o cabecalho (isso somente ocorrera se
03941     // StartPosition for maior do que 0, SendHeader for true, e o arquivo
03942     // for um dos arquivos para os quais precisamos enviar um cabecalho
03943     // neste caso).
03944     if( ( StartPosition > 0 ) && ( SendHeader ) )
03945     {
03946         if( !SendFileHeader( Request, FileName, RealFileSize ) )
03947         {
03948             #ifdef RIO_DEBUG2
03949             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03950                           "Error when sending header for file %s ",
03951                           FileName );
03952             #endif
03953 
03954             if( !Close( Request ) )
03955             {
03956                 #ifdef RIO_DEBUG2
03957                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03958                               "Error when executing Close" );
03959                 #endif
03960             }
03961 
03962             return HTTP_SERVICE_UNAVAILABLE;
03963         }
03964     }
03965     else
03966     {
03967         // Envia para o cliente o tamanho do arquivo a ser enviado.
03968         // Obs: Se a funcao que coloca cabecalho for chamada (o cabecalho ser
03969         // enviado dependera de o arquivo exigir isso ou nao), o tamanho sera
03970         // definido dentro desta funcao.
03971         ap_set_content_length( Request, RealFileSize );
03972     }
03973 
03974     // Agora que vamos comecar a enviar os blocos ao cliente, nao podemos mais
03975     // enviar o XML caso um erro ocorra.
03976     *SendXML = false;
03977 
03978     // Copia ate que todos os blocos sejam enviados ou ate que um erro ocorra.
03979     while( HasNextBlock )
03980     {
03981         // O acesso e para enviar um arquivo do servidor para o cliente. Obtem
03982         // o mutex para acessar exclusivamente as variaveis do buffer.
03983         status = pthread_mutex_lock( &m_Mutex );
03984         if( status < 0 )
03985         {
03986             m_SystemStatus = status;
03987 
03988             #ifdef RIO_DEBUG2
03989             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03990                           "Error locking m_Mutex: %u (%s)",
03991                           m_SystemStatus, strerror( m_SystemStatus )  );
03992             #endif
03993 
03994             // Cancela a copia atual.
03995             if( !Close( Request ) )
03996             {
03997                 #ifdef RIO_DEBUG2
03998                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03999                               "Error when executing Close" );
04000                 #endif
04001             }
04002 
04003             return HTTP_INTERNAL_SERVER_ERROR;
04004         }
04005 
04006         Block = m_SendBlock;
04007         m_SendBlock++;
04008 
04009         #ifdef RIO_DEBUG2
04010         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04011                       "Trying to copy block %u", m_SendBlock - 1 );
04012         #endif
04013 
04014         HasNextBlock = ( m_SendBlock < m_TotalBlocks );
04015 
04016         // Libera o mutex para acessar exclusivamente as variaveis do buffer.
04017         status = pthread_mutex_unlock( &m_Mutex );
04018         if( status < 0 )
04019         {
04020             m_SystemStatus = status;
04021 
04022             #ifdef RIO_DEBUG2
04023             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04024                           "Error unlocking m_Mutex: %u (%s)",
04025                            m_SystemStatus, strerror( m_SystemStatus )  );
04026             #endif
04027 
04028             // Cancela a copia atual.
04029             if( !Close( Request ) )
04030             {
04031                 #ifdef RIO_DEBUG2
04032                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04033                               "Error when executing Close" );
04034                 #endif
04035             }
04036 
04037             return HTTP_INTERNAL_SERVER_ERROR;
04038         }
04039 
04040         // Obtem o proximo bloco do buffer circular.
04041 
04042         if( !m_CircularBuffer->GetElement( m_ApacheBuffer ) )
04043         {
04044             m_SystemStatus = m_CircularBuffer->GetError();
04045 
04046             #ifdef RIO_DEBUG2
04047             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04048                          "Error reading block %u from circular buffer: %u (%s)",
04049                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
04050             #endif
04051 
04052             // Cancela a copia atual.
04053             if( !Close( Request ) )
04054             {
04055                 #ifdef RIO_DEBUG2
04056                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04057                               "Error when executing Close" );
04058                 #endif
04059             }
04060 
04061             return HTTP_INTERNAL_SERVER_ERROR;
04062         }
04063 
04064         // Descobre o que deve ser copiado. Se for o primeiro bloco, deveremos
04065         // descartar os bytes iniciais, se o inicio da copia nao for no inicio
04066         // do bloco.
04067         if( isFirstBlock )
04068         {
04069             Data = &m_ApacheBuffer[ StartFirstBlock ];
04070             if( HasNextBlock )
04071             {
04072                 // Se e o primeiro bloco, deveremos pular os primeiros bytes, se
04073                 // necessario (isso dependera do deslocamento inicial).
04074                 DataSize = m_BlockSize - StartFirstBlock;
04075             }
04076             else
04077                 DataSize = FileSize - StartFirstBlock;
04078 
04079             // Os proximos blocos sempre devem ser copiados do inicio.
04080             isFirstBlock = false;
04081         }
04082         else
04083         {
04084             // Se nao e o primeiro bloco, deveremos sempre comecar do inicio do
04085             // bloco mas, se este for o ultimo bloco, vamos copiar somente a
04086             // parte inicial do bloco (o bloco somente sera todo copiado se o
04087             // tamanho do arquivo for multiplo do tamanho do bloco).
04088             Data = m_ApacheBuffer;
04089             if( HasNextBlock )
04090                 DataSize = m_BlockSize;
04091             else
04092                 DataSize = FileSize - ( ( m_TotalBlocks - 1 ) * m_BlockSize );
04093         }
04094 
04095         // Envia os dados para o cliente.
04096         if( !SendBlock( Request, Data, DataSize ) )
04097         {
04098             #ifdef RIO_DEBUG2
04099             ap_log_error( APLOG_MARK, APLOG_ERR, m_ApacheStatus, m_Server,
04100                           "Error sending block %u to the client", Block );
04101             #endif
04102 
04103             // Cancela a copia atual.
04104             if( !Close( Request ) )
04105             {
04106                 #ifdef RIO_DEBUG2
04107                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04108                               "Error when executing Close" );
04109                 #endif
04110 
04111             }
04112 
04113             return HTTP_SERVICE_UNAVAILABLE;
04114         }
04115     }
04116 
04117     // Finaliza a copia do arquivo e fecha tudo (o arquivo e o stream).
04118     if( !Close( Request ) )
04119     {
04120         #ifdef RIO_DEBUG2
04121         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04122                       "Error when executing Close" );
04123         #endif
04124 
04125         return HTTP_INTERNAL_SERVER_ERROR;
04126     }
04127 
04128     return OK;
04129 }

void CServerInterface::EndXML ( request_rec *  Request,
unsigned int  CommandId 
) [static, private]

Funcao para gerar o final do xml, usando uma TAG composta por rioexec mais, se existir, o nome do comando.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
CommandId Identificador do comando executado. Se o comando for CMD_INV_ID (na verdade, qualquer valor maior ou igual a este), a TAG sera rioexec. Porem, caso o valor seja menor do que CMD_INV_ID, a TAG sera rioexec_<commando>, onde commando sera obtido da posicao CommandId da tabela CommandTable dada em ServerInterface.cpp.

Definition at line 2430 of file ServerInterface.cpp.

02431 {
02432     // Finaliza a TAG de acordo com o identificador do comando.
02433     if( CommandId < CMD_INV_ID )
02434         ap_rprintf( Request, "</rioexec_%s>\n",
02435                     CommandTable[ CommandId ].Command );
02436     else
02437         ap_rprintf( Request, "</rioexec>\n" );
02438 }

bool CServerInterface::ExecuteAdduserCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando adduser, que cria um novo usuario no servidor RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 5096 of file ServerInterface.cpp.

05098 {
05099     // Armazena o estado de retorno da funcao.
05100     bool Status;
05101     // Armazena a senha encriptada do usuario.
05102     char *EncryptedPassword;
05103 
05104     // Inicializa o retorno da funcao.
05105     Status = true;
05106 
05107     // Tenta encriptar a senha do usuario passada como parametro.
05108     EncryptedPassword = encryptPassword( Params[ 2 ] );
05109     if( EncryptedPassword == NULL )
05110     {
05111         m_SystemStatus = ENOMEM;
05112         Status = false;
05113 
05114         #ifdef RIO_DEBUG2
05115         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05116                       "CServerInterface::ExecuteAdduserCommand Erro ao "
05117                       "encriptar a senha do usuario: %u (%s)", m_SystemStatus,
05118                       strerror( m_SystemStatus ) );
05119         #endif
05120     }
05121     else
05122     {
05123         // Tenta executar a funcao CreateUser.
05124         m_RioStatus = m_Session->CreateUser( Params[ 1 ], EncryptedPassword );
05125 
05126         if( FAILED( m_RioStatus ) )
05127         {
05128             Status = false;
05129 
05130             #ifdef RIO_DEBUG2
05131             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05132                            "CServerInterface::ExecuteAdduserCommand Erro ao "
05133                            "executar o comando adduser para o usuario %s!",
05134                            Params[ 1 ] );
05135             #endif
05136         }
05137 
05138         // Deleta a senha encriptada, que nao e mais necessaria.
05139         delete[] EncryptedPassword;
05140     }
05141 
05142     // Gera o XML da requisicao.
05143     GenerateXMLStatus( Request, CMD_ADDUSER_ID, m_SessionId );
05144 
05145     // Retorna o estado da execucao do adduser.
05146     return Status;
05147 }

int CServerInterface::ExecuteCommands ( request_rec *  Request,
char *  Command,
bool *  RemoveObject,
unsigned int *  SessionId 
)

Funcao para decodificar e executar todos os comandos do objeto da classe, similares aos comandos do riosh.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Command ponteiro para a string com o comando
RemoveObject ponteiro para um valor booleando que, quando for alterado para true indicara, a quem chamou a funcao, que o objeto deve ser removido (isso acontecera quando o comando login falhar, ou quando o comando quit, para terminar a conexao com o servidor, for executado).
SessionId ponteiro para o endereco com o valor do Id associado a sessao. No caso do comando login, o ponteiro devera ser NULL e, nos outros comandos, devera ser diferente de NULL.
Returns:
codigo do protocolo http que sera repassado ao cliente. Caso ocorra algum erro, ele sera passado via arquivo de XML ao cliente para todos os comandos com excecao dos comandos download e upload, cujo codigo de erro sera retornado aqui.

Definition at line 5364 of file ServerInterface.cpp.

05367 {
05368     // Armazena os parametros do comando (a posicao 0 e o proprio comando).
05369     char **Params;
05370     // Armazena o retorno da funcao do apache (o codigo do protocolo http).
05371     //int HttpResult;
05372     // Armazena a posicao do comando atualmente verificado.
05373     unsigned int CommandPos;
05374     // Armazena o identificador do comando passado como parametro (se ele for
05375     // valido).
05376     unsigned int CommandId;
05377     // Arnmazena o retorno de uma das funcoes da classe.
05378     bool Status;
05379     // Armazena o numero de parametros do comando.
05380     unsigned int TotalParams;
05381     // Armazena o numero de um parametro do comando no vetor Param.
05382     unsigned int ParamPos;
05383     // Define se o erro de comando nao ter sido achado e devido ao numero de
05384     // parametros incorretos ou a um comando invalido.
05385     bool InvalidParams;
05386     // Define se devemos retornar um erro ou enviar um XML no caso de um numero
05387     // de parametros incorreto para um comando.
05388     bool SendXmlError;
05389     // Armazena o resultado a ser retornado pela funcao para o apache.
05390     int HttpResult;
05391 
05392     // Ininicialza os codigos de erro da classe, para que a execucao do novo
05393     // comando incorretamente considere erros gerados por um comando anterior.
05394     m_RioStatus = S_OK;
05395     m_ApacheStatus = APR_SUCCESS;
05396     m_SystemStatus = 0;
05397 
05398     // Inicializa os parametros para os seus valores default.
05399     *RemoveObject = false;
05400 
05401     // Verifica se a classe foi inicializada.
05402     if( !m_Started )
05403     {
05404         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_NOT_STARTED;
05405 
05406         #ifdef RIO_DEBUG2
05407         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05408                        "The object has not started" );
05409         #endif
05410 
05411         // Gera o XML da requisicao com os erros.
05412         GenerateXMLStatus( Request, CMD_INV_ID, 0 );
05413 
05414         // Gera a linha do log.
05415         SaveExecLogLine( Request, Command );
05416 
05417         return OK;
05418 
05419     }
05420 
05421     // Divide o comando em varios comandos (devemos aqui remover as aspas).
05422     m_ApacheStatus = apr_tokenize_to_argv( Command, &Params, Request->pool );
05423     if( m_ApacheStatus != APR_SUCCESS )
05424     {
05425         // Ocorreu um erro na criacao dos parametros. Devemos retornar este erro
05426         // ao cliente.
05427 
05428         // Gera o XML da requisicao com os erros.
05429         GenerateXMLStatus( Request, CMD_INV_ID, 0 );
05430 
05431         // Gera a linha do log.
05432         SaveExecLogLine( Request, Command );
05433 
05434         // Retorna OK para o apache.
05435         return OK;
05436     }
05437 
05438     // Conta o numero de parametros do comando, ignorando o proprio comando.
05439     ParamPos = 1;
05440     TotalParams = 0;
05441 
05442     #ifdef RIO_DEBUG2
05443     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05444                    "String (com o comando) passada a funcao: %s", Command );
05445 
05446     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05447                    "Parametro 0 do comando (o comando): %s", Params[ 0 ] );
05448     #endif
05449 
05450     while( Params[ ParamPos ] != NULL )
05451     {
05452         #ifdef RIO_DEBUG2
05453         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05454                        "Parametro %u do comando: %s", ParamPos,
05455                        Params[ ParamPos ] );
05456         #endif
05457         TotalParams++;
05458         ParamPos++;
05459     }
05460 
05461     #ifdef RIO_DEBUG2
05462     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05463                    "Total de parametros no comando %s: %u", Command,
05464                    TotalParams );
05465     #endif
05466 
05467     // Agora que fizemos a divisao, verificamos se o comando e valido, e se ele
05468     // possui o numero correto de parametros.
05469     CommandPos = 0;
05470     CommandId = CMD_INV_ID;
05471     InvalidParams = false;
05472     SendXmlError = true;
05473     while( ( CommandTable[ CommandPos ].Command != NULL ) &&
05474            ( CommandId == CMD_INV_ID ) && ( !InvalidParams ) )
05475     {
05476         // Verifica se o primeiro parametro, com o nome do comando, e igual ao
05477         // comando atual.
05478         #ifdef RIO_DEBUG2
05479         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05480                        "Comparando com o comando da posicao %u: Command=%s, "
05481                        "CommandId=%u,MininumParams=%u,MaximumParams=%u",
05482                        CommandPos, CommandTable[ CommandPos ].Command,
05483                        CommandTable[ CommandPos ].CommandId,
05484                        CommandTable[ CommandPos ].MininumParams,
05485                        CommandTable[ CommandPos ].MaximumParams );
05486         #endif
05487 
05488         if( strcmp( Params[ 0 ], CommandTable[ CommandPos ].Command ) == 0 )
05489         {
05490             // Verifica se o comando possui o numero adequado de parametros.
05491             // Por enquanto, somente aceitamos o comando se o numero de
05492             // parametros for o correto.
05493             #ifdef RIO_DEBUG2
05494             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05495                            "O comando da posicao %u e igual ao %s. Verificando "
05496                            "se o numero de parametros %u esta correto",
05497                            CommandPos, Command, TotalParams );
05498             #endif
05499 
05500             // Salva a ID do comando.
05501             CommandId = CommandTable[ CommandPos ].CommandId;
05502 
05503             if( ( TotalParams < CommandTable[ CommandPos ].MininumParams ) ||
05504                 ( TotalParams > CommandTable[ CommandPos ].MaximumParams ) )
05505             {
05506 
05507                 #ifdef RIO_DEBUG2
05508                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05509                                "Numero de parametros %u do comando %u "
05510                                "incorreto!", TotalParams, CommandId );
05511                 #endif
05512 
05513                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COMMAND_SYNTAX;
05514 
05515                 // Gera o XML da requisicao com os erros.
05516                 GenerateXMLStatus( Request, CommandId, 0 );
05517 
05518                 // Gera a linha do log.
05519                 SaveExecLogLine( Request, Command );
05520 
05521                 return OK;
05522             }
05523         }
05524 
05525         // Atualiza o ponteiro para o proximo comando.
05526         CommandPos++;
05527     }
05528 
05529     // Verifica se o metodo e o POST ou o GET.
05530     if( ( strcmp( Request->method, "GET" ) != 0 ) &&
05531         ( strcmp( Request->method, "POST" ) != 0 ) &&
05532         ( strcmp( Request->method, "PUT" )))
05533     {
05534         // Define o codigo de erro do RIO para indicar que o metodo http e
05535         // invalido.
05536         m_ApacheStatus = APR_BADARG;
05537 
05538         // Gera o XML da requisicao com os erros.
05539         GenerateXMLStatus( Request, CommandId, 0 );
05540 
05541         // Gera a linha do log.
05542         SaveExecLogLine( Request, Command );
05543 
05544         return OK;
05545     }
05546 
05547     // Verifica se o metodo e compativel com o comando executado. Todos os
05548     // comandos, com excecao do upload, devem ser do tipo GET, enquando que o
05549     // upload deve ser do tipo PUT.
05550     if( ( ( strcmp( Request->method, "GET" ) == 0 ) &&
05551           ( CommandId == CMD_UPLOAD_ID ) ) ||
05552         ( ( ( strcmp( Request->method, "POST" ) == 0 ) ||
05553             ( strcmp( Request->method, "PUT" ) == 0 ) ) &&
05554             ( CommandId != CMD_UPLOAD_ID ) ) )
05555     {
05556         // Define o codigo de erro do RIO para indicar que o metodo http e
05557         // invalido.
05558         m_ApacheStatus = APR_BADARG;
05559 
05560         // Gera o XML da requisicao com os erros.
05561         GenerateXMLStatus( Request, CommandId, 0 );
05562 
05563         // Gera a linha do log.
05564         SaveExecLogLine( Request, Command );
05565 
05566         return OK;
05567     }
05568 
05569     // Verifica se a sessao foi aberta, caso o comando seja diferente do login.
05570     // TODO: Teste temporario (login diretamente na itapema). descomentar depois
05571     // a checagem da sessao.
05572     if( ( ( m_Session == NULL ) || ( !m_isSessionOpen ) ||
05573           ( m_SessionId == 0 ) ) && ( CommandId != CMD_LOGIN_ID ) )
05574     {
05575         #ifdef RIO_DEBUG2
05576         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05577                        "Sessao nao aberta: m_Session = %ld, m_isSessionOpen = "
05578                        "%s e m_SessionId = %u!", ( long ) m_Session,
05579                        ( ( m_isSessionOpen ) ? "true": "false" ), m_SessionId );
05580         #endif
05581 
05582         m_RioStatus = ERROR_RIOSESSION + ERROR_SESSION_NOT_OPENED;
05583 
05584         // Gera o XML da requisicao com os erros.
05585         GenerateXMLStatus( Request, CommandId, 0 );
05586 
05587         // Gera a linha do log.
05588         SaveExecLogLine( Request, Command );
05589 
05590         return OK;
05591     }
05592 
05593     // Verifica se um identificador de sessao foi passado, caso o comando nao
05594     // seja invalido e o login ou, caso o comando seja valido e nao um logi,
05595     // se o identificador foi passado e se ele e valido.
05596     if( SessionId == NULL )
05597     {
05598         // Neste caso, o comando deve ser o de login ou invalido pois um comando
05599         // valido diferente de login deve definir o identificador da sessao. O
05600         // comando invalido foi incluido aqui para fazer com que o erro de
05601         // comando invalido seja prioritario em relacao ao erro de nao definir o
05602         // identificador da sessao.
05603         if( ( CommandId != CMD_LOGIN_ID ) && ( CommandId != CMD_INV_ID ) )
05604         {
05605             #ifdef RIO_DEBUG2
05606             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05607                            "Error: sessionid not defined!" );
05608 
05609             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05610                            "A opcao sessionid com o identificador da sessao "
05611                            "nao foi definida!" );
05612             #endif
05613 
05614             m_RioStatus = ERROR_RIOMODULE + ERROR_SESSIONID_NOT_DEFINED;
05615 
05616             // Gera o XML da requisicao com os erros.
05617             GenerateXMLStatus( Request, CommandId, 0 );
05618 
05619             // Gera a linha do log.
05620             SaveExecLogLine( Request, Command );
05621 
05622             return OK;
05623         }
05624     }
05625     else
05626     {
05627         // Foi passado um ponteiro para um identificador. Deveremos gerar um
05628         // erro se o comando for o login, pois ele nao usa esta opcao.
05629         if( CommandId == CMD_LOGIN_ID )
05630         {
05631             #ifdef RIO_DEBUG2
05632             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05633                            "Error: sessionid already defined!" );
05634 
05635             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05636                            "A opcao sessionid com o identificador da sessao "
05637                            "%u foi definida para o comando login!",
05638                            *SessionId );
05639             #endif
05640 
05641             m_RioStatus = ERROR_RIOMODULE + ERROR_SESSIONID_ALREADY_DEFINED;
05642 
05643             // Gera o XML da requisicao com os erros.
05644             GenerateXMLStatus( Request, CommandId, 0 );
05645 
05646             // Gera a linha do log.
05647             SaveExecLogLine( Request, Command );
05648 
05649             return OK;
05650 
05651         }
05652 
05653         // Como o comando nao e o login, deveremos verificar se o identificador
05654         // da sessao e valido.
05655         if( ( *SessionId == 0 ) || ( m_SessionId != *SessionId ) )
05656         {
05657             #ifdef RIO_DEBUG2
05658             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05659                            "O valor da sessao %u e invalido! Deveria ser "
05660                            "igual a %u!", *SessionId, m_SessionId );
05661             #endif
05662 
05663             m_RioStatus = ERROR_RIOMODULE + ERROR_INVALID_SESSION;
05664 
05665             // Gera o XML da requisicao com os erros.
05666             GenerateXMLStatus( Request, CommandId, 0 );
05667 
05668             // Gera a linha do log.
05669             SaveExecLogLine( Request, Command );
05670 
05671             return OK;
05672         }
05673     }
05674 
05675     // Inicializa o retorno da funcao (codigo http para o comando download,
05676     // alterado pelo retorno da funcao ExecuteDownloadCommand, ou OK para os
05677     // outros comandos).
05678     HttpResult = OK;
05679 
05680     // Executa os comandos, de acordo com a ID criada.
05681     switch( CommandId )
05682     {
05683         // Neste caso, devemos executar o comando de abertura da sessao.
05684         case CMD_LOGIN_ID:
05685             // Executa o comando para fazer o login
05686 
05687             // Tenta criar o buffer que armazenara o nome do usuario associado a
05688             // sessao.
05689             try
05690             {
05691                 // Aloca uma string para armazenar o nome do usuario.
05692                 m_UserName = new char[ strlen( Params[ 1 ] ) + 1 ];
05693 
05694                 // Copia o nome do usuario.
05695                 strcpy( m_UserName, Params[ 1 ] );
05696 
05697                 #ifdef RIO_DEBUG2
05698                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05699                                "Tentando executar a funcao "
05700                                "ExecuteLoginCommand!" );
05701                 #endif
05702                 Status = ExecuteLoginCommand( Request, Params );
05703                 #ifdef RIO_DEBUG2
05704                 if( !Status )
05705                 {
05706                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05707                                    "Erro ao executar a funcao "
05708                                    "ExecuteLoginCommand!" );
05709                 }
05710                 #endif
05711             }
05712             catch( bad_alloc &ba )
05713             {
05714                 m_SystemStatus = ENOMEM;
05715 
05716                 #ifdef RIO_DEBUG2
05717                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05718                                "Erro allocating (bad_alloc, error=%s) m_User: "
05719                                "%u (%s)", ba.what(), m_SystemStatus,
05720                                strerror( m_SystemStatus ) );
05721                 #endif
05722 
05723                 m_UserName = NULL;
05724 
05725                 Status = false;
05726             }
05727 
05728             break;
05729 
05730         // Neste caso, devemos executar o comando de abertura da sessao.
05731         case CMD_QUIT_ID:
05732             // Executa o comando para terminar a sessao.
05733             #ifdef RIO_DEBUG2
05734             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05735                            "Tentando executar a funcao ExecuteQuitCommand!" );
05736             #endif
05737             Status = ExecuteQuitCommand( Request, Params );
05738             #ifdef RIO_DEBUG2
05739             if( !Status )
05740             {
05741                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05742                                "Erro ao executar a funcao ExecuteQuitCommand!"
05743                              );
05744             }
05745             #endif
05746 
05747             // Indica que o objeto deve ser removido, pois foi executado o
05748             // comando de finalizar a sessao. Isso somente devera ser feito se
05749             // a sessao foi corretamente fechada.
05750             *RemoveObject = Status;
05751 
05752             break;
05753 
05754         // Neste caso, devemos executar o comando de listagem de diretorios.
05755         case CMD_SESSIONS_ID:
05756             // Executa o comando para terminar a sessao.
05757             #ifdef RIO_DEBUG2
05758             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05759                            "Tentando executar a funcao ExecuteSessionsCommand!"
05760                          );
05761             #endif
05762             Status = ExecuteSessionsCommand( Request, Params );
05763             #ifdef RIO_DEBUG2
05764             if( !Status )
05765             {
05766                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05767                                "Erro ao executar a funcao "
05768                                "ExecuteSessionsCommand!" );
05769             }
05770             #endif
05771 
05772             break;
05773 
05774         // Neste caso, devemos executar o comando de listagem de diretorios.
05775         case CMD_LS_ID:
05776             // Executa o comando para listar os diretorios.
05777             #ifdef RIO_DEBUG2
05778             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05779                            "Tentando executar a funcao ExecuteLsCommand!"
05780                          );
05781             #endif
05782             Status = ExecuteLsCommand( Request, Params );
05783             #ifdef RIO_DEBUG2
05784             if( !Status )
05785             {
05786                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05787                                "Erro ao executar a funcao ExecuteLsCommand!" );
05788             }
05789             #endif
05790 
05791             break;
05792 
05793         // Neste caso, devemos executar o comando que remove um diretorio
05794         // (de modo recursivo) ou um arquivo.
05795         case CMD_RM_ID:
05796             // Executa o comando para listar os diretorios.
05797             #ifdef RIO_DEBUG2
05798             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05799                            "Tentando executar a funcao ExecuteRmCommand!" );
05800             #endif
05801             Status = ExecuteRmCommand( Request, Params );
05802             #ifdef RIO_DEBUG2
05803             if( !Status )
05804             {
05805                  ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05806                                 "Erro ao executar a funcao ExecuteRmCommand!" );
05807              }
05808             #endif
05809 
05810             break;
05811 
05812         // Neste caso, devemos executar o comando que cria um diretorio.
05813         case CMD_MKDIR_ID:
05814             // Executa o comando para listar os diretorios.
05815             #ifdef RIO_DEBUG2
05816             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05817                            "Tentando executar a funcao ExecuteRmCommand!" );
05818             #endif
05819             Status = ExecuteMkdirCommand( Request, Params );
05820             #ifdef RIO_DEBUG2
05821             if( !Status )
05822             {
05823                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05824                              "Erro ao executar a funcao ExecuteMkdirCommand!" );
05825             }
05826             #endif
05827             break;
05828 
05829         // Neste caso, devemos executar o comando que envia um arquivo do
05830         // servidor para o cliente.
05831         case CMD_DOWNLOAD_ID:
05832             // Executa o comando para baixar um arquivo do servidor
05833             #ifdef RIO_DEBUG2
05834             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05835                            "Tentando executar a funcao ExecuteDownloadCommand!"
05836                          );
05837             #endif
05838             HttpResult = ExecuteDownloadCommand( Request, Params, TotalParams );
05839             #ifdef RIO_DEBUG2
05840             if( HttpResult != OK )
05841             {
05842                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05843                                "Erro ao executar a funcao "
05844                                "ExecuteDownloadCommand, com HttpResult igual "
05845                                "a %u", HttpResult );
05846                 Status = false;
05847             } else
05848                 Status = true;
05849             PrintErrors();
05850             #endif
05851 
05852             break;
05853 
05854         // Neste caso, devemos executar o comando para mover um arquivo ou
05855         // diretorio.
05856         case CMD_MV_ID:
05857             // Executa o comando para terminar a sessao.
05858             #ifdef RIO_DEBUG2
05859             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05860                            "Tentando executar a funcao ExecuteMvCommand!"
05861                          );
05862             #endif
05863             Status = ExecuteMvCommand( Request, Params );
05864             #ifdef RIO_DEBUG2
05865             if( !Status )
05866             {
05867                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05868                                "Erro ao executar a funcao ExecuteMvCommand!" );
05869             }
05870             #endif
05871 
05872             break;
05873 
05874         // Neste caso, devemos executar o comando que envia um arquivo do
05875         // cliente para o servidor.
05876         case CMD_UPLOAD_ID:
05877             // Executa o comando para enviar um arquivo para o servidor.
05878             #ifdef RIO_DEBUG2
05879             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05880                            "Tentando executar a funcao ExecuteUploadCommand!"
05881                          );
05882             #endif
05883             Status = ExecuteUploadCommand( Request, Params );
05884             #ifdef RIO_DEBUG2
05885             if( !Status )
05886             {
05887                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05888                                "Erro ao executar a funcao "
05889                                "ExecuteUploadCommand!" );
05890             }
05891             PrintErrors();
05892             #endif
05893 
05894             break;
05895 
05896         // Funcao para efetivamente executar o comando adduser, que cria um novo
05897         // usuario no servidor RIO.
05898         case CMD_ADDUSER_ID:
05899             // Executa o comando para criar um novo usuario.
05900             #ifdef RIO_DEBUG2
05901             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05902                            "Tentando executar a funcao ExecuteAdduserCommand!"
05903                          );
05904             #endif
05905             Status = ExecuteAdduserCommand( Request, Params );
05906             #ifdef RIO_DEBUG2
05907             if( !Status )
05908             {
05909                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05910                                "Erro ao executar a funcao "
05911                                "ExecuteAdduserCommand!" );
05912             }
05913             PrintErrors();
05914             #endif
05915 
05916             break;
05917 
05918         // Funcao para efetivamente executar o comando deluser, que remove um
05919         // usuario do servidor RIO.
05920         case CMD_DELUSER_ID:
05921             // Executa o comando para deletar um usuario.
05922             #ifdef RIO_DEBUG2
05923             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05924                            "Tentando executar a funcao ExecuteDeluserCommand!"
05925                          );
05926             #endif
05927             Status = ExecuteDeluserCommand( Request, Params );
05928             #ifdef RIO_DEBUG2
05929             if( !Status )
05930             {
05931                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05932                                "Erro ao executar a funcao "
05933                                "ExecuteDeluserCommand!" );
05934             }
05935             PrintErrors();
05936             #endif
05937 
05938             break;
05939 
05940         // Funcao para efetivamente executar o comando passwd, que muda a senha
05941         // de um usuario do RIO.
05942         case CMD_PASSWD_ID:
05943             // Executa o comando para mudar a senha de um usuario.
05944             #ifdef RIO_DEBUG2
05945             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05946                            "Tentando executar a funcao ExecutePasswdCommand!" );
05947             #endif
05948             Status = ExecutePasswdCommand( Request, Params );
05949             #ifdef RIO_DEBUG2
05950             if( !Status )
05951             {
05952                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05953                                "Erro ao executar a funcao ExecutePasswdCommand!"
05954                              );
05955             }
05956             PrintErrors();
05957             #endif
05958 
05959             break;
05960 
05961         // Funcao para efetivamente executar o comando userlist, que retorna a
05962         // lista com todos os usuarios do RIO.
05963         case CMD_USERLIST_ID:
05964             // Executa o comando para obter a lista de usuarios.
05965             #ifdef RIO_DEBUG2
05966             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05967                            "Tentando executar a funcao "
05968                            "ExecuteUserListCommand!" );
05969             #endif
05970             Status = ExecuteUserListCommand( Request, Params );
05971             #ifdef RIO_DEBUG2
05972             if( !Status )
05973             {
05974                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05975                                "Erro ao executar a funcao "
05976                                "ExecuteUserListCommand!" );
05977             }
05978             PrintErrors();
05979             #endif
05980 
05981             break;
05982 
05983         // Neste caso, o ID deveria ser CMD_INV_ID.
05984         default:
05985             Status = false;
05986             #ifdef RIO_DEBUG2
05987             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05988                            "Entrando na opcao default do case. CommandId = %u!",
05989                            CommandId );
05990             #endif
05991 
05992             // Verificamos se a ID e de um comando invalido. Se nao for, entao
05993             // temos um erro de implementacao (um possivel comando nao tratado,
05994             // mas colocado na tabela de comandos).
05995             if( CommandId != CMD_INV_ID )
05996             {
05997                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_UNEXPECTED;
05998                 CommandId = CMD_INV_ID;
05999             }
06000             else
06001                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_INVALID_COMMAND;
06002 
06003             #ifdef RIO_DEBUG2
06004             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
06005                            "Foi passado um identificador %u de comando "
06006                            "invalido! O erro retornado do RIO sera %8x (%s)!",
06007                            CommandId, m_RioStatus,
06008                            GetErrorDescription( m_RioStatus ).c_str() );
06009             #endif
06010 
06011             // Gera o XML da requisicao com os erros
06012             GenerateXMLStatus( Request, CommandId, 0 );
06013 
06014             break;
06015     }
06016 
06017     // Gera a linha do log.
06018     SaveExecLogLine( Request, Command );
06019 
06020     // Se o comando executado foi o quit precisamos, adicionalmente, remover o
06021     // nome do usuario e a senha (isso antes era feito na funcao Disconnect, mas
06022     // precisamos fazer aqui agora por causa da geracao dos logs..
06023     if( CommandId == CMD_QUIT_ID )
06024     {
06025         #ifdef RIO_DEBUG2
06026         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request, "Quit executado! "
06027                        " Removendo o usuario e resetando a ID da sessao!" );
06028         #endif
06029 
06030         // Deleta o nome do usuario.
06031         if( m_UserName != NULL )
06032             delete[] m_UserName;
06033         m_UserName = NULL;
06034 
06035         // Invalida o identificador da sessao.
06036         m_SessionId = 0;
06037     }
06038 
06039     // Precisamos remover o nome do usuario se ele foi alocado, e se o comando
06040     // login falhou.
06041     if( ( !Status ) && ( CommandId == CMD_LOGIN_ID  ) )
06042     {
06043         if( m_UserName != NULL )
06044             delete[] m_UserName;
06045     }
06046 
06047     // Retorna o resultado da funcao para o apache.
06048     return HttpResult;
06049 }

bool CServerInterface::ExecuteDeluserCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando deluser, que remove um usuario do servidor RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 5151 of file ServerInterface.cpp.

05153 {
05154     // Armazena o estado de retorno da funcao.
05155     bool Status;
05156     // Armazena o ponteiro para o diretorio do usuario "/" + nome do usuario.
05157     char *UserPath;
05158     // Armazena as informacoes do diretorio passado como parametro ao comando.
05159     ObjectInfo UserPathObjectInfo;
05160 
05161     // Inicializa o retorno da funcao.
05162     Status = true;
05163 
05164     // Tenta alocar o espaco para o diretorio do usuario.
05165     try
05166     {
05167         UserPath = new char[ strlen( Params[ 1 ] ) + 2];
05168 
05169         // Define o nome do diretorio.
05170         strcpy( UserPath, "/" );
05171         strcat( UserPath, Params[ 1 ] );
05172 
05173         // Tenta executar a funcao RemoveUser, para remover um usuario do rio.
05174         m_RioStatus = m_Session->RemoveUser( Params[ 1 ] );
05175 
05176         if( FAILED( m_RioStatus ) )
05177         {
05178             Status = false;
05179 
05180             #ifdef RIO_DEBUG2
05181             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05182                            "CServerInterface::ExecuteDeluserCommand Erro ao "
05183                            "executar o comando deluser para o usuario %s!",
05184                            Params[ 1 ] );
05185             #endif
05186         }
05187         else
05188         {
05189             // Se o usuario foi removido com sucesso, removemos entao o seu
05190             // diretorio.
05191 
05192              // Obtem as informacoes do diretorio do usuario.
05193              Status = m_RioExplorer->getObjectInfo( UserPath, m_Session,
05194                                                     &UserPathObjectInfo, true );
05195 
05196              // Se a informacao do diretorio do usuario foi obtida com sucesso,
05197              // executa entao a funcao rm.
05198              if( Status )
05199              {
05200                  // Tenta executar a funcao rm.
05201                  Status = m_RioExplorer->rm( &UserPathObjectInfo, m_Session,
05202                                              false, true );
05203 
05204                 if( !Status )
05205                 {
05206                     // Obtem o erro gerado pela execucao da funcao.
05207                     m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
05208 
05209                     #ifdef RIO_DEBUG2
05210                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05211                                    "CServerInterface::ExecuteDeluserCommand "
05212                                    "Erro ao executar o comando rm no objeto "
05213                                    "%s!", UserPath );
05214                     #endif
05215                 }
05216              }
05217              else
05218              {
05219                  // Obtem o erro gerado pela execucao da funcao.
05220                  m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
05221 
05222                  #ifdef RIO_DEBUG2
05223                  ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05224                                 "CServerInterface::ExecuteDeluserCommand Erro "
05225                                 "ao obter as informacoes do objeto %s!",
05226                                 UserPath );
05227                  #endif
05228              }
05229         }
05230 
05231         // Remove a string com o diretorio do usuario.
05232         delete[] UserPath;
05233     }
05234     catch( bad_alloc &ba )
05235     {
05236         #ifdef RIO_DEBUG2
05237         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05238                        "CServerInterface::ExecuteDeluserCommand Erro ao "
05239                        "criar a string com o nome do diretorio para o usuario "
05240                        "%s!", Params[ 1 ] );
05241         #endif
05242 
05243         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_MEMORY;
05244     }
05245 
05246     // Gera o XML da requisicao.
05247     GenerateXMLStatus( Request, CMD_DELUSER_ID, m_SessionId );
05248 
05249     // Retorna o estado da execucao do deluser.
05250     return Status;
05251 }

int CServerInterface::ExecuteDownloadCommand ( request_rec *  Request,
char **  Params,
unsigned int  TotalParams 
) [private]

Funcao para efetivamente executar o comando download, usado para enviar um arquivo do servidor para o cliente.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
TotalParams numero de parametros passados ao comando.
Returns:
OK se nenhum erro ocorreu ou o erro do protocolo http caso algum erro ocorra.

Definition at line 4243 of file ServerInterface.cpp.

04246 {
04247     // Armazena o resultado da funcao DownloadFile.
04248     int httpResult;
04249     // Define se devemos ou nao enviar o cabecalho.
04250     bool SendHeader;
04251     // Define o byte inicial a ser lido do arquivo,
04252     RioObjectSize StartPosition;
04253     // Armazena as informacoes do diretorio passado como parametro ao comando.
04254     ObjectInfo DownloadObjectInfo;
04255     // Armazena o estado da execucao das funcoes do objeto da classe
04256     // RioExplorer.
04257     bool Status;
04258     // Define se devemos enviar um XML caso um erro tenha ocorrido (antes de o
04259     // arquivo comecar a ser enviado).
04260     bool SendXML;
04261 
04262     // Inicialmente o XML sempre deve ser enviado em caso de erro.
04263     SendXML = true;
04264 
04265     // Inicializa a variavel que verifica se ocorreu um erro ao executar uma
04266     // funcao.
04267     Status = true;
04268 
04269     // Inicializa o erro do apache
04270     httpResult = OK;
04271 
04272     // De acordo com a existencia ou nao sdo segundo parametro, setamos o valor
04273     // de FirstByte para 0 ou para o valor lido do segundo parametro.
04274     if( TotalParams < 2 )
04275     {
04276         StartPosition = 0;
04277         SendHeader = false;
04278     }
04279     else
04280     {
04281         StartPosition = atoi( Params[ 2 ] );
04282         // Se o terceiro parametro existir, ele devera ser "on" para habilitar o
04283         // cabecalho, ou "off" para desabilita-lo. Qualquer outro valor ira
04284         // gerar um erro. Se o parametro nao for passado, o cabecalho nao sera
04285         // enviado.
04286         if( TotalParams < 3 )
04287         {
04288             SendHeader = false;
04289         }
04290         else
04291         {
04292             // Verifica se o parametro e valido.
04293             if( ( strcasecmp( Params[ 3 ], "on" ) != 0 ) &&
04294                 ( strcasecmp( Params[ 3 ], "off" ) != 0 ) )
04295             {
04296                 #ifdef RIO_DEBUG2
04297                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04298                               "O parametro %s nao e valido!",
04299                               Params[ 3 ] );
04300                 #endif
04301 
04302                 Status = false;
04303             }
04304             else
04305                 SendHeader = ( strcasecmp( Params[ 3 ], "on" ) == 0 );
04306         }
04307     }
04308 
04309     // Verifica se o usuario pode acessar o diretorio, se nenhum erro ocorreu
04310     // ao processar os parametros.
04311     if( Status )
04312     {
04313         Status = CheckDirectoryPermission( Params[ 1 ] );
04314         if( Status )
04315         {
04316             // Verifica se o caminho dado e realmente associado a um arquivo.
04317             Status = m_RioExplorer->getObjectInfo( Params[ 1 ], m_Session,
04318                                                    &DownloadObjectInfo, true );
04319             // Se a informacao do arquivo ou do diretorio foi obtida com
04320             // sucesso, executa entao devemos verificar se o nome esta associado
04321             // a um arquivo.
04322             if( Status )
04323             {
04324                 // Se o nome for de um diretorio, devemos retornar com um erro.
04325                 if( DownloadObjectInfo.isDir() )
04326                 {
04327                     m_RioStatus = ERROR_SERVERINTERFACE +
04328                                   ERROR_OBJECT_IS_DIRECTORY;
04329 
04330                     #ifdef RIO_DEBUG2
04331                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04332                                   "O arquivo %s e um diretorio!",
04333                                   Params[ 1 ] );
04334                     #endif
04335 
04336                     Status = false;
04337                }
04338             }
04339             else
04340             {
04341                 // Obtem o erro gerado pela execucao da funcao.
04342                 m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
04343             }
04344         }
04345     }
04346 
04347     // Envia o arquivo para o cliente, se nenhum erro ocorreu antes.
04348     if( Status )
04349     {
04350         // Tenta enviar o arquivo para o cliente.
04351         #ifdef RIO_DEBUG2
04352         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04353                       "Tentando enviar o arquivo %s, a partir do byte %lld. Um "
04354                       "cabecalho %s enviado se o arquivo precisar!",
04355                       Params[ 1 ], StartPosition,
04356                       ( ( SendHeader ) ? "sera" : "nao sera" ) );
04357         #endif
04358 
04359         // Chama a funcao para baixar o arquivo.
04360         httpResult = DownloadFile( Request, Params[ 1 ], &SendXML,
04361                                    StartPosition, SendHeader );
04362 
04363         #ifdef RIO_DEBUG2
04364         // Verifica se ocorreu algum erro.
04365         if( httpResult != OK )
04366         {
04367             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04368                           "Erro ao baixar o arquivo %s!", Params[ 1 ] );
04369         }
04370         #endif
04371     }
04372 
04373     // Se SendXML for true, deveremos enviar o XML com os erros (neste caso um
04374     // erro sempre precisa ter ocorrido) e retornar OK ou, no caso contrario,
04375     // retornar o erro http.
04376     if( SendXML )
04377     {
04378         // Gera o XML da requisicao.
04379         GenerateXMLStatus( Request, CMD_DOWNLOAD_ID, m_SessionId );
04380 
04381         return OK;
04382     }
04383     else
04384         return httpResult;
04385 }

bool CServerInterface::ExecuteLoginCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando login, chamando a funcao Connect para efetuar o login no servidor e depois o XML com o resultado do comando.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2688 of file ServerInterface.cpp.

02690 {
02691     // Armazena o retorno das funcoes chamadas da classe.
02692     bool Status;
02693 
02694     #ifdef RIO_DEBUG2
02695     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02696     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02697                   "CServerInterface::ExecuteLoginCommand m_isSessionOpen [I] = "
02698                   "%s", ( m_isSessionOpen ) ? "true": "false" );
02699     #endif
02700 
02701     // Verifica se o usuario e o guest. Se for o guest, devemos retornar um
02702     // erro, pois o acesso ao guest nao e permitido.
02703     if( strcmp( Params[ 1 ], "guest" ) == 0 )
02704     {
02705         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_INVALID_USER;
02706 
02707         #ifdef RIO_DEBUG2
02708         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02709                        "User guest cannot execute commands!" );
02710         #endif
02711 
02712         Status = false;
02713 
02714     }
02715     else
02716     {
02717         // Usuario nao e o guest.
02718         Status = true;
02719     }
02720 
02721     // Faz a conexao com o servidor. O usuario e o segundo parametro e a senha
02722     // o terceiro porque o primeiro parametro sempre e o comando, se nenhum
02723     // erro ja ocorreu.
02724     if( Status )
02725     {
02726         Status = Connect( Request, Params[ 1 ], Params[ 2 ] );
02727         #ifdef RIO_DEBUG2
02728         if( !Status )
02729         {
02730             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02731                            "Erro ao executar a funcao Connect!" );
02732         }
02733         #endif
02734     }
02735 
02736     // Gera o XML da requisicao.
02737     GenerateXMLStatus( Request, CMD_LOGIN_ID, m_SessionId );
02738 
02739     #ifdef RIO_DEBUG2
02740     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02741     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02742                   "CServerInterface::ExecuteLoginCommand m_isSessionOpen [F] = "
02743                   "%s", ( m_isSessionOpen ) ? "true": "false" );
02744     #endif
02745 
02746     return Status;
02747 }

bool CServerInterface::ExecuteLsCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando ls, usado para mostrar as informacoes sobre um diretorio do servidor RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2849 of file ServerInterface.cpp.

02850 {
02851     // Armazena as informacoes do diretorio passado como parametro ao comando.
02852     ObjectInfo LsObjectInfo;
02853     // Armazena o estado da execucao das funcoes do objeto da classe
02854     // RioExplorer.
02855     bool Status;
02856     // Armazena o tempo de acesso de um diretorio ou arquivo, para ser usado ao
02857     // gerarmos o XML.
02858     AccessTime ObjectAcessTime;
02859     // Armazena o MD5 do objeto.
02860     char ObjectMd5[ MD5SIZE ];
02861 
02862     // Armazena o vetor com as informacoes do(s) arquivo(s) e diretorio(s)
02863     // retornados pela funcao ls do objeto da classe CModuleRioExplorer.
02864     vector<ObjectInfo> LsObjets;
02865 
02866     // Gera o inicio do XML da requisicao.
02867     StartXML( Request, CMD_LS_ID );
02868 
02869     // Primeiramente verifica se o usuario pode acessar o caminho.
02870     Status = CheckDirectoryPermission( Params[ 1 ] );
02871     if( Status )
02872     {
02873         // Obtem as informacoes do objeto. O nome do objeto e o primeiro
02874         // parametro (que e o 1, pois o parametro 0 sempre aponta para o
02875         // comando).
02876         Status = m_RioExplorer->getObjectInfo( Params[ 1 ], m_Session,
02877                                                &LsObjectInfo, true );
02878 
02879 
02880         // Se as informacoes sobre o objeto (caso exista) foram obtidas com
02881         // sucesso, entao deveremos executar o comando, usando a funcao ls do
02882         // objeto da classe CModuleRioExplorer, para depois processar os dados
02883         // para gerar o XML.
02884         if( Status )
02885         {
02886             // Verifica se o parametro passado e um diretorio.
02887             if( !LsObjectInfo.isDir() )
02888             {
02889                 // Se o parametro for um arquivo, gera um erro, pois somente
02890                 // podemos usar diretorios no ls.
02891 
02892                 Status = false;
02893 
02894                 m_RioStatus = ERROR_SERVERINTERFACE +
02895                               ERROR_OBJECT_NOT_DIRECTORY;
02896 
02897                 #ifdef RIO_DEBUG2
02898                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02899                                "CServerInterface::ExecuteLsCommand O objeto %s "
02900                                "nao e um diretorio! Erro retornado %8X (%s)!",
02901                                Params[ 1 ], m_RioStatus,
02902                                GetErrorDescription( m_RioStatus ).c_str() );
02903                 #endif
02904             }
02905             else
02906             {
02907                 // Tenta executar o comando ls.
02908                 Status = m_RioExplorer->ls( &LsObjectInfo, &LsObjets, m_Session,
02909                                             true, false, NULL, 0 );
02910 
02911                 if( !Status )
02912                 {
02913                     // Obtem o erro gerado pela execucao da funcao.
02914                     m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
02915 
02916                     #ifdef RIO_DEBUG2
02917                     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02918                                    "CServerInterface::ExecuteLsCommand Erro ao "
02919                                    "executar o comando ls no diretorio %s!",
02920                                    Params[ 1 ] );
02921                     #endif
02922                 }
02923             }
02924         }
02925         else
02926         {
02927             // Obtem o erro gerado pela execucao da funcao.
02928             m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
02929 
02930             #ifdef RIO_DEBUG2
02931             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02932                            "CServerInterface::ExecuteLsCommand Erro ao obter "
02933                            "as informacoes do objeto %s!", Params[ 1 ] );
02934             #endif
02935         }
02936     }
02937 
02938     // Adiciona o estado do comando ao XML.
02939     AddStatusToXML( Request, m_SessionId );
02940 
02941     // Se nao ocorreu nenhum erro ao executar o ls, entao montamos o restante do
02942     // XML com o conteudo do diretorio.
02943     if( Status )
02944     {
02945         // Adiciona as informacoes do diretorio passado como parametro (niveis
02946         // um e dois de tabulacao).
02947         ap_rprintf( Request, "\t<ls dirname=\"%s\">\n",
02948                     LsObjectInfo.getFullPath().c_str() );
02949         ap_rprintf( Request, "\t\t<size>%lld</size>\n",
02950                     LsObjectInfo.getSize() );
02951         ap_rprintf( Request, "\t\t<owner>%s</owner>\n",
02952                     LsObjectInfo.getOwner().c_str() );
02953         ap_rprintf( Request, "\t\t<group>%s</group>\n",
02954                     LsObjectInfo.getGroup().c_str() );
02955         ap_rprintf( Request, "\t\t<permission></permission>\n" );
02956         // Obtem o tempo do ultimo acesso (este e o tempo de modificacao?).
02957         ObjectAcessTime = LsObjectInfo.getTime();
02958         ap_rprintf( Request, "\t\t<datemodified>%04u-%02u-%02u %02u:%02u"
02959                              "</datemodified>\n", ObjectAcessTime.Year,
02960                              ObjectAcessTime.Month, ObjectAcessTime.Day,
02961                              ObjectAcessTime.Hour, ObjectAcessTime.Minute );
02962 
02963         // Processa o vetor com os arquivos.
02964         for( unsigned int i = 0; i < LsObjets.size(); i++ )
02965         {
02966             // Salva as informacoes do tempo de acesso do objeto.
02967             ObjectAcessTime = LsObjets[ i ].getTime();
02968 
02969             // Gera o XML para cada arquivo, de acordo com ele ser um arquivo ou
02970             // um diretorio.
02971             if( LsObjets[ i ].isDir() )
02972             {
02973                 // O objeto e um diretorio.
02974                 ap_rprintf( Request, "\t\t<dir dirname=\"%s\">\n",
02975                             LsObjets[ i ].getFullPath().c_str() );
02976                 ap_rprintf( Request, "\t\t\t<size>%lld</size>\n",
02977                             LsObjets[ i ].getSize() );
02978                 ap_rprintf( Request, "\t\t\t<owner>%s</owner>\n",
02979                             LsObjets[ i ].getOwner().c_str() );
02980                 ap_rprintf( Request, "\t\t\t<group>%s</group>\n",
02981                             LsObjets[ i ].getGroup().c_str() );
02982                 ap_rprintf( Request, "\t\t\t<permission>%s</permission>\n",
02983                             short2Permission(
02984                                      LsObjets[ i ].getPermission() ).c_str() );
02985                 // Obtem o tempo do ultimo acesso (este e o tempo de
02986                 // modificacao?).
02987                 ObjectAcessTime = LsObjets[ i ].getTime();
02988                 ap_rprintf( Request, "\t\t\t<datemodified>"
02989                                      "%04u-%02u-%02u %02u:%02u"
02990                                      "</datemodified>\n", ObjectAcessTime.Year,
02991                                      ObjectAcessTime.Month, ObjectAcessTime.Day,
02992                                      ObjectAcessTime.Hour,
02993                                      ObjectAcessTime.Minute );
02994                 ap_rprintf( Request, "\t\t</dir>\n" );
02995             }
02996             else
02997             {
02998                 // O objeto e um arquivo.
02999                 ap_rprintf( Request, "\t\t<file>\n" );
03000                 ap_rprintf( Request, "\t\t\t<name>%s</name>\n",
03001                             LsObjets[ i ].getFullPath().c_str() );
03002                 ap_rprintf( Request, "\t\t\t<size>%lld</size>\n",
03003                             LsObjets[ i ].getSize() );
03004                 ap_rprintf( Request, "\t\t\t<owner>%s</owner>\n",
03005                             LsObjets[ i ].getOwner().c_str() );
03006                 ap_rprintf( Request, "\t\t\t<group>%s</group>\n",
03007                             LsObjets[ i ].getGroup().c_str() );
03008                 ap_rprintf( Request, "\t\t\t<permission>%s</permission>\n",
03009                             short2Permission(
03010                                       LsObjets[ i ].getPermission() ).c_str() );
03011                 // Obtem o tempo do ultimo acesso (este e o tempo de
03012                 // modificacao?).
03013                 ObjectAcessTime = LsObjets[ i ].getTime();
03014                 ap_rprintf( Request, "\t\t\t<datemodified>"
03015                                      "%04u-%02u-%02u %02u:%02u"
03016                                      "</datemodified>\n", ObjectAcessTime.Year,
03017                                      ObjectAcessTime.Month, ObjectAcessTime.Day,
03018                                      ObjectAcessTime.Hour,
03019                                      ObjectAcessTime.Minute );
03020                 // Obtem o md5.
03021                 LsObjets[ i ].getMd5sum( &ObjectMd5[ 0 ] );
03022                 ap_rprintf( Request, "\t\t\t<md5sum>%s</md5sum>\n", ObjectMd5 );
03023                 ap_rprintf( Request, "\t\t</file>\n" );
03024             }
03025         }
03026         ap_rprintf( Request, "\t</ls>\n" );
03027     }
03028 
03029     EndXML( Request, CMD_LS_ID );
03030 
03031     // Retorna o estado da execucao do ls.
03032     return Status;
03033 }

bool CServerInterface::ExecuteMkdirCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando mkdir, usado para criar um diretorio.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 3358 of file ServerInterface.cpp.

03360 {
03361     // Armazena o estado da execucao das funcoes do objeto da classe
03362     // RioExplorer.
03363     bool Status;
03364 
03365     // Tenta executar a funcao mkdir.
03366     Status = m_RioExplorer->mkdir( Params[ 1 ], m_Session, true );
03367 
03368     if( !Status )
03369     {
03370         // Obtem o erro gerado pela execucao da funcao.
03371         m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
03372 
03373         #ifdef RIO_DEBUG2
03374         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03375                        "CServerInterface::ExecuteMkdirCommand Erro ao "
03376                        "executar o comando rm no diretorio %s!",
03377                        Params[ 1 ] );
03378         #endif
03379     }
03380 
03381     // Gera o XML da requisicao.
03382     GenerateXMLStatus( Request, CMD_MKDIR_ID, m_SessionId );
03383 
03384     // Retorna o estado da execucao do mkdir.
03385     return Status;
03386 }

bool CServerInterface::ExecuteMvCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando mv, usado para criar um diretorio.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 4389 of file ServerInterface.cpp.

04390 {
04391     // Armazena o estado da execucao das funcoes do objeto da classe
04392     // RioExplorer.
04393     bool Status;
04394 
04395     // Tenta executar a funcao rm.
04396     Status = m_RioExplorer->mv( Params[ 1 ], Params[ 2 ], m_Session, false );
04397 
04398     if( !Status )
04399     {
04400         // Obtem o erro gerado pela execucao da funcao.
04401         m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
04402 
04403         #ifdef RIO_DEBUG2
04404         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
04405                        "CServerInterface::ExecuteMvCommand Erro ao "
04406                        "executar o comando mv do arquivo %s para o %s!",
04407                        Params[ 1 ], Params[ 2 ] );
04408         #endif
04409     }
04410 
04411     // Gera o XML da requisicao.
04412     GenerateXMLStatus( Request, CMD_MV_ID, m_SessionId );
04413 
04414     // Retorna o estado da execucao do mv.
04415     return Status;
04416 }

bool CServerInterface::ExecutePasswdCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando passwd, que muda a senha de um usuario do RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 5255 of file ServerInterface.cpp.

05257 {
05258     // Armazena o estado de retorno da funcao.
05259     bool Status;
05260 
05261     // Armazena a senha encriptada do usuario.
05262     char *EncryptedPassword;
05263 
05264     // Inicializa o retorno da funcao.
05265     Status = true;
05266 
05267     // Tenta encriptar a senha do usuario passada como parametro.
05268     EncryptedPassword = encryptPassword( Params[ 2 ] );
05269     if( EncryptedPassword == NULL )
05270     {
05271         m_SystemStatus = ENOMEM;
05272         Status = false;
05273 
05274         #ifdef RIO_DEBUG2
05275         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05276                       "CServerInterface::ExecutePasswdCommand Erro ao "
05277                       "encriptar a senha do usuario: %u (%s)", m_SystemStatus,
05278                       strerror( m_SystemStatus ) );
05279         #endif
05280     }
05281     else
05282     {
05283         // Tenta executar a funcao ChangePassword.
05284         m_RioStatus = m_Session->ChangePassword( Params[ 1 ],
05285                                                  EncryptedPassword );
05286 
05287         if( FAILED( m_RioStatus ) )
05288         {
05289             Status = false;
05290 
05291             #ifdef RIO_DEBUG2
05292             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05293                            "CServerInterface::ExecutePasswdCommand Erro ao "
05294                            "executar o comando adduser para o usuario %s!",
05295                            Params[ 1 ] );
05296             #endif
05297         }
05298 
05299         // Deleta a senha encriptada, que nao e mais necessaria.
05300         delete[] EncryptedPassword;
05301     }
05302 
05303     // Gera o XML da requisicao.
05304     GenerateXMLStatus( Request, CMD_PASSWD_ID, m_SessionId );
05305 
05306     // Retorna o estado da execucao do passwd.
05307     return Status;
05308 }

bool CServerInterface::ExecuteQuitCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando quit, usado para finalizar uma conexao ativa com o servidor RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2751 of file ServerInterface.cpp.

02752 {
02753     // Armazena o retorno das funcoes chamadas da classe.
02754     bool Status;
02755     // Armazena uma copia do identificador da sessao para podermos gerar o
02756     // estado, pois a funcao Disconnect invalida o identificador (muda o valor
02757     // dele para 0) ao fechar a sessao.
02758     unsigned int SessionId;
02759 
02760     // Armazena uma copia do identificador da sessao atual.
02761     SessionId = m_SessionId;
02762 
02763     #ifdef RIO_DEBUG2
02764     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02765     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02766                   "CServerInterface::ExecuteQuitCommand m_isSessionOpen [I] "
02767                   "= %s, SessionId (m_SessionId) = %u",
02768                   ( m_isSessionOpen ) ? "true": "false", SessionId );
02769     #endif
02770 
02771     // Executa o comando somente se o identificador da sessao e valido.
02772     // O identificador e valido. Entao, podemos finalizar a sessao.
02773     Status = Disconnect();
02774     #ifdef RIO_DEBUG2
02775     if( !Status )
02776     {
02777         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02778                        "Erro ao executar a funcao Disconnect!" );
02779     }
02780     #endif
02781 
02782     // Gera o XML da requisicao.
02783     GenerateXMLStatus( Request, CMD_QUIT_ID, SessionId );
02784 
02785     #ifdef RIO_DEBUG2
02786     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02787     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02788                   "CServerInterface::ExecuteQuitCommand m_isSessionOpen [F] "
02789                   "= %s, m_SessionId = %u",
02790                   ( m_isSessionOpen ) ? "true": "false", m_SessionId );
02791     #endif
02792 
02793     return Status;
02794 }

bool CServerInterface::ExecuteRmCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando rm, usado para remover um arquivo ou um diretorio (de modo recursivo).

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 3240 of file ServerInterface.cpp.

03241 {
03242     // Armazena as informacoes do diretorio passado como parametro ao comando.
03243     ObjectInfo LsObjectInfo;
03244     // Armazena o estado da execucao das funcoes do objeto da classe
03245     // RioExplorer.
03246     bool Status;
03247 
03248     // Armazena o caminho convertido
03249     char ConvertedPath[ MaxPathSize + 1 ];
03250 
03251     // Tenta converter o caminho
03252     #ifdef RIO_DEBUG2
03253     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03254                    "Tentando converter %s", Params[ 1 ] );
03255     #endif
03256 
03257     Status = ConvertPath( Request, Params[ 1 ], ConvertedPath, MaxPathSize );
03258     if( Status )
03259     {
03260         #ifdef RIO_DEBUG2
03261         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03262                    "Caminho %s convertido para %s", Params[ 1 ],
03263                    ConvertedPath );
03264         #endif
03265         // Obtem as informacoes do objeto. O nome do objeto e o primeiro
03266         // parametro (que e o 1, pois o parametro 0 sempre aponta para o
03267         // comando).
03268         Status = m_RioExplorer->getObjectInfo( ConvertedPath, m_Session,
03269                                                &LsObjectInfo, true );
03270 
03271         // Se a informacao do arquivo ou do diretorio foi obtida com sucesso,
03272         // executa entao a funcao rm.
03273         if( Status )
03274         {
03275             // Armazena o camiho do objeto a ser removido
03276             const char *ObjectFullPath;
03277             // Armazena o tamanho da string com o nome do usuario.
03278             //unsigned int UserNameSize;
03279 
03280             // Inicializa as duas variaveis definidas acima.
03281             ObjectFullPath = LsObjectInfo.getFullPath().c_str();
03282             //UserNameSize = strlen( m_UserName );
03283 
03284             #ifdef RIO_DEBUG2
03285             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03286                            "Arquivo a ser removido %s, usuario %s!",
03287                            ObjectFullPath, m_UserName );
03288             #endif
03289 
03290             // Verifica se o diretorio a ser removido e o diretorio do usuario.
03291             if( strcmp( &ObjectFullPath[ 1 ], m_UserName ) == 0 )
03292             {
03293                 #ifdef RIO_DEBUG2
03294                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03295                                "Diretorio do usuario %s detectado!",
03296                                m_UserName );
03297                 #endif
03298 
03299                 Status = false;
03300                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_PERMISSION_DENIED;
03301             }
03302             else
03303             {
03304                 #ifdef RIO_DEBUG2
03305                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03306                                "Tentando remover o objeto %s!",
03307                                ObjectFullPath );
03308                 #endif
03309 
03310                 // Tenta executar a funcao rm.
03311                 Status = m_RioExplorer->rm( &LsObjectInfo, m_Session, false,
03312                                             true );
03313             }
03314 
03315             if( !Status )
03316             {
03317                 // Obtem o erro gerado pela execucao da funcao.
03318                 m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
03319 
03320                 #ifdef RIO_DEBUG2
03321                 ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03322                                "CServerInterface::ExecuteRmCommand Erro ao "
03323                                "executar o comando rm no objeto %s!",
03324                                ConvertedPath );
03325                 #endif
03326             }
03327         }
03328         else
03329         {
03330             // Obtem o erro gerado pela execucao da funcao.
03331             m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
03332 
03333             #ifdef RIO_DEBUG2
03334             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03335                            "CServerInterface::ExecuteRmCommand Erro ao obter "
03336                            "as informacoes do objeto %s!", ConvertedPath );
03337             #endif
03338         }
03339     }
03340     #ifdef RIO_DEBUG2
03341     else
03342     {
03343         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
03344                        "CServerInterface::ExecuteRmCommand Erro ao converter "
03345                        "o caminho %s!", Params[ 1 ] );
03346     }
03347     #endif
03348 
03349     // Gera o XML da requisicao.
03350     GenerateXMLStatus( Request, CMD_RM_ID, m_SessionId );
03351 
03352     // Retorna o estado da execucao do rm.
03353     return Status;
03354 }

bool CServerInterface::ExecuteSessionsCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando session, usado para mostrar as informacoes sobre as sessoes do servidor RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 2798 of file ServerInterface.cpp.

02800 {
02801     // Armazena o retorno das funcoes chamadas da classe.
02802     bool Status;
02803     // Estrutura para armazenar as informacoes das sessoes.
02804     SessionsInfo Info;
02805 
02806     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02807     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02808                   "CServerInterface::ExecuteSessionsCommand m_isSessionOpen "
02809                   "[I] = %s", ( m_isSessionOpen ) ? "true": "false" );
02810 
02811     // O identificador e valido. Entao, podemos executar o comando sessions.
02812     Status = m_RioExplorer->sessions( &Info );
02813     if( !Status )
02814     {
02815         // Obtem o erro gerado pela execucao da funcao.
02816         m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
02817 
02818         #ifdef RIO_DEBUG2
02819         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02820                        "Erro ao executar a funcao Disconnect!" );
02821         #endif
02822     }
02823 
02824     // Gera o XML da requisicao.
02825     StartXML( Request, CMD_SESSIONS_ID );
02826     AddStatusToXML( Request, m_SessionId );
02827     // Adiciona as informacoes do comando (se nenhum erro ocorreu).
02828     if( Status )
02829     {
02830         // Mostra o numero maximo de sessoes.
02831         ap_rprintf( Request, "\t<maxsessions> %u </maxsessions>\n",
02832                     Info.number_of_max_sessions );
02833         // Mostra o numero de sessoes ativas.
02834         ap_rprintf( Request, "\t<activesessions> %u </activesessions>\n",
02835                     Info.number_of_active_sessions );
02836     }
02837     EndXML( Request, CMD_SESSIONS_ID );
02838 
02839     // Impressao temporaria para verificar o valor de m_isSessionOpen.
02840     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02841                   "CServerInterface::ExecuteSessionsCommand m_isSessionOpen "
02842                   "[F] = %s", ( m_isSessionOpen ) ? "true": "false" );
02843 
02844     return Status;
02845 }

bool CServerInterface::ExecuteUploadCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando upload, usado para enviar um arquivo do cliente para o servidor.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a copia foi cancelada com sucesso ou false se algum erro ocorreu ao copiar o arquivo do cliente.

Definition at line 4980 of file ServerInterface.cpp.

04982 {
04983     // Armazena as informacoes do diretorio passado como parametro ao comando.
04984     ObjectInfo UploadObjectInfo;
04985     // Armazena o estado da execucao das funcoes do objeto da classe
04986     // RioExplorer.
04987     bool Status;
04988 
04989     // Verifica se o usuario pode acessar o diretorio.
04990     Status = CheckDirectoryPermission( Params[ 1 ] );
04991 
04992     // Se nao ocorreu um erro ao verificar a permissao do arquivo, entao
04993     // tentamos obter as informacoes dele.
04994     if( Status )
04995     {
04996         // Verifica se o caminho dado e realmente associado a um arquivo.
04997         Status = m_RioExplorer->getObjectInfo( Params[ 1 ], m_Session,
04998                                                &UploadObjectInfo, true );
04999 
05000         // Se a informacao do arquivo ou do diretorio foi obtida com sucesso,
05001         // executa entao devemos verificar se o nome esta associado a um arquivo.
05002         if( Status )
05003         {
05004             // Se o nome for de um diretorio, devemos retornar com um erro.
05005             if( UploadObjectInfo.isDir() )
05006             {
05007                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_OBJECT_IS_DIRECTORY;
05008 
05009                 #ifdef RIO_DEBUG2
05010                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05011                               "O arquivo %s e um diretorio!",
05012                               Params[ 1 ] );
05013                 #endif
05014 
05015                 Status = false;
05016             }
05017 
05018             if( Status )
05019             {
05020                 // Como o arquivo existe, devemos remove-lo se RemoveFile for
05021                 // true, ou dar um erro em caso contrario.
05022                 #ifdef RIO_DEBUG2
05023                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05024                               "Tentando remover o arquivo %s!", Params[ 1 ] );
05025                 #endif
05026 
05027                 Status = m_RioExplorer->rm( &UploadObjectInfo, m_Session, false,
05028                                             false );
05029                 if( !Status )
05030                 {
05031                     // Obtem o erro gerado pela execucao da funcao.
05032                     m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
05033 
05034                     #ifdef RIO_DEBUG2
05035                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05036                                   "Erro ao remover o arquivo %s!",
05037                                   Params[ 1 ] );
05038                     #endif
05039                 }
05040             }
05041         }
05042         else
05043         {
05044             // Obtem o erro gerado pela execucao da funcao.
05045             m_RioExplorer->getError( &m_RioStatus, &m_SystemStatus );
05046 
05047             // Verifica se e algum erro ou um erro ao abrir o objeto (porque ele
05048             // nao existe).
05049             if( ( m_RioStatus & ERROR_CODE_MASK ) != ERROR_OBJECT_OPEN_FAILED )
05050             {
05051                 #ifdef RIO_DEBUG2
05052                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05053                               "Erro ao obter as informacoes do arquivo %s!",
05054                               Params[ 1 ] );
05055                 #endif
05056             }
05057             else
05058             {
05059                 // Neste caso, o arquivo simplesmente nao existe, o que e
05060                 // valido.
05061                 m_RioStatus = S_OK;
05062                 m_SystemStatus = 0;
05063                 Status = true;
05064             }
05065         }
05066     }
05067 
05068     // Chama a funcao para baixar o arquivo.
05069     if( Status )
05070     {
05071         // Tenta enviar o arquivo para o cliente.
05072         #ifdef RIO_DEBUG2
05073         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05074                       "Tentando receber o arquivo %s com md5 igual a %s!",
05075                       Params[ 1 ], Params[ 2 ] );
05076         #endif
05077 
05078         Status = UploadFile( Request, Params[ 1 ], Params[ 2 ] );
05079     }
05080     #ifdef RIO_DEBUG2
05081     else
05082     {
05083         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
05084                       "Erro ao receber o arquivo %s!", Params[ 1 ] );
05085     }
05086     #endif
05087 
05088     // Gera o XML da requisicao.
05089     GenerateXMLStatus( Request, CMD_UPLOAD_ID, m_SessionId );
05090 
05091     return true;
05092 }

bool CServerInterface::ExecuteUserListCommand ( request_rec *  Request,
char **  Params 
) [private]

Funcao para efetivamente executar o comando userlist, que retorna a lista com todos os usuarios do RIO.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Params lista de parametros do comando, terminada em NULL. O primeiro parametro (o 0) sempre e o comando.
Returns:
true se a comando foi executado com sucesso e false em caso contrario (as variaveis m_RioStatus, m_ApacheStatus e m_SystemStatus indicarao qual foi o erro).

Definition at line 5312 of file ServerInterface.cpp.

05314 {
05315     // Armazena o estado de retorno da funcao.
05316     bool Status;
05317     // Armazena o vetor com os nomes dos usuarios.
05318     vector< string > UserList;
05319 
05320     // Inicializa o retorno da funcao.
05321     Status = true;
05322 
05323     // Tenta executar a funcao GetUserList.
05324     m_RioStatus = m_Session->GetUserList( UserList );
05325 
05326     if( FAILED( m_RioStatus ) )
05327     {
05328         Status = false;
05329 
05330         #ifdef RIO_DEBUG2
05331         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
05332                        "CServerInterface::ExecuteUserListCommand Erro ao "
05333                        "executar o comando adduser para o usuario %s!",
05334                        Params[ 1 ] );
05335         #endif
05336     }
05337 
05338     // Gera o inicio do XML da requisicao.
05339     StartXML( Request, CMD_USERLIST_ID );
05340 
05341     // Adiciona o estado do comando ao XML.
05342     AddStatusToXML( Request, m_SessionId );
05343 
05344     // Se nenhum erro ocorreu, adiconamos os usuarios.
05345     if( Status )
05346     {
05347         // Adiciona os usuarios ao XML.
05348         for( unsigned int i = 0; i < UserList.size(); i++ )
05349         {
05350             ap_rprintf( Request, "\t<user>%s</user>\n",
05351                         UserList[ i ].c_str() );
05352 
05353         }
05354     }
05355 
05356     EndXML( Request, CMD_USERLIST_ID );
05357 
05358     // Retorna o estado da execucao do passwd.
05359     return Status;
05360 }

bool CServerInterface::FinalizeCopy ( request_rec *  Request  )  [private]

Funcao para cancelar uma copia em andamento.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Returns:
true se a copia foi cancelada com sucesso ou false se algum erro ocorreu ao cancelar a copia.

Definition at line 3389 of file ServerInterface.cpp.

03390 {
03391     int status;
03392     bool isReadingFile;
03393 
03394     // Obtem o mutex para acessar exclusivamente as variaveis do buffer.
03395     status = pthread_mutex_lock( &m_Mutex );
03396     if( status < 0 )
03397     {
03398         m_SystemStatus = status;
03399 
03400         #ifdef RIO_DEBUG2
03401         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03402                       "Error locking m_Mutex: %u (%s)",
03403                       m_SystemStatus, strerror( m_SystemStatus )  );
03404         #endif
03405 
03406         return false;
03407     }
03408 
03409     // Limpa o buffer com os blocos que ja tinham sido lidos do servidor ou do
03410     // apache.
03411     if( !m_CircularBuffer->CleanBuffer() )
03412     {
03413          #ifdef RIO_DEBUG2
03414          ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03415                        "Error when cleaning m_CircularBuffer" );
03416          #endif
03417      }
03418 
03419     // Salva o valor anterior de m_isReadingRioFile, pois somente devemos
03420     // esperar caso a thread de copia estivesse copiando um arquivo.
03421     isReadingFile = m_isReadingRioFile;
03422 
03423     // Para uma copia em andamento do servidor para o cliente.
03424     if( isReadingFile )
03425     {
03426         // Remove quaiquer valores do Buffer circular, pois comecamos uma nova
03427         // Altera as variaveis da copia para um estado que indica que nao estamos
03428         // mais copiando.
03429         m_isReadingRioFile = false;
03430         m_RioBlock = 0;
03431         m_SendBlock = 0;
03432         m_TotalBlocks = 0;
03433 
03434          // Envia o termino da copia, se nao tivermos mais blocos para serem
03435          // enviados.
03436          if( !TerminateCopyToClient( Request ) )
03437          {
03438               #ifdef RIO_DEBUG2
03439               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03440                            "Error when executing TerminateCopyToClient" );
03441               #endif
03442          }
03443 
03444          status = pthread_cond_wait( &m_ThreadBlocked, &m_Mutex );
03445          // Espera que a thread fique bloqueada
03446          if( status < 0 )
03447          {
03448              m_SystemStatus = status;
03449 
03450              #ifdef RIO_DEBUG2
03451              ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03452                            "Error closing file: %u (%s)", m_SystemStatus,
03453                            strerror( m_SystemStatus ) );
03454              #endif
03455 
03456              // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03457              status = pthread_mutex_unlock( &m_Mutex );
03458              if( status < 0 )
03459              {
03460                  m_SystemStatus = status;
03461 
03462                  #ifdef RIO_DEBUG2
03463                  ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03464                                "Error unlocking m_Mutex: %u (%s)",
03465                                 m_SystemStatus, strerror( m_SystemStatus )  );
03466                  #endif
03467 
03468              }
03469 
03470              return false;
03471          }
03472     }
03473 
03474     // Salva o valor anterior de m_isReadingApacheFile, pois somente devemos
03475     // esperar caso a thread de copia estivesse copiando um arquivo.
03476     isReadingFile = m_isReadingApacheFile;
03477 
03478     // Para uma copia em andamento do cliente para o servidor.
03479     if( isReadingFile )
03480     {
03481         // Remove quaiquer valores do Buffer circular, pois comecamos uma nova
03482         // Altera as variaveis da copia para um estado que indica que nao estamos
03483         // mais copiando.
03484         m_isReadingApacheFile = false;
03485         m_IsApacheEof = false;
03486         m_isReadingApacheFile = 0;
03487         m_UploadRequest = NULL;
03488 
03489         status = pthread_cond_wait( &m_ThreadBlocked, &m_Mutex );
03490         // Espera que a thread fique bloqueada.
03491         if( status < 0 )
03492         {
03493             m_SystemStatus = status;
03494 
03495             #ifdef RIO_DEBUG2
03496             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03497                           "Error closing file: %u (%s)", m_SystemStatus,
03498                           strerror( m_SystemStatus ) );
03499             #endif
03500 
03501             // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03502             status = pthread_mutex_unlock( &m_Mutex );
03503             if( status < 0 )
03504             {
03505                 m_SystemStatus = status;
03506 
03507                 #ifdef RIO_DEBUG2
03508                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03509                               "Error unlocking m_Mutex: %u (%s)",
03510                                m_SystemStatus, strerror( m_SystemStatus )  );
03511                 #endif
03512 
03513             }
03514 
03515             return false;
03516         }
03517     }
03518 
03519     // Libera o mutex para acessar exclusivamente as variaveis do buffer.
03520     status = pthread_mutex_unlock( &m_Mutex );
03521     if( status < 0 )
03522     {
03523         m_SystemStatus = status;
03524 
03525         #ifdef RIO_DEBUG2
03526         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
03527                       "Error unlocking m_Mutex: %u (%s)",
03528                       m_SystemStatus, strerror( m_SystemStatus )  );
03529         #endif
03530 
03531         return false;
03532     }
03533 
03534     return true;
03535 }

void CServerInterface::GenerateExecLogLine ( request_rec *  Request,
const char *  UserName,
unsigned int  SessionId,
apr_status_t  ApacheStatus,
int  SystemStatus,
RioResult  RioStatus,
const char *  Command,
unsigned int  ExecPort 
) [static, private]

Gera uma linha no log da classe que executa os comandos.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
UserName nome do usuario a ser salvo no log.
SessionId identificador de sessao a ser salvo no log.
ApacheStatus codigo de erro do Apache. Somente sera colocado no XML se for diferente de APR_SUCCESS.
SystemStatus codigo de erro do sistema. Somente sera colocado no XML se for diferente de 0.
RioStatus codigo de erro do RIO. Somente sera colocado no XML se for diferente de S_OK.
Command ponteiro para a string com o comando.
ExecPort porta UDP usado para enviar os logs para a classe de logs associada com a classe que executa os comandos.

Definition at line 2458 of file ServerInterface.cpp.

02466 {
02467     // Variavel usada para armazenar o objeto que enviara a mensagem com a linha
02468     // do log.
02469     CClientUserLogs *ClientExecLogs;
02470 
02471     // Aponta para o inicio do proximo parametro do comando (sendo 0, o
02472     // primeiro, indicando o comando).
02473     unsigned int StartParam;
02474 
02475     // Aponta para o inicio do proximo parametro do comando (sendo 0, o
02476     // primeiro, indicando o comando).
02477     unsigned int EndParam;
02478 
02479     // Armazena a posicao em que o parametro de senha esta no comando (0 se o
02480     // comando nao tem este parametro).
02481     unsigned int PasswordParamPos;
02482 
02483     // Armazena a posicao do comando atualmente avaliado da tabela
02484     // LogCommandTable.
02485     unsigned int CommandPos;
02486 
02487     // Variavel para armazenar temporariamente um caractere.
02488     char TempChar;
02489 
02490     // Armazena o retorno da funcao do RIO.
02491     RioResult RioError;
02492 
02493     // Armazerna o retorno da funcao snprintf.
02494     int status;
02495 
02496     // Armazena um ponteiro local para o usuario.
02497     const char *LocalUserName;
02498 
02499     // Linha com o log (tamanho maximo da linha do log mais o terminador).
02500     char LogLine[ MAXLOGLINESIZE + 1 ];
02501 
02502     // Define o nome do usuario na variavel local de acordo com o ponteiro de
02503     // UserName. Se o ponteiro for NULL, entao usa o nome "none".
02504     if( UserName == NULL )
02505         LocalUserName = "none";
02506     else
02507         LocalUserName = UserName;
02508 
02509     // Cria a linha do log, dependendo dos erros gerados.
02510     if( ( ApacheStatus == APR_SUCCESS ) && ( SystemStatus == 0 ) &&
02511         ( RioStatus == S_OK ) )
02512         status = snprintf( LogLine, MAXLOGLINESIZE + 1, "%s %s %u OK %s",
02513                            Request->connection->remote_ip, LocalUserName,
02514                            SessionId, Command );
02515     else
02516         status = snprintf( LogLine, MAXLOGLINESIZE + 1, "%s %s %u Apache:%u,"
02517                                                         "RIO:%08X,System:%u %s",
02518                            Request->connection->remote_ip, LocalUserName,
02519                            SessionId, ApacheStatus, RioStatus, SystemStatus,
02520                            Command );
02521 
02522     // Verifica se ocorreu algum erro ao gerar a linha.
02523     if( status < 0 )
02524     {
02525         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02526                        "CServerInterface::GenerateExecLogLine Erro %u "
02527                        "(%s) ao gerar a linha de log!", errno, strerror( errno )
02528                      );
02529 
02530         return;
02531 
02532     }
02533 
02534     // Remove a senha da linha do comando.
02535 
02536     // Determinamos o inicio do comando (o primeiro parametro). Note que o
02537     // inicio e a posicao, em LogLine, igual ao tamanho de LogLine menos o
02538     // tamanho de Command.
02539     StartParam = strlen( LogLine ) - strlen( Command );
02540 
02541     // Pula os espacos iniciais antes do comando.
02542     while( ( LogLine[ StartParam ] == ' ' ) ||
02543            ( LogLine[ StartParam ] == '\t' ) )
02544         StartParam++;
02545 
02546     // Descobre o final do comando
02547     EndParam = StartParam;
02548     while( ( LogLine[ EndParam ] != ' ' ) &&
02549            ( LogLine[ EndParam ] != '\t' ) &&
02550            ( LogLine[ EndParam ] != 0 ) )
02551         EndParam++;
02552 
02553     // Se existirem parametros (pode existir um erro de sintaxe no comando),
02554     // verificamos se o comando tem senha e se o parametro com a senha foi
02555     // passado (mais uma vez, podemos ter um erro de sintaxe).
02556     if( LogLine[ EndParam ] != 0 )
02557     {
02558         // Guarda o caractere, para podermos comparar o nome do comando com a
02559         // tabela de comandos com senhas
02560         TempChar = LogLine[ EndParam ];
02561 
02562         // Temporariamente finalizamos a string neste ponto, para podermos
02563         // buscar o comando na tabela de comandos com senhas.
02564         LogLine[ EndParam ] = 0;
02565 
02566         // Inicializa a posicao do parametro password para 0, para indicar que
02567         // o comando nao tem, por default, uma senha.
02568         PasswordParamPos = 0;
02569 
02570         // Procura pelo comando na tabela
02571         CommandPos = 0;
02572         while( ( LogCommandTable[ CommandPos ].Command != NULL ) &&
02573                ( PasswordParamPos == 0 ) )
02574         {
02575             if( strcmp( &LogLine[ StartParam ],
02576                 LogCommandTable[ CommandPos ].Command ) == 0 )
02577                 PasswordParamPos = LogCommandTable[ CommandPos ].PasswordParam;
02578             else
02579                 CommandPos++;
02580         }
02581 
02582         // Restaura o caractere alterado anteriormente.
02583         LogLine[ EndParam ] = TempChar;
02584 
02585         // Se PasswordParamPos for diferente de 0, entao o comando tem um
02586         // parametro de senha, e a sua posicao esta em PasswordParamPos.
02587         if( PasswordParamPos > 0 )
02588         {
02589             // Garda a posicao inicial do parametro.
02590             StartParam = EndParam;
02591 
02592             // Descobre a posicao do parametro com a senha.
02593             while( PasswordParamPos > 0 )
02594             {
02595                 // Pula os espacos iniciais do parametro.
02596                 while( ( LogLine[ StartParam ] == ' ' ) ||
02597                        ( LogLine[ StartParam ] == '\t' ) )
02598                     StartParam++;
02599 
02600                 // Se nao for o ultimo parametro, devemos ignora-lo
02601                 if( PasswordParamPos > 1 )
02602                 {
02603                     // Descobre o final do parametro.
02604                     while( ( LogLine[ StartParam ] != ' ' ) &&
02605                            ( LogLine[ StartParam ] != '\t' ) &&
02606                            ( LogLine[ StartParam ] != 0 ) )
02607                         StartParam++;
02608                 }
02609 
02610                 // Atualiza o contador de parametros.
02611                 PasswordParamPos--;
02612             }
02613 
02614             // Agora, estamos na posicao do parametro. Basta entao mudarmos
02615             // todos os caracteres para "*" ate encontrarmos um espaco,
02616             // tab ou o termino da string.
02617             while( ( LogLine[ StartParam ] != ' ' ) &&
02618                    ( LogLine[ StartParam ] != '\t' ) &&
02619                    ( LogLine[ StartParam ] != 0 ) )
02620             {
02621                 LogLine[ StartParam ] = '*';
02622                 StartParam++;
02623             }
02624         }
02625 
02626     }
02627 
02628     // Tenta criar um novo objeto para salvar os logs.
02629     try
02630     {
02631         // Tenta criar o objeto do cliente.
02632         ClientExecLogs = new CClientUserLogs( Request );
02633 
02634         RioError = ClientExecLogs->Initialize( ExecPort );
02635 
02636         if( !FAILED( RioError ) )
02637         {
02638             // Envia a linha do log, usando o objeto ClientUserLogs.
02639             RioError = ClientExecLogs->NewLogLine( LogLine );
02640 
02641             #if RIO_DEBUG2
02642             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02643                            "CServerInterface::GenerateExecLogLine Erro %8X "
02644                            "(%s) ao tentar inserir a linha de log %s!",
02645                            RioError, GetErrorDescription( RioError ).c_str(),
02646                            LogLine );
02647             #endif
02648 
02649         }
02650         #ifdef RIO_DEBUG2
02651         else
02652             ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02653                            "CServerInterface::GenerateExecLogLine Erro %8X "
02654                            "(%s) ao inicializar o objeto usado para enviar a "
02655                            "linha de log %s!", RioError,
02656                            GetErrorDescription( RioError ).c_str(), LogLine );
02657         #endif
02658 
02659         // Deleta o objeto usado para enviar a linha de log (com ou
02660         // sem sucesso).
02661         delete ClientExecLogs;
02662     }
02663     catch( bad_alloc &ba )
02664     {
02665         #ifdef RIO_DEBUG2
02666         ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02667                        "CServerInterface::GenerateExecLogLineErro de alocacao "
02668                        "de memoria (bad_alloc, error = %s) ao criar o objeto "
02669                        "para enviar a linha de log %s!", ba.what(), LogLine );
02670         #endif
02671     }
02672 }

void CServerInterface::GenerateXMLError ( request_rec *  Request,
apr_status_t  ApacheStatus,
int  SystemStatus,
RioResult  RioStatus 
) [static]

Gera o XML com os erros passados como parametro, usando a TAG rioexec.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
ApacheStatus codigo de erro do Apache. Somente sera colocado no XML se for diferente de APR_SUCCESS.
SystemStatus codigo de erro do sistema. Somente sera colocado no XML se for diferente de 0.
RioStatus codigo de erro do RIO. Somente sera colocado no XML se for diferente de S_OK.

Definition at line 6377 of file ServerInterface.cpp.

06380 {
06381     #ifdef RIO_DEBUG2
06382     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
06383                    "Tentando gerar o XML para os seguintes erros: Apache = %u, "
06384                    "Sistema = %u e Rio = %08x", ApacheStatus, SystemStatus,
06385                    RioStatus );
06386     #endif
06387 
06388     StartXML( Request, CMD_INV_ID );
06389     AddErrorToXML( Request, ApacheStatus, SystemStatus, RioStatus );
06390     EndXML( Request, CMD_INV_ID );
06391 }

void CServerInterface::GenerateXMLStatus ( request_rec *  Request,
unsigned int  CommandId,
unsigned int  SessionId 
) [private]

Funcao para gerar o estado da execucao dos comandos que nao retornam informacoes no XML diferente do estado (isto e, todos os comandos com excecao do sessions e do ls), usando uma TAG composta por rioexec mais, se existir, o nome do comando.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
CommandId Identificador do comando executado. Se o comando for CMD_INV_ID (na verdade, qualquer valor maior ou igual a este), a TAG sera rioexec. Porem, caso o valor seja menor do que CMD_INV_ID, a TAG sera rioexec_<commando>, onde commando sera obtido da posicao CommandId da tabela CommandTable dada em ServerInterface.cpp.
SessionId identificador da sessao a ser usado caso nao exista nenhum erro reportado no objeto.

Definition at line 2441 of file ServerInterface.cpp.

02444 {
02445     #ifdef RIO_DEBUG2
02446     ap_log_rerror( APLOG_MARK, APLOG_ERR, 0, Request,
02447                    "Tentando gerar o XML para os seguintes erros: Apache = %u, "
02448                    "Sistema = %u e Rio = %08x", m_ApacheStatus, m_SystemStatus,
02449                    m_RioStatus );
02450     #endif
02451 
02452     StartXML( Request, CommandId );
02453     AddStatusToXML( Request, SessionId );
02454     EndXML( Request, CommandId );
02455 }

void CServerInterface::GetErrors ( apr_status_t *  ApacheStatus,
int *  SystemStatus,
RioResult RioStatus 
)

Funcao para retornar os codigos de erro caso alguma das funcoes acima retorne false.

O erro somente sera enviado se alguma das variaveis indicarem um erro, ou seja, se ApacheStatus for diferente de APR_SUCCESS, SystemStatus for diferente de 0, ou RioStatus for diferente de S_OK.

Parameters:
ApacheStatus ponteiro para armazenar o codigo de erro do Apache. Se for NULL, o erro nao sera armazenado.
SystemStatus ponteiro para armazenar o codigo de erro do sistema. Se for NULL, o erro nao sera armazenado.
RioStatus ponteiro para armazenar o codigo de erro do RIO. Se for NULL, o erro nao sera armazenado.

Definition at line 6357 of file ServerInterface.cpp.

06359 {
06360     if( ( ApacheStatus != NULL ) && ( m_ApacheStatus != APR_SUCCESS ) )
06361         *ApacheStatus = m_ApacheStatus;
06362     if( ( SystemStatus != NULL ) && ( m_SystemStatus != 0 ) )
06363         *SystemStatus = m_SystemStatus;
06364     if( ( RioStatus != NULL ) && ( m_RioStatus != S_OK ) )
06365         *RioStatus = m_RioStatus;
06366 }

server_rec * CServerInterface::GetServer (  ) 

Funcao para obter um ponteiro para a requisicao HTTP associada ao servidor apache2.

Returns:
ponteiro para a estrutura do sevidor apache2.

Definition at line 6439 of file ServerInterface.cpp.

06440 {
06441     return m_Server;
06442 }

bool CServerInterface::NoError (  ) 

Funcao para verificar se algum erro ocorreu ao executarmos uma das funcoes da classe.

Returns:
true se nenhum erro ocorreu ou false se algum erro ocorreu.

Definition at line 6370 of file ServerInterface.cpp.

06371 {
06372     return( ( m_ApacheStatus == APR_SUCCESS) && ( m_SystemStatus == 0 ) &&
06373             ( m_RioStatus == S_OK ) );
06374 }

bool CServerInterface::OpenRioObject ( const char *  FileName,
RioAccess  Access 
) [private]

Definition at line 1054 of file ServerInterface.cpp.

01055 {
01056     // Armazena o resultado da execucao de uma das funcoes do RIO.
01057     RioResult hResult;
01058 
01059     // Verifica se o objeto passado como parametro e valido.
01060     if( m_isObjectOpen )
01061     {
01062         m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_ALREADY_OPENED;
01063         
01064         #ifdef RIO_DEBUG2
01065         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01066                       "Error opening object (1): %u (%s)", m_RioStatus,
01067                       GetErrorDescription( m_RioStatus ).c_str() );
01068         #endif
01069         
01070         return false;
01071     }
01072 
01073     // Verifica se a sessao e valida e esta aberta.
01074     if( ( m_Session == NULL ) || ( !m_isSessionOpen ) )
01075     {
01076         if( m_Session == NULL )
01077             m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
01078         else
01079             m_RioStatus = ERROR_RIOSTREAM + ERROR_SESSION_NOT_OPENED;
01080 
01081         #ifdef RIO_DEBUG2
01082         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01083                       "Erro opening object (2): %u (%s)", m_RioStatus,
01084                       GetErrorDescription( m_RioStatus ).c_str() );
01085         #endif
01086 
01087         return false;
01088     }
01089 
01090     // Verifica se a stream e valida e esta aberta.
01091     if( ( m_Stream == NULL ) || ( !m_isStreamOpen ) )
01092     {
01093         if( m_Stream == NULL )
01094             m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
01095         else
01096             m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_NOT_OPENED;
01097         
01098         #ifdef RIO_DEBUG2
01099         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01100                       "Erro opening object (3): %u (%s)", m_RioStatus,
01101                       GetErrorDescription( m_RioStatus ).c_str() );
01102         #endif
01103         
01104         return false;
01105     }
01106 
01107     // Se for um acesso para a escrita, precisamos criar um novo objeto.
01108     if( ( Access & RIO_WRITE_ACCESS ) )
01109     {
01110         hResult = m_Session->CreateObject( FileName, ObjectInfo::FILE_TYPE_DATA,
01111                                            NULL );
01112 
01113         if( FAILED( hResult ) &&
01114             ( ( hResult & 0xff ) != ( unsigned ) ERROR_OBJECT_EXISTS ) )
01115         {
01116             m_RioStatus = hResult;
01117 
01118             #ifdef RIO_DEBUG2
01119             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01120                          "Erro creating object: %u (%s)", m_RioStatus,
01121                          GetErrorDescription( m_RioStatus ).c_str() );
01122             #endif
01123 
01124             return false;
01125         }
01126     }
01127 
01128     // Cria o objeto que sera usado para ler o arquivo.
01129     m_Object = new CRioObject;
01130     if( m_Object == NULL )
01131     {
01132         m_RioStatus = ERROR_RIOOBJECT + ERROR_MEMORY;
01133         
01134         #ifdef RIO_DEBUG2
01135         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01136                       "Error creating RIO object: %u (%s)", m_RioStatus,
01137                       GetErrorDescription( m_RioStatus ).c_str()
01138                     );
01139         #endif
01140 
01141         return false;
01142     }
01143 
01144     // Abre, no servidor, o arquivo associado ao objeto.
01145     // RIO_READ_ACCESS | RIO_SHARE_READ
01146     hResult = m_Object->Open( FileName, Access, m_Stream );
01147     if( FAILED( hResult ) )
01148     {
01149         m_RioStatus = hResult;
01150         
01151         #ifdef RIO_DEBUG2
01152         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01153                       "Erro opening object (4): %u (%s)", m_RioStatus,
01154                       GetErrorDescription( m_RioStatus ).c_str() );
01155         #endif
01156         
01157         return false;
01158     }
01159     else
01160     {
01161         m_isObjectOpen = true;
01162         
01163         return true;
01164     }
01165 }      

bool CServerInterface::OpenRioSession ( const char *  ServerName,
const char *  UserName,
const char *  UserPassword 
) [private]

Funcao para abrir a sessao com o servidor RIO, com o servidor dado pelo parametro m_ServerName.

Parameters:
ServerName ponteiro para o nome do servidor RIO.
UserName ponteiro para o nome do usuario do RIO.
UserPassword ponteiro para a senha do usuario apontado por UserName.
Returns:
true se a sessao foi criada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

Definition at line 782 of file ServerInterface.cpp.

00785 {
00786     RioResult hResult;
00787     char *EncryptedPassword;
00788     
00789     // Verifica se a sessao ja foi aberta.
00790     if( m_isSessionOpen ) 
00791     {
00792         m_RioStatus = ERROR_RIOSESSION + ERROR_SESSION_ALREADY_OPENED;
00793         
00794         #ifdef RIO_DEBUG2
00795         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00796                       "Error opening RIO session (1): %u (%s)", m_RioStatus,
00797                       GetErrorDescription( m_RioStatus ).c_str()
00798                     );
00799         #endif
00800         
00801         return false;
00802     }
00803 
00804     // Tenta encriptar a senha passada como parametro.
00805     EncryptedPassword = encryptPassword( UserPassword );
00806     if( EncryptedPassword == NULL )
00807     {
00808         m_SystemStatus = ENOMEM;
00809 
00810         #ifdef RIO_DEBUG2
00811         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00812                       "Error encrypting user password: %u (%s)", m_SystemStatus,
00813                       strerror( m_SystemStatus ) );
00814         #endif
00815 
00816         return false;
00817     }
00818 
00819     // Cria o objeto que sera usado para criarmos a sessao com o RIO.
00820     m_Session = new CRioSession;
00821     if( m_Session == NULL )
00822     {
00823         m_RioStatus = ERROR_RIOSESSION + ERROR_MEMORY;
00824 
00825         #ifdef RIO_DEBUG2
00826         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00827                       "Error creating RIO session: %u (%s)", m_RioStatus,
00828                       GetErrorDescription( m_RioStatus ).c_str()  );
00829         #endif
00830         
00831         // Deleta a string com a senha encriptada.
00832         delete[] EncryptedPassword;
00833 
00834         return false;
00835     }
00836 
00837     // Tenta se conectar ao servidor RIO (o valor 1 no ultimo parametro
00838     // indica que desejamos se conectar ao servidor RIO, ao inves da RIOPL).
00839     hResult = m_Session->Connect( ServerName, UserName, EncryptedPassword, 1 );
00840     if( FAILED( hResult ) ) 
00841     {
00842         m_RioStatus = hResult;
00843 
00844         #ifdef RIO_DEBUG2
00845         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00846                       "Error opening RIO session (2): %u (%s)", hResult,
00847                       GetErrorDescription( hResult ).c_str() );
00848         #endif
00849 
00850         // Deleta a string com a senha encriptada.
00851         delete[] EncryptedPassword;
00852         
00853         // Deleta a sessao.
00854         delete m_Session;
00855         m_Session = NULL;
00856 
00857         return false;
00858     }
00859 
00860     // Deleta a string com a senha encriptada.
00861     delete[] EncryptedPassword;
00862 
00863     m_isSessionOpen = true;
00864     
00865     return true;
00866 }

bool CServerInterface::OpenRioStream ( RioStreamDirection  Direction  )  [private]

Funcao para abrir um stream associado a sessao apontada pelo ponteiro m_Session.

Returns:
true se o stream foi criada com sucesso e false em caso contrario (neste caso, m_RioStatus indicara o erro que ocorreu).

Definition at line 915 of file ServerInterface.cpp.

00917 {
00918     // Armazena os dados do trafego do stream.
00919     RioStreamTraffic Traffic;
00920     // Armazena o resultado da execucao de uma das funcoes do RIO.
00921     RioResult hResult;
00922     // Numero maximo de requisicoes (trafego de tempo nao real).
00923     // Obs: Copiado de RioExplorer.cpp.
00924     static const int MaxRequests = 20;
00925 
00926     // Verifica se a stream ja esta aberta.
00927     if( m_isStreamOpen ) 
00928     {
00929         m_RioStatus = ERROR_RIOSTREAM + ERROR_STREAM_ALREADY_OPENED;
00930         
00931         #ifdef RIO_DEBUG2
00932         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00933                       "Error opening RIO stream (1): %u (%s)",
00934                       m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00935                     );
00936         #endif
00937         
00938         return false;
00939     }
00940 
00941     // Verifica se a sessao e valida e esta aberta.
00942     if( ( m_Session == NULL ) || ( !m_isSessionOpen ) )
00943     {
00944         if( m_Session == NULL )
00945             m_RioStatus = ERROR_RIOSTREAM + ERROR_NOT_INITIALIZED;
00946         else
00947             m_RioStatus = ERROR_RIOSTREAM + ERROR_SESSION_NOT_OPENED;
00948         
00949         #ifdef RIO_DEBUG2
00950         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00951                       "Erro opening RIO stream (2): %u (%s)", m_RioStatus,
00952                       GetErrorDescription( m_RioStatus ).c_str() );
00953         #endif
00954         
00955         return false;
00956     }
00957 
00958     // Cria o stream usado para copiar os arquivos.
00959     m_Stream = new CRioStream();
00960     if( m_Stream == NULL )
00961     {
00962         m_RioStatus = ERROR_RIOSTREAM + ERROR_MEMORY;
00963         
00964         #ifdef RIO_DEBUG2
00965         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00966                       "Error creating RIO stream: %u (%s)", m_RioStatus,
00967                       GetErrorDescription( m_RioStatus ).c_str()
00968                      );
00969         #endif
00970 
00971         return false;
00972     }
00973 
00974     // Inicializa os dados do stream.
00975     Traffic.Type = RIO_TRAFFIC_NRT;
00976     Traffic.TrafficNRT.Reserved = 0;
00977     Traffic.MaxRequests = MaxRequests;
00978     Traffic.Direction = Direction; // RioStreamDirectionRead
00979     Traffic.LogicalBlockSize = m_BlockSize;
00980 
00981     // Abre o stream
00982     hResult = m_Stream->Open( &Traffic, m_Session );
00983     if( FAILED( hResult ) ) 
00984     {
00985         m_RioStatus = hResult;
00986         
00987         #ifdef RIO_DEBUG2
00988         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00989                       "Error opening RIO stream (3): %u (%s)",
00990                       m_RioStatus, GetErrorDescription( m_RioStatus ).c_str()
00991                     );
00992         #endif
00993         
00994         return false;
00995     }
00996 
00997     m_isStreamOpen = true;
00998 
00999     return true;
01000 }

void CServerInterface::PrintErrors (  ) 

Funcao para mostrar os codigos de erro no log do apache.

Somente os codigos com erro serao mostrados (ou seja, nao sera mostrado o erro do apache se ele for APR_SUCCESS, nao sera mostrado o erro do sistema se ele for 0, e nao sera mostrado o erro do RIO se ele for S_OK).

Definition at line 6409 of file ServerInterface.cpp.

06410 {
06411     // Mostra o erro do RIO, se necessario
06412     if( m_RioStatus != S_OK )
06413         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06414                       "RioError = %8X (%s)", m_RioStatus,
06415                       GetErrorDescription( m_RioStatus ).c_str() );
06416 
06417     // Mostra o erro do apache (se necessario)
06418     if( m_ApacheStatus != APR_SUCCESS )
06419     {
06420         char ApacheStrError[ MAXAPACHESTRERRORSIZE ];
06421 
06422         // Obtem o erro do apache
06423         apr_strerror( m_ApacheStatus, ApacheStrError,
06424                       MAXAPACHESTRERRORSIZE );
06425 
06426         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06427                       "ApacheError = %u (%s)", m_ApacheStatus, ApacheStrError );
06428     }
06429 
06430     // Mostra o erro do sistema (se necessario)
06431     if( m_SystemStatus != 0 )
06432         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06433                       "SystemError = %u (%s)", m_SystemStatus,
06434                       strerror( m_SystemStatus ) );
06435 }

void CServerInterface::ReadApacheThreadFunction (  )  [private]

Funcao usada pela thread que copia os blocos do cliente.

Parameters:
Class ponteiro para o objeto da classe que criou a thread.
Returns:
valor nulo.

Definition at line 1879 of file ServerInterface.cpp.

01880 {
01881     bool NoError;
01882     bool IsApacheEof;
01883     int status;
01884     unsigned int DataSize;
01885     #ifdef RIO_DEBUG2
01886     RioBlock Block;
01887     #endif
01888 
01889     #ifdef RIO_DEBUG2
01890     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01891                   "READAPACHETHREADID %lu", syscall( SYS_gettid ) );
01892     #endif
01893 
01894     // Executa ate que um erro ocorra ou que seja informado que a thread deve
01895     // terminar a sua execucao.
01896     while( 1 )
01897     {
01898           // Obtem o mutex para acessar exclusivamente as variaveis do buffer
01899           status = pthread_mutex_lock( &m_Mutex );
01900           if( status < 0 )
01901           {
01902               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01903                             "error locking mutex m_Mutex" );
01904           }
01905 
01906           // Verifica se a thread deve terminar a sua execucao.
01907           if( m_ThreadCanceled )
01908           {
01909               // Libera o mutex para acessar exclusivamente as variaveis do
01910               // buffer.
01911               status = pthread_mutex_unlock( &m_Mutex );
01912               if( status < 0 )
01913               {
01914                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01915                                 "error unlocking mutex m_Mutex" );
01916               }
01917 
01918               #ifdef RIO_DEBUG2
01919               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01920                             "Finalizando a thread ReadApacheThreadFunction!" );
01921               #endif
01922 
01923               return;
01924           }
01925 
01926           // Informa as outra thread que a thread esta esperando para iniciar
01927           // a copia.
01928           status = pthread_cond_signal( &m_ThreadBlocked );
01929           if( status < 0 )
01930           {
01931               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01932                             "error signalling condition variable "
01933                             "m_ThreadBlocked" );
01934           }
01935 
01936           // Verifica se uma copia esta em andamento. Caso nao esteja, espera
01937           // na variavel de condicao m_ReadRioStarted ate uma copia ser
01938           // iniciada.
01939           if( !m_isReadingApacheFile )
01940           {
01941               status = pthread_cond_wait( &m_ReadApacheStarted, &m_Mutex );
01942 
01943               if( status < 0 )
01944               {
01945                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01946                                 "error waiting in condition variable "
01947                                 "m_ReadApacheStarted" );
01948               }
01949 
01950           }
01951 
01952           #ifdef RIO_DEBUG2
01953           // Inicializa o contador do bloco.
01954           Block = 0;
01955           #endif
01956 
01957           while( ( m_isReadingApacheFile ) && ( !m_ThreadCanceled ) )
01958           {
01959               // Libera o mutex para acessar exclusivamente as variaveis do
01960               // buffer.
01961               status = pthread_mutex_unlock( &m_Mutex );
01962               if( status < 0 )
01963               {
01964                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01965                                 "error unlocking mutex m_Mutex" );
01966               }
01967 
01968               // Inicializa o tamanho com o tamanho maximo do bloco.
01969               DataSize = m_BlockSize;
01970 
01971               // Tenta ler o bloco do servidor RIO.
01972               NoError = ReceiveBlock( m_UploadRequest, m_ApacheBuffer,
01973                                       &DataSize, &IsApacheEof );
01974 
01975               // Verifica a coerencia do bloco recebido (isto e, se IsApacheEof
01976               // nao for true, o tamanho do bloco retornado sempre deveria ser
01977               // m_BlockSize.
01978               if( ( !IsApacheEof ) && ( DataSize != m_BlockSize ) )
01979               {
01980                   #ifdef RIO_DEBUG2
01981                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01982                                 "Error receiving block %u! Size of received "
01983                                 "block is %u, but must be the maximum size "
01984                                 "%u because an EOF has not detected!",
01985                                 Block, DataSize, m_BlockSize );
01986                   #endif
01987                   NoError = false;
01988 
01989               }
01990 
01991               // Obtem o mutex para acessar exclusivamente as variaveis do
01992               // buffer.
01993               status = pthread_mutex_lock( &m_Mutex );
01994               if( status < 0 )
01995               {
01996                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01997                                 "error locking mutex m_Mutex" );
01998               }
01999 
02000               // Define os valores das variaveis m_IsApacheEof e
02001               // m_LastApacheBlockSize se DataSize for diferente de 0.
02002               m_IsApacheEof = IsApacheEof;
02003 
02004               if( !NoError )
02005               {
02006                   #ifdef RIO_DEBUG2
02007                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02008                                 "error executing ReadRioObjectBlock" );
02009                   #endif
02010               }
02011               else if( ( !IsApacheEof ) || ( DataSize != 0 ) )
02012               {
02013                   m_LastApacheBlockSize = DataSize;
02014 
02015                   // Libera o mutex para acessar exclusivamente as variaveis do
02016                   // buffer.
02017                   status = pthread_mutex_unlock( &m_Mutex );
02018                   if( status < 0 )
02019                   {
02020                       ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02021                                     "error unlocking mutex m_Mutex" );
02022                   }
02023 
02024                   #ifdef RIO_DEBUG2
02025                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02026                                 "Trying to insert apache block %u in "
02027                                 "CircularBuffer with %u bytes, eof = %s!",
02028                                 Block, DataSize,
02029                                 ( ( IsApacheEof ) ? "true": "false" ) );
02030                   #endif
02031 
02032                   // Tenta inserir o bloco lido no buffer circular.
02033                   NoError = m_CircularBuffer->SetElement( m_ApacheBuffer );
02034                   if( !NoError )
02035                   {
02036                       m_SystemStatus = m_CircularBuffer->GetError();
02037 
02038                       #ifdef RIO_DEBUG2
02039                       ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02040                                     "Error copying apache block to circular "
02041                                     "buffer: %u (%s)", m_SystemStatus,
02042                                      strerror( m_SystemStatus ) );
02043                       #endif
02044 
02045                   }
02046 
02047                   // Obtem novamente o mutex para acessar exclusivamente as
02048                   // variaveis do buffer.
02049                   status = pthread_mutex_lock( &m_Mutex );
02050                   if( status < 0 )
02051                   {
02052                       ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02053                                     "error locking mutex m_Mutex" );
02054                   }
02055 
02056               }
02057 
02058               // Verifica se ja todos os blocos ja foram lidos. Se isso ja
02059               // ocorreu, entao devemos cancelar a leitura.
02060               if( ( m_IsApacheEof ) || ( !NoError ) )
02061               {
02062                   #ifdef RIO_DEBUG2
02063                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02064                                 "Fim da recepcao! Desbloqueando a outra thread "
02065                                 ", se isso for necessario!" );
02066                   #endif
02067 
02068                   // Indica que a copia terminou.
02069                   m_isReadingApacheFile = false;
02070 
02071                   // Se um erro ocorreu ou se a copia terminou, deveremos tambem
02072                   // desbloquear a thread que repassa os blocos para o servidor
02073                   // RIO, se ela estiver bloqueada no buffer circular esperando
02074                   // por elementos.
02075                   m_CircularBuffer->CancelGetElement();
02076               }
02077 
02078               #ifdef RIO_DEBUG2
02079               // Incrementa a variavel com o numero do bloco, usada pela
02080               // depuracao.
02081               Block++;
02082               #endif
02083           }
02084 
02085           // Libera o mutex para acessar exclusivamente as variaveis do buffer.
02086           status = pthread_mutex_unlock( &m_Mutex );
02087           if( status < 0 )
02088           {
02089               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
02090                             "error unlocking mutex m_Mutex" );
02091           }
02092     }
02093 }

void * CServerInterface::ReadApacheThreadFunctionEp ( void *  Class  )  [static, private]

Funcao usada pela thread que recebe os blocos do cliente.

A funcao simplesmente converte o ponteiro e depois chama a funcao ReadApacheThreadFunction.

Parameters:
Class ponteiro para o objeto da classe que criou a thread.
Returns:
valor nulo.

Definition at line 1863 of file ServerInterface.cpp.

01864 {
01865     CServerInterface *Module;
01866 
01867     // Obtem o ponteiro para a classe de interfaxe com o servidor.
01868     Module = ( CServerInterface * ) Class;
01869 
01870     // Chama a funcao que executa a thread de leitura dos blocos do apache.
01871     Module->ReadApacheThreadFunction();
01872 
01873     // Retorno da funcao.
01874     return NULL;
01875 
01876 }

void CServerInterface::ReadCallBack ( RioRequest Request  )  [static, private]

Funcao de callback executada apos a leitura (com sucesso ou nao) do bloco.

Parameters:
Request ponteiro para o pedido do bloco.

Definition at line 1285 of file ServerInterface.cpp.

01286 {
01287     CServerInterface *Module = ( CServerInterface* ) Request->User;
01288 
01289     #ifdef RIO_DEBUG2
01290     ap_log_error( APLOG_MARK, APLOG_ERR, 0, Module->GetServer(),
01291                   "Block %u arrived. Sending signal!", Request->Block );
01292     #endif
01293         
01294     // Envia um sinal, para avisar que o bloco ja chegou.
01295     if( !Module->SendSignal() )
01296         ap_log_error( APLOG_MARK, APLOG_ERR, 0, Module->GetServer(),
01297                       "Error when executing SendSignal" );
01298 }

bool CServerInterface::ReadRioObjectBlock ( RioBlock  Block  )  [private]

Definition at line 1318 of file ServerInterface.cpp.

01319 {
01320     RioResult hResult;
01321     RioRequest Request;
01322     int status;
01323     
01324     bool CopyBlock;
01325 
01326     #ifdef RIO_DEBUG2
01327     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01328                   "Trying reading block %u", Block );
01329     #endif
01330     
01331     // Numero de tentativas de ler um bloco (devemos considerar isso?)
01332     unsigned int numberofretrys = 0;
01333 
01334     // Verifica se o objeto e valido e esta aberto.
01335     if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
01336     {
01337         if( m_Object == NULL )
01338             m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
01339         else
01340             m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
01341         
01342         #ifdef RIO_DEBUG2
01343         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01344                       "Object not opened: %u (%s)", m_RioStatus,
01345                       GetErrorDescription( m_RioStatus ).c_str() );
01346         #endif
01347         
01348         return false;
01349     }
01350 
01351     // Inicializa a estrutura com o pedido do bloco.
01352     Request.Size = m_BlockSize;
01353     Request.Buffer = m_RioBuffer;
01354     Request.CallBackFunction = ReadCallBack;
01355     Request.User = (void *) this;
01356     Request.Block = Block; 
01357     Request.Result = S_OK;
01358     Request.Status = RIO_REQUEST_FREE;
01359 
01360     CopyBlock = true;
01361     while( CopyBlock )
01362     {
01363         // Espera pelo recebimento de um bloco.
01364 
01365         status = pthread_mutex_lock( &m_ReadWriteMutex );
01366         if( status != 0 )
01367         {
01368             m_SystemStatus = status;
01369             
01370             #ifdef RIO_DEBUG2
01371             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01372                           "Error reading block %u (1.1): %u (%s)",
01373                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01374             #endif
01375 
01376             return false;
01377         }
01378 
01379         // Tenta ler um bloco do servidor
01380         hResult = m_Object->StreamRead( &Request );
01381 
01382         if( FAILED( hResult ) )
01383         {
01384             m_RioStatus = hResult;
01385 
01386             #ifdef RIO_DEBUG2
01387             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01388                           "Error reading block %u (1.2): %u (%s)",
01389                           Block, m_RioStatus,
01390                           GetErrorDescription( m_RioStatus ).c_str() );
01391             #endif
01392 
01393             return false;
01394         }
01395 
01396         status = pthread_cond_wait( &m_ReadWriteCond, &m_ReadWriteMutex );
01397         if( status != 0 )
01398         {
01399             m_SystemStatus = status;
01400             
01401             #ifdef RIO_DEBUG2
01402             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01403                           "Error reading block %u (1.3): %u (%s)",
01404                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01405             #endif
01406             status = pthread_mutex_unlock( &m_ReadWriteMutex );
01407             if( status != 0 )
01408             {
01409                 m_SystemStatus = status;
01410 
01411                 #ifdef RIO_DEBUG2
01412                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01413                               "Error unlocking mutex: %u (%s)", status,
01414                               strerror( status ) );
01415                 #endif
01416             } 
01417 
01418             return false;
01419         }
01420 
01421         status = pthread_mutex_unlock( &m_ReadWriteMutex );
01422         if( status != 0 )
01423         {
01424             m_SystemStatus = status;
01425 
01426             #ifdef RIO_DEBUG2
01427             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01428                           "Error reading block %u (1.4): %u (%s)",
01429                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01430             #endif
01431 
01432             return false;
01433         }
01434 
01435         // Verifica se a copia do bloco ocorreu com sucesso.
01436         if( Request.Result == S_OK )
01437         {
01438             CopyBlock = false;
01439         }
01440         else if( ( Request.Result & 0xFF ) ==
01441                  ERROR_SERVICE_TEMPORARY_UNAVAILABLE )
01442         {
01443             // Obs: O 0xFF acima (com o AND logico) e para somente
01444             // considerar o codigo de erro geral, desconsiderando a parte do
01445             // erro que identifica a clase (AND - & - com 0xFF00) e o codigo
01446             // 0xE000 do RIO (obtido com AND - & - 0xFFFF0000). Neste caso,
01447             // o servidor caiu ao requisitarmos o bloco. Tentaremos ler
01448             // novamente o bloco se o numero de tentativas nao expirou.
01449             numberofretrys++;
01450 
01451             if( numberofretrys >= MAXNUMBEROFBLOCKRETRYS )
01452             {
01453                 m_RioStatus = ERROR_RIOOBJECT +
01454                               ERROR_SERVICE_TEMPORARY_UNAVAILABLE;
01455 
01456                 #ifdef RIO_DEBUG2
01457                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01458                               "Error reading block %u (1.5): %u (%s)",
01459                               Block, m_RioStatus,
01460                               GetErrorDescription( m_RioStatus ).c_str() );
01461                 #endif
01462                     
01463                 return false;
01464             }
01465         }
01466         else
01467         {
01468             m_RioStatus = Request.Result;
01469 
01470             #ifdef RIO_DEBUG2
01471             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01472                           "Error reading block %u (1.6): %u (%s)",
01473                           Block, m_RioStatus,
01474                           GetErrorDescription( m_RioStatus ).c_str() );
01475             #endif
01476 
01477             return false;
01478         }
01479     }
01480     
01481     return true;
01482 }

void CServerInterface::ReadRioThreadFunction (  )  [private]

Funcao usada pela thread que copia os blocos para o cliente.

Parameters:
Class ponteiro para o objeto da classe que criou a thread.
Returns:
valor nulo.

Definition at line 1723 of file ServerInterface.cpp.

01724 {
01725     RioBlock Block;
01726     bool NoError;
01727     int status;
01728     
01729     #ifdef RIO_DEBUG2
01730     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01731                   "READRIOTHREADID %lu", syscall( SYS_gettid ) );
01732     #endif               
01733     
01734     // Executa ate que um erro ocorra ou que seja informado que a thread deve
01735     // terminar a sua execucao.
01736     while( 1 )
01737     {
01738           // Verifica se a thread deve terminar a sua execucao.
01739           if( m_ThreadCanceled )
01740               return;
01741 
01742           // Obtem o mutex para acessar exclusivamente as variaveis do buffer
01743           status = pthread_mutex_lock( &m_Mutex );
01744           if( status < 0 )
01745           {
01746               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01747                             "error locking mutex m_Mutex" );
01748           }
01749           // Informa as outra thread que a thread esta esperando para iniciar
01750           // a copia.
01751           status = pthread_cond_signal( &m_ThreadBlocked );
01752           if( status < 0 )
01753           {
01754               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01755                             "error signalling condition variable "
01756                             "m_ThreadBlocked" );
01757           }
01758 
01759           // Verifica se uma copia esta em andamento. Caso nao esteja, espera
01760           // na variavel de condicao m_ReadRioStarted ate uma copia ser
01761           // iniciada.
01762           if( !m_isReadingRioFile )
01763           {
01764               status = pthread_cond_wait( &m_ReadRioStarted, &m_Mutex );
01765 
01766               if( status < 0 )
01767               {
01768                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01769                                 "error waiting in condition variable "
01770                                 "m_ReadRioStarted" );
01771               }
01772                                           
01773           }
01774 
01775           while( ( m_isReadingRioFile ) && ( !m_ThreadCanceled ) )
01776           {
01777               // Copia o valor do proximo bloco.
01778               Block = m_RioBlock;
01779 
01780               // Libera o mutex para acessar exclusivamente as variaveis do 
01781               // buffer.
01782               status = pthread_mutex_unlock( &m_Mutex );
01783               if( status < 0 )
01784               {
01785                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01786                                 "error unlocking mutex m_Mutex" );
01787               }
01788               
01789               // Tenta ler o bloco do servidor RIO.
01790               NoError = ReadRioObjectBlock( Block );
01791 
01792               if( !NoError ) 
01793               {
01794                   #ifdef RIO_DEBUG2
01795                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01796                                 "error executing ReadRioObjectBlock" );
01797                   #endif
01798               }
01799               else
01800               {
01801                   #ifdef RIO_DEBUG2
01802                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01803                                 "Trying to insert block %u in CircularBuffer!",
01804                                 Block );
01805                   #endif
01806 
01807                   // Tenta inserir o bloco lido no buffer circular.
01808                   NoError = m_CircularBuffer->SetElement( m_RioBuffer );
01809                   if( !NoError )
01810                   {
01811                       m_SystemStatus = m_CircularBuffer->GetError();
01812         
01813                       #ifdef RIO_DEBUG2
01814                       ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01815                                     "Error copying block %u to circular "
01816                                     "buffer: %u (%s)", Block, m_SystemStatus,
01817                                      strerror( m_SystemStatus ) );
01818                       #endif
01819 
01820                   }
01821               }
01822 
01823               // Obtem novamente o mutex para acessar exclusivamente as 
01824               // variaveis do buffer.
01825               status = pthread_mutex_lock( &m_Mutex );
01826               if( status < 0 )
01827               {
01828                   ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01829                                 "error locking mutex m_Mutex" );
01830               }
01831               
01832               // Incrementa o m_RioBlock para apontar para o proximo
01833               // bloco.
01834               m_RioBlock++;
01835               // Verifica se ja todos os blocos ja foram lidos. Se isso ja 
01836               // ocorreu, entao devemos cancelar a leitura.
01837               if( ( m_RioBlock >= m_TotalBlocks ) || ( !NoError ) )
01838               {
01839                   // Se algum erro ocorreu ou a copia terminou, entao deveremos
01840                   // indicar o termino da copia.
01841                   m_isReadingRioFile = false;
01842                   // Se um erro ocorreu, deveremos tambem desbloquear a thread
01843                   // que repassa os blocos para o apache, se ela estiver 
01844                   // bloqueada no buffer circular esperando por elementos.
01845                   if( !NoError )
01846                       m_CircularBuffer->CancelGetElement();
01847                   
01848               }  
01849           }
01850           // Libera o mutex para acessar exclusivamente as variaveis do buffer.
01851           status = pthread_mutex_unlock( &m_Mutex );
01852           if( status < 0 )
01853           {
01854               ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01855                             "error unlocking mutex m_Mutex" );
01856           }
01857     }
01858 }

void * CServerInterface::ReadRioThreadFunctionEp ( void *  Class  )  [static, private]

Funcao usada pela thread que copia os blocos para o cliente.

A funcao simplesmente converte o ponteiro e depois chama a funcao ReadRioThreadFunction.

Parameters:
Class ponteiro para o objeto da classe que criou a thread.
Returns:
valor nulo.

Definition at line 1707 of file ServerInterface.cpp.

01708 {
01709     CServerInterface *Module;
01710 
01711     // Obtem o ponteiro para a classe de interfaxe com o servidor.
01712     Module = ( CServerInterface * ) Class;
01713 
01714     // Chama a funcao que executa a thread de leitura dos blocos do RIO.
01715     Module->ReadRioThreadFunction();
01716 
01717     // Retorno da funcao.
01718     return NULL;
01719 
01720 }

bool CServerInterface::ReceiveBlock ( request_rec *  Request,
char *  Data,
unsigned int *  DataSize,
bool *  IsEOF 
) [private]

Funcao para receber dados do cliente, os armazenando no buffer passado no parametro Data, sendo que no maximo DataSize bytes serao recebidos.

Parameters:
Request ponteiro para a requisicao da qual receberemos o bloco.
Data ponteiro para o buffer com os dados (o bloco atual).
DataSize ponteiro para o tamanho maximo dos dados. Este parametro sera alterado pela funcao para o numero de bytes realmente lidos do cliente (este valor pode ser menor do que o valor passado, se o cliente enviou menos dados do que o desejado).
IsEOF ponteiro para um valor booleano que, se for igual a true, indicara que o bloco lido e o ultimo lido do apache e, em caso contrario, que mais blocos ainda devem ser lidos do apache.
Returns:
true se os dados foram recebidos com sucesso e false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

Definition at line 532 of file ServerInterface.cpp.

00534 {
00535     // Brigade para receber os dados lidos do apache
00536     apr_bucket_brigade *DataBrigate;
00537     // Bucket usado para ler os dados da brigate.
00538     apr_bucket *DataBucket;
00539     // Armazena o codigo de erro das funcoes do apache chamadas.
00540     apr_status_t ApacheStatus;
00541     // Aramzena o tamanho dos dados lidos do bucket DataBucket.
00542     apr_size_t BucketDataSize;
00543     // Armazena o ponteiro para os dados lidos do bucket DataBucket.
00544     const char *BucketData;
00545     // Armazena uma copia do tamanho maximo da leitura.
00546     unsigned int TotalDataSize;
00547 
00548     // Inicializa as variaveis locais.
00549     TotalDataSize = *DataSize;
00550 
00551     // Inicializa os ponteiros passados a funcao.
00552     *Data = 0;
00553     *DataSize = 0;
00554     *IsEOF = false;
00555 
00556     while( ( !( *IsEOF ) ) && ( ( *DataSize < TotalDataSize ) ) )
00557     {
00558         // Cria a estrutura de dados para enviar um fragmento.
00559         DataBrigate = apr_brigade_create( Request->pool,
00560                                           Request->connection->bucket_alloc );
00561         if( DataBrigate == NULL )
00562         {
00563             #ifdef RIO_DEBUG2
00564             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00565                           "unable to create brigade" );
00566             #endif
00567 
00568             m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00569             return false;
00570         }
00571 
00572         // Tenta ler um bloco do apache com no maximo TotalDataSize bytes.
00573         ApacheStatus = ap_get_brigade( Request->input_filters, DataBrigate,
00574                                        AP_MODE_READBYTES, APR_BLOCK_READ,
00575                                        TotalDataSize - ( *DataSize ) );
00576         if( ApacheStatus != APR_SUCCESS )
00577         {
00578             #ifdef RIO_DEBUG2
00579             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00580                           "unable to read up to %u bytes from filters",
00581                           TotalDataSize - ( *DataSize ) );
00582             #endif
00583 
00584             m_ApacheStatus = ApacheStatus;
00585 
00586             // Destroi a brigade. O erro e ignorado.
00587             ApacheStatus = apr_brigade_destroy( DataBrigate );
00588             #ifdef RIO_DEBUG2
00589             if( ApacheStatus != APR_SUCCESS )
00590             {
00591                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00592                               "warning: error when deleting brigate!" );
00593             }
00594             #endif
00595 
00596             return false;
00597         }
00598 
00599         // Processa os buckets enquando a brigate nao estiver vazia.
00600         while( !APR_BRIGADE_EMPTY( DataBrigate ) )
00601         {
00602             DataBucket = APR_BRIGADE_FIRST( DataBrigate );
00603             if( APR_BUCKET_IS_EOS( DataBucket ) )
00604             {
00605                  #ifdef RIO_DEBUG2
00606                  ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00607                                "Chegamos ao final dos dados lidos pela conexao "
00608                                "do Apache. Foram lidos %u bytes de no maxino "
00609                                "%u bytes", *DataSize, TotalDataSize );
00610                  #endif
00611 
00612                  // Chegamos ao final do arquivo.
00613                  *IsEOF = true;
00614 
00615                  // Final dos dados copiados. Devemos, neste caso, sair do
00616                  // while.
00617                  break;
00618             }
00619 
00620             // Tenta ler dados do bucket (este tamanho nao deveria passar o
00621             // valor de TotalDataSize, pois lemos no maximo isso pela brigade).
00622             ApacheStatus = apr_bucket_read( DataBucket, &BucketData,
00623                                             &BucketDataSize,
00624                                             APR_NONBLOCK_READ );
00625             if( ApacheStatus != APR_SUCCESS )
00626             {
00627                 #ifdef RIO_DEBUG2
00628                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00629                               "error when reading data from a bucket" );
00630                 #endif
00631 
00632                 m_ApacheStatus = ApacheStatus;
00633 
00634                 // Deleta a brigate, ignorando o erro.
00635                 ApacheStatus = apr_brigade_destroy( DataBrigate );
00636 
00637                 #ifdef RIO_DEBUG2
00638                 if( ApacheStatus != APR_SUCCESS )
00639                 {
00640                     ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus,
00641                                   m_Server, "warning: error when deleting "
00642                                   "brigate!" );
00643                 }
00644                 #endif
00645 
00646                 return false;
00647             }
00648 
00649              // Somente copia os dados se algo foi lido pelo apache.
00650              if( BucketDataSize > 0 )
00651              {
00652                  // Copia os dados para a posicao atual do buffer, se o tamanho
00653                  // nao exeder TotalDataSize (se isso acontecer, temos
00654                  // certamente um erro, porque a brigate leu no maximo
00655                  // m_BlockSize bytes).
00656                  if( ( *DataSize + BucketDataSize ) > TotalDataSize )
00657                  {
00658                      #ifdef RIO_DEBUG2
00659                      ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00660                                    "error when reading data from a bucket. "
00661                                    "Actual data size %u plus %u is greather "
00662                                    "then %u!", *DataSize, BucketDataSize,
00663                                    TotalDataSize );
00664                      #endif
00665 
00666                       m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00667 
00668                       // Deleta a brigate, ignorando o erro.
00669                       ApacheStatus = apr_brigade_destroy( DataBrigate );
00670                       #ifdef RIO_DEBUG2
00671                       if( ApacheStatus != APR_SUCCESS )
00672                       {
00673                           ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus,
00674                                         m_Server, "warning: error when "
00675                                         "deleting brigate!" );
00676                       }
00677                       #endif
00678 
00679                       return false;
00680                  }
00681 
00682                  // Copia os dados do bucket para a posicao correta do ponteiro
00683                  // apontado por &Data[ *DataSize ].
00684                  memcpy( &Data[ *DataSize ], BucketData, BucketDataSize );
00685 
00686                  // Atualiza o contador de dados lidos com os dados que acabaram
00687                  // de ser copiados.
00688                  *DataSize = *DataSize + BucketDataSize;
00689              }
00690 
00691             // Remove o bucket da brigate.
00692             apr_bucket_delete( DataBucket );
00693         }
00694 
00695         // Se nao copiados nenhum dado, entao atingimos o final do arquivo.
00696         *IsEOF = ( *IsEOF ) || ( ( *DataSize == 0 ) );
00697 
00698         // Remove a brigate usada para ler os dados.
00699         ApacheStatus = apr_brigade_destroy( DataBrigate );
00700         if( ApacheStatus != APR_SUCCESS )
00701         {
00702             #ifdef RIO_DEBUG2
00703             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00704                           "unable to destroy brigade" );
00705             #endif
00706 
00707             m_ApacheStatus = ApacheStatus;
00708             return false;
00709         }
00710     }
00711 
00712     return true;
00713 }

void CServerInterface::SaveExecLogLine ( request_rec *  Request,
const char *  Command 
) [private]

Funcao para gerar uma linha no log dos comandos, usando a porta definida na classe (se o valor for 0, nenhum log sera gerado), e os erros da classe (a funcao estatica GenerateExecLogLine e usada ao gerar os logs).

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
Command ponteiro para a string com o comando.

Definition at line 2677 of file ServerInterface.cpp.

02679 {
02680     // Chama a funcao da classe para gerar os logs, usando as informacoes da
02681     // classe e a porta e o comando passados como parametro.
02682     GenerateExecLogLine( Request, m_UserName, m_SessionId, m_ApacheStatus,
02683                          m_SystemStatus, m_RioStatus, Command, m_ExecLogPort );
02684 }

void CServerInterface::SaveExecLogLineError ( request_rec *  Request,
apr_status_t  ApacheStatus,
int  SystemStatus,
RioResult  RioStatus,
const char *  Command,
unsigned int  ExecPort 
) [static]

Gera uma linha no log da classe que executa os comandos.

O usuario usado, neste caso, sera "none" e o identificador da sessao sera 0.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
ApacheStatus codigo de erro do Apache. Somente sera colocado no XML se for diferente de APR_SUCCESS.
SystemStatus codigo de erro do sistema. Somente sera colocado no XML se for diferente de 0.
RioStatus codigo de erro do RIO. Somente sera colocado no XML se for diferente de S_OK.
Command ponteiro para a string com o comando.
ExecPort porta UDP usado para enviar os logs para a classe de logs associada com a classe que executa os comandos.

Definition at line 6395 of file ServerInterface.cpp.

06401 {
06402     // Chama a funcao da classe para gerar os logs, usando o usuario "none" e
06403     // um identificador de sessao 0.
06404     GenerateExecLogLine( Request, NULL, 0, ApacheStatus, SystemStatus,
06405                          RioStatus, Command, ExecPort );
06406 }

bool CServerInterface::SendBlock ( request_rec *  Request,
const char *  Data,
unsigned int  DataSize 
) [private]

Funcao para enviar dados ao cliente, armazenados no buffer passado no parametro Data.

O numero de bytes e dado em DataSize. Os dados serao enviados em fragmentos de tamanho de no maximo m_FragmentSize bytes (note que o ultimo fragmento pode ser menor, caso DataSize nao seja multiplo de m_FragmentSize).

Parameters:
Request ponteiro para a requisicao pela qual enviaremos o bloco.
Data ponteiro para o buffer com os dados (o bloco atual).
DataSize tamanho dos dados (quando a implementacao estiver completa, este tamanho sera igual ao do bloco para os blocos intermediarios mas podera nao ser este tamanho para o bloco inicial - caso a copia nao comece no inicio do arquivo - e para o bloco final - pois o tamanho do arquivo nao e necessariamente multiplo do bloco-).
Returns:
true se os dados foram enviados com sucesso e false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

Definition at line 314 of file ServerInterface.cpp.

00316 {
00317     // Brigade que armazenara os dados a serem enviados.
00318     apr_bucket_brigade *DataBrigate;
00319     // Bucket do tipo flush, usando para enviar imediatamente os dados salvos na
00320     // brigate.
00321     apr_bucket *FlushBucket;
00322     // Armazena o codigo de erro das funcoes do apache chamadas.
00323     apr_status_t ApacheStatus;
00324     // Ponteiros para lidar com os fragmentos do dado enviado. NextFargement e
00325     // o numero do proximo fragmento. TotalFragments define o numero total de
00326     // fragmentos. FragmentSize define o tamanho do proximo fragmento a ser
00327     // enviado (igual a m_FragmentSize para todos os fragmentos menos o ultimo,
00328     // que pode ser menor dependendo do tamanho dos dados (DataSize) ser ou nao
00329     // multiplo de m_FragmentSize. SendDataSize define a quantidade de bytes
00330     // salvos na brigate.
00331     unsigned int NextFragment, TotalFragments, FragmentSize, SendDataSize;
00332     // Ponteiro para o proximo fragmento (o primeiro fragmento comeca no
00333     // endereco dado pelo ponteiro Data).
00334     const char *PosNextFragment;
00335 
00336     // Define o tamanho do fragmento.
00337     FragmentSize = m_FragmentSize;
00338 
00339     #ifdef RIO_DEBUG2
00340     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00341                   "Tentando escrever um bloco com %u bytes. Tamanho do "
00342                   "fragmento e de %u bytes", DataSize, FragmentSize );
00343     #endif
00344 
00345     // Verifica o tamanho de cada fragmento.
00346     if( FragmentSize > DataSize )
00347     {
00348         #ifdef RIO_DEBUG2
00349         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00350                       "Warning: fragment size %u > datasize %u. "
00351                       "Setting to data size", FragmentSize, DataSize );
00352         #endif
00353         FragmentSize = DataSize;
00354     }
00355     #ifdef RIO_DEBUG2
00356     if( ( DataSize % FragmentSize ) != 0 )
00357         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00358                       "Warning: data size %u is not multiple of fragment "
00359                       "size %u. Last fragment will be smaller", DataSize,
00360                       FragmentSize );
00361     #endif
00362 
00363     // Calcula o numero total de fragmentos.
00364     TotalFragments = ( DataSize + FragmentSize - 1 ) / FragmentSize;
00365     NextFragment = 0;
00366 
00367     #ifdef RIO_DEBUG2
00368     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00369                   "Trying to send %u bytes: %u fragments of max size %u",
00370                   DataSize, TotalFragments, FragmentSize );
00371     #endif
00372 
00373     while( NextFragment < TotalFragments )
00374     {
00375         // Determina o tamanho dos dados a serem enviados.
00376         if( NextFragment < ( TotalFragments - 1 ) )
00377             SendDataSize = FragmentSize;
00378         else
00379             SendDataSize = DataSize - ( ( TotalFragments - 1 ) * 
00380                                         FragmentSize );
00381 
00382         #ifdef RIO_DEBUG2
00383         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00384                       "Trying to send fragment %u/%u with %u bytes",
00385                       NextFragment + 1, TotalFragments, SendDataSize );
00386         #endif
00387 
00388         // Cria a estrutura de dados para enviar um fragmento.
00389         DataBrigate = apr_brigade_create( Request->pool,
00390                                           Request->connection->bucket_alloc );
00391         if( DataBrigate == NULL )
00392         {
00393             #ifdef RIO_DEBUG2
00394             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00395                           "unable to create brigade" );
00396             #endif
00397                        
00398             m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00399             return false;  
00400         }
00401 
00402         // Envia o fragmento ao cliente.
00403         PosNextFragment = &Data[ NextFragment * FragmentSize ];
00404         ApacheStatus = apr_brigade_write( DataBrigate, NULL, NULL,
00405                                           PosNextFragment, SendDataSize );
00406         if( ApacheStatus != APR_SUCCESS )
00407         {
00408             #ifdef RIO_DEBUG2
00409             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00410                           "unable to write data in brigade" );
00411             #endif
00412                        
00413             m_ApacheStatus = ApacheStatus;
00414 
00415             // Destroi a brigade. O erro e ignorado.
00416             ApacheStatus = apr_brigade_destroy( DataBrigate );
00417 
00418             #ifdef RIO_DEBUG2
00419             if( ApacheStatus != APR_SUCCESS )
00420             {
00421                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00422                               "warning: error when deleting brigate!" );
00423 
00424             }
00425             #endif
00426 
00427             return false;  
00428         }
00429 
00430         // Cria um bucket para indicar o final do fragmento.
00431         FlushBucket = apr_bucket_flush_create(
00432                                             Request->connection->bucket_alloc );
00433         if( FlushBucket == NULL )
00434         {
00435             #ifdef RIO_DEBUG2
00436             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00437                           "unable to create flush bucket" );
00438             #endif
00439 
00440             m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00441 
00442             // Destroi a brigade. O erro e ignorado.
00443             ApacheStatus = apr_brigade_destroy( DataBrigate );
00444 
00445             #ifdef RIO_DEBUG2
00446             if( ApacheStatus != APR_SUCCESS )
00447             {
00448                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00449                               "warning: error when deleting brigate!" );
00450 
00451             }
00452             #endif
00453 
00454             return false;  
00455         }
00456 
00457         // Insere o bucket no final da brigade.
00458         APR_BRIGADE_INSERT_TAIL( DataBrigate, FlushBucket );
00459    
00460         // Passa o fragmento ja escrito para os outros filtros
00461         ApacheStatus = ap_pass_brigade( Request->output_filters, DataBrigate );
00462         if( ApacheStatus != APR_SUCCESS )
00463         {
00464             #ifdef RIO_DEBUG2
00465             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00466                           "unable to pass brigade to filters" );
00467             #endif
00468 
00469             m_ApacheStatus = ApacheStatus;
00470 
00471             // Destroi a brigade. O erro e ignorado.
00472             ApacheStatus = apr_brigade_destroy( DataBrigate );
00473 
00474             #ifdef RIO_DEBUG2
00475             if( ApacheStatus != APR_SUCCESS )
00476             {
00477                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00478                               "warning: error when deleting brigate!" );
00479 
00480             }
00481             #endif
00482 
00483             return false;  
00484         }
00485     
00486         ApacheStatus = ap_fflush( Request->output_filters, DataBrigate );
00487         if( ApacheStatus != APR_SUCCESS )
00488         { 
00489             #ifdef RIO_DEBUG2
00490             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00491                           "unable to execute fflush" );
00492             #endif
00493 
00494             m_ApacheStatus = ApacheStatus;
00495 
00496             // Destroi a brigade. O erro e ignorado.
00497             ApacheStatus = apr_brigade_destroy( DataBrigate );
00498 
00499             #ifdef RIO_DEBUG2
00500             if( ApacheStatus != APR_SUCCESS )
00501             {
00502                 ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00503                               "warning: error when deleting brigate!" );
00504 
00505             }
00506             #endif
00507 
00508             return false;  
00509         }
00510 
00511         ApacheStatus = apr_brigade_destroy( DataBrigate );
00512         if( ApacheStatus != APR_SUCCESS )
00513         { 
00514             #ifdef RIO_DEBUG2
00515             ap_log_error( APLOG_MARK, APLOG_ERR, ApacheStatus, m_Server,
00516                           "unable to destroy brigade" );
00517             #endif
00518 
00519             m_ApacheStatus = ApacheStatus;
00520             return false;  
00521         }
00522 
00523         // Atualiza NextFragment para o proximo fragmento.
00524         NextFragment++;
00525     }
00526 
00527     return true;
00528 }

bool CServerInterface::SendFileHeader ( request_rec *  Request,
const char *  FileName,
RioObjectSize  FileSize 
) [private]

Funcao para enviar um cabecalho antes dos dados do arquivo, caso o arquivo necessite do envio deste cabecalho.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
FileName nome do arquivo que desejamos avaliar se o envio do cabecalho e necessario.
FileSize variavel com o tamanho do arquivo, para sabermos como calcular o tamanho a ser colocado no campo da resposta que define o tamanho do arquivo.
Returns:
true a funcao foi executada com sucesso e false, em caso contrario, ou seja, se foi necessario enviar o cabecalho mais um erro ocorreu ao fazermos isso.

Definition at line 3578 of file ServerInterface.cpp.

03581 {
03582     const char *StartFinalExtension;
03583     const char *Header;
03584     unsigned int HeaderSize;
03585     RioObjectSize RealFileSize;
03586 
03587     // Inicialmente, o tamanho a ser enviado e igual ao tamanho do arquivo.
03588     RealFileSize = FileSize;
03589 
03590     // Procura pelo inicico da ultima extensao no nome do arquivo.
03591     StartFinalExtension = strrchr( FileName, '.' );
03592 
03593     // Se o arquivo possuir uma extensao, StartFinalExtension + 1 apontara
03594     // para o inicio da proxima extensao.
03595     if( StartFinalExtension != NULL )
03596     {
03597         // Um dos arquivos para o qual precisamos enviar um cabecalho e um
03598         // video  do flash.
03599         if( strcmp( StartFinalExtension + 1, "flv" ) == 0 )
03600         {
03601             Header = FLVX_HEADER;
03602             HeaderSize = FLVX_HEADER_LEN;
03603             RealFileSize = RealFileSize + HeaderSize;
03604         }
03605         else
03606         {
03607             // Por enquanto, somente enviaremos o cabecalho para os arquivos
03608             // .flv.
03609             Header = NULL;
03610             HeaderSize = 0;
03611         }
03612 
03613         ap_set_content_length( Request, RealFileSize );
03614 
03615         if( Header != NULL )
03616             return SendBlock( Request, Header, HeaderSize );
03617 
03618     }
03619 
03620     return true;
03621 }

bool CServerInterface::SendSignal (  )  [private]

Funcao para gerar um sinal para a variavel de condicao m_CopyCond (esta funcao e usada pela callback chamada apos o recebimento de um bloco).

Returns:
true se o sinal foi enviado com sucesso e false se algum erro ocorreu ao enviar o sinal.

Definition at line 1230 of file ServerInterface.cpp.

01231 {
01232     int status;
01233 
01234     // Obtem o mutex m_ReadWriteMutex.
01235     status = pthread_mutex_lock( &m_ReadWriteMutex );
01236     if( status != 0 )
01237     {
01238         m_SystemStatus = status;
01239 
01240         #ifdef RIO_DEBUG2
01241         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01242                       "Error locking mutex m_ReadWriteMutex: %u (%s)",
01243                       m_SystemStatus, strerror( m_SystemStatus ) );
01244         #endif
01245 
01246         return false;
01247     }
01248 
01249     // Gera o sinal para a variavel de condicao m_ReadWriteCond, associadao ao
01250     // mutex m_ReadWriteMutex.
01251     status = pthread_cond_signal( &m_ReadWriteCond );
01252     if( status < 0 )
01253     {
01254         m_SystemStatus = status;
01255 
01256         #ifdef RIO_DEBUG2
01257         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01258                       "Error sending signal: %u (%s)", m_SystemStatus,
01259                       strerror( m_SystemStatus ) );
01260         #endif
01261 
01262         return false;
01263     }
01264 
01265     // Libera o mutex m_ReadWriteMutex.
01266     status = pthread_mutex_unlock( &m_ReadWriteMutex );
01267     if( status != 0 )
01268     {
01269         m_SystemStatus = status;
01270 
01271         #ifdef RIO_DEBUG2
01272         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01273                       "Error unlocking mutex m_ReadWriteMutex: %u (%s)",
01274                       m_SystemStatus, strerror( m_SystemStatus ) );
01275         #endif
01276 
01277         return false;
01278     }
01279 
01280     return true;
01281 }

bool CServerInterface::Start ( char *  ServerName,
unsigned int  CircularBufferSize,
unsigned int  FragmentSize,
unsigned int  DefaultSessionId = 0,
unsigned int  ExecLogPort = 0 
)

Funcao para inicializar o objeto da classe RioModule (ou seja, abrir a conexao e o stream).

Parameters:
ServerName nome do servidor a que vamos nos conectar.
CircularBufferSize numero de entradas do buffer de recepcao.
FragmentSize tamanho dos fragmentos enviados ao cliente.
DefaultSessionId valor default para o identificador da sessao. Se for igual a 0 (o valor default, se o parametro nao for usado, um identificador aleatorio sera usado. Porem, se for diferente de 0, o identificador passado sempre sera usado.
ExecLogPort novo parametro indicando a porta UDP usada pelos logs. O valor 0 default do parametro desabilita a geracao dos logs.
Returns:
true se a inicializacao do objeto foi completada com sucesso ou false em caso contrario.

Definition at line 6052 of file ServerInterface.cpp.

06056 {
06057     int status;
06058 
06059     // Verifica se a classe ja foi inicializada.
06060     if( m_Started )
06061     {
06062         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_STARTED;
06063 
06064         #ifdef RIO_DEBUG2
06065         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06066                       "The module is already started" );
06067         #endif
06068         
06069         return false;
06070  
06071     }
06072 
06073     // Copia o nome do servidor passado como parametro.
06074     try
06075     {
06076         m_ServerName = new char[ strlen( ServerName ) + 1 ];
06077     }
06078     catch( bad_alloc &ba )
06079     {
06080         m_SystemStatus = ENOMEM;
06081 
06082         #ifdef RIO_DEBUG2
06083         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06084                       "Insufficient memory (bad_alloc, error=%s) to create "
06085                       "m_ServerName!", ba.what() );
06086         #endif
06087             
06088         return false;
06089     }
06090     strcpy( m_ServerName, ServerName );
06091     
06092     // Cria o objeto para a classe RioExplorer
06093     try
06094     {
06095         m_RioExplorer = new CModuleRioExplorer( m_Server );
06096     }
06097     catch( bad_alloc &ba )
06098     {
06099         // Delera o nome do servidor.
06100         delete[] m_ServerName;
06101         m_ServerName = NULL;
06102 
06103         // Inicializa o erro com o erro de memoria.
06104         m_SystemStatus = ENOMEM;
06105 
06106         #ifdef RIO_DEBUG2
06107         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06108                       "Insufficient memory (bad_alloc, error=%s) to create "
06109                       "m_RioExplorer!", ba.what() );
06110         #endif
06111 
06112         return false;
06113     }
06114 
06115     // Salva o valor da porta usada pelos logs.
06116     m_ExecLogPort = ExecLogPort;
06117 
06118     // Inicializa a variavel que informa que a thread nao deve ser cancelada.
06119     m_ThreadCanceled = false;
06120     
06121     // Cria a thread que copia os blocos do RIO, um a um, apos o arquivo ser
06122     // aberto (devemos criar a thread com os mesmos atributos do RIO?)
06123     status = pthread_create( &m_ReadRioThread, NULL, ReadRioThreadFunctionEp,
06124                              ( void * ) this ); 
06125     if( status < 0 )
06126     {
06127         // Delera o nome do servidor.
06128         delete[] m_ServerName;
06129         m_ServerName = NULL;
06130 
06131         // Deleta o objeto da classe RioExplorer.
06132         delete m_RioExplorer;
06133 
06134         // Inicializa o erro com o erro de memoria.
06135         m_SystemStatus = status;
06136         
06137         #ifdef RIO_DEBUG2
06138         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06139                       "Error creating copy thread: %u (%s)", m_SystemStatus,
06140                       strerror( m_SystemStatus ) );
06141         #endif
06142 
06143         return false;
06144         
06145     }
06146 
06147     // Cria a thread que copia os blocos do cliente, um a um, apos o arquivo ser
06148     // aberto (devemos criar a thread com os mesmos atributos do RIO?)
06149     status = pthread_create( &m_ReadApacheThread, NULL,
06150                              ReadApacheThreadFunctionEp, ( void * ) this );
06151     if( status < 0 )
06152     {
06153         if( m_ReadRioThread != 0 )
06154         {
06155             // Informa a thread de copia dos blocos que ela deve terminar a sua
06156             // execucao.
06157             m_ThreadCanceled = true;
06158 
06159             // Envia um sinal para a thread desbloquerar, caso ela esteja
06160             // bloqueada.
06161             status = pthread_cond_signal( &m_ReadRioStarted );
06162             if( status < 0 )
06163             {
06164                 m_SystemStatus = status;
06165 
06166                 #ifdef RIO_DEBUG2
06167                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06168                               "Error signalling m_ReadRioStarted: %u (%s)",
06169                               m_SystemStatus, strerror( m_SystemStatus )  );
06170                 #endif
06171 
06172                 return false;
06173             }
06174 
06175             // Espera que a thread termine a sua execucao.
06176             status = pthread_join( m_ReadRioThread, NULL );
06177 
06178             if( status < 0 )
06179             {
06180                 m_SystemStatus = status;
06181 
06182                 #ifdef RIO_DEBUG2
06183                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06184                            "Error when joining ReadRioThread: %u (%s)",
06185                            m_SystemStatus, strerror( m_SystemStatus ) );
06186                 #endif
06187 
06188                 return false;
06189             }
06190         }
06191 
06192         // Delera o nome do servidor.
06193         delete[] m_ServerName;
06194         m_ServerName = NULL;
06195 
06196         // Deleta o objeto da classe RioExplorer.
06197         delete m_RioExplorer;
06198 
06199         // Inicializa o erro com o erro de memoria.
06200         m_SystemStatus = status;
06201 
06202         #ifdef RIO_DEBUG2
06203         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06204                       "Error creating copy thread: %u (%s)", m_SystemStatus,
06205                       strerror( m_SystemStatus ) );
06206         #endif
06207 
06208         return false;
06209 
06210     }
06211 
06212     // Inicializa o valor default da sessao
06213     m_DefaultSessionId = DefaultSessionId;
06214 
06215     // Inicializa o tamanho do fragmento.
06216     m_FragmentSize = FragmentSize;
06217 
06218     // Define o tamanho do buffer circular.
06219     m_CircularBufferSize = CircularBufferSize;
06220 
06221     // Altera o valor de m_Initialized para indicar que a classe foi
06222     // inicializada com sucesso.    
06223     m_Started = true;
06224 
06225     return true;
06226 }

void CServerInterface::StartXML ( request_rec *  Request,
unsigned int  CommandId 
) [static, private]

Funcao para gerar o inicio do xml, usando uma TAG composta por rioexec mais, se existir, o nome do comando.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
CommandId Identificador do comando executado. Se o comando for CMD_INV_ID (na verdade, qualquer valor maior ou igual a este), a TAG sera rioexec. Porem, caso o valor seja menor do que CMD_INV_ID, a TAG sera rioexec_<commando>, onde commando sera obtido da posicao CommandId da tabela CommandTable dada em ServerInterface.cpp.

Definition at line 2338 of file ServerInterface.cpp.

02339 {
02340     // Guarda o ponteiro para o comando (NULL se nao for usado).
02341     const char *Command;
02342 
02343     // Inicializa o nome do comando.
02344     if( CommandId < CMD_INV_ID )
02345         Command = CommandTable[ CommandId ].Command;
02346     else
02347         Command = NULL;
02348 
02349     ap_set_content_type( Request, RIOMODULE_MIME_XML );
02350     if( Command != NULL )
02351     {
02352         // Armazena a linha do cabecalho (o tamanho e fixo para evitar erros de
02353         // memoria).
02354         char HeaderLine[ MaxPathSize ];
02355 
02356         // Compoe o nome do arquivo de "dica".
02357         sprintf( HeaderLine, "inline; filename=rioexec_%s.xml", Command );
02358 
02359         // Coloca o nome do arquivo no cabecalho de saida.
02360         apr_table_set( Request->headers_out, RIOMODULE_HTTP_FILENAME,
02361                        HeaderLine );
02362         ap_rprintf( Request, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
02363         ap_rprintf( Request, "<rioexec_%s>\n", Command );
02364     }
02365     else
02366     {
02367         // Coloca o nome rioexec.xml no cabecalho de saida.
02368         apr_table_set( Request->headers_out, RIOMODULE_HTTP_FILENAME,
02369                        "inline; filename=rioexec.xml" );
02370         ap_rprintf( Request, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
02371         ap_rprintf( Request, "<rioexec>\n" );
02372     }
02373 
02374 }

bool CServerInterface::Stop (  ) 

Definition at line 6229 of file ServerInterface.cpp.

06230 {
06231     int status;
06232     
06233     // Verifica se a classe foi inicializada.
06234     if( !m_Started )
06235     {
06236         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_NOT_STARTED;
06237 
06238         #ifdef RIO_DEBUG2
06239         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06240                       "The object has not started" );
06241         #endif
06242         
06243         return false;
06244  
06245     }
06246 
06247     // Cancela a thread que le os blocos do RIO.
06248     if( m_ReadRioThread != 0 )
06249     {
06250         // Informa a thread de copia dos blocos que ela deve terminar a sua 
06251         // execucao.
06252         m_ThreadCanceled = true;
06253 
06254         // Envia um sinal para a thread desbloquerar, caso ela esteja bloqueada.
06255         status = pthread_cond_signal( &m_ReadRioStarted );
06256         if( status < 0 )
06257         {
06258             m_SystemStatus = status;
06259         
06260             #ifdef RIO_DEBUG2
06261             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06262                           "Error signalling m_ReadRioStarted: %u (%s)",
06263                           m_SystemStatus, strerror( m_SystemStatus )  );
06264             #endif               
06265         
06266             return false;
06267         }
06268 
06269         // Espera que a thread termine a sua execucao.
06270         status = pthread_join( m_ReadRioThread, NULL );
06271 
06272         if( status < 0 )
06273         {
06274             m_SystemStatus = status;
06275             
06276             #ifdef RIO_DEBUG2
06277             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06278                        "Error when joining ReadRioThread: %u (%s)",
06279                        m_SystemStatus, strerror( m_SystemStatus ) );
06280             #endif
06281 
06282             return false;
06283         }
06284     }
06285 
06286     // Cancela a thread que le os blocos do cliente.
06287     if( m_ReadApacheThread != 0 )
06288     {
06289         // Informa a thread de copia dos blocos que ela deve terminar a sua
06290         // execucao.
06291         m_ThreadCanceled = true;
06292 
06293         // Envia um sinal para a thread desbloquerar, caso ela esteja bloqueada.
06294         status = pthread_cond_signal( &m_ReadApacheStarted );
06295         if( status < 0 )
06296         {
06297             m_SystemStatus = status;
06298 
06299             #ifdef RIO_DEBUG2
06300             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06301                           "Error signalling m_ReadApacheStarted: %u (%s)",
06302                           m_SystemStatus, strerror( m_SystemStatus )  );
06303             #endif
06304 
06305             return false;
06306         }
06307 
06308         // Espera que a thread termine a sua execucao.
06309         status = pthread_join( m_ReadApacheThread, NULL );
06310 
06311         if( status < 0 )
06312         {
06313             m_SystemStatus = status;
06314 
06315             #ifdef RIO_DEBUG2
06316             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06317                        "Error when joining ReadApacheThread: %u (%s)",
06318                        m_SystemStatus, strerror( m_SystemStatus ) );
06319             #endif
06320         
06321             return false;
06322         }
06323     }
06324 
06325     // Fecha a sessao, se existir uma sessao pendente, se existir uma sessao
06326     // ativa.
06327     if( m_Session != NULL )
06328     {
06329         status = Disconnect();
06330         if( !status )
06331         {
06332             #ifdef RIO_DEBUG2
06333             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
06334                           "Error when disconnecting from server" );
06335             #endif
06336 
06337             return false;
06338         }
06339     }
06340 
06341     // Remove o nome do servidor.
06342     if( m_ServerName != NULL )
06343         delete m_ServerName;
06344 
06345     // Deleta o objeto da classe RioExplorer.
06346     if( m_RioExplorer != NULL )
06347         delete m_RioExplorer;
06348     m_RioExplorer = NULL;
06349 
06350     m_Started = false;
06351 
06352     return true;
06353 }

bool CServerInterface::TerminateCopyToClient ( request_rec *  Request  )  [private]

Funcao para terminar o envio de dados ao client.

Parameters:
Request ponteiro para a requisicao associada a copia (de/para o servidor) de um arquivo.
Returns:
true se a copia foi terminada com sucesso, ou false em caso contrario (neste caso, m_ApacheStatus indicara o erro que ocorreu).

Definition at line 716 of file ServerInterface.cpp.

00717 {
00718     apr_bucket_brigade *bb;
00719     apr_bucket *b;
00720     apr_status_t rv;
00721 
00722     // Cria a estrutura de dados para cancelar o envio do arquivo ao cliente.
00723 
00724     bb = apr_brigade_create( Request->pool,
00725                              Request->connection->bucket_alloc );
00726     if( bb == NULL ) 
00727     {
00728         #ifdef RIO_DEBUG2
00729         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00730                       "unable to create brigade" );
00731         #endif
00732                        
00733         m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00734         return false;  
00735     }
00736 
00737     // Cria um bucket para indicar o final do arquivo.
00738     b = apr_bucket_eos_create( Request->connection->bucket_alloc );
00739     if( b == NULL ) 
00740     {
00741         #ifdef RIO_DEBUG2
00742         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
00743                       "unable to create EOS bucket" );
00744         #endif
00745 
00746         m_ApacheStatus = HTTP_INTERNAL_SERVER_ERROR;
00747         return false;  
00748     }
00749 
00750     // Insere o bucket no final da brigade.
00751     APR_BRIGADE_INSERT_TAIL( bb, b );
00752    
00753     // Passa o bloco ja escrito para os outros filtros
00754     rv = ap_pass_brigade( Request->output_filters, bb );
00755     if( rv != APR_SUCCESS )
00756     {
00757         #ifdef RIO_DEBUG2
00758         ap_log_error( APLOG_MARK, APLOG_ERR, rv, m_Server,
00759                       "unable to pass brigade to filters" );
00760         #endif
00761 
00762         m_ApacheStatus = rv;
00763         return false;  
00764     }
00765     
00766     rv = ap_fflush( Request->output_filters, bb );
00767     if( rv != APR_SUCCESS )
00768     {
00769         #ifdef RIO_DEBUG2
00770         ap_log_error( APLOG_MARK, APLOG_ERR, rv, m_Server,
00771                       "unable to execute fflush" );
00772         #endif
00773 
00774         m_ApacheStatus = rv;
00775         return false;  
00776     }
00777     else
00778         return true;
00779 }

bool CServerInterface::UploadFile ( request_rec *  Request,
const char *  FileName,
char *  FileMd5sum 
) [private]

Funcao para criar um arquivo no servidor RIO com os seus bytes enviados pelo cliente.

Parameters:
Request ponteiro para a requisicao associada a conexao http com o cliente.
FileName ponteiro para o nome do arquivo a ser aberto.
FileMd5sum ponteiro para o valor MD5 do arquivo a ser criado e copiado para o servidor
Returns:
true se a copia foi cancelada com sucesso ou false se algum erro ocorreu ao copiar o arquivo do cliente.

Definition at line 4420 of file ServerInterface.cpp.

04422 {
04423     RioResult hResult;
04424     int status;
04425     RioObjectSize LastFileSize, FileSize;
04426     const char *FileSizeHeader;
04427     RioObjectSize DataSize;
04428     bool IsApacheEof;
04429     unsigned int TotalElements;
04430     unsigned int TotalBlocks;
04431     unsigned int LastApacheBlockSize;
04432     RioBlock Block;
04433 
04434     // Obtem o mutex para acessar exclusivamente as variaveis do buffer.
04435     status = pthread_mutex_lock( &m_Mutex );
04436     if( status < 0 )
04437     {
04438         m_SystemStatus = status;
04439 
04440         #ifdef RIO_DEBUG2
04441         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04442                       "Error locking m_Mutex: %u (%s)",
04443                       m_SystemStatus, strerror( m_SystemStatus )  );
04444 
04445         #endif
04446 
04447         return false;
04448     }
04449 
04450     // Verifica se uma copia esta em progresso.
04451     if( m_isReadingApacheFile )
04452     {
04453         #ifdef RIO_DEBUG2
04454         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04455                       "A copy is already in progress" );
04456         #endif
04457 
04458         // Define o erro do RIO.
04459         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COPYING_OBJECT;
04460 
04461         // Libera o mutex para acessar exclusivamente as variaveis do buffer.
04462         status = pthread_mutex_unlock( &m_Mutex );
04463         if( status < 0 )
04464         {
04465             m_SystemStatus = status;
04466 
04467             #ifdef RIO_DEBUG2
04468             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04469                           "Error unlocking m_Mutex: %u (%s)",
04470                           m_SystemStatus, strerror( m_SystemStatus )  );
04471             #endif
04472         }
04473 
04474         return false;
04475     }
04476 
04477     // Libera o mutex para acessar exclusivamente as variaveis do buffer.
04478     status = pthread_mutex_unlock( &m_Mutex );
04479     if( status < 0 )
04480     {
04481         m_SystemStatus = status;
04482 
04483         #ifdef RIO_DEBUG2
04484         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04485                       "Error unlocking m_Mutex: %u (%s)",
04486                       m_SystemStatus, strerror( m_SystemStatus )  );
04487         #endif
04488 
04489         return false;
04490     }
04491 
04492     // Abre um stream para escrevermos dados
04493     if( !OpenRioStream( RioStreamDirectionWrite ) )
04494     {
04495         #ifdef RIO_DEBUG2
04496         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04497                       "Error creating RIO Stream: %u (%s)", m_RioStatus,
04498                       GetErrorDescription( m_RioStatus ).c_str() );
04499         #endif
04500 
04501         return false;
04502     }
04503 
04504     // Tenta abrir o arquivo que desejamos criar e salvar.
04505     if( !OpenRioObject( FileName, RIO_WRITE_MASK ) )
04506     {
04507         #ifdef RIO_DEBUG2
04508         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04509                       "Error opening RioObject: %u (%s)", m_RioStatus,
04510                       GetErrorDescription( m_RioStatus ).c_str() );
04511         #endif
04512 
04513         if( !CloseRioStream() )
04514         {
04515             #ifdef RIO_DEBUG2
04516             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04517                           "Error closing RioStream: %u (%s)", m_RioStatus,
04518                           GetErrorDescription( m_RioStatus ).c_str() );
04519             #endif
04520         }
04521 
04522         return false;
04523     }
04524 
04525     // Obtem o tamanho do arquivo do cabecalho.
04526     FileSizeHeader = apr_table_get( Request->headers_in, "Content-Length" );
04527     if( FileSizeHeader == NULL )
04528     {
04529         #ifdef RIO_DEBUG2
04530         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04531                       "Content-Length header not defined! " );
04532         #endif
04533 
04534         if( !Close( Request ) )
04535         {
04536             #ifdef RIO_DEBUG2
04537             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04538                           "Error when executing Close" );
04539             #endif
04540         }
04541 
04542         return false;
04543     }
04544     FileSize = atoll( FileSizeHeader );
04545 
04546     #ifdef RIO_DEBUG2
04547     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04548                   "FileSize obteined from Content-Length header is %llu bytes!",
04549                   FileSize );
04550     #endif
04551 
04552     // Zera o tamanho do arquivo (isso e necessario?).
04553     hResult = m_Object->SetSize( 0, FileMd5sum );
04554 
04555     if( FAILED( hResult ) )
04556     {
04557         m_RioStatus = hResult;
04558 
04559         #ifdef RIO_DEBUG2
04560         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04561                       "Error setting object size to 0: %u (%s)", m_RioStatus,
04562                       GetErrorDescription( m_RioStatus ).c_str() );
04563         #endif
04564 
04565         if( !Close( Request ) )
04566         {
04567             #ifdef RIO_DEBUG2
04568             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04569                           "Error when executing Close" );
04570             #endif
04571         }
04572 
04573         return false;
04574     }
04575 
04576     // Obtem o mutex para acessar exclusivamente as variaveis do buffer.
04577     status = pthread_mutex_lock( &m_Mutex );
04578     if( status < 0 )
04579     {
04580         m_SystemStatus = status;
04581 
04582         #ifdef RIO_DEBUG2
04583         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04584                       "Error locking m_Mutex: %u (%s)",
04585                       m_SystemStatus, strerror( m_SystemStatus )  );
04586         #endif
04587 
04588         if( !Close( Request ) )
04589         {
04590             #ifdef RIO_DEBUG2
04591             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04592                           "Error when executing Close" );
04593             #endif
04594         }
04595 
04596         return false;
04597     }
04598 
04599     // Informa que comecamos a copia do arquivo.
04600     m_isReadingApacheFile = true;
04601 
04602     // Inicializa as variaveis associadas a copia.
04603     m_IsApacheEof = false;
04604     m_UploadRequest = Request;
04605     m_LastApacheBlockSize = 0;
04606     TotalBlocks = ( FileSize + m_BlockSize - 1 ) / m_BlockSize;
04607 
04608     // Inicializa o buffer circular (caso ja tenha sido inicializado).
04609     if( !m_CircularBuffer->ReinitializeBuffer() )
04610     {
04611         m_SystemStatus = m_CircularBuffer->GetError();
04612 
04613         #ifdef RIO_DEBUG2
04614         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04615                      "Error reinitializing circular buffer: %u (%s)",
04616                       m_SystemStatus, strerror( m_SystemStatus ) );
04617         #endif
04618 
04619         // Cancela a copia atual.
04620         if( !Close( Request ) )
04621         {
04622             #ifdef RIO_DEBUG2
04623             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04624                           "Error when executing Close" );
04625             #endif
04626         }
04627 
04628         return false;
04629     }
04630 
04631     // Envia um sinal para desbloquear a thread, pois iniciamos uma copia de
04632     // dados.
04633     status = pthread_cond_signal( &m_ReadApacheStarted );
04634     if( status < 0 )
04635     {
04636         m_SystemStatus = status;
04637 
04638         #ifdef RIO_DEBUG2
04639         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04640                       "Error signalling m_ReadApacheStarted: %u (%s)",
04641                       m_SystemStatus, strerror( m_SystemStatus )  );
04642         #endif
04643 
04644         return false;
04645     }
04646 
04647     // Libera o mutex para acessar exclusivamente as variaveis do buffer.
04648     status = pthread_mutex_unlock( &m_Mutex );
04649     if( status < 0 )
04650     {
04651         m_SystemStatus = status;
04652 
04653         #ifdef RIO_DEBUG2
04654         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04655                       "Error unlocking m_Mutex: %u (%s)",
04656                       m_SystemStatus, strerror( m_SystemStatus )  );
04657         #endif
04658 
04659         if( !Close( Request ) )
04660         {
04661             #ifdef RIO_DEBUG2
04662             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04663                           "Error when executing Close" );
04664             #endif
04665         }
04666 
04667         return false;
04668     }
04669 
04670     // Inicialmente supomos que temos pelo menos um bloco para ser copiado.
04671     Block = 0;
04672     LastFileSize = 0;
04673 
04674     #ifdef RIO_DEBUG2
04675     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04676                   "Tentando receber o arquivo %s com %llu bytes e %u blocos!",
04677                   FileName, FileSize, TotalBlocks );
04678     #endif
04679 
04680     // Copia ate que todos os blocos sejam enviados ou ate que um erro ocorra.
04681     while( Block < TotalBlocks )
04682     {
04683         #ifdef RIO_DEBUG2
04684         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04685                       "Tentando receber o bloco %u de %u do arquivo %s!",
04686                       Block, TotalBlocks, FileName );
04687         #endif
04688 
04689         // Tenta verificar se existe elementos no buffer. O valor de
04690         // HasNextBlock informara se existem novos blocos que ainda precisam
04691         // ser removidos do buffer.
04692         if( !m_CircularBuffer->TotalElements( &TotalElements ) )
04693         {
04694             m_SystemStatus = m_CircularBuffer->GetError();
04695 
04696             #ifdef RIO_DEBUG2
04697             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04698                          "Error cheking for elementos in circular buffer: "
04699                          "%u (%s)", m_SystemStatus,
04700                          strerror( m_SystemStatus ) );
04701             #endif
04702 
04703             // Cancela a copia atual.
04704             if( !Close( Request ) )
04705             {
04706                 #ifdef RIO_DEBUG2
04707                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04708                               "Error when executing Close" );
04709                 #endif
04710             }
04711 
04712             return false;
04713         }
04714 
04715         // Tenta obter um bloco do buffer circular.
04716         if( !m_CircularBuffer->GetElement( m_RioBuffer ) )
04717         {
04718             m_SystemStatus = m_CircularBuffer->GetError();
04719 
04720             #ifdef RIO_DEBUG2
04721             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04722                           "Error reading block %u from circular buffer: "
04723                           "%u (%s)", Block, m_SystemStatus,
04724                           strerror( m_SystemStatus ) );
04725             #endif
04726 
04727             // Cancela a copia atual.
04728             if( !Close( Request ) )
04729             {
04730                  #ifdef RIO_DEBUG2
04731                  ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04732                                "Error when executing Close" );
04733                  #endif
04734             }
04735 
04736             return false;
04737         }
04738 
04739         // O acesso e para enviar um arquivo do servidor para o cliente. Obtem
04740         // o mutex para acessar exclusivamente as variaveis do buffer.
04741         status = pthread_mutex_lock( &m_Mutex );
04742         if( status < 0 )
04743         {
04744             m_SystemStatus = status;
04745 
04746             #ifdef RIO_DEBUG2
04747             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04748                           "Error locking m_Mutex: %u (%s)",
04749                           m_SystemStatus, strerror( m_SystemStatus )  );
04750             #endif
04751 
04752             // Cancela a copia atual.
04753             if( !Close( Request ) )
04754             {
04755                 #ifdef RIO_DEBUG2
04756                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04757                               "Error when executing Close" );
04758                 #endif
04759             }
04760 
04761             return false;
04762         }
04763 
04764         #ifdef RIO_DEBUG2
04765         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04766                       "Trying to copy block %u", Block );
04767         #endif
04768 
04769         // Salva uma copia da variavel booleana que indica se a thread ja acabou
04770         // de receber blocos do apache.
04771         IsApacheEof = m_IsApacheEof;
04772         LastApacheBlockSize = m_LastApacheBlockSize;
04773 
04774         // Libera o mutex para acessar exclusivamente as variaveis do buffer.
04775         status = pthread_mutex_unlock( &m_Mutex );
04776         if( status < 0 )
04777         {
04778             m_SystemStatus = status;
04779 
04780             #ifdef RIO_DEBUG2
04781             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04782                           "Error unlocking m_Mutex: %u (%s)",
04783                            m_SystemStatus, strerror( m_SystemStatus )  );
04784             #endif
04785 
04786             // Cancela a copia atual.
04787             if( !Close( Request ) )
04788             {
04789                 #ifdef RIO_DEBUG2
04790                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04791                               "Error when executing Close" );
04792                 #endif
04793             }
04794 
04795             return false;
04796         }
04797 
04798         // Descobre o tamanho correto do bloco a ser salvo (se nao for o
04799         // ultimo, o tamanho e dado em m_BlockSize e, se for o ultimo, o
04800         // tamanho e dado em m_LastApacheBlockSize.
04801         if( Block < ( TotalBlocks - 1 ) )
04802         {
04803             // Ainda existem mais blocos. Devemos verificar se o tamanho do
04804             // bloco recebido e igual ao do apache, se este for o ultimo bloco
04805             // lido.
04806             DataSize = m_BlockSize;
04807 
04808             // Verifica se o tamanho recebido e coerente.
04809             if( ( TotalElements == 1 ) && ( IsApacheEof ) &&
04810                 ( DataSize != LastApacheBlockSize) )
04811             {
04812                 #ifdef RIO_DEBUG2
04813                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04814                               "Unexpected end of data found in saving block "
04815                               "%u! Received %u bytes but expected %llu bytes!",
04816                               Block, LastApacheBlockSize, DataSize );
04817                 #endif
04818 
04819                 // Cancela a copia atual.
04820                 if( !Close( Request ) )
04821                 {
04822                     #ifdef RIO_DEBUG2
04823                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04824                                   "Error when executing Close" );
04825                     #endif
04826                 }
04827 
04828                 // Define o erro do RIO.
04829                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COPYING_OBJECT;
04830 
04831                 return false;
04832             }
04833         }
04834         else
04835         {
04836             // Este deveria ser o ultimo bloco, mas isso pode estar errado, se
04837             // menos dados forem recebidos.
04838             DataSize = FileSize - ( ( TotalBlocks - 1 ) * m_BlockSize );
04839 
04840             // Devemos verificar se o tamanho do ultimo bloco esta correto. Se
04841             // estiver incorreto, menos dados foram recebidos e devemos gerar
04842             // um erro.
04843             if( LastApacheBlockSize < DataSize )
04844             {
04845                 #ifdef RIO_DEBUG2
04846                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04847                               "Unexpected end of data found in saving block "
04848                               "%u! Expected %llu bytes but received %u "
04849                               "bytes!", Block, DataSize,
04850                               LastApacheBlockSize );
04851                 #endif
04852 
04853                 // Cancela a copia atual.
04854                 if( !Close( Request ) )
04855                 {
04856                     #ifdef RIO_DEBUG2
04857                     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04858                                   "Error when executing Close" );
04859                     #endif
04860                 }
04861 
04862                 // Define o erro do RIO.
04863                 m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COPYING_OBJECT;
04864 
04865                 return false;
04866             }
04867         }
04868 
04869         #ifdef RIO_DEBUG2
04870         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04871                       "Trying to save block %u with md5 %s and size %llu "
04872                       "of %u bytes!", Block, FileMd5sum, DataSize,
04873                       m_BlockSize );
04874         #endif
04875 
04876         // Tenta salvar o bloco no servidor.
04877         if( !WriteRioObjectBlock( Block, FileMd5sum, DataSize,
04878             &LastFileSize) )
04879         {
04880             #ifdef RIO_DEBUG2
04881             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04882                           "Error when executing WriteRioObjectBlock!" );
04883             #endif
04884 
04885             // Cancela a copia atual.
04886             if( !Close( Request ) )
04887             {
04888                 #ifdef RIO_DEBUG2
04889                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04890                               "Error when executing Close" );
04891                #endif
04892             }
04893 
04894             return false;
04895         }
04896 
04897         // Verifica se mais dados foram recebidos apos o ultimo bloco.
04898         if( ( Block == ( TotalBlocks - 1 ) ) && ( ( TotalElements > 1 ) ||
04899             ( LastApacheBlockSize > DataSize ) ) )
04900         {
04901             #ifdef RIO_DEBUG2
04902             unsigned int TotalData;
04903 
04904             // Calcula a quantidade de dados recebidos.
04905             if( DataSize == m_BlockSize )
04906                 TotalData = TotalElements * m_BlockSize;
04907             else
04908                 TotalData = ( TotalElements - 1 ) * m_BlockSize +
04909                             LastApacheBlockSize;
04910 
04911             // Imprime a mensagem
04912             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04913                           "There exists more data after block %u! Size %llu is "
04914                           "incorrect?", Block, FileSize );
04915             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04916                           "Received %u bytes but expected only %llu bytes!",
04917                           TotalData, DataSize );
04918             #endif
04919 
04920             // Cancela a copia atual.
04921             if( !Close( Request ) )
04922             {
04923                 #ifdef RIO_DEBUG2
04924                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04925                               "Error when executing Close" );
04926                 #endif
04927             }
04928 
04929             // Define o erro do RIO.
04930             m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COPYING_OBJECT;
04931 
04932             return false;
04933         }
04934         // Atualiza o numero do bloco.
04935         Block++;
04936     }
04937 
04938     // Finaliza a copia do arquivo e fecha tudo (o arquivo e o stream).
04939     if( !Close( Request ) )
04940     {
04941         #ifdef RIO_DEBUG2
04942         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04943                       "Error when executing Close" );
04944         #endif
04945 
04946         return false;
04947     }
04948 
04949     // Verifica se a copia foi feita com sucesso (ou seja, se LastFileSize, que
04950     // tem o numero total de bytes, e igual a FileSize).
04951     if( LastFileSize != FileSize )
04952     {
04953         // O tamanho esta incorreto. Devemos retornar um erro.
04954         #ifdef RIO_DEBUG2
04955         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04956                       "O arquivo %s foi recebido incorretamente! Recebidos "
04957                       "%llu bytes quando esperavamos %llu bytes!", FileName,
04958                       LastFileSize, FileSize );
04959         #endif
04960         // Define o erro do RIO.
04961         m_RioStatus = ERROR_SERVERINTERFACE + ERROR_COPYING_OBJECT;
04962 
04963         return false;
04964     }
04965     else
04966     {
04967         // O tamanho esta correto. Entao a copia foi feita corretamente.
04968         #ifdef RIO_DEBUG2
04969         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
04970                       "O arquivo %s com tamanho %llu foi recebido "
04971                       "corretamente!", FileName, FileSize );
04972         #endif
04973 
04974         return true;
04975     }
04976 }

void CServerInterface::WriteCallBack ( RioRequest Request  )  [static, private]

Funcao de callback executada apos a escrita (com sucesso ou nao) do bloco.

Parameters:
Request ponteiro para o pedido do bloco.

Definition at line 1301 of file ServerInterface.cpp.

01302 {
01303     CServerInterface *Module = ( CServerInterface* ) Request->User;
01304 
01305     #ifdef RIO_DEBUG2
01306     ap_log_error( APLOG_MARK, APLOG_ERR, 0, Module->GetServer(),
01307                   "Block %u copied to server. Sending signal!",
01308                   Request->Block );
01309     #endif
01310 
01311     // Envia um sinal, para avisar que o bloco ja chegou.
01312     if( !Module->SendSignal() )
01313         ap_log_error( APLOG_MARK, APLOG_ERR, 0, Module->GetServer(),
01314                       "Error when executing SendSignal" );
01315 }

bool CServerInterface::WriteRioObjectBlock ( RioBlock  Block,
char *  Md5Sum,
RioObjectSize  UsedBlockSize,
RioObjectSize ActualFileSize 
) [private]

Definition at line 1486 of file ServerInterface.cpp.

01489 {
01490 
01491     RioResult hResult;
01492     RioRequest Request;
01493     int status;
01494 
01495     bool CopyBlock;
01496 
01497     #ifdef RIO_DEBUG2
01498     ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01499                   "Trying writing block %u", Block );
01500     #endif
01501 
01502     // Numero de tentativas de escrever um bloco (devemos considerar isso?)
01503     unsigned int numberofretrys = 0;
01504 
01505     // Verifica se o objeto e valido e esta aberto.
01506     if( ( m_Object == NULL ) || ( !m_isObjectOpen ) )
01507     {
01508         if( m_Object == NULL )
01509             m_RioStatus = ERROR_RIOOBJECT + ERROR_NOT_INITIALIZED;
01510         else
01511             m_RioStatus = ERROR_RIOOBJECT + ERROR_OBJECT_NOT_OPENED;
01512 
01513         #ifdef RIO_DEBUG2
01514         ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01515                       "Object not opened: %u (%s)", m_RioStatus,
01516                       GetErrorDescription( m_RioStatus ).c_str() );
01517         #endif
01518 
01519         return false;
01520     }
01521 
01522     // Inicializa a estrutura com o pedido do bloco.
01523     Request.Size = m_BlockSize;
01524     Request.Buffer = m_RioBuffer;
01525     Request.CallBackFunction = WriteCallBack;
01526     Request.User = (void *) this;
01527     Request.Block = Block;
01528     Request.Result = S_OK;
01529     Request.Status = RIO_REQUEST_FREE;
01530 
01531     // Tenta aumentar o tamanho do arquivo que esta sendo salvo em UsedBlockSize
01532     // bytes.
01533     hResult = m_Object->SetSize( *ActualFileSize + UsedBlockSize, Md5Sum );
01534     if( FAILED( hResult ) )
01535     {
01536         if( ( hResult & 0xff )  == (signed) ERROR_DISKFULL )
01537             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01538                           "Nao conseguiu alocar blocos para objeto: Disco(s) "
01539                           "cheio(s)." );
01540         else
01541             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01542                           "Nao conseguiu alocar blocos para objeto: erro = %u "
01543                           "(%8X - %s).", ( unsigned int ) ( hResult & 0xff ),
01544                           hResult, GetErrorDescription( hResult ).c_str() );
01545         return false;
01546     }
01547 
01548     // Adiciona o novo tamanho ao tamanho do arquivo.
01549     *ActualFileSize = *ActualFileSize + UsedBlockSize;
01550 
01551     // Tenta salvar um bloco no servidor
01552     CopyBlock = true;
01553     while( CopyBlock )
01554     {
01555         // Espera pelo envio de cada copia do bloco.
01556 
01557         status = pthread_mutex_lock( &m_ReadWriteMutex );
01558         if( status != 0 )
01559         {
01560             m_SystemStatus = status;
01561 
01562             #ifdef RIO_DEBUG2
01563             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01564                           "Error writing block %u (1.1): %u (%s)",
01565                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01566             #endif
01567 
01568             return false;
01569         }
01570 
01571         // Tenta salvar um bloco no servidor.
01572         hResult = m_Object->StreamWrite( &Request );
01573 
01574         if( FAILED( hResult ) )
01575         {
01576             m_RioStatus = hResult;
01577 
01578             #ifdef RIO_DEBUG2
01579             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01580                           "Error writing block %u (1.2): %u (%s)",
01581                           Block, m_RioStatus,
01582                           GetErrorDescription( m_RioStatus ).c_str() );
01583             #endif
01584 
01585             return false;
01586         }
01587 
01588         status = pthread_cond_wait( &m_ReadWriteCond, &m_ReadWriteMutex );
01589         if( status != 0 )
01590         {
01591             m_SystemStatus = status;
01592 
01593             #ifdef RIO_DEBUG2
01594             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01595                           "Error writing block %u (1.3): %u (%s)",
01596                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01597             #endif
01598             status = pthread_mutex_unlock( &m_ReadWriteMutex );
01599             if( status != 0 )
01600             {
01601                 m_SystemStatus = status;
01602 
01603                 #ifdef RIO_DEBUG2
01604                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01605                               "Error unlocking mutex: %u (%s)", status,
01606                               strerror( status ) );
01607                 #endif
01608             }
01609 
01610             return false;
01611         }
01612 
01613         status = pthread_mutex_unlock( &m_ReadWriteMutex );
01614         if( status != 0 )
01615         {
01616             m_SystemStatus = status;
01617 
01618             #ifdef RIO_DEBUG2
01619             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01620                           "Error reading block %u (1.4): %u (%s)",
01621                           Block, m_SystemStatus, strerror( m_SystemStatus ) );
01622             #endif
01623 
01624             return false;
01625         }
01626 
01627         // Verifica se a escrita do bloco foi feita com sucesso.
01628         if( Request.Result == S_OK )
01629         {
01630             // Como a requisicao do bloco terminou com sucesso, terminamos a
01631             // escrita do bloco.
01632             CopyBlock = false;
01633         }
01634         else if( ( ( Request.Result & 0xFF ) ==
01635                      ERROR_SERVICE_TEMPORARY_UNAVAILABLE ) ||
01636                  ( ( Request.Result & 0xFF ) ==  ERROR_INVALID_DISK ) )
01637         {
01638             // Obs: O 0xFF acima (com o AND logico) e para somente considerar
01639             // o codigo de erro geral, desconsiderando a parte do erro que
01640             // identifica a clase (AND - & - com 0xFF00) e o codigo 0xE000 do
01641             // RIO (obtido com AND - & - 0xFFFF0000).
01642             // Neste caso, o servidor caiu ao requisitarmos o bloco. Tentaremos
01643             // escrever novamente o bloco se o numero de tentativas nao expirou.
01644             // Aqui, ao contrario da leitura, devemos tambem tratar o erro
01645             // ERROR_INVALID_DISK, pois isso pode somente significar que um
01646             // dos discos se tornou invalido.
01647             numberofretrys++;
01648             if( numberofretrys >= MAXNUMBEROFBLOCKRETRYS )
01649             {
01650                 m_RioStatus = ERROR_RIOOBJECT +
01651                               ERROR_SERVICE_TEMPORARY_UNAVAILABLE;
01652 
01653                 #ifdef RIO_DEBUG2
01654                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01655                               "Error writing block %u (1.5): %u (%s)",
01656                               Block, m_RioStatus,
01657                               GetErrorDescription( m_RioStatus ).c_str() );
01658                 #endif
01659 
01660                 return false;
01661             }
01662             // Realoca os blocos fisicos associados ao bloco logico dado por
01663             // curBlock
01664             hResult = m_Object->ReallocBlocks( Block );
01665             if( FAILED( hResult ) )
01666             {
01667                 m_RioStatus = hResult;
01668 
01669                 #ifdef RIO_DEBUG2
01670                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01671                               "Write failed to realocate fisical blocs of the "
01672                               "logical block %u: %8X (%s)", Block, m_RioStatus,
01673                               GetErrorDescription( m_RioStatus ).c_str() );
01674                 #endif
01675 
01676                 return false;
01677             }
01678             #ifdef RIO_DEBUG2
01679             else
01680                 ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01681                               "CServerInterface::WriteRioObjectBlock blocos "
01682                               "fisicos do bloco logico %u realocados com "
01683                               "sucesso", Block );
01684             #endif
01685         }
01686         else
01687         {
01688             m_RioStatus = Request.Result;
01689 
01690             #ifdef RIO_DEBUG2
01691             ap_log_error( APLOG_MARK, APLOG_ERR, 0, m_Server,
01692                           "Error writing block %u (1.6): %u (%s)",
01693                           Block, m_RioStatus,
01694                           GetErrorDescription( m_RioStatus ).c_str() );
01695             #endif
01696 
01697             return false;
01698         }
01699     }
01700 
01701     return true;
01702 }


Field Documentation

Definition at line 166 of file ServerInterface.h.

apr_status_t CServerInterface::m_ApacheStatus [private]

Definition at line 148 of file ServerInterface.h.

unsigned int CServerInterface::m_BlockSize [private]

Definition at line 175 of file ServerInterface.h.

Definition at line 156 of file ServerInterface.h.

Definition at line 159 of file ServerInterface.h.

unsigned int CServerInterface::m_DefaultSessionId [private]

Definition at line 126 of file ServerInterface.h.

unsigned int CServerInterface::m_ExecLogPort [private]

Definition at line 224 of file ServerInterface.h.

Definition at line 145 of file ServerInterface.h.

unsigned int CServerInterface::m_FragmentSize [private]

Definition at line 177 of file ServerInterface.h.

Definition at line 212 of file ServerInterface.h.

Definition at line 136 of file ServerInterface.h.

Definition at line 216 of file ServerInterface.h.

Definition at line 179 of file ServerInterface.h.

Definition at line 128 of file ServerInterface.h.

Definition at line 132 of file ServerInterface.h.

Definition at line 210 of file ServerInterface.h.

pthread_mutex_t CServerInterface::m_Mutex [private]

Definition at line 202 of file ServerInterface.h.

Definition at line 134 of file ServerInterface.h.

pthread_cond_t CServerInterface::m_ReadApacheStarted [private]

Definition at line 219 of file ServerInterface.h.

Definition at line 222 of file ServerInterface.h.

pthread_cond_t CServerInterface::m_ReadRioStarted [private]

Definition at line 182 of file ServerInterface.h.

pthread_t CServerInterface::m_ReadRioThread [private]

Definition at line 198 of file ServerInterface.h.

pthread_cond_t CServerInterface::m_ReadWriteCond [private]

Definition at line 194 of file ServerInterface.h.

pthread_mutex_t CServerInterface::m_ReadWriteMutex [private]

Definition at line 192 of file ServerInterface.h.

Definition at line 169 of file ServerInterface.h.

Definition at line 163 of file ServerInterface.h.

Definition at line 205 of file ServerInterface.h.

Definition at line 152 of file ServerInterface.h.

Definition at line 171 of file ServerInterface.h.

server_rec* CServerInterface::m_Server [private]

Definition at line 117 of file ServerInterface.h.

Definition at line 140 of file ServerInterface.h.

Definition at line 119 of file ServerInterface.h.

unsigned int CServerInterface::m_SessionId [private]

Definition at line 122 of file ServerInterface.h.

Definition at line 114 of file ServerInterface.h.

Definition at line 130 of file ServerInterface.h.

Definition at line 150 of file ServerInterface.h.

pthread_cond_t CServerInterface::m_ThreadBlocked [private]

Definition at line 186 of file ServerInterface.h.

Definition at line 200 of file ServerInterface.h.

unsigned int CServerInterface::m_TotalBlocks [private]

Definition at line 173 of file ServerInterface.h.

request_rec* CServerInterface::m_UploadRequest [private]

Definition at line 214 of file ServerInterface.h.

Definition at line 207 of file ServerInterface.h.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:33 2012 for RIO by  doxygen 1.6.3