void Modo_Cliente() { string comando, cmd; Conexao c; try { c = Cria_Conexao (); // Inicializa conexao. } catch (string s_comando) { cout << s_comando; return ;} while (! cin.eof()) { cout << PROMPT; getline(cin,comando); istringstream s_comando(comando); s_comando >> cmd; if (cmd == "lls" || cmd == "lcd" || cmd == "lpwd" ) Request_Command_Local(comando); else if (cmd == "ls" || cmd == "cd" || cmd == "pwd") Request_Command(comando, c); else if (cmd == "get") Request_Get(comando, c); else if (cmd == "put") Request_Put(comando, c); else if (cmd == "exit" || cmd == "quit") return; else { if (comando.size() > 0) { // Ignora msg a seguir caso seja apenas um '/n'. cout << cmd << " nao eh um comando valido." << endl;; Imprime_Comandos(); } } } }
void Send_Put(Conexao c) { _Mensagem _msg; Mensagem msg = &_msg; string descritor; string nome_arq; long tam_arq; char buffer[256]; Recebe_Msg(c,msg); while (msg->Tipo == TIPO_9) { // Descritor de Arquivo. strncpy(buffer, (char*) msg->dados, msg->Tamanho); // Guarda em 'buffer' buffer[msg->Tamanho] = '\0'; // os dados da msg. descritor = descritor + buffer; // <Nome_do_Arquivo>#<Tamanho>. Limpa_Dados(msg); Recebe_Msg(c,msg); } istringstream s_comando(descritor); getline(s_comando, nome_arq, '#'); // Copia o nome do arquivo para 'nome_arq'. s_comando >> tam_arq; FILE *arq; arq = fopen(nome_arq.c_str(), "w"); if (arq == NULL) { Manda_String(c, TIPO_E, ""); // Erro. Manda_String(c, TIPO_A, "Erro: Nao foi possivel abrir o arquivo.\n"); // Mostra na tela do cliente. Manda_String(c, TIPO_F, ""); // Final de Transmissao. } else { Manda_String(c, TIPO_F, ""); // Final de Transmissao. Recebe_Msg(c,msg); while (msg->Tipo == TIPO_2) { // Dados. fwrite(msg->dados,sizeof(char), msg->Tamanho, arq); // Comeca a copiar os arquivos. Limpa_Dados(msg); Recebe_Msg(c,msg); } fclose(arq); } }
Cliente::Cliente() { if ( !isRoot() ) { cerr << "Você precisa ser root para rodar a aplicação" << endl; exit( 1 ); } uchar paridade; Pacote *rec; string comando, cmd; Conexao *Con = NULL; Comandos *Cmd = new Comandos(); bool recebido, enviado; int tentativasRecebimento = 0; int linhaEdit = 0; // linha que será editada (inicia em zero devido do IF da linha 134) while ( !cin.eof() ) { cout << endl; cout << PROMPT; getline( cin, comando ); if ( !Cmd->VerificarComando( comando ) ) { continue; } // coloca em cmd o char do comando istringstream s_comando( comando ); char cmd; string param; s_comando >> cmd; cmd = toupper( cmd ); if (cmd == 'Q') { Cmd->Sair(); } // coloca em "param" o parâmetro do comando, se houver if ( ! s_comando.eof() ) { s_comando >> param; } // o tamanho do pacote não pode ser 0, para o C++ não interpretar como \0 (byte nulo) int tamanhoPacote = param.size() == 0 ? 1 : param.size(); param = param.size() == 0 ? "B" : param; // O comando vai no Tipo. O parâmetro (se houver) vai no Dado Pacote *pack = new Pacote( tamanhoPacote, 0, Cmd->IDComando( cmd ), param ); ENVIO: Con = ( Con == NULL ) ? new Conexao() : Con; if ( pack != NULL ) { do { enviado = Protocolo::MandaPacote( Con, pack ); } while ( !enviado ); } do { do { rec = new Pacote(); recebido = Protocolo::RecebePacote( Con, rec ); tentativasRecebimento++; } while ( !recebido && tentativasRecebimento < 3 ); if ( !recebido ) { goto ENVIO; } paridade = Pacote::Paridade( rec->getDado() ); if ( rec->getTipo() == TIPO_EOF ) { break; } if ( rec->getTipo() != TIPO_ACK ) { if ( paridade == rec->getCRC() ) { // manda ACK somente se a paridade estiver certa e o pacote recebido não for um ACK do servidor Protocolo::MandaACK( Con ); } else { // manda NACK Protocolo::MandaNACK( Con ); continue; } } /* Verifica o tipo do pacote recebido */ switch ( rec->getTipo() ) { case TIPO_ACK: // verifica se o ACK é uma resposta ao envio de um APPEND if ( pack != NULL ) { if ( pack->getTipo() == TIPO_APPEND ) { string dado; cout << "Dados a serem enviados: " << endl; getline( cin, dado ); Protocolo::MandaString( Con, TIPO_DADOS, dado ); pack = NULL; } else if ( pack->getTipo() == TIPO_EDIT ) { // se ainda não definimos o número da linha a ser editada... if ( linhaEdit == 0 ) { Pacote *pack_numLinha; cout << "Digite o número da linha a ser editada: "; scanf( "%d%*c", &linhaEdit ); char charLinha[10]; sprintf( charLinha, "%d", linhaEdit ); string strLinha( charLinha ); pack_numLinha = new Pacote( strLinha.length(), 0, TIPO_NUM_LINHA, strLinha ); Protocolo::MandaPacote( Con, pack_numLinha ); pack_numLinha = NULL; } else { string dadosLinha; cout << "Digite os novos dados da linha" << endl; getline( cin, dadosLinha ); Protocolo::MandaString( Con, TIPO_DADOS, dadosLinha ); pack = NULL; linhaEdit = 0; } } } rec = NULL; break; case TIPO_NACK: // reenvia o pacote e volta do loop Protocolo::MandaPacote( Con, pack ); rec = NULL; continue; case TIPO_PRINT: Pacote::Exibir( rec ); rec = NULL; break; case TIPO_ERR: cout << "ERRO: " << rec->getDado() << endl; break; } Con->FecharConexao( Con ); } while ( recebido ); }
void Send_Command(string str_comando, Conexao c) { string cmd, cmd_esconde; istringstream s_comando(str_comando); s_comando >> cmd; if (cmd == "cd") { string path; char * err; char ch; s_comando.get(ch); getline(s_comando,path); // Copia o comando para 'path'. if (chdir(path.c_str()) != 0) { // Muda o diretorio para 'path'. err = strerror(errno); Manda_String(c, TIPO_E, ""); // Erro. string msg_erro = err + (": " + path + "'\n"); Manda_String(c, TIPO_A, msg_erro.c_str()); // Mostra na tela. } else { Manda_String(c,TIPO_A,""); } } else if (cmd == "put") { Send_Put(c); return; } else if (cmd == "get") { Send_Get(str_comando, c); return; } else { FILE *erro, *saida; char *dados = NULL; size_t n = 0; ssize_t tam; cmd_esconde = str_comando + " 2>&1 > /dev/null"; // Nao deixa o comando aparecer na tela do servidor. erro = popen(cmd_esconde.c_str(),"r"); tam = getdelim(&dados, &n, EOF, erro); // Guarda em 'dados' o conteudo de 'erro'. if (tam > 0) { Manda_String(c, TIPO_E, ""); // Erro. Manda_String(c, TIPO_A, dados); // Imprime o erro na tela. if (dados) free (dados); } else { if(dados) free (dados); dados = NULL; n = 0; saida = popen(str_comando.c_str(),"r"); // Executa o comando 'str' e guarda em 'saida'. tam = getdelim(&dados, &n, EOF, saida); // Guarda em 'dados' o conteudo de 'saida'. if (tam > 0) Manda_String(c, TIPO_A, dados); // Mostra na tela do cliente o resultado do comando. else Manda_String(c, TIPO_A,""); if (dados) free (dados); pclose(saida); } pclose(erro); } Manda_String(c,TIPO_F,""); // Final de Transmissao. }