Robo HTTP em C

1. Robo HTTP em C

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 00:55h

Seguinte, trabalho com desenvolvimento de software mas 90% do tempo com java (que acaba deixando todo programador meio burro) e os outros 10% com outras tecnologias sendo uns 4% de C/C++, sendo praticamente 90% deste tempo com C++ e Win32. Resumindo, quase não mexo com C profissionalmente (mto raro). Então mexo com C mais por hobby, ai pra brincar resolvi implementar um robo http. Ja implementei um parecido em diversas linguagens e ja tinha implementado um GET em C mas nunca GET e POST e armazenamento de COOKIE. Pois bem, a ideia foi fazer um ROBO HTTP, que se autentique no VOL e depois exiba o ranking (mostrado quando se esta autenticado no VOL). O robo pode ser implementado para outras coisas, o VOL foi apenas para simulacao. A ideia e postar depois o script no VOL para compartilhar com todos pois não vi nada parecido no VOL, porém antes disso temos algumas problemas:
Eu mandei um outro script e cometi alguns erros e o pessoal chega chutando o balde, como falei, o java deixa agente burro, entao acho melhor deixar tudo 100% pra depois mandar.
1) Não tive problemas em escrever o código. É só compilar ele com gcc e verão que funciona (se o vol não mudar o HTML :P), porém no recebimento dos dados do socket se acompanharem com o tcpflow, verão que os dados são lidos rapidamente, mas parece que a conexão continua ativa, tornando lento a finalização do recebimento. Onde será que errei??? Se alguem puder dar uma luz.
2) Verifiquem a forma que as coisas estão implementadas, se tem forma melhor de implementa-las pois minha experiencia com C é mais no mundo windows e além do mais como falei em C++ e geralmente usando stl, então vejam se tem bugs, para postar algo sem problemas e não ser criticado no VOL.

Ah, irei postar o código no próximo post para evitar algo muito grande. Aguarda resposta da galera e duvidas eu tbem respondo :)

Abs


  


2. the code

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 00:56h

------- rankvol.c ----
/**
* rankvol.c
*
* Neste programa iremos conectar com um servidor web, obter o cookie e entao
* com este cookie obter novos dados do servidor.
*
* Iremos utilizar o VOL como exemplo.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>

/* Aqui iremos declarar algumas variaveis globais */
static char servidor[] = "www.vivaolinux.com.br";
static char scriptLogin[] = "/testarLogin.php";
static char scriptHome[] = "/index.php";
static int portaServidor = 80;

/* Iremos armazenar aqui o login e a senha */
char login[17];
char senha[101];

/* Vamos lidar com buffer de 1Kb (1024 bytes) e mais um byte para o armazenamento do null */
char buffer[1025];

/* Vamos utilizar buffers grandes de 64Kb e 256Kb. Nao estaremos lidando com pacotes maiores no momento */
/* Futuramente podemos implementar algo dinamico */
char bufEnvio[65535];
char bufRetorno[262144];

/* Prototipos */
int abrirConexao(char * servidorConexao, int portaConexao);
char * obterHeaderHttp(char * servidorConexao, char * cookie);
void enviarDados(int socket, char * buffer);
char * receberDados(int socket);
char * obterPagina(char * script, char * dadosForm, char * cookie);
char * obterCookie();
int efetuarLogin(char * login, char * senha, char * cookie);
long obterRanking(char * cookie);

/* Esta funcao le um caractere. Veio de uma dica na net. :P
Para evitar o uso de ncurses esse e o jeito de usar algo tipo o getch
Nao sei ainda se roda no windows */
int lerCarac() {
struct termios oldt, newt;
int chLido;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
chLido = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return chLido;
}

/* Entrada do programa */
main(int argc, char *argv[])
{
/* Entrada de dados */
printf("\nHTTP-Robot - Exemplo de Robo HTTP - Mostra ranking no VOL:\n\n");
printf("Entre com o login do VOL: ");

/* O fgets ja coloca um null na ultima posicao automaticamente */
/* Assim tambem evitamos buffer overflow :P */
fgets(login, 17, stdin);

/* Precisamos remover o enter, aproveitamos e ja colocamos um final de string */
if (login[strlen(login) - 1] == 10) {
login[strlen(login)-1] = 0;
} else {
login[strlen(login)] = 0;
}

/* Agora vamos ler a senha */
printf("Entre com a senha do VOL: ");
char chLido = 0;
while (chLido != 10 && strlen(senha) < 101) {
chLido = lerCarac();
if (chLido > 27) {
// Caracter lido e asterisco na tela
putchar(42);
fflush(stdout);
senha[strlen(senha)] = chLido;
}
}

/* Forca finalizacao da string da senha */
senha[strlen(senha)] = 0;
printf("\n");

/* Precisamos obter o cookie */
char * cookie = obterCookie();
printf("Cookie de sessao obtido: [%s]\n", cookie);

/* Vamos enviar os dados do login */
if (!efetuarLogin(login, senha, cookie)) {
printf("Nao foi possivel efetuar o login. Verifique se o login e senha estao corretos.\n");
exit(-1);
} else {
printf("Login efetuado com sucesso.\n");
}

/* Agora vamos obter o ranking */
long ranking = obterRanking(cookie);
if (ranking == 0) {
printf("Ranking nao localizado. Verifique se o layout da home do vol foi modificado.\n");
} else {
printf("Seu ranking no VOL e: %d\n", ranking);
}

/* E nao podemos esquecer de liberar da memoria */
if (cookie != NULL) {
free(cookie);
}

/* Se chegar aqui e pq tudo deu certo */
printf("Programa finalizado com sucesso.\n");
return 0;
}

