#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 |
CRioSession * | m_Session |
unsigned int | m_SessionId |
unsigned int | m_DefaultSessionId |
bool | m_isSessionOpen |
CRioStream * | m_Stream |
bool | m_isStreamOpen |
CRioObject * | m_Object |
bool | m_isObjectOpen |
char * | m_ServerName |
char * | m_FileName |
apr_status_t | m_ApacheStatus |
int | m_SystemStatus |
RioResult | m_RioStatus |
CircularBuffer * | m_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 |
CModuleRioExplorer * | m_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 |
Definition at line 109 of file ServerInterface.h.
CServerInterface::CServerInterface | ( | server_rec * | Server | ) |
Construtor da classe RioModule, para criar um novo objeto desta classe.
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 }
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.
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).
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.
FileName | ponteiro para o nome do objeto cujo caminho desejamos verificar. |
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.
Request | ponteiro para a requisicao associada a conexao http com o cliente. |
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.
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).
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. |
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.
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). |
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).
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.
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. |
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.
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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.
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. |
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).
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. |
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.
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. |
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.
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. |
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.
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. |
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.
Request | ponteiro para a requisicao associada a conexao http com o cliente. |
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.
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.
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.
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.
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.
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.
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.
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. |
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.
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.
Class | ponteiro para o objeto da classe que criou a thread. |
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.
Class | ponteiro para o objeto da classe que criou a thread. |
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.
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.
Class | ponteiro para o objeto da classe que criou a thread. |
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.
Class | ponteiro para o objeto da classe que criou a thread. |
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.
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. |
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).
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.
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).
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-). |
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.
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. |
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).
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).
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. |
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.
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.
Request | ponteiro para a requisicao associada a copia (de/para o servidor) de um arquivo. |
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.
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 |
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.
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 }
char* CServerInterface::m_ApacheBuffer [private] |
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.
CircularBuffer* CServerInterface::m_CircularBuffer [private] |
Definition at line 156 of file ServerInterface.h.
unsigned int CServerInterface::m_CircularBufferSize [private] |
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.
char* CServerInterface::m_FileName [private] |
Definition at line 145 of file ServerInterface.h.
unsigned int CServerInterface::m_FragmentSize [private] |
Definition at line 177 of file ServerInterface.h.
bool CServerInterface::m_IsApacheEof [private] |
Definition at line 212 of file ServerInterface.h.
bool CServerInterface::m_isObjectOpen [private] |
Definition at line 136 of file ServerInterface.h.
bool CServerInterface::m_isReadingApacheFile [private] |
Definition at line 216 of file ServerInterface.h.
bool CServerInterface::m_isReadingRioFile [private] |
Definition at line 179 of file ServerInterface.h.
bool CServerInterface::m_isSessionOpen [private] |
Definition at line 128 of file ServerInterface.h.
bool CServerInterface::m_isStreamOpen [private] |
Definition at line 132 of file ServerInterface.h.
unsigned int CServerInterface::m_LastApacheBlockSize [private] |
Definition at line 210 of file ServerInterface.h.
pthread_mutex_t CServerInterface::m_Mutex [private] |
Definition at line 202 of file ServerInterface.h.
CRioObject* CServerInterface::m_Object [private] |
Definition at line 134 of file ServerInterface.h.
pthread_cond_t CServerInterface::m_ReadApacheStarted [private] |
Definition at line 219 of file ServerInterface.h.
pthread_t CServerInterface::m_ReadApacheThread [private] |
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.
RioBlock CServerInterface::m_RioBlock [private] |
Definition at line 169 of file ServerInterface.h.
char* CServerInterface::m_RioBuffer [private] |
Definition at line 163 of file ServerInterface.h.
Definition at line 205 of file ServerInterface.h.
RioResult CServerInterface::m_RioStatus [private] |
Definition at line 152 of file ServerInterface.h.
RioBlock CServerInterface::m_SendBlock [private] |
Definition at line 171 of file ServerInterface.h.
server_rec* CServerInterface::m_Server [private] |
Definition at line 117 of file ServerInterface.h.
char* CServerInterface::m_ServerName [private] |
Definition at line 140 of file ServerInterface.h.
CRioSession* CServerInterface::m_Session [private] |
Definition at line 119 of file ServerInterface.h.
unsigned int CServerInterface::m_SessionId [private] |
Definition at line 122 of file ServerInterface.h.
bool CServerInterface::m_Started [private] |
Definition at line 114 of file ServerInterface.h.
CRioStream* CServerInterface::m_Stream [private] |
Definition at line 130 of file ServerInterface.h.
int CServerInterface::m_SystemStatus [private] |
Definition at line 150 of file ServerInterface.h.
pthread_cond_t CServerInterface::m_ThreadBlocked [private] |
Definition at line 186 of file ServerInterface.h.
bool CServerInterface::m_ThreadCanceled [private] |
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.
char* CServerInterface::m_UserName [private] |
Definition at line 207 of file ServerInterface.h.