Prezado Augusto:
 
Segue abaixo o tutorial mencionado:
 
Em função do numero de e-mails que recebi referente ao tutorial do mirror de atualização do AVG, acho que vale a pena notificar algumas modificações feita pela Grisoft.

Torne o seu servidor um mirror de atualização do Antivírus AVG (atualizado com as alterações da Grisoft)

Em setembro, elaborei um tutorial que permitia transformar um servidor Linux em um mirror de atualização do AVG, com atualização automática permitindo que as estações clientes façam seus upgrades sem que cada uma delas precise fazer o download diretamente da Internet. Entretanto a Grisoft alterou a estrutura de pasta no seu link de atualização (divisão do link em
http://files.grisoft.cz/softw/60/xx/ e http://files.grisoft.cz/softw/60/fe/).

 
Pelo o que eu entendi, estas mudanças foi para diminuir os arquivos de atualização e dividi-los em duas etapas. Assim sendo a primeira atualização será feitas duas vezes. Mas apartir desde ponto as atualizações serão executadas apenas na fase necessária (diminuindo o tempo e o fluxo da atuliazação).
 
Aproveitando fiz algumas modificações no tutorial.
1.. Torna-lo compartivel com esta divisão de links
2.. Apagar os arquivos das atualizações anteriores.
3.. Enviar emails (programa em java) para as contas configurada avisando a existência da nova versão .
4.. Enviar emails (programa em java) aos administradores quando houver algum erro no processo de copia do arquivos.

** Usei o java para enviar o e-mail, pois vou pretendo usar a minha base
de dados de cliente em interbase como destinatário.


Criando o mirror da AVG:

 
Em primeiro lugar, este tutorial parte do princípio que o serviço apache está devidamente configurado. Vamos ao diretório padrão principal do apache e criaremos as demais pastas:

 
[root@servidorproxy /]# mkdir -p softw softw/60 softw/60/fe
[root@servidorproxy /]# mkdir -p softw softw/60 softw/60/xx

 
Agora vamos efetuar o download de todo o conteudo do site da grisoft:
Download do link 1:

 
[root@servidorproxy /]# cd /home/httpd/html/softw/60/fe
[root@servidorproxy fe]#
[root@servidorproxy fe]# wget -r -nd http://files.grisoft.cz/softw/60/fe
--12:05:54-- http://10.0.0.253/icons/back.gif
=> `back.gif'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 216 [image/gif]
0K 100% 0:00 216K
12:05:54 (70,31 KB/s) - `back.gif' recebido [216/216]

 

 
--12:05:54-- http://10.0.0.253/softw/60/fe/avg6info.ctf
=> `avg6info.ctf'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 346 [text/plain]
0K 100% 0:00 346K
12:05:54 (168,95 KB/s) - `avg6info.ctf' recebido [346/346]

 

 
--12:05:54-- http://10.0.0.253/softw/60/fe/d602xbmj.bin
=> `d602xbmj.bin'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 3,154,835 [application/octet-stream]
0K .......... .......... .......... .......... .......... 1% 0:02 1,38M
50K .......... .......... .......... .......... .......... 3% 0:03 800K
100K .......... .......... .......... .......... .......... 4% 0:01 1,83M
150K .......... .......... .......... .......... .......... 6% 0:03 966K
“” “” “”
“” “” “”
“” “” “”

 
3000K .......... .......... .......... .......... .......... 98% 0:00 826K
3050K .......... .......... .......... 100% 0:00 142K
12:08:13 (613,48 KB/s) - `d602xbmj.bin.1' recebido [3154835/3154835]

 

 
FINALIZADO --12:08:13--
Baixados: 3,154,835 bytes em 1 arquivos

 
Download do link 2:

 
[root@servidorproxy fe]# cd /home/httpd/html/softw/60/xx
[root@servidorproxy xx]#

 

 
[root@servidorproxy fe]# wget -r -nd http://files.grisoft.cz/softw/60/xx
--12:05:54-- http://10.0.0.253/icons/back.gif
=> `back.gif'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 216 [image/gif]
0K 100% 0:00 216K
12:05:54 (70,31 KB/s) - `back.gif' recebido [216/216]

 

 
--12:05:54-- http://10.0.0.253/softw/60/xx/avg6info.ctf
=> `avg6info.ctf'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 346 [text/plain]
0K 100% 0:00 346K
12:05:54 (168,95 KB/s) - `avg6info.ctf' recebido [346/346]

 

 
--12:05:54-- http://10.0.0.253/softw/60/xx/c602xemg.bin
=> `c602xemg.bin'
Conectando-se a 10.0.0.253:80... conectado!
Requisição enviada ao servidor HTTP, esperando resposta... 200 OK
Tamanho: 3,154,835 [application/octet-stream]
0K .......... .......... .......... .......... .......... 1% 0:02 1,38M
50K .......... .......... .......... .......... .......... 3% 0:03 800K
100K .......... .......... .......... .......... .......... 4% 0:01 1,83M
150K .......... .......... .......... .......... .......... 6% 0:03 966K
“” “” “”
“” “” “”
“” “” “”

 
3000K .......... .......... .......... .......... .......... 98% 0:00 826K
3050K .......... .......... .......... 100% 0:00 142K
12:08:13 (613,48 KB/s) - `d602xbmj.bin.1' recebido [3154835/3154835]

 

 
FINALIZADO --12:08:13--
Baixados: 3,154,835 bytes em 1 arquivos

 
Agora vamos mudar os direitos dos arquivos baixados para execução e leitura para o grupo e demais usuáriao, e poder total ao dono:

 
[root@servidorproxy xx]#
[root@servidorproxy /]# cd /home/httpd/html/
[root@servidorproxy html]# chmod -R 2755 softw

 

 
Pronto neste ponto o seu servidor está preparado para atendere as atualizações cliente do AVG Antivirus.
Para testar digite em algum browse o ip do seu servidor + “softw/60/fe”

 
Exemplo: http://10.0.0.255/softw/60 softw/60/fe

 
Agora confira com o conteudo da Grisoft:

 
http://files.grisoft.cz/softw/60/fe/

 
Configurando as estações:

 
Agora vamos configurar as estações windows, mudando o conteúdo do arquivo URL.INI. Para facilitar o exemplo, vamos supor que o servidor tenha o seguinte IP da placa de rede da intranet : 10.0.0.253.
No prompt do DOS siga os seguintes passos:

 
Microsoft(R) Windows 98
(C)Copyright Microsoft Corp 1981-1997.

 
C:\WINDOWS>cd \arquiv~1\grisoft\avg6
C:\Arquivos de programas\Grisoft\AVG6>edit url.ini

 
Edite o arquivo deixando-o desta maneira:

 
[SERVER_NAME]
1=AVG Intranet

 
[SERVER_URL]
1=http://10.0.0.253/softw/60/fe
Actual URL=1

 

 
Pronto! Com este arquivo em mão, basta copia-lo nas outras estações e assim que o AVG for reiniciado ele já irá procurar a atualização na intranet.

 
A estrela deste tutorial (O Script):

 
Este script efetua o download do arquivo avg6info.ctf, que contém a lista dos arquivos de atualização, data e versão.
Após o download ele verifica se existem algum arquivo a ser baixado, verificando a existencia no disco de cada um deles.
Se o arquivo avg6info.ctf não foi baixado com sucesso, ele volta o seu backup.
Em caso de erro no processo de download, o script envia um e-mail aos administradores do sistemas, cujos e-mails deverão estar no arquivo adm.
Agora o se o todo o script de atualização foi executado com sucesso, será enviado um e-mail a todos os clientes definido no arquivos clientes. Os arquivos da atualização anterior serão apagado, para não consumir um significativo espaço em disco.

 
Criando o script principal, o updateAVG:

 
[root@servidorproxy /etc]# cd /bin
[root@servidorproxy /bin]# vi updateAVG

 
Coloque o seguinte conteúdo no arquivo:

 
-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo-| updateAVG |-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo

 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
HOME=/

 
# Criei 3 variaveis em disco em função da dificuldade de exportar os seus
# conteúdos após os loops deste scrips.
#
# As variaveis são:
# erro: seu conteudo informa se houve alguma erro durante a execução do script
# email: seu conteudo informa se havera enviao de e-mail
# apagar: esta variavel define se o script apagara os arquivos da atuliazação anterior

 
echo false > /tmp/erro.tmp
echo false > /tmp/email.tmp
echo false > /tmp/apagar.tmp

 
# Verificando o Link 1:
cd /home/httpd/html/softw/60/xx/

 
# Criando o Backup do arquivo
mv avg6info.ctf avg6info.ctf.old

 
# Download do arquivo de informação
wget -r -nd -t 3 -w 10 http://files.grisoft.cz/softw/60/xx/avg6info.ctf

 
# Loop de leitura do conteudo do arquivo
cat avg6info.ctf | grep bin | cut -c 2-13 > lista.txt

 
cat lista.txt | while read mArquivo
do
if [ ! -f $mArquivo ]
then
# Se o arquivo existir, faça o download
# Se ocorrer algum erro, seta a variavel, caso contrário muda o atributo do
# do arquivo e setar a variavel responsável para exclusão dos arquivo antigos
# e a variavel de envio de e-mail
wget -r -nd -t 3 -w 10 http://files.grisoft.cz/softw/60/xx/$mArquivo
if [ "$?" = "1" ];
then echo true > /tmp/erro.tmp
else chmod 755 $mArquivo
echo true > /tmp/apagar.tmp
fi
echo true > /tmp/email.tmp
fi
done

 

 
# ler o conetudo da variavel no disco
email=`cat /tmp/email.tmp`
erro=`cat /tmp/erro.tmp`
apagar=`cat /tmp/apagar.tmp`

 
# Se não houve nenhum erro, entre na rotina de exclusão dos arq. Antigos.
if [ "$erro" = "false" ]
then
if [ "$apagar" = "true" ]
then
# Se a variavel apagar estiver habilitada, entao proceda com
# a rotina de exclusão.
cat avg6info.ctf.old | grep bin | cut -c 2-13 > lista.txt
cat lista.txt | while read mArquivo
do
# Se o arquivo existir, então o apague!
if [ -f $mArquivo ]
then
rm -rf $mArquivo
fi
done
fi
# Apaga o antigo arquivo de informação
rm avg6info.ctf.old
else
# se houve erro, então volte o arquivo de informação antigo
rm -rf avg6info.ctf
mv avg6info.ctf.old avg6info.ctf
fi

 
# Desabilita a variavel apagar
echo false > /tmp/apagar.tmp

 
# Verificando o Link 1:
cd /rede/web/softw/60/fe/

 
# Criando o Backup do arquivo
mv avg6info.ctf avg6info.ctf.old

 
# Download do arquivo de informação
wget -r -nd -t 3 -w 10 http://files.grisoft.cz/softw/60/fe/avg6info.ctf

 
# Loop de leitura do conteudo do arquivo
cat avg6info.ctf | grep -v xx | grep bin | cut -c 2-13 > lista.txt
cat lista.txt | while read mArquivo ;
do
if [ ! -f $mArquivo ]
then
# Se o arquivo existir, faça o download
# Se ocorrer algum erro, seta a variavel, caso contrário muda o atributo do
# do arquivo e setar a variavel responsável para exclusão dos arquivo antigos
# e a variavel de envio de e-mail
wget -r -nd -t 3 -w 10 http://files.grisoft.cz/softw/60/fe/$mArquivo
if [ "$?" = "1" ];
then echo true > /tmp/erro.tmp
else chmod 755 $mArquivo
echo true > /tmp/apagar.tmp
fi
echo true > /tmp/email.tmp
fi

 
done
# ler o conetudo das variaveis no disco
email=`cat /tmp/email.tmp`
erro=`cat /tmp/erro.tmp`
apagar=`cat /tmp/apagar.tmp`
 
# Se não houve nenhum erro, entre na rotina de exclusão dos arq. Antigos.
if [ "$erro" = "false" ];
then
if [ "$apagar" = "true" ]
then
# Se a variavel apagar estiver habilitada, entao proceda com
# a rotina de exclusão.
cat avg6info.ctf.old | grep -v xx | grep bin | cut -c 2-13 > lista.txt
cat lista.txt | while read mArquivo
do
# Se o arquivo existir, então o apague!
if [ -f $mArquivo ]
then
rm -rf $mArquivo
fi
done
fi
# Apaga o antigo arquivo de informação
rm avg6info.ctf.old

 
if [ "$email" = "true" ]; then
# Se a variavel e-mail estiver setada entao envia email aos clientes
/bin/emailsok
fi
else
# se houve erro, então volte o arquivo de informação antigo
rm -rf avg6info.ctf
mv avg6info.ctf.old avg6info.ctf
if [ "$email" = "true" ]; then
# Se a variavel e-mail estiver setada entao envia email aos administradores
/bin/emailserro
fi
fi
-oOo-oOo-oOo-oOo-oOo-oOo-oOo-| Fim updateAVG |-oOo-oOo-oOo-oOo-oOo-oOo-oOo-oOo
Agora vamos dar o direitos de execução para o nosso script:

 
[root@servidorproxy /bin]# chmod 755 updadeAVG

 
O envio de e-mail (opcional):

 
Usei um programa em java para enviar os e-mails aos administradores e clientes. Caso você não utilize o java (e nem deseja), basta ignora este tópico e comentas as seguintes linhas dentro do script anterior:
/bin/emailserro
/bin/emailsok

 
O principal motivo do uso do java, foi a facilidade de efetuar a leitura em um banco de dados cliente-servidor para extrair a lista de clientes que receberão o aviso da existência da nova versão. Sendo assim muito simples a adaptação as necessecidades de cada empresa.

 
Estou partindo do principio que o java está corretamente instalado, em caso de dúvida existe tutoriais de instalação em www.vivaolinux.com.br e www.javafree.com.br.
Não podemos também esquecer da classe mail-API que pode ser baixado na seção de download em www.javafree.com.br/download.
Para encurtar o caminho das pedras, após instalar a classe Mail-API, basta apenas declarar os arquivos na variavel ambiental CLASS:

 
CLASSPATH=.:/usr/java/j2sdk1.4.1_04/jre/lib/ext:/usr/java/j2sdk1.4.1_04/lib/tools.jar:/usr/java/j2sdk1.4.1_04/jre/lib:/usr/java/j2sdk1.4.1_04/lib:/usr/java/j2sdk1.4.1_04/javamail/mail.jar:/usr/java/j2sdk1.4.1_04/javamail/activation.jar

 
Segue abaixo o fonte do programa que envia o e-mail, devemos digita-lo e salva-lo na pasta /bin.
OBS: Vale a pena resaltar que este programa eu extrair dos exemplos do pacote Mail-API.

 
oOo-oOo-oOo-oOo-oOo-oOo-oOo-| msgsendsample.java |-oOo-oOo-oOo-oOo-oOo-oOo-oOo

 
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

 
/**
*
* @author Max Spivak
*/
public class msgsendsample {
// static String msgText = "This is a message body.\nHere's the second line.";

 
public static void main(String[] args) {
if (args.length != 5) {
usage();
System.exit(1);
}

 
System.out.println();
 
String to = args[0];
String from = args[1];
String host = args[2];

 
boolean debug = Boolean.valueOf(args[3]).booleanValue();
 
String msgText = args [4];

 
// create some properties and get the default Session
Properties props = new Properties();
props.put("mail.smtp.host", host);
if (debug) props.put("mail.debug", args[3]);

 
Session session = Session.getInstance(props, null);
session.setDebug(debug);
 
try {
// create a message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(args[0])};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("E-mail Automatico: NETi TECNOLOGIA");
msg.setSentDate(new Date());
// If the desired charset is known, you can use
// setText(text, charset)
msg.setText(msgText);
 
Transport.send(msg);
} catch (MessagingException mex) {
System.out.println("\n--Exception handling in msgsendsample.java");

 
mex.printStackTrace();
System.out.println();
Exception ex = mex;
do {
if (ex instanceof SendFailedException) {
SendFailedException sfex = (SendFailedException)ex;
Address[] invalid = sfex.getInvalidAddresses();
if (invalid != null) {
System.out.println(" ** Invalid Addresses");
if (invalid != null) {
for (int i = 0; i < invalid.length; i++)
System.out.println(" " + invalid[i]);
}
}
Address[] validUnsent = sfex.getValidUnsentAddresses();
if (validUnsent != null) {
System.out.println(" ** ValidUnsent Addresses");
if (validUnsent != null) {
for (int i = 0; i < validUnsent.length; i++)
System.out.println(" "+validUnsent[i]);
}
}
Address[] validSent = sfex.getValidSentAddresses();
if (validSent != null) {
System.out.println(" ** ValidSent Addresses");
if (validSent != null) {
for (int i = 0; i < validSent.length; i++)
System.out.println(" "+validSent[i]);
}
}
}
System.out.println();
if (ex instanceof MessagingException)
ex = ((MessagingException)ex).getNextException();
else
ex = null;
} while (ex != null);
}
}

 
private static void usage() {
System.out.println("usage: java msgsendsample <to> <from> <smtp> true|false <message>");
}
}

 
oOo-oOo-oOo-oOo-oOo-oOo-| fim do msgsendsample.java |-oOo-oOo-oOo-oOo-oOo-oOo
 

 
Este programa envia um e-mail baseados nos parametros recebido via linha de comando. Sua sintaxe é: java msgsendsample <email-destino> <e-mail-origem> <IP do servidor smtp> <true|false modo debug> <mensagem>
Com este programa em mãos, criei um script para ler um arquivo texto que contem os e-mail destinatário, assim usando o mesmo como paramentro para o programa msgsendsample.java
Criei dois scripts. O emailsok, que envia um e-mail avisando a existencia de uma nova atuliazação para todos os endereços incluso no arquivo clientes que deve ser salvo na pasta /bin.
Já o script emailserro envia um e-mail de notificação de erro durante o serviço de transferência de dados para os administradores do sistema, cujo os e-mails deverão estar no arquivo adm que também deverá se encontrar na pasta /bin.

 
Seque abaixo os dois scripts:
Criando o script emailsok:

 
[root@servidorproxy /etc]# cd /bin
[root@servidorproxy /bin]# vi emailsok

 
Coloque o seguinte conteúdo no arquivo:

 
oOo-oOo-oOo-oOo-oOo-oOo-| emailsok |-oOo-oOo-oOo-oOo-oOo-oOo

 
CLASSPATH=.:/usr/java/j2sdk1.4.1_04/jre/lib/ext:/usr/java/j2sdk1.4.1_04/lib/tools.jar:/usr/java/j2sdk1.4.1_04/jre/lib:/usr/java/j2sdk1.4.1_04/lib:/usr/java/j2sdk1.4.1_04/javamail/mail.jar:/usr/java/j2sdk1.4.1_04/javamail/activation.jar

 
cd /bin

 
cat clientes | while read mArquivo
do
/usr/java/j2sdk1.4.1_04/bin/java msgsendsample $mArquivo neti@netitec.com.br mail.mdbrasil.com.br false "SERVICO NETi: Existe uma nova versao do antivirus AVG, certifique a sua atualizacao."

 
done

 
oOo-oOo-oOo-oOo-oOo-oOo-| fim do emailsok |-oOo-oOo-oOo-oOo-oOo-oOo

 
Criando o script emailserro:

 
[root@servidorproxy /etc]# cd /bin
[root@servidorproxy /bin]# vi emailserro

 
Coloque o seguinte conteúdo no arquivo:

 
oOo-oOo-oOo-oOo-oOo-oOo-| emailserro |-oOo-oOo-oOo-oOo-oOo-oOo

 
CLASSPATH=.:/usr/java/j2sdk1.4.1_04/jre/lib/ext:/usr/java/j2sdk1.4.1_04/lib/tools.jar:/usr/java/j2sdk1.4.1_04/jre/lib:/usr/java/j2sdk1.4.1_04/lib:/usr/java/j2sdk1.4.1_04/javamail/mail.jar:/usr/java/j2sdk1.4.1_04/javamail/activation.jar

 
cd /bin

 
cat adm | while read mArquivo
do
/usr/java/j2sdk1.4.1_04/bin/java msgsendsample $mArquivo neti@netitec.com.br mail.mdbrasil.com.br false "SERVICO NETi: Houve um erro no processo de atualizacao do antivirus, certifique!!!!"

 
done

 
oOo-oOo-oOo-oOo-oOo-oOo-| fim do emailserro |-oOo-oOo-oOo-oOo-oOo-oOo
Estes scripts apenas le o conteudo dos arquivos texto, armazena a leitura na variavel mArquivo que é usada como parâmentro no programa em java.
Caso o programa em java não envie o e-mail nos scripts acima,use o parâmetro -classpath, isto aconteceu em algumas distribuições linux que por algum motivo não consegui exportar a variavel ambiental CLASSPATH.
Segue abaixo um exemplo de como usar o parâmetro -classpath na chamada do programa em java.

 
/usr/java/j2sdk1.4.1_04/bin/java -classpath .:/usr/java/j2sdk1.4.1_04/jre/lib/ext:/usr/java/j2sdk1.4.1_04/lib/tools.jar:/usr/java/j2sdk1.4.1_04/jre/lib:/usr/java/j2sdk1.4.1_04/lib:/usr/java/j2sdk1.4.1_04/javamail/mail.jar:/usr/java/j2sdk1.4.1_04/javamail/activation.jar msgsendsample $mArquivo neti@netitec.com.br mail.mdbrasil.com.br false "SERVICO NETi: Houve um erro no processo de atualizacao do antivirus, certifique!!!!"

 
Agora vamos dar o direitos de execução para os nosso scripts:

 
[root@servidorproxy /bin]# chmod 755 emailsok
[root@servidorproxy /bin]# chmod 755 emailserro

 
Agendando o script:

 
Como o scritp executa de forma muito rápida e os arquivos de atualização não são tão grandes, eu agendei o scrip para ser executado de uma em uma hora.
Veja o meu arquivo crontab

 
[root@servidorproxy /]# cd /etc/
[root@servidorproxy /etc]# cat crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

 
# run-parts
# 01 * * * * root run-parts /etc/cron.hourly
# 02 4 * * * root run-parts /etc/cron.daily
# 22 4 * * 0 root run-parts /etc/cron.weekly
# 42 4 1 * * root run-parts /etc/cron.monthly
00 * * * * root /bin/updateAVG %
[root@servidorproxy /etc]#

 
Com este tutorial apenas o servidor efetua o download da vacina na hora que estiver disponível e todas as maquinas clientes não precisam fazem a atualização via internet. Sem contar que a atualização no servidor local fica bem rápido.

 
*** Não esqueça de criar os arquivos /bin/clientes e /bin/adm contendo os e-mails destino.

 
Autor deste tutorial: Alessandro de Oliveira Faria (CABELO)
e-mail: alessandrofaria@netitec.com.br