/* Rotina para obter o cookie da sessao */
char * obterCookie() {

/*
Primeiro precisamos do cookie
Vamos obte-lo chamando a index.php e pegando o Set-Cookie
*/
printf("Acessando home e obtendo cookie de sessao ...\n");
char * dadosHome = obterPagina(scriptHome, NULL, NULL);
char * posCookieIni = strstr(dadosHome, "Set-Cookie: ");
if (posCookieIni == NULL) {
printf("Erro ao obter o cookie. Pode ser problema de conexao.\n");
exit(-1);
}
char * posCookieFim = strstr(posCookieIni + 12, ";");
if (posCookieFim == NULL) {
printf("Erro ao obter o cookie. Pode ser problema de conexao.\n");
exit(-1);
}
char * cookie = (char *) malloc(sizeof(char) * 2048);
if (cookie == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
int tamanho = strlen(posCookieIni) - strlen(posCookieFim) - 12;
strncpy(cookie, posCookieIni + 12, tamanho);
cookie[tamanho] = 0;

/* Nao precisamos mais dos dados da home */
/* Automaticamente estaremos limpando posCookieIni e posCokieFim */
if (dadosHome != NULL) {
free(dadosHome);
}
return cookie;

}

/* Para efetuar login no VOL */
int efetuarLogin(char * login, char * senha, char * cookie) {

printf("Efetuando login no VOL ...\n");
int resLogin = 0;

/* 2Kb sao suficientes para os dados do form */
char * dadosForm = (char *) malloc(sizeof(char) * 2048);
if (dadosForm == NULL) {
printf("Falta de memoria.");
exit(-1);
}

if ((strlen(login) + strlen(senha) + 87) > 65534) {
printf("Erro de estouro de buffer. Mais que 64Kb de dados.\n");
exit(-1);
}
sprintf(dadosForm, "referer=index.php&formLogin=%s&formSenha=%s", login, senha);

/* Botoes do form */
strcat(dadosForm, "&imageField2.x=0&imageField2.y=0&Submit=Entrar\n");
char * dadosRecebidos = obterPagina(scriptLogin, dadosForm, cookie);

/* Vamos tentar identificar o login atraves de 2 informacoes:
1-O vol retorna um HTTP/1.1 302 Found para redirecionar para a home quando o login esta ok
2-Ele retorna um Location: no header */
char * tmpBufHttp = strstr(dadosRecebidos, "302 Found");
if (tmpBufHttp != NULL) {
char * tmpBufLocation = strstr(dadosRecebidos, "Location:");
if (tmpBufLocation != NULL) {
/* Se ele encontrar as 2 strings vamos considerar que houve autenticacao com sucesso */
if ((strlen(tmpBufHttp) < strlen(dadosRecebidos))
&& (strlen(tmpBufLocation) < strlen(dadosRecebidos))) {
/* Mas antes vamos procurar por acesso restrito para verificar se nao mudaram a regra */
char * tmpBufAcesso = strstr(dadosRecebidos, "acesso restrito");
if (tmpBufAcesso == NULL) {
resLogin = 1;
}
}
}
}

/* Vamos limpar da memoria */
if (dadosForm != NULL) {
free(dadosForm);
}
if (dadosRecebidos != NULL) {
/* Ao limpar dadosRecebidos estaremos limpando tmpBufHttp e tmpBufLocation */
free(dadosRecebidos);
}
return resLogin;

}

/* Apos autenticado, obtem o ranking mostrado na home do VOL */
long obterRanking(char * cookie) {

/* Vamos obter a home */
printf("Obtendo ranking a partir da home ...\n");
long ranking = 0;
char * dadosHome = obterPagina(scriptHome, NULL, cookie);

char * posRank = strstr(dadosHome, "Ranking: <b>");
if (posRank != NULL) {
char * posFimRank = strstr(posRank, "°");
if (posFimRank != NULL) {
int tamRank = strlen(posRank) - strlen(posFimRank) - 12;
char * tmpRank = (char *) malloc(sizeof(char) * (tamRank + 1));
if (tmpRank == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
strncpy(tmpRank, posRank + 12, tamRank);
tmpRank[tamRank] = 0;

/* Agora devemos converter para long e depois limpar da memoria */
ranking = strtol(tmpRank, NULL, 10);
if (tmpRank != NULL) {
free(tmpRank);
}
}
}

/* Nao precisamos mais dos dados da home */
/* Automaticamente estaremos limpando posRank e posFimRank */
if (dadosHome != NULL) {
free(dadosHome);
}
return ranking;
}

/* Funcao para conectar no host */
int abrirConexao(char * servidorConexao, int portaConexao) {
int meuSocket;
struct sockaddr_in sockAddr;
struct hostent *hEnt;

/* Vamos obter os dados do host */
hEnt = gethostbyname(servidorConexao);
if (hEnt == NULL) {
printf("Erro ao obter os dados do host.\n");
exit(-1);
}

/* Agora vamos obter o socket */
meuSocket = socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
if (meuSocket == -1) {
printf("Erro ao obter socket tcp.\n");
exit(-1);
}

/* Entao conectamos */
memcpy(&sockAddr.sin_addr, hEnt->h_addr, hEnt->h_length);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(portaConexao);
if (connect(meuSocket, (struct sockaddr *) &sockAddr, sizeof(sockAddr)) == -1) {
printf("Erro ao conectar no servidor.\n");
exit(-1);
}

/* E voltamos o socket conectado */
return meuSocket;
}

/* Esta funcao obtem um header http */
char * obterHeaderHttp(char * servidorConexao, char * cookie) {

/* Vamos usar um buffer grande (2kb nao tem perigo de estourar) */
char * headerHttp = (char *) malloc(sizeof(char) * 2048);
if (headerHttp == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
strcpy(headerHttp, "Host: ");
strcat(headerHttp, servidorConexao);
strcat(headerHttp, "\n");
strcat(headerHttp, "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.14)\n");

strcat(headerHttp, "Accept: text/xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\n");

strcat(headerHttp, "Accept-Language: en-us,en;q=0.5\n");

strcat(headerHttp, "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n");

strcat(headerHttp, "Keep-Alive: 300\n");
if (cookie != NULL) {
strcat(headerHttp, "Cookie: ");
strcat(headerHttp, cookie);
strcat(headerHttp, ";\n");
}

strcat(headerHttp, "Connection: keep-alive\n");
headerHttp[strlen(headerHttp)] = 0;
return headerHttp;
}

/* Funcao para enviar dados via socket */
void enviarDados(int socket, char * buffer) {
write(socket, buffer, strlen(buffer));
}

/* Funcao para receber dados via socket.
Vamos trabalhar com um limite de 256Kb suficiente para nossa aplicacao
Esta funcao retorna um ponteiro para os dados recebidos
*/
char * receberDados(int socket) {
char * dados = (char *) malloc(sizeof(char) * 262144);
if (dados == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
int contBuf = 0;
while ((contBuf = recv(socket, buffer, 1024, 0)) > 0) {
/* Para mostrar que esta recebendo alguma coisa */
putchar(42);
fflush(stdout);

/* Adiciona ao buffer se possivel */
buffer[contBuf] = 0;
if (dados != NULL) {
if ((strlen(dados) + 1025) > 262143) {
printf("Estouro do buffer no recebimento de dados.\n");
exit(-1);
}
}
if (dados == NULL) {
strcpy(dados, buffer);
} else {
strcat(dados, buffer);
}
}
dados[strlen(dados)] = 0;
return dados;
}

/* Obtem os dados de uma pagina html */
char * obterPagina(char * script, char * dadosForm, char * cookie) {

int meuSocket;
printf("Conectando: (%s) ... \n", servidor);
meuSocket = abrirConexao(servidor, portaServidor);
if (meuSocket == -1) {
printf("Erro ao conectar no servidor.\n");
exit(-1);
}

/* Vamos obter o header */
char * headerHttp = obterHeaderHttp(servidor, cookie);

/* Vamos gerar o post de envio */
if (dadosForm == NULL) {
sprintf(bufEnvio, "GET %s HTTP/1.1\n", script);
} else {
sprintf(bufEnvio, "POST %s HTTP/1.1\n", script);
}
if ((strlen(bufEnvio) + strlen(headerHttp)) > 65534) {
printf("Erro de estouro de buffer. Mais que 64Kb de dados.\n");
exit(-1);
}
strcat(bufEnvio, headerHttp);

/* Temos de adicionar algumas informacoes para mandar o form */
if (dadosForm != NULL) {
if ((strlen(bufEnvio) + 64) > 65534) {
printf("Erro de estouro de buffer. Mais que 64Kb de dados.\n");
exit(-1);
}
strcat(bufEnvio, "Content-Type: application/x-www-form-urlencoded\n");

strcat(bufEnvio, "Content-Length: ");
char * tmpBuf = (char *) malloc(sizeof(char) * 1024);
if (tmpBuf == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
sprintf(tmpBuf, "%d", strlen(dadosForm));
if ((strlen(bufEnvio) + strlen(tmpBuf) + 2) > 65534) {
printf("Erro de estouro de buffer. Mais que 64Kb de dados.\n");
exit(-1);
}
strcat(bufEnvio, tmpBuf);
strcat(bufEnvio, "\n");
if (tmpBuf != NULL) {
free(tmpBuf);
}
}
strcat(bufEnvio, "\n");

/* Armazena os dados do form */
if (dadosForm != NULL) {
if ((strlen(bufEnvio) + strlen(dadosForm)) > 65534) {
printf("Erro de estouro de buffer. Mais que 64Kb de dados.\n");
exit(-1);
}
strcat(bufEnvio, dadosForm);
}

/* Envia os dados */
enviarDados(meuSocket, bufEnvio);
printf("Dados foram enviados, recebendo dados ...\n");
char * dadosRecebidos = receberDados(meuSocket);
close(meuSocket);
printf("\n");

/* Vamos limpar da memoria */
if (headerHttp != NULL) {
free(headerHttp);
}
return dadosRecebidos;
}
------- fim rankvol.c ----

Infelizmente o VOL detona com a identação :(


3. ah detalhe

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 00:58h

implementei isso em algumas horas de programação, e como ja expliquei C não é normal no meu dia-a-dia então, me desculpem se cometi algum erro GROTESCO!


4. outra coisa

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 01:01h

também não testei portabilidade em windows nem em outras distros/kernel linux. Irei testar se o codigo é compativel. A principio foi compilado no ubuntu 7.04 no gcc 4.1.2

Pretendo melhorar também a parte do buffer (fixo de 64Kb e 256kb) para algo dinamico. Nao me preocupei com isso pois fiz o prog. meio na correria.


5. pow ninguem?

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 10:53h

incrivel que quando agente faz algo errado ou fala algo errado vem uma penca de gente metendo a boca, agora qdo precisa de ajuda... pow pessoal... ajuda ai, quem manja de socket veja pq do problema da lentidão da finalização da conexão. E vejam se o resto do programa ta legal tbem. valew

ah o código não compila no windows. Alguem sabe se tem de implementar diferente o socket (eu sempre implementei winsock no VC++ mas nunca implementei socket no gcc no windows). Ou será que tem como baixar as libs?


6. Re: Robo HTTP em C

Rodrigo Ferreira Valentim
engos

(usa openSUSE)

Enviado em 08/05/2008 - 11:22h

Você terminou de postar isso a 1h e acha que quantas pessoas conseguiram ver isso até agora?

Aqui o pessoal ajuda no tempo livre, pois ninguem recebe para isso, levando em consideração seu problema deveria esperar até segunda-feira, para dar tempo ao pessoal de testar com calma.

Teria o prazer de ajudar, mas como nem no trabalho aceito cobranças desse tipo, lhe deixo a seguinte dica para resolver todos esses problemas:

Não reinvente a roda!

Use bibliotecas que já fazem isso para você, particularmente estou usando e gostando da Poco:

http://pocoproject.org/

Ela funciona tanto em Windows como em Linux e tem vários códigos de exemplos das funções dela.


7. desculpa cara.

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 12:14h

que ninguem tem obrigação eu sei, mas o fato que se vc posta algo errado em questão de minutos tem um monte de nego metendo a boca, agora se precisa de ajuda, mas blz. Você ajuda se quiser, se acha que é uma cobrança blz então, tem tanta gente que pede pelo amor de deus e não sei oq e nem por isso eu deixo de ajudar. Quanto a usar algo "pronto" infelizmente a ideia não é esta, pois como falei ja implementei em diversas outras tecnologias, a ideia é fazer algo "meio que do zero". Desculpa qualquer coisa, mas não foi fato de cobrança mas ninguem fala nem um "vou ver". E ah, poco é C++, já implementei usando coisas prontas em c++, mas como falei no começo, agora quero implementar em C. Não precisamos reinventar a roda para resolver problemas do dia a dia, mas para aprender algumas coisas, é preciso sim.


8. Re: Robo HTTP em C

Jeffeson Luiz Oliveira de Campos
foguinho.peruca

(usa Ubuntu)

Enviado em 08/05/2008 - 12:37h

qnt ao html:
use espaços al inves d tab para q não seja perdida a tabulação em qqr editor e use a largura max d 80 colunas para não haver quebras horriveis d texto...

qnt a ajuda:

concordo q para aprender podemos implementar as coisas jah feitas novamente mas se tah com mto problema pq vc naum olha os fontes q jah foram implementados pra esse problema. Afinal, essa naum eh uma das principais vantagens do sw livre O.o?


9. entao foguinho

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 14:28h

eu uso espaço ao inves de tab sim, mas mesmo assim o vol perde a identação quando mando o post.
Quanto a colocar em 80 colunas, não acho que isso seja tão problemático igual você falou, mas é uma idéia legal, embora geralmente tem se usado 120 colunas como padrão (80 colunas era na epoca que não existia modo grafico), mas mesmo assim pode-se seguir visto que é um programa em modo terminal.

Do restante, já olhei varios códigos e como falei, o programa ta funcionando mas ta demorando pra fechar a conexão. Acho que o problema esta no header http que tou enviando, deve ser algum detalhe bobo.

E ah, ja portei pra windows, mas continua o mesmo problema da lentidão. Portei agora pouco (precisou de pouca mudança), e assim que testar se o codigo ta compilando dos 2 lados eu mando pra ca.

abs


10. seguinte

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 18:05h

Problema da lentidão era por causa do timeout. Descobri que o HTTP SERVER mantem a conexão aberta se não tiver erros até o timeout e como eu deixava o recv em loop para receber por buffers, esse timeout default era grande. Mudei um pouco adicionando um timeout menor (3 segundos) e adicionando o TCP_NODELAY, para o pacote vir em blocos grandes sem espera. Mesmo assim nao sei se pode ter problemas com redes lenta devido ao timeout de 3 segundos, mas no meu teste funcionou perfeitamente.
Outra coisa que implementei foi a alocacao dinamica do buffer recebido.
Alem disso deixei em 80 colunas como o amigo disse :)
Agora ta pronto (mais 2 horas do dia de hoje perdidas, mas tava meio sussa no trampo).
Ah, portei tbem o código para windows e compilei com gcc 3.4 e 4.2 (win e linux), falta testar em outras versões.
Acho que esse vai pra area de scripts do VOL, mas de costume pergunto. Algum problema grotesco a arrumar ??? para o script não bater la e chegarem metendo a boca???

Ah pra compilar no windows precisa linkar com wsock32
c:\gcc rankvol.c -o rankvol.exe -l wsock32
No linux somente:
# gcc ranvol.c -o rankvol

No proximo post vai o código. Critiquem a vontade e se tiver ok e não tiverem sugestões, vou mandar para a area de scripts do vol.

Ah, vai perder a identação, mas vou mandar o arquivo com uuencode no proximo post.

valew


11. the portable code

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 18:06h

----------- rankvol.c --------
/**
* rankvol.c
*
* Neste programa iremos conectar com um servidor web, obter o cookie e entao
* com este cookie obter novos dados do servidor.
*
* Iremos utilizar o VOL como exemplo.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#include <conio.h>
#else
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <termios.h>
#endif

#ifdef WIN32
#define FILE_SEPARATOR ''
#define MSG_WAITALL 0
#define CHAR_ENTER 13
#else
#define FILE_SEPARATOR '/'
#define CHAR_ENTER 10
#endif

#ifndef TCP_NODELAY
#define TCP_NODELAY 1
#endif

/* Aqui iremos declarar algumas variaveis globais */
static char servidor[] = "www.vivaolinux.com.br";
static char scriptLogin[] = "/testarLogin.php";
static char scriptHome[] = "/index.php";

/* Porta HTTP do servidor */
static int portaServidor = 80;

/* Iremos armazenar aqui o login e a senha */
char login[17];
char senha[101];

/* Vamos lidar com buffer de 1Kb (1024 bytes) e mais
um byte para o armazenamento do null */
char buffer[1025];

/* Vamos utilizar buffer de 32Kb para o pacote de subida */
#define BUF_32KB 32768
#define BUF_32KB_WORK 32767
char bufEnvio[BUF_32KB];

/* Prototipos */
int abrirConexao(char * servidorConexao, int portaConexao);
char * obterHeaderHttp(char * servidorConexao, char * cookie);
void enviarDados(int socket, char * buffer);
char * receberDados(int socket);
char * obterPagina(char * script, char * dadosForm, char * cookie);
char * obterCookie();
int efetuarLogin(char * login, char * senha, char * cookie);
long obterRanking(char * cookie);

/* Esta funcao le um caractere. Veio de uma dica na net,
mas fiz algumas modificacoes :P
Para evitar o uso de ncurses esse e o jeito de usar algo tipo o getch
No windows deveremos usar o famoso conio.he o proprio getch */
int lerCarac() {
int chLido;
#ifdef WIN32
chLido = getch();
#else
struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
chLido = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#endif
return chLido;
}

/* Entrada do programa */
main(int argc, char *argv[])
{
/* Entrada de dados */
printf("\nHTTP-Robot - Exemplo de Robo HTTP - Mostra ranking no VOL:\n\n");
printf("Entre com o login do VOL: ");

/* O fgets ja coloca um null na ultima posicao automaticamente */
/* Assim tambem evitamos buffer overflow :P */
fgets(login, 17, stdin);

/* Remover o enter, aproveitamos e colocamos um final de string */
if (login[strlen(login) - 1] == 10) {
login[strlen(login)-1] = 0;
} else {
login[strlen(login)] = 0;
}

/* Agora vamos ler a senha */
printf("Entre com a senha do VOL: ");
char chLido = 0;
while (chLido != CHAR_ENTER && strlen(senha) < 101) {
chLido = lerCarac();
if (chLido > 27) {
/* Caracter lido e asterisco na tela */
putchar(42);
fflush(stdout);
senha[strlen(senha)] = chLido;
}
}

/* Forca finalizacao da string da senha */
senha[strlen(senha)] = 0;
printf("\n");

/* Precisamos obter o cookie */
char * cookie = obterCookie();
printf("Cookie de sessao obtido: [%s]\n", cookie);

/* Vamos enviar os dados do login */
if (!efetuarLogin(login, senha, cookie)) {
printf("Nao foi possivel efetuar o login.\n");
printf("Verifique se o login e senha estao corretos.\n");
exit(-1);
} else {
printf("Login efetuado com sucesso.\n");
}

/* Agora vamos obter o ranking */
long ranking = obterRanking(cookie);
if (ranking == 0) {
printf("Ranking nao localizado. \n");
printf("Verifique se o layout da home do vol foi modificado.\n");
} else {
printf("Seu ranking no VOL e: %d\n", ranking);
}

/* E nao podemos esquecer de liberar da memoria */
if (cookie != NULL) {
free(cookie);
}

/* Se chegar aqui e pq tudo deu certo */
printf("Programa finalizado com sucesso.\n");
return 0;
}

/* Rotina para obter o cookie da sessao */
char * obterCookie() {

/*
Primeiro precisamos do cookie
Vamos obte-lo chamando a index.php e pegando o Set-Cookie
*/
printf("\nAcessando home e obtendo cookie de sessao ...\n");
char * dadosHome = obterPagina(scriptHome, NULL, NULL);
char * posCookieIni = strstr(dadosHome, "Set-Cookie: ");
if (posCookieIni == NULL) {
printf("Erro ao obter o cookie. Pode ser problema de conexao.\n");
exit(-1);
}
char * posCookieFim = strstr(posCookieIni + 12, ";");
if (posCookieFim == NULL) {
printf("Erro ao obter o cookie. Pode ser problema de conexao.\n");
exit(-1);
}
char * cookie = (char *) malloc(sizeof(char) * 2048);
if (cookie == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
int tamanho = strlen(posCookieIni) - strlen(posCookieFim) - 12;
strncpy(cookie, posCookieIni + 12, tamanho);
cookie[tamanho] = 0;

/* Nao precisamos mais dos dados da home */
/* Automaticamente estaremos limpando posCookieIni e posCokieFim */
if (dadosHome != NULL) {
free(dadosHome);
}
return cookie;

}

/* Para efetuar login no VOL */
int efetuarLogin(char * login, char * senha, char * cookie) {

printf("Efetuando login no VOL ...\n");
int resLogin = 0;

/* 2Kb sao suficientes para os dados do form */
char * dadosForm = (char *) malloc(sizeof(char) * 2048);
if (dadosForm == NULL) {
printf("Falta de memoria.");
exit(-1);
}

if ((strlen(login) + strlen(senha) + 87) > BUF_32KB_WORK) {
printf("Erro de estouro de buffer.\n");
exit(-1);
}
sprintf(dadosForm, "referer=index.php&formLogin=%s&formSenha=%s",
login, senha);

/* Botoes do form */
strcat(dadosForm, "&imageField2.x=0&imageField2.y=0&Submit=Entrar\n");
char * dadosRecebidos = obterPagina(scriptLogin, dadosForm, cookie);

/* Vamos tentar identificar o login atraves de 2 informacoes:
1-O vol retorna um HTTP/1.1 302 Found para redirecionar
para a home quando o login esta ok
2-Ele retorna um Location: no header
3-Verificamos ainda o acesso negado (pagina login) */
char * tmpBufHttp = strstr(dadosRecebidos, "302 Found");
if (tmpBufHttp != NULL) {
char * tmpBufLocation = strstr(dadosRecebidos, "Location:");
if (tmpBufLocation != NULL) {
/* Se ele encontrar as 2 strings vamos considerar que houve
autenticacao com sucesso */
if ((strlen(tmpBufHttp) < strlen(dadosRecebidos))
&& (strlen(tmpBufLocation) < strlen(dadosRecebidos))) {
/* Mas antes vamos procurar por acesso restrito para verificar
se nao mudaram a regra */
char * tmpBufAcesso = strstr(dadosRecebidos, "acesso restrito");
if (tmpBufAcesso == NULL) {
resLogin = 1;
}
}
}
}

/* Vamos limpar da memoria */
if (dadosForm != NULL) {
free(dadosForm);
}
if (dadosRecebidos != NULL) {
/* Ao limpar dadosRecebidos estaremos limpando tmpBufHttp
e tmpBufLocation */
free(dadosRecebidos);
}
return resLogin;

}

/* Apos autenticado, obtem o ranking mostrado na home do VOL */
long obterRanking(char * cookie) {

/* Vamos obter a home */
printf("Obtendo ranking a partir da home ...\n");
long ranking = 0;
char * dadosHome = obterPagina(scriptHome, NULL, cookie);

char * posRank = strstr(dadosHome, "Ranking: <b>");
if (posRank != NULL) {
char * posFimRank = strstr(posRank, "°");
if (posFimRank != NULL) {
int tamRank = strlen(posRank) - strlen(posFimRank) - 12;
char * tmpRank = (char *) malloc(sizeof(char) * (tamRank + 1));
if (tmpRank == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
strncpy(tmpRank, posRank + 12, tamRank);
tmpRank[tamRank] = 0;

/* Agora devemos converter para long
e depois limpar da memoria */
ranking = strtol(tmpRank, NULL, 10);
if (tmpRank != NULL) {
free(tmpRank);
}
}
}

/* Nao precisamos mais dos dados da home */
/* Automaticamente estaremos limpando posRank e posFimRank */
if (dadosHome != NULL) {
free(dadosHome);
}
return ranking;
}

/* Funcao para conectar no host */
int abrirConexao(char * servidorConexao, int portaConexao) {
#ifdef WIN32
WSADATA wsaData;
WORD wVersionRequested;
int err;

wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
fprintf(stderr, "Nao achou WinSock DLL.\n");
exit(-1);
}
#endif

int meuSocket;
struct sockaddr_in sockAddr;
struct hostent *hEnt;

/* Vamos obter os dados do host */
hEnt = gethostbyname(servidorConexao);
if (hEnt == NULL) {
printf("Erro ao obter os dados do host.\n");
exit(-1);
}

/* Agora vamos obter o socket */
meuSocket = socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
if (meuSocket == -1) {
printf("Erro ao obter socket tcp.\n");
exit(-1);
}

/* Vamos definir o TCP_NODELAY (usado para comunicacoes de ida e
volta para melhorar a performance) */
int flagTcpNoDelay = 1;
int resTcpNoDelay = setsockopt(meuSocket, IPPROTO_TCP, TCP_NODELAY,
(char *) &flagTcpNoDelay, sizeof(int));
if (resTcpNoDelay < 0) {
printf("Erro ao setar tcp_nodelay.\n");
exit(-1);
}

/* Vamos definir tambem o timeout do socket
(Voce pode precisar mudar em redes lentas) */
struct timeval tv;
int timeouts = 0;
tv.tv_sec = 3;
tv.tv_usec = 0;
if (setsockopt(meuSocket, SOL_SOCKET, SO_RCVTIMEO,
(char *) &tv, sizeof tv)) {
printf("Erro ao definir timeout.");
exit(-1);
}

/* Entao conectamos */
memcpy(&sockAddr.sin_addr, hEnt->h_addr, hEnt->h_length);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(portaConexao);
if (connect(meuSocket, (struct sockaddr *) &sockAddr,
sizeof(sockAddr)) < 0) {
printf("Erro ao conectar no servidor.\n");
exit(-1);
}

/* E voltamos o socket conectado */
return meuSocket;
}

/* Esta funcao obtem um header http */
char * obterHeaderHttp(char * servidorConexao, char * cookie) {

/* Vamos usar um buffer grande (2kb nao tem perigo de estourar) */
char * headerHttp = (char *) malloc(sizeof(char) * 2048);
if (headerHttp == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
strcpy(headerHttp, "Host: ");
strcat(headerHttp, servidorConexao);
strcat(headerHttp, "\n");
strcat(headerHttp, "User-Agent: Mozilla/5.0 ");
strcat(headerHttp, "X11; U; Linux i686; en-US; rv:1.8.1.14)\n");
strcat(headerHttp, "Accept: text/xml,text/html;q=0.9,text/plain;");
strcat(headerHttp, "q=0.8,image/png,*/*;q=0.5\n");
strcat(headerHttp, "Accept-Language: en-us,en;q=0.5\n");
strcat(headerHttp, "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n");
strcat(headerHttp, "Keep-Alive: 300\n");
if (cookie != NULL) {
strcat(headerHttp, "Cookie: ");
strcat(headerHttp, cookie);
strcat(headerHttp, ";\n");
}
strcat(headerHttp, "Connection: keep-alive\n");
headerHttp[strlen(headerHttp)] = 0;
return headerHttp;
}

/* Funcao para enviar dados via socket */
void enviarDados(int socket, char * buffer) {
int envio = send(socket, buffer, strlen(buffer), 0);
if (envio < 1) {
printf("Erro no envio dos dados: [%d].\n", envio);
exit(-1);
}
}

/* Funcao para receber dados via socket.
Vamos trabalhar com alocacao dinamica.
Esta funcao retorna um ponteiro para os dados recebidos
*/
char * receberDados(int socket) {
char * dados = (char *) malloc(sizeof(char) * 1025);
if (dados == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
int contBuf = 0;
while ((contBuf = recv(socket, buffer, 1024, 0)) > 0) {
/* Para mostrar que esta recebendo alguma coisa */
putchar(42);
fflush(stdout);

/* Adiciona ao buffer se possivel */
buffer[contBuf] = 0;

if (dados == NULL) {
strcpy(dados, buffer);
} else {
/* Realocamos mais 1kb */
dados = realloc(dados, strlen(dados) + 1025);
if (dados == NULL) {
printf("Erro na realocacao dinamica.\n");
exit(-1);
}
strcat(dados, buffer);
}

/* Limpar buffer */
int n = 0;
for(n = 0; n <= 1024; n++) {
buffer[n] = 0;
}
}
dados[strlen(dados)] = 0;
return dados;
}

/* Obtem os dados de uma pagina html */
char * obterPagina(char * script, char * dadosForm, char * cookie) {

int meuSocket;
printf("Conectando: (%s) ... \n", servidor);
meuSocket = abrirConexao(servidor, portaServidor);
if (meuSocket == -1) {
printf("Erro ao conectar no servidor.\n");
exit(-1);
}

/* Vamos obter o header */
char * headerHttp = obterHeaderHttp(servidor, cookie);

/* Vamos gerar o post de envio */
if (dadosForm == NULL) {
sprintf(bufEnvio, "GET %s HTTP/1.1\n", script);
} else {
sprintf(bufEnvio, "POST %s HTTP/1.1\n", script);
}
if ((strlen(bufEnvio) + strlen(headerHttp)) > BUF_32KB_WORK) {
printf("Erro de estouro de buffer.\n");
exit(-1);
}
strcat(bufEnvio, headerHttp);

/* Vamos limpar da memoria */
if (headerHttp != NULL) {
free(headerHttp);
}

/* Temos de adicionar algumas informacoes para mandar o form */
if (dadosForm != NULL) {
if ((strlen(bufEnvio) + 64) > BUF_32KB_WORK) {
printf("Erro de estouro de buffer.\n");
exit(-1);
}
strcat(bufEnvio, "Content-Type: application/x-www-form-urlencoded\n");

strcat(bufEnvio, "Content-Length: ");
char * tmpBuf = (char *) malloc(sizeof(char) * 1024);
if (tmpBuf == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
sprintf(tmpBuf, "%d", strlen(dadosForm));
if ((strlen(bufEnvio) + strlen(tmpBuf) + 2) > BUF_32KB_WORK) {
printf("Erro de estouro de buffer.\n");
exit(-1);
}
strcat(bufEnvio, tmpBuf);
strcat(bufEnvio, "\n");
if (tmpBuf != NULL) {
free(tmpBuf);
}
}
strcat(bufEnvio, "\n");

/* Armazena os dados do form */
if (dadosForm != NULL) {
if ((strlen(bufEnvio) + strlen(dadosForm)) > BUF_32KB_WORK) {
printf("Erro de estouro de buffer.\n");
exit(-1);
}
strcat(bufEnvio, dadosForm);
}

/* Envia os dados */
enviarDados(meuSocket, bufEnvio);
printf("Dados foram enviados, recebendo dados ...\n");
char * dadosRecebidos = receberDados(meuSocket);
#ifdef WIN32
closesocket(meuSocket);
WSACleanup();
#else
close(meuSocket);
#endif
printf("\n");

return dadosRecebidos;
}
----------- fim rankvol.c --------



12. será que o vol aceita uuencode?

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 08/05/2008 - 18:14h

begin 644 rankvol.c
M+RHJ#0HJ(')A;FMV;VPN8PT**@T**B!.97-T92!P<F]G<F%M82!I<F5M;W,@
M8V]N96-T87(@8V]M('5M('-E<G9I9&]R('=E8BP@;V)T97(@;R!C;V]K:64@
M92!E;G1A;PT**B!C;VT@97-T92!C;V]K:64@;V)T97(@;F]V;W,@9&%D;W,@
M9&\@<V5R=FED;W(N#0HJ#0HJ($ER96UO<R!U=&EL:7IA<B!O(%9/3"!C;VUO
M(&5X96UP;&\N#0HJ+PT*(VEN8VQU9&4@/'-T9&EO+F@^#0HC:6YC;'5D92 \
M<W1D;&EB+F@^#0HC:6YC;'5D92 \<W1R:6YG+F@^#0HC:6YC;'5D92 \97)R
M;F\N:#X-"B-I;F-L=61E(#QU;FES=&0N:#X-"@T*(VEF9&5F(%=)3C,R#0H@
M(" @(VEN8VQU9&4@/'=I;F1O=W,N:#X-"B @(" C:6YC;'5D92 \=VEN<V]C
M:RYH/@T*(" @("-I;F-L=61E(#QC;VYI;RYH/@T*(V5L<V4-"B @(" C:6YC
M;'5D92 \;F5T9&(N:#X-"B @(" C:6YC;'5D92 \;F5T:6YE="]I;BYH/@T*
M(" @("-I;F-L=61E(#QS>7,O<V]C:V5T+F@^#0H@(" @(VEN8VQU9&4@/'-Y
M<R]T>7!E<RYH/@T*(" @("-I;F-L=61E(#QT97)M:6]S+F@^#0HC96YD:68-
M"@T*(VEF9&5F(%=)3C,R#0H@(" @(V1E9FEN92!&24Q%7U-%4$%2051/4B G
M)PT*(" @("-D969I;F4@35-'7U=!251!3$P@, T*(" @("-D969I;F4@0TA!
M4E]%3E1%4B Q,PT*(V5L<V4-"B @(" C9&5F:6YE($9)3$5?4T5005)!5$]2
M("<O)PT*(" @("-D969I;F4@0TA!4E]%3E1%4B Q, T*(V5N9&EF#0H-"B-I
M9FYD968@5$-07TY/1$5,05D-"B @(" C9&5F:6YE(%1#4%].3T1%3$%9(#$-
M"B-E;F1I9@T*#0HO*B!!<75I(&ER96UO<R!D96-L87)A<B!A;&=U;6%S('9A
M<FEA=F5I<R!G;&]B86ES("HO#0IS=&%T:6,@8VAA<B!S97)V:61O<EM=(#T@
M(G=W=RYV:79A;VQI;G5X+F-O;2YB<B([#0IS=&%T:6,@8VAA<B!S8W)I<'1,
M;V=I;EM=(#T@(B]T97-T87),;V=I;BYP:' B.PT*<W1A=&EC(&-H87(@<V-R
M:7!T2&]M95M=(#T@(B]I;F1E>"YP:' B.PT*#0HO*B!0;W)T82!(5%10(&1O
M('-E<G9I9&]R("HO#0IS=&%T:6,@:6YT('!O<G1A4V5R=FED;W(@/2 X,#L-
M"@T*+RH@27)E;6]S(&%R;6%Z96YA<B!A<75I(&\@;&]G:6X@92!A('-E;FAA
M("HO#0IC:&%R(&QO9VEN6S$W73L-"F-H87(@<V5N:&%;,3 Q73L-"@T*+RH@
M5F%M;W,@;&ED87(@8V]M(&)U9F9E<B!D92 Q2V(@*#$P,C0@8GET97,I(&4@
M;6%I<R -"G5M(&)Y=&4@<&%R82!O(&%R;6%Z96YA;65N=&\@9&\@;G5L;" J
M+PT*8VAA<B!B=69F97);,3 R-5T[( T*#0HO*B!686UO<R!U=&EL:7IA<B!B
M=69F97(@9&4@,S)+8B!P87)A(&\@<&%C;W1E(&1E('-U8FED82 J+PT*(V1E
M9FEN92!"549?,S)+0B S,C<V. T*(V1E9FEN92!"549?,S)+0E]73U)+(#,R
M-S8W#0IC:&%R(&)U9D5N=FEO6T)51E\S,DM"73L-"@T*+RH@4')O=&]T:7!O
M<R J+PT*:6YT(&%B<FER0V]N97AA;RAC:&%R("H@<V5R=FED;W)#;VYE>&%O
M+"!I;G0@<&]R=&%#;VYE>&%O*3L-"F-H87(@*B!O8G1E<DAE861E<DAT=' H
M8VAA<B J('-E<G9I9&]R0V]N97AA;RP@8VAA<B J(&-O;VMI92D[#0IV;VED
M(&5N=FEA<D1A9&]S*&EN="!S;V-K970L(&-H87(@*B!B=69F97(I.PT*8VAA
M<B J(')E8V5B97)$861O<RAI;G0@<V]C:V5T*3L-"F-H87(@*B!O8G1E<E!A
M9VEN82AC:&%R("H@<V-R:7!T+"!C:&%R("H@9&%D;W-&;W)M+"!C:&%R("H@
M8V]O:VEE*3L-"F-H87(@*B!O8G1E<D-O;VMI92@I.PT*:6YT(&5F971U87),
M;V=I;BAC:&%R("H@;&]G:6XL(&-H87(@*B!S96YH82P@8VAA<B J(&-O;VMI
M92D[#0IL;VYG(&]B=&5R4F%N:VEN9RAC:&%R("H@8V]O:VEE*3L-"@T*+RH@
M17-T82!F=6YC86\@;&4@=6T@8V%R86-T97)E+B!696EO(&1E('5M82!D:6-A
M(&YA(&YE="P@#0IM87,@9FEZ(&%L9W5M87,@;6]D:69I8V%C;V5S(#I0( T*
M4&%R82!E=FET87(@;R!U<V\@9&4@;F-U<G-E<R!E<W-E(&4@;R!J96ET;R!D
M92!U<V%R(&%L9V\@=&EP;R!O(&=E=&-H( T*3F\@=VEN9&]W<R!D979E<F5M
M;W,@=7-A<B!O(&9A;6]S;R!C;VYI;RYH92!O('!R;W!R:6\@9V5T8V@@*B\-
M"FEN="!L97)#87)A8R@I('L-"B @("!I;G0@8VA,:61O.PT*(" @("-I9F1E
M9B!724XS,@T*(" @(" @("!C:$QI9&\@/2!G971C:"@I.PT*(" @("-E;'-E
M#0H@(" @(" @('-T<G5C="!T97)M:6]S(&]L9'0L(&YE=W0[#0H@(" @(" @
M('1C9V5T871T<BA35$1)3E]&24Q%3D\L("9O;&1T*3L-"B @(" @(" @;F5W
M=" ](&]L9'0[#0H@(" @(" @(&YE=W0N8U]L9FQA9R F/2!^*"!)0T%.3TX@
M?"!%0TA/("D[#0H@(" @(" @('1C<V5T871T<BA35$1)3E]&24Q%3D\L(%1#
M4T%.3U<L("9N97=T*3L-"B @(" @(" @8VA,:61O(#T@9V5T8VAA<B@I.PT*
M(" @(" @("!T8W-E=&%T='(H4U1$24Y?1DE,14Y/+"!40U-!3D]7+" F;VQD
M="D[#0H@(" @(V5N9&EF#0H@(" @<F5T=7)N(&-H3&ED;SL-"GT-"@T*+RH@
M16YT<F%D82!D;R!P<F]G<F%M82 J+PT*;6%I;BAI;G0@87)G8RP@8VAA<B J
M87)G=EM=*0T*>PT*(" @("\J($5N=')A9&$@9&4@9&%D;W,@*B\-"B @("!P
M<FEN=&8H(EQN2%144"U2;V)O=" M($5X96UP;&\@9&4@4F]B;R!(5%10("T@
M36]S=')A(')A;FMI;F<@;F\@5D],.EQN7&XB*3L-"B @("!P<FEN=&8H(D5N
M=')E(&-O;2!O(&QO9VEN(&1O(%9/3#H@(BD[#0H-"B @(" O*B!/(&9G971S
M(&IA(&-O;&]C82!U;2!N=6QL(&YA('5L=&EM82!P;W-I8V%O(&%U=&]M871I
M8V%M96YT92 J+PT*(" @("\J($%S<VEM('1A;6)E;2!E=FET86UO<R!B=69F
M97(@;W9E<F9L;W<@.E @*B\-"B @("!F9V5T<RAL;V=I;BP@,3<L('-T9&EN
M*3L-"@T*(" @("\J(%)E;6]V97(@;R!E;G1E<BP@87!R;W9E:71A;6]S(&4@
M8V]L;V-A;6]S('5M(&9I;F%L(&1E('-T<FEN9R J+PT*(" @(&EF("AL;V=I
M;EMS=')L96XH;&]G:6XI("T@,5T@/3T@,3 I('L-"B @(" @(" @;&]G:6Y;
M<W1R;&5N*&QO9VEN*2TQ72 ](# [#0H@(" @?2!E;'-E('L-"B @(" @(" @
M;&]G:6Y;<W1R;&5N*&QO9VEN*5T@/2 P.PT*(" @('T-"@T*(" @("\J($%G
M;W)A('9A;6]S(&QE<B!A('-E;FAA("HO#0H@(" @<')I;G1F*")%;G1R92!C
M;VT@82!S96YH82!D;R!63TPZ("(I.PT*(" @(&-H87(@8VA,:61O(#T@,#L-
M"B @("!W:&EL92 H8VA,:61O("$]($-(05)?14Y415(@)B8@<W1R;&5N*'-E
M;FAA*2 \(#$P,2D@>PT*(" @(" @("!C:$QI9&\@/2!L97)#87)A8R@I.PT*
M(" @(" @("!I9B H8VA,:61O(#X@,C<I('L-"B @(" @(" @(" @("\J($-A
M<F%C=&5R(&QI9&\@92!A<W1E<FES8V\@;F$@=&5L82 J+PT*(" @(" @(" @
M(" @<'5T8VAA<B@T,BD[#0H@(" @(" @(" @("!F9FQU<V@H<W1D;W5T*3L-
M"B @(" @(" @(" @('-E;FAA6W-T<FQE;BAS96YH82E=(#T@8VA,:61O.PT*
M(" @(" @("!]#0H@(" @?0T*#0H@(" @+RH@1F]R8V$@9FEN86QI>F%C86\@
M9&$@<W1R:6YG(&1A('-E;FAA("HO#0H@(" @<V5N:&%;<W1R;&5N*'-E;FAA
M*5T@/2 P.PT*(" @('!R:6YT9B@B7&XB*3L-"@T*(" @("\J(%!R96-I<V%M
M;W,@;V)T97(@;R!C;V]K:64@*B\-"B @("!C:&%R("H@8V]O:VEE(#T@;V)T
M97)#;V]K:64H*3L-"B @("!P<FEN=&8H(D-O;VMI92!D92!S97-S86\@;V)T
M:61O.B!;)7-=7&XB+"!C;V]K:64I.PT*#0H@(" @+RH@5F%M;W,@96YV:6%R
M(&]S(&1A9&]S(&1O(&QO9VEN("HO#0H@(" @:68@*"%E9F5T=6%R3&]G:6XH
M;&]G:6XL('-E;FAA+"!C;V]K:64I*2![#0H@(" @(" @('!R:6YT9B@B3F%O
M(&9O:2!P;W-S:79E;"!E9F5T=6%R(&\@;&]G:6XN7&XB*3L-"B @(" @(" @
M<')I;G1F*")697)I9FEQ=64@<V4@;R!L;V=I;B!E('-E;FAA(&5S=&%O(&-O
M<G)E=&]S+EQN(BD[#0H@(" @(" @(&5X:70H+3$I.R -"B @("!](&5L<V4@
M>PT*(" @(" @("!P<FEN=&8H(DQO9VEN(&5F971U861O(&-O;2!S=6-E<W-O
M+EQN(BD[#0H@(" @?0T*#0H@(" @+RH@06=O<F$@=F%M;W,@;V)T97(@;R!R
M86YK:6YG("HO#0H@(" @;&]N9R!R86YK:6YG(#T@;V)T97)286YK:6YG*&-O
M;VMI92D[#0H@(" @:68@*')A;FMI;F<@/3T@,"D@>PT*(" @(" @("!P<FEN
M=&8H(E)A;FMI;F<@;F%O(&QO8V%L:7IA9&\N(%QN(BD[#0H@(" @(" @('!R
M:6YT9B@B5F5R:69I<75E('-E(&\@;&%Y;W5T(&1A(&AO;64@9&\@=F]L(&9O
M:2!M;V1I9FEC861O+EQN(BD[#0H@(" @?2!E;'-E('L-"B @(" @(" @<')I
M;G1F*")3974@<F%N:VEN9R!N;R!63TP@93H@)61<;B(L(')A;FMI;F<I.PT*
M(" @('T-"@T*(" @("\J($4@;F%O('!O9&5M;W,@97-Q=65C97(@9&4@;&EB
M97)A<B!D82!M96UO<FEA("HO#0H@(" @:68@*&-O;VMI92 A/2!.54Q,*2![
M#0H@(" @(" @(&9R964H8V]O:VEE*3L-"B @("!]#0H-"B @(" O*B!392!C
M:&5G87(@87%U:2!E('!Q('1U9&\@9&5U(&-E<G1O("HO#0H@(" @<')I;G1F
M*")0<F]G<F%M82!F:6YA;&EZ861O(&-O;2!S=6-E<W-O+EQN(BD[#0H@(" @
M<F5T=7)N(# [#0I]#0H-"B\J(%)O=&EN82!P87)A(&]B=&5R(&\@8V]O:VEE
M(&1A('-E<W-A;R J+PT*8VAA<B J(&]B=&5R0V]O:VEE*"D@>PT*#0H@(" @
M+RH@#0H@(" @(" @(%!R:6UE:7)O('!R96-I<V%M;W,@9&\@8V]O:VEE( T*
M(" @(" @("!686UO<R!O8G1E+6QO(&-H86UA;F1O(&$@:6YD97@N<&AP(&4@
M<&5G86YD;R!O(%-E="U#;V]K:64-"B @(" @(" @*B\-"B @("!P<FEN=&8H
M(EQN06-E<W-A;F1O(&AO;64@92!O8G1E;F1O(&-O;VMI92!D92!S97-S86\@
M+BXN7&XB*3L-"B @("!C:&%R("H@9&%D;W-(;VUE(#T@;V)T97)086=I;F$H
M<V-R:7!T2&]M92P@3E5,3"P@3E5,3"D[#0H@(" @8VAA<B J('!O<T-O;VMI
M94EN:2 ]('-T<G-T<BAD861O<TAO;64L(")3970M0V]O:VEE.B B*3L-"B @
M("!I9B H<&]S0V]O:VEE26YI(#T]($Y53$PI('L-"B @(" @(" @<')I;G1F
M*")%<G)O(&%O(&]B=&5R(&\@8V]O:VEE+B!0;V1E('-E<B!P<F]B;&5M82!D
M92!C;VYE>&%O+EQN(BD[#0H@(" @(" @(&5X:70H+3$I.PT*(" @('T-"B @
M("!C:&%R("H@<&]S0V]O:VEE1FEM(#T@<W1R<W1R*'!O<T-O;VMI94EN:2 K
M(#$R+" B.R(I.PT*(" @(&EF("AP;W-#;V]K:65&:6T@/3T@3E5,3"D@>PT*
M(" @(" @("!P<FEN=&8H(D5R<F\@86\@;V)T97(@;R!C;V]K:64N(%!O9&4@
M<V5R('!R;V)L96UA(&1E(&-O;F5X86\N7&XB*3L-"B @(" @(" @97AI="@M
M,2D[#0H@(" @?0T*(" @(&-H87(@*B!C;V]K:64@/2 H8VAA<B J*2!M86QL
M;V,H<VEZ96]F*&-H87(I("H@,C T."D[#0H@(" @:68@*&-O;VMI92 ]/2!.
M54Q,*2![#0H@(" @(" @('!R:6YT9B@B1F%L=&$@9&4@;65M;W)I82Y<;B(I
M.PT*(" @(" @("!E>&ET*"TQ*3L-"B @("!]#0H@(" @:6YT('1A;6%N:&\@
M/2!S=')L96XH<&]S0V]O:VEE26YI*2 M('-T<FQE;BAP;W-#;V]K:65&:6TI
M("T@,3([#0H@(" @<W1R;F-P>2AC;V]K:64L('!O<T-O;VMI94EN:2 K(#$R
M+"!T86UA;FAO*3L-"B @("!C;V]K:65;=&%M86YH;UT@/2 P.PT*#0H@(" @
M+RH@3F%O('!R96-I<V%M;W,@;6%I<R!D;W,@9&%D;W,@9&$@:&]M92 J+PT*
M(" @("\J($%U=&]M871I8V%M96YT92!E<W1A<F5M;W,@;&EM<&%N9&\@<&]S
M0V]O:VEE26YI(&4@<&]S0V]K:65&:6T@*B\-"B @("!I9B H9&%D;W-(;VUE
M("$]($Y53$PI('L-"B @(" @(" @9G)E92AD861O<TAO;64I.PT*(" @('T-
M"B @("!R971U<FX@8V]O:VEE.PT*#0I]#0H-"B\J(%!A<F$@969E='5A<B!L
M;V=I;B!N;R!63TP@*B\-"FEN="!E9F5T=6%R3&]G:6XH8VAA<B J(&QO9VEN
M+"!C:&%R("H@<V5N:&$L(&-H87(@*B!C;V]K:64I('L-"@T*(" @('!R:6YT
M9B@B169E='5A;F1O(&QO9VEN(&YO(%9/3" N+BY<;B(I.PT*(" @(&EN="!R
M97-,;V=I;B ](# [#0H-"B @(" O*B R2V(@<V%O('-U9FEC:65N=&5S('!A
M<F$@;W,@9&%D;W,@9&\@9F]R;2 J+PT*(" @(&-H87(@*B!D861O<T9O<FT@
M/2 H8VAA<B J*2!M86QL;V,H<VEZ96]F*&-H87(I("H@,C T."D[#0H@(" @
M:68@*&1A9&]S1F]R;2 ]/2!.54Q,*2![#0H@(" @(" @('!R:6YT9B@B1F%L
M=&$@9&4@;65M;W)I82XB*3L-"B @(" @(" @97AI="@M,2D[#0H@(" @?0T*
M#0H@(" @:68@*"AS=')L96XH;&]G:6XI("L@<W1R;&5N*'-E;FAA*2 K(#@W
M*2 ^($)51E\S,DM"7U=/4DLI('L-"B @(" @(" @<')I;G1F*")%<G)O(&1E
M(&5S=&]U<F\@9&4@8G5F9F5R+EQN(BD[#0H@(" @(" @(&5X:70H+3$I.PT*
M(" @('T-"B @("!S<')I;G1F*&1A9&]S1F]R;2P@(G)E9F5R97(]:6YD97@N
M<&AP)F9O<FU,;V=I;CTE<R9F;W)M4V5N:&$])7,B+" -"B @(" @(" @(" @
M(&QO9VEN+"!S96YH82D[#0H-"B @(" O*B!";W1O97,@9&\@9F]R;2 J+PT*
M(" @('-T<F-A="AD861O<T9O<FTL("(F:6UA9V5&:65L9#(N>#TP)FEM86=E
M1FEE;&0R+GD],"93=6)M:70]16YT<F%R7&XB*3L-"B @("!C:&%R("H@9&%D
M;W-296-E8FED;W,@/2!O8G1E<E!A9VEN82AS8W)I<'1,;V=I;BP@9&%D;W-&
M;W)M+"!C;V]K:64I.PT*#0H@(" @+RH@5F%M;W,@=&5N=&%R(&ED96YT:69I
M8V%R(&\@;&]G:6X@871R879E<R!D92 R(&EN9F]R;6%C;V5S.@T*(" @(" @
M(" Q+4\@=F]L(')E=&]R;F$@=6T@2%144"\Q+C$@,S R($9O=6YD('!A<F$@
M<F5D:7)E8VEO;F%R( T*(" @(" @(" @('!A<F$@82!H;VUE('%U86YD;R!O
M(&QO9VEN(&5S=&$@;VL-"B @(" @(" @,BU%;&4@<F5T;W)N82!U;2!,;V-A
M=&EO;CH@;F\@:&5A9&5R( T*(" @(" @(" S+59E<FEF:6-A;6]S(&%I;F1A
M(&\@86-E<W-O(&YE9V%D;R H<&%G:6YA(&QO9VEN*2 J+PT*(" @(&-H87(@
M*B!T;7!"=69(='1P(#T@<W1R<W1R*&1A9&]S4F5C96)I9&]S+" B,S R($9O
M=6YD(BD[#0H@(" @:68@*'1M<$)U9DAT=' @(3T@3E5,3"D@>PT*(" @(" @
M("!C:&%R("H@=&UP0G5F3&]C871I;VX@/2!S=')S='(H9&%D;W-296-E8FED
M;W,L("),;V-A=&EO;CHB*3L-"B @(" @(" @:68@*'1M<$)U9DQO8V%T:6]N
M("$]($Y53$PI('L-"B @(" @(" @(" @("\J(%-E(&5L92!E;F-O;G1R87(@
M87,@,B!S=')I;F=S('9A;6]S(&-O;G-I9&5R87(@<75E(&AO=79E( T*(" @
M(" @(" @(" @(" @875T96YT:6-A8V%O(&-O;2!S=6-E<W-O("HO#0H@(" @
M(" @(" @("!I9B H*'-T<FQE;BAT;7!"=69(='1P*2 \('-T<FQE;BAD861O
M<U)E8V5B:61O<RDI( T*(" @(" @(" @(" @(" @(" @(" F)B H<W1R;&5N
M*'1M<$)U9DQO8V%T:6]N*2 \('-T<FQE;BAD861O<U)E8V5B:61O<RDI*2![
M#0H@(" @(" @(" @(" @(" @+RH@36%S(&%N=&5S('9A;6]S('!R;V-U<F%R
M('!O<B!A8V5S<V\@<F5S=')I=&\@<&%R82!V97)I9FEC87(@#0H@(" @(" @
M(" @(" @(" @(" @<V4@;F%O(&UU9&%R86T@82!R96=R82 J+PT*(" @(" @
M(" @(" @(" @(&-H87(@*B!T;7!"=69!8V5S<V\@/2!S=')S='(H9&%D;W-2
M96-E8FED;W,L(")A8V5S<V\@<F5S=')I=&\B*3L-"B @(" @(" @(" @(" @
M("!I9B H=&UP0G5F06-E<W-O(#T]($Y53$PI('L-"B @(" @(" @(" @(" @
M(" @(" @<F5S3&]G:6X@/2 Q.PT*(" @(" @(" @(" @(" @('T-"B @(" @
M(" @(" @('T-"B @(" @(" @?0T*(" @('T-"@T*(" @("\J(%9A;6]S(&QI
M;7!A<B!D82!M96UO<FEA("HO#0H@(" @:68@*&1A9&]S1F]R;2 A/2!.54Q,
M*2![#0H@(" @(" @(&9R964H9&%D;W-&;W)M*3L-"B @("!]#0H@(" @:68@
M*&1A9&]S4F5C96)I9&]S("$]($Y53$PI('L-"B @(" @(" @+RH@06\@;&EM
M<&%R(&1A9&]S4F5C96)I9&]S(&5S=&%R96UO<R!L:6UP86YD;R!T;7!"=69(
M='1P( T*(" @(" @(" @("!E('1M<$)U9DQO8V%T:6]N("HO#0H@(" @(" @
M(&9R964H9&%D;W-296-E8FED;W,I.PT*(" @('T-"B @("!R971U<FX@<F5S
M3&]G:6X[#0H-"GT-"@T*+RH@07!O<R!A=71E;G1I8V%D;RP@;V)T96T@;R!R
M86YK:6YG(&UO<W1R861O(&YA(&AO;64@9&\@5D],("HO#0IL;VYG(&]B=&5R
M4F%N:VEN9RAC:&%R("H@8V]O:VEE*2![#0H-"B @(" O*B!686UO<R!O8G1E
M<B!A(&AO;64@*B\-"B @("!P<FEN=&8H(D]B=&5N9&\@<F%N:VEN9R!A('!A
M<G1I<B!D82!H;VUE("XN+EQN(BD[#0H@(" @;&]N9R!R86YK:6YG(#T@,#L-
M"B @("!C:&%R("H@9&%D;W-(;VUE(#T@;V)T97)086=I;F$H<V-R:7!T2&]M
M92P@3E5,3"P@8V]O:VEE*3L-"@T*(" @(&-H87(@*B!P;W-286YK(#T@<W1R
M<W1R*&1A9&]S2&]M92P@(E)A;FMI;F<Z(#QB/B(I.PT*(" @(&EF("AP;W-2
M86YK("$]($Y53$PI('L@#0H@(" @(" @(&-H87(@*B!P;W-&:6U286YK(#T@
M<W1R<W1R*'!O<U)A;FLL("*P(BD[#0H@(" @(" @(&EF("AP;W-&:6U286YK
M("$]($Y53$PI('L-"B @(" @(" @(" @(&EN="!T86U286YK(#T@<W1R;&5N
M*'!O<U)A;FLI("T@<W1R;&5N*'!O<T9I;5)A;FLI("T@,3([#0H@(" @(" @
M(" @("!C:&%R("H@=&UP4F%N:R ]("AC:&%R("HI(&UA;&QO8RAS:7IE;V8H
M8VAA<BD@*B H=&%M4F%N:R K(#$I*3L-"B @(" @(" @(" @(&EF("AT;7!2
M86YK(#T]($Y53$PI('L-"B @(" @(" @(" @(" @("!P<FEN=&8H(D9A;'1A
M(&1E(&UE;6]R:6$N7&XB*3L-"B @(" @(" @(" @(" @("!E>&ET*"TQ*3L-
M"B @(" @(" @(" @('T-"B @(" @(" @(" @('-T<FYC<'DH=&UP4F%N:RP@
M<&]S4F%N:R K(#$R+"!T86U286YK*3L-"B @(" @(" @(" @('1M<%)A;FM;
M=&%M4F%N:UT@/2 P.PT*#0H@(" @(" @(" @(" O*B!!9V]R82!D979E;6]S
M(&-O;G9E<G1E<B!P87)A(&QO;F<@#0H@(" @(" @(" @(" @("!E(&1E<&]I
M<R!L:6UP87(@9&$@;65M;W)I82 J+PT*(" @(" @(" @(" @<F%N:VEN9R ]
M('-T<G1O;"AT;7!286YK+"!.54Q,+" Q,"D[#0H@(" @(" @(" @("!I9B H
M=&UP4F%N:R A/2!.54Q,*2![#0H@(" @(" @(" @(" @(" @9G)E92AT;7!2
M86YK*3L-"B @(" @(" @(" @('T-"B @(" @(" @?0T*(" @('T-"@T*(" @
M("\J($YA;R!P<F5C:7-A;6]S(&UA:7,@9&]S(&1A9&]S(&1A(&AO;64@*B\-
M"B @(" O*B!!=71O;6%T:6-A;65N=&4@97-T87)E;6]S(&QI;7!A;F1O('!O
M<U)A;FL@92!P;W-&:6U286YK("HO#0H@(" @:68@*&1A9&]S2&]M92 A/2!.
M54Q,*2![#0H@(" @(" @(&9R964H9&%D;W-(;VUE*3L-"B @("!]#0H@(" @
M<F5T=7)N(')A;FMI;F<[#0I]#0H-"B\J($9U;F-A;R!P87)A(&-O;F5C=&%R
M(&YO(&AO<W0@*B\-"FEN="!A8G)I<D-O;F5X86\H8VAA<B J('-E<G9I9&]R
M0V]N97AA;RP@:6YT('!O<G1A0V]N97AA;RD@>PT*(" @("-I9F1E9B!724XS
M,@T*(" @(" @("!74T%$051!('=S841A=&$[#0H@(" @(" @(%=/4D0@=U9E
M<G-I;VY297%U97-T960[#0H@(" @(" @(&EN="!E<G([#0H-"B @(" @(" @
M=U9E<G-I;VY297%U97-T960@/2!-04M%5T]21"@R+" P*3L-"B @(" @(" @
M97)R(#T@5U-!4W1A<G1U<"AW5F5R<VEO;E)E<75E<W1E9"P@)G=S841A=&$I
M.PT*(" @(" @("!I9B H97)R("$](# I('L-"B @(" @(" @(" @(&9P<FEN
M=&8H<W1D97)R+" B3F%O(&%C:&]U(%=I;E-O8VL@1$Q,+EQN(BD[#0H@(" @
M(" @(" @("!E>&ET*"TQ*3L-"B @(" @(" @?0T*(" @("-E;F1I9@T*#0H@
M(" @:6YT(&UE=5-O8VME=#L-"B @("!S=')U8W0@<V]C:V%D9')?:6X@<V]C
M:T%D9'([#0H@(" @<W1R=6-T(&AO<W1E;G0@*FA%;G0[#0H-"B @(" O*B!6
M86UO<R!O8G1E<B!O<R!D861O<R!D;R!H;W-T("HO#0H@(" @:$5N=" ](&=E
M=&AO<W1B>6YA;64H<V5R=FED;W)#;VYE>&%O*3L-"B @("!I9B H:$5N=" ]
M/2!.54Q,*2![#0H@(" @(" @('!R:6YT9B@B17)R;R!A;R!O8G1E<B!O<R!D
M861O<R!D;R!H;W-T+EQN(BD[#0H@(" @(" @(&5X:70H+3$I.PT*(" @('T-
M"@T*(" @("\J($%G;W)A('9A;6]S(&]B=&5R(&\@<V]C:V5T("HO#0H@(" @
M;65U4V]C:V5T(#T@<V]C:V5T*$%&7TE.150L(%-/0TM?4U1214%-+"!G971P
M<F]T;V)Y;F%M92@B=&-P(BDM/G!?<')O=&\I.PT*(" @(&EF("AM9753;V-K
M970@/3T@+3$I('L-"B @(" @(" @<')I;G1F*")%<G)O(&%O(&]B=&5R('-O
M8VME="!T8W N7&XB*3L-"B @(" @(" @97AI="@M,2D[#0H@(" @?0T*#0H@
M(" @+RH@5F%M;W,@9&5F:6YI<B!O(%1#4%].3T1%3$%9("AU<V%D;R!P87)A
M(&-O;75N:6-A8V]E<R!D92!I9&$@92 -"B @(" @("!V;VQT82!P87)A(&UE
M;&AO<F%R(&$@<&5R9F]R;6%N8V4I(" J+PT*(" @(&EN="!F;&%G5&-P3F]$
M96QA>2 ](#$[#0H@(" @:6YT(')E<U1C<$YO1&5L87D@/2!S971S;V-K;W!T
M*&UE=5-O8VME="P@25!04D]43U]40U L(%1#4%].3T1%3$%9+ T*(" @(" @
M(" H8VAA<B J*2 F9FQA9U1C<$YO1&5L87DL('-I>F5O9BAI;G0I*3L-"B @
M("!I9B H<F5S5&-P3F]$96QA>2 \(# I('L-"B @(" @(" @<')I;G1F*")%
M<G)O(&%O('-E=&%R('1C<%]N;V1E;&%Y+EQN(BD[#0H@(" @(" @(&5X:70H
M+3$I.PT*(" @('T-"B @(" -"B @(" O*B!686UO<R!D969I;FER('1A;6)E
M;2!O('1I;65O=70@9&\@<V]C:V5T( T*(" @(" @("A6;V-E('!O9&4@<')E
M8VES87(@;75D87(@96T@<F5D97,@;&5N=&%S*2 J+PT*(" @('-T<G5C="!T
M:6UE=F%L('1V.PT*(" @(&EN="!T:6UE;W5T<R ](# [#0H@(" @='8N='9?
M<V5C(#T@,SL-"B @("!T=BYT=E]U<V5C(#T@,#L-"B @("!I9B H<V5T<V]C
M:V]P="AM9753;V-K970L(%-/3%]33T-+150L(%-/7U)#5E1)345/+" -"B @
M(" @(" @(" @("AC:&%R("HI("9T=BP@<VEZ96]F('1V*2D@>PT*(" @(" @
M("!P<FEN=&8H(D5R<F\@86\@9&5F:6YI<B!T:6UE;W5T+B(I.PT*(" @(" @
M("!E>&ET*"TQ*3L-"B @("!]#0H-"B @(" O*B!%;G1A;R!C;VYE8W1A;6]S
M("HO#0H@(" @;65M8W!Y*"9S;V-K061D<BYS:6Y?861D<BP@:$5N="T^:%]A
M9&1R+"!H16YT+3YH7VQE;F=T:"D[#0H@(" @<V]C:T%D9'(N<VEN7V9A;6EL
M>2 ]($%&7TE.150[#0H@(" @<V]C:T%D9'(N<VEN7W!O<G0@/2!H=&]N<RAP
M;W)T84-O;F5X86\I.PT*(" @(&EF("AC;VYN96-T*&UE=5-O8VME="P@*'-T
M<G5C="!S;V-K861D<B J*2 F<V]C:T%D9'(L( T*(" @(" @(" @(" @<VEZ
M96]F*'-O8VM!9&1R*2D@/" P*2![#0H@(" @(" @('!R:6YT9B@B17)R;R!A
M;R!C;VYE8W1A<B!N;R!S97)V:61O<BY<;B(I.PT*(" @(" @("!E>&ET*"TQ
M*3L-"B @("!]#0H-"B @(" O*B!%('9O;'1A;6]S(&\@<V]C:V5T(&-O;F5C
M=&%D;R J+PT*(" @(')E='5R;B!M9753;V-K970[#0I]#0H-"B\J($5S=&$@
M9G5N8V%O(&]B=&5M('5M(&AE861E<B!H='1P("HO#0IC:&%R("H@;V)T97)(
M96%D97)(='1P*&-H87(@*B!S97)V:61O<D-O;F5X86\L(&-H87(@*B!C;V]K
M:64I('L-"@T*(" @("\J(%9A;6]S('5S87(@=6T@8G5F9F5R(&=R86YD92 H
M,FMB(&YA;R!T96T@<&5R:6=O(&1E(&5S=&]U<F%R*2 J+PT*(" @(&-H87(@
M*B!H96%D97)(='1P(#T@*&-H87(@*BD@;6%L;&]C*'-I>F5O9BAC:&%R*2 J
M(#(P-#@I.PT*(" @(&EF("AH96%D97)(='1P(#T]($Y53$PI('L-"B @(" @
M(" @<')I;G1F*")&86QT82!D92!M96UO<FEA+EQN(BD[#0H@(" @(" @(&5X
M:70H+3$I.PT*(" @('T-"B @("!S=')C<'DH:&5A9&5R2'1T<"P@(DAO<W0Z
M("(I.PT*(" @('-T<F-A="AH96%D97)(='1P+"!S97)V:61O<D-O;F5X86\I
M.PT*(" @('-T<F-A="AH96%D97)(='1P+" B7&XB*3L-"B @("!S=')C870H
M:&5A9&5R2'1T<"P@(E5S97(M06=E;G0Z($UO>FEL;&$O-2XP("(I.PT*(" @
M('-T<F-A="AH96%D97)(='1P+" B6#$Q.R!5.R!,:6YU>"!I-C@V.R!E;BU5
M4SL@<G8Z,2XX+C$N,30I7&XB*3L-"B @("!S=')C870H:&5A9&5R2'1T<"P@
M(D%C8V5P=#H@=&5X="]X;6PL=&5X="]H=&UL.W$],"XY+'1E>'0O<&QA:6X[
M(BD[#0H@(" @<W1R8V%T*&AE861E<DAT=' L(")Q/3 N."QI;6%G92]P;F<L
M*B\J.W$],"XU7&XB*3L-"B @("!S=')C870H:&5A9&5R2'1T<"P@(D%C8V5P
M="U,86YG=6%G93H@96XM=7,L96X[<3TP+C5<;B(I.R -"B @("!S=')C870H
M:&5A9&5R2'1T<"P@(D%C8V5P="U#:&%R<V5T.B!)4T\M.#@U.2TQ+'5T9BTX
M.W$],"XW+"H[<3TP+C=<;B(I.PT*(" @('-T<F-A="AH96%D97)(='1P+" B
M2V5E<"U!;&EV93H@,S P7&XB*3L-"B @("!I9B H8V]O:VEE("$]($Y53$PI
M('L-"B @(" @(" @<W1R8V%T*&AE861E<DAT=' L(")#;V]K:64Z("(I.PT*
M(" @(" @("!S=')C870H:&5A9&5R2'1T<"P@8V]O:VEE*3L-"B @(" @(" @
M<W1R8V%T*&AE861E<DAT=' L("([7&XB*3L-"B @("!]#0H@(" @<W1R8V%T
M*&AE861E<DAT=' L(")#;VYN96-T:6]N.B!K965P+6%L:79E7&XB*3L-"B @
M("!H96%D97)(='1P6W-T<FQE;BAH96%D97)(='1P*5T@/2 P.PT*(" @(')E
M='5R;B!H96%D97)(='1P.PT*?0T*#0HO*B!&=6YC86\@<&%R82!E;G9I87(@
M9&%D;W,@=FEA('-O8VME=" J+PT*=F]I9"!E;G9I87)$861O<RAI;G0@<V]C
M:V5T+"!C:&%R("H@8G5F9F5R*2![#0H@(" @:6YT(&5N=FEO(#T@<V5N9"AS
M;V-K970L(&)U9F9E<BP@<W1R;&5N*&)U9F9E<BDL(# I.PT*(" @(&EF("AE
M;G9I;R \(#$I('L-"B @(" @(" @<')I;G1F*")%<G)O(&YO(&5N=FEO(&1O
M<R!D861O<SH@6R5D72Y<;B(L(&5N=FEO*3L-"B @(" @(" @97AI="@M,2D[
M#0H@(" @?0T*?0T*#0HO*B!&=6YC86\@<&%R82!R96-E8F5R(&1A9&]S('9I
M82!S;V-K970N( T*5F%M;W,@=')A8F%L:&%R(&-O;2!A;&]C86-A;R!D:6YA
M;6EC82X-"D5S=&$@9G5N8V%O(')E=&]R;F$@=6T@<&]N=&5I<F\@<&%R82!O
M<R!D861O<R!R96-E8FED;W,-"BHO#0IC:&%R("H@<F5C96)E<D1A9&]S*&EN
M="!S;V-K970I('L-"B @("!C:&%R("H@9&%D;W,@/2 H8VAA<B J*2!M86QL
M;V,H<VEZ96]F*&-H87(I("H@,3 R-2D[#0H@(" @:68@*&1A9&]S(#T]($Y5
M3$PI('L-"B @(" @(" @<')I;G1F*")&86QT82!D92!M96UO<FEA+EQN(BD[
M#0H@(" @(" @(&5X:70H+3$I.PT*(" @('T-"B @("!I;G0@8V]N=$)U9B ]
M(# [#0H@(" @=VAI;&4@*"AC;VYT0G5F(#T@<F5C=BAS;V-K970L(&)U9F9E
M<BP@,3 R-"P@,"DI(#X@,"D@>PT*(" @(" @(" O*B!087)A(&UO<W1R87(@
M<75E(&5S=&$@<F5C96)E;F1O(&%L9W5M82!C;VES82 J+PT*(" @(" @("!P
M=71C:&%R*#0R*3L-"B @(" @(" @9F9L=7-H*'-T9&]U="D[#0H-"B @(" @
M(" @+RH@061I8VEO;F$@86\@8G5F9F5R('-E('!O<W-I=F5L("HO#0H@(" @
M(" @(&)U9F9E<EMC;VYT0G5F72 ](# [#0H@(" @(" @(" @(" @(" @#0H@
M(" @(" @(&EF("AD861O<R ]/2!.54Q,*2![#0H@(" @(" @(" @("!S=')C
M<'DH9&%D;W,L(&)U9F9E<BD[#0H@(" @(" @('T@96QS92![#0H@(" @(" @
M(" @(" O*B!296%L;V-A;6]S(&UA:7,@,6MB("HO#0H@(" @(" @(" @("!D
M861O<R ](')E86QL;V,H9&%D;W,L('-T<FQE;BAD861O<RD@*R Q,#(U*3L-
M"B @(" @(" @(" @(&EF("AD861O<R ]/2!.54Q,*2![#0H@(" @(" @(" @
M(" @(" @<')I;G1F*")%<G)O(&YA(')E86QO8V%C86\@9&EN86UI8V$N7&XB
M*3L-"B @(" @(" @(" @(" @("!E>&ET*"TQ*3L-"B @(" @(" @(" @('T-
M"B @(" @(" @(" @('-T<F-A="AD861O<RP@8G5F9F5R*3L-"B @(" @(" @
M?2 @(" @#0H-"B @(" @(" @+RH@3&EM<&%R(&)U9F9E<B J+PT*(" @(" @
M("!I;G0@;B ](# [(" @(" @(" -"B @(" @(" @9F]R*&X@/2 P.R!N(#P]
M(#$P,C0[(&XK*RD@>PT*(" @(" @(" @(" @8G5F9F5R6VY=(#T@,#L-"B @
M(" @(" @?0T*(" @('T-"B @("!D861O<UMS=')L96XH9&%D;W,I72 ](# [
M#0H@(" @<F5T=7)N(&1A9&]S.PT*?0T*#0HO*B!/8G1E;2!O<R!D861O<R!D
M92!U;6$@<&%G:6YA(&AT;6P@*B\-"F-H87(@*B!O8G1E<E!A9VEN82AC:&%R
M("H@<V-R:7!T+"!C:&%R("H@9&%D;W-&;W)M+"!C:&%R("H@8V]O:VEE*2![
M#0H-"B @("!I;G0@;65U4V]C:V5T.PT*(" @('!R:6YT9B@B0V]N96-T86YD
M;SH@*"5S*2 N+BX@7&XB+"!S97)V:61O<BD[#0H@(" @;65U4V]C:V5T(#T@
M86)R:7)#;VYE>&%O*'-E<G9I9&]R+"!P;W)T85-E<G9I9&]R*3L-"B @("!I
M9B H;65U4V]C:V5T(#T]("TQ*2![#0H@(" @(" @('!R:6YT9B@B17)R;R!A
M;R!C;VYE8W1A<B!N;R!S97)V:61O<BY<;B(I.PT*(" @(" @("!E>&ET*"TQ
M*3L-"B @("!]#0H-"B @(" O*B!686UO<R!O8G1E<B!O(&AE861E<B J+PT*
M(" @(&-H87(@*B!H96%D97)(='1P(#T@;V)T97)(96%D97)(='1P*'-E<G9I
M9&]R+"!C;V]K:64I.PT*#0H@(" @+RH@5F%M;W,@9V5R87(@;R!P;W-T(&1E
M(&5N=FEO("HO#0H@(" @:68@*&1A9&]S1F]R;2 ]/2!.54Q,*2![#0H@(" @
M(" @('-P<FEN=&8H8G5F16YV:6\L(")'150@)7,@2%144"\Q+C%<;B(L('-C
M<FEP="D[#0H@(" @?2!E;'-E('L-"B @(" @(" @<W!R:6YT9BAB=69%;G9I
M;RP@(E!/4U0@)7,@2%144"\Q+C%<;B(L('-C<FEP="D[#0H@(" @?0T*(" @
M(&EF("@H<W1R;&5N*&)U9D5N=FEO*2 K('-T<FQE;BAH96%D97)(='1P*2D@
M/B!"549?,S)+0E]73U)+*2![#0H@(" @(" @('!R:6YT9B@B17)R;R!D92!E
M<W1O=7)O(&1E(&)U9F9E<BY<;B(I.PT*(" @(" @("!E>&ET*"TQ*3L-"B @
M("!]#0H@(" @<W1R8V%T*&)U9D5N=FEO+"!H96%D97)(='1P*3L-"B @(" -
M"B @(" O*B!686UO<R!L:6UP87(@9&$@;65M;W)I82 J+R @(" -"B @("!I
M9B H:&5A9&5R2'1T<" A/2!.54Q,*2![#0H@(" @(" @(&9R964H:&5A9&5R
M2'1T<"D[#0H@(" @?2 @(" -"@T*(" @("\J(%1E;6]S(&1E(&%D:6-I;VYA
M<B!A;&=U;6%S(&EN9F]R;6%C;V5S('!A<F$@;6%N9&%R(&\@9F]R;2 J+PT*
M(" @(&EF("AD861O<T9O<FT@(3T@3E5,3"D@>PT*(" @(" @("!I9B H*'-T
M<FQE;BAB=69%;G9I;RD@*R V-"D@/B!"549?,S)+0E]73U)+*2![#0H@(" @
M(" @(" @("!P<FEN=&8H(D5R<F\@9&4@97-T;W5R;R!D92!B=69F97(N7&XB
M*3L-"B @(" @(" @(" @(&5X:70H+3$I.PT*(" @(" @("!]#0H@(" @(" @
M('-T<F-A="AB=69%;G9I;RP@(D-O;G1E;G0M5'EP93H@87!P;&EC871I;VXO
M>"UW=W<M9F]R;2UU<FQE;F-O9&5D7&XB*3L-"@T*(" @(" @("!S=')C870H
M8G5F16YV:6\L(")#;VYT96YT+4QE;F=T:#H@(BD[#0H@(" @(" @(&-H87(@
M*B!T;7!"=68@/2 H8VAA<B J*2!M86QL;V,H<VEZ96]F*&-H87(I("H@,3 R
M-"D[#0H@(" @(" @(&EF("AT;7!"=68@/3T@3E5,3"D@>PT*(" @(" @(" @
M(" @<')I;G1F*")&86QT82!D92!M96UO<FEA+EQN(BD[#0H@(" @(" @(" @
M("!E>&ET*"TQ*3L-"B @(" @(" @?0T*(" @(" @("!S<')I;G1F*'1M<$)U
M9BP@(B5D(BP@<W1R;&5N*&1A9&]S1F]R;2DI.PT*(" @(" @("!I9B H*'-T
M<FQE;BAB=69%;G9I;RD@*R!S=')L96XH=&UP0G5F*2 K(#(I(#X@0E5&7S,R
M2T)?5T]22RD@>PT*(" @(" @(" @(" @<')I;G1F*")%<G)O(&1E(&5S=&]U
M<F\@9&4@8G5F9F5R+EQN(BD[#0H@(" @(" @(" @("!E>&ET*"TQ*3L-"B @
M(" @(" @?0T*(" @(" @("!S=')C870H8G5F16YV:6\L('1M<$)U9BD[#0H@
M(" @(" @('-T<F-A="AB=69%;G9I;RP@(EQN(BD[#0H@(" @(" @(&EF("AT
M;7!"=68@(3T@3E5,3"D@>PT*(" @(" @(" @(" @9G)E92AT;7!"=68I.PT*
M(" @(" @("!]#0H@(" @?0T*(" @('-T<F-A="AB=69%;G9I;RP@(EQN(BD[
M#0H-"B @(" O*B!!<FUA>F5N82!O<R!D861O<R!D;R!F;W)M("HO( T*(" @
M(&EF("AD861O<T9O<FT@(3T@3E5,3"D@>PT*(" @(" @("!I9B H*'-T<FQE
M;BAB=69%;G9I;RD@*R!S=')L96XH9&%D;W-&;W)M*2D@/B!"549?,S)+0E]7
M3U)+*2![#0H@(" @(" @(" @("!P<FEN=&8H(D5R<F\@9&4@97-T;W5R;R!D
M92!B=69F97(N7&XB*3L-"B @(" @(" @(" @(&5X:70H+3$I.PT*(" @(" @
M("!]#0H@(" @(" @('-T<F-A="AB=69%;G9I;RP@9&%D;W-&;W)M*3L-"B @
M("!]#0H-"B @(" O*B!%;G9I82!O<R!D861O<R J+PT*(" @(&5N=FEA<D1A
M9&]S*&UE=5-O8VME="P@8G5F16YV:6\I.PT*(" @('!R:6YT9B@B1&%D;W,@
M9F]R86T@96YV:6%D;W,L(')E8V5B96YD;R!D861O<R N+BY<;B(I.PT*(" @
M(&-H87(@*B!D861O<U)E8V5B:61O<R ](')E8V5B97)$861O<RAM9753;V-K
M970I.R @( T*(" @("-I9F1E9B!724XS,@T*(" @(" @("!C;&]S97-O8VME
M="AM9753;V-K970I.PT*(" @(" @("!74T%#;&5A;G5P*"D[#0H@(" @(V5L
M<V4-"B @(" @(" @8VQO<V4H;65U4V]C:V5T*3L-"B @(" C96YD:68-"B @
M("!P<FEN=&8H(EQN(BD[#0H-"B @("!R971U<FX@9&%D;W-296-E8FED;W,[
%#0I]#0H!

end




01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts