Lab de Processos e Bibliotecas¶
No lab de Sistemas Operacionais iremos trabalhar com bibliotecas e processos para a criação de um programa similar ao wget
. Nosso programa, chamado de web_downloader
, fará download de páginas web usando a biblioteca libCurl
.
Restrições¶
Este exercício serve como avaliação dos conceitos vistos na disciplina. Portanto, algumas restrições serão aplicadas aos código de vocês:
- todo trabalho com arquivos deverá ser feito usando as APIs POSIX vistas em aula
- seu programa deverá compilar sem warnings usando as opções
-Wall -Wno-unused-result -Og -g -lcurl
- você deverá usar a biblioteca
libCurl
para realizar o download das páginas. Veja sua documentação para aprender a usá-la - se você usar algum trecho de código da documentação (ou de outra fonte), coloque uma atribuição em um comentário no código.
Entrega¶
Você deverá colocar sua entrega na pasta lab/lab-processos
em seu repositório de atividades, na branch principal. Não precisa soltar release/tag.
Avaliação¶
O programa será avaliado de forma manual usando uma rubrica que descreve as funcionalidades implementadas. Quanto maior o número de funcionalidades maior será a nota.
Conceito I (zero)¶
- O programa não compila
- O programa não implementa algum dos requisitos da rubrica D.
Conceito D (4,0)¶
- O programa compila com warnings.
- O programa roda na linha de comando como abaixo, salvando o resultado como
exemplo_com_pagina.html
, ou seja, ignorandohttp://
ehttps://
, substituindo todas barras e pontos (exceto o último) por_
.
$> web_downloader http://exemplo.com/pagina.html
Conceito C (6,0)¶
- O programa compila sem warnings.
- O programa recebe uma flag
-f
seguida pelo nome de um arquivo. Seu programa deverá ler o arquivo e fazer o download de cada url dentro do arquivo. Você pode supor que cada linha do arquivo contém exatamente uma URL. As regras para o nome do arquivo correspondente são as mesmas do item anterior.
$> web_downloader -f lista_download.txt
- O download de cada página é feito em um processo separado e em paralelo. Você deve observar uma diminuição grande no tempo de download de páginas pequenas.
- Ao terminar de baixar uma página, você deverá mostrar a mensagem "{url} baixada com sucesso!"
Conceito B (8,0)¶
- O processo principal só termina depois que todos os arquivos foram baixados.
- O programa abre até
N
processos em paralelo. Se houver mais queN
urls então os processos deverão sempre existir no máximoN+1
processos (N
para fazer download mais o original). Esse valor é passado pela linha de comando via flag-N
. Se nada for passado assumaN=4
.
Conceito A (10,0)¶
- As mensagens de finalização de baixar uma página são mostradas sem estar embaralhadas mesmo se vários processos terminarem ao mesmo tempo.
- Ao apertar Ctrl+C o programa pergunta se o usuário deseja realmente sair. Se sim, todas as transferências são paradas e os arquivos que não foram baixados até o fim são deletados.
- Se o download falhar por alguma razão seu programa deverá mostrar a mensagem "{url} não pode ser baixada.". Nenhum arquivo deverá ser produzido neste caso.
Obs: Considere os conceitos como cumulativos, ou seja, cada versão deve manter as funcionalidades do conceito anterior e acrescentar novas. Ex: a versão do conceito B também deve funcionar com download direto passando apenas a URL (sem -f arquivo
).
Prazo:¶
Dicas:¶
- Instale o pacote libcurl4-openssl-dev
$ sudo apt install libcurl4-openssl-dev
-
Exemplo muuuuuito simples para começar:
/* Compile: gcc downloaderExemplo.c -o downloaderExemplo -Wall -Wno-unused-result -Og -g -lcurl Teste: ./downloaderExemplo https://www.vivabonito.com.br/wp-content/uploads/2022/01/Gruta-do-Mimoso-5.jpg mimoso.jpg Referência: https://curl.se/libcurl/c/simple.html */ #include<stdio.h> #include<curl/curl.h> int main(int argc, char **argv) { CURL *curl; FILE *fp; int resultado; curl = curl_easy_init(); if(curl) { if(argc != 3) { printf("ERRO: use o downloader assim:\n\n./downloaderExemplo URL NOME_ARQUIVO_LOCAL\n"); return -1; } // segundo parâmetro é nome do arquivo a ser gravado fp = fopen(argv[2], "wb"); // primeiro parâmetro é URL a ser baixada curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0"); curl_easy_setopt(curl, CURLOPT_URL, argv[1]); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); // faça o download resultado = curl_easy_perform(curl); if(resultado == CURLE_OK) printf("Arquivo baixado corretamente\n"); else printf("ERRO: %s\n", curl_easy_strerror(resultado)); fclose(fp); curl_easy_cleanup(curl); } return 0; }
-
Veja outro exemplo em: https://curl.se/libcurl/c/10-at-a-time.html. Compile-o assim:
$ gcc testeCurl.c -o testeCurl -Wall -Wno-unused-result -Og -g -lcurl