From: <Saved by Mozilla 5.0 (Windows)>
Subject: CGI em Shell Script
Date: Thu, 21 Nov 2013 00:44:05 -0200
MIME-Version: 1.0
Content-Type: multipart/related;
	type="text/html";
	boundary="----=_NextPart_000_0000_6D0A9E5D.23B91C28"
X-MAF-Information: Produced By MAF V3.0.0

This is a multi-part message in MIME format.

------=_NextPart_000_0000_6D0A9E5D.23B91C28
Content-Type: text/html;
	charset="windows-1252"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thobias.org/doc/cgi_shell.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dwindows-1=
252">
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dwindows-1=
252">
<meta name=3D"generator" content=3D"http://txt2tags.sf.net">
<title>CGI em Shell Script</title>
</head><body bgcolor=3D"white" text=3D"black">
<p align=3D"center"></p><center><h1>CGI em Shell Script</h1>
<font size=3D"4">
<i>Thobias Salazar Trevisan</i><br>
08/04/2003
</font></center>

<p>
</p><hr noshade=3D"noshade" size=3D"1">
<p>
</p><p>
 </p><ol>
 <li><a href=3D"#toc1">Introdu=E7=E3o</a>
 </li><li><a href=3D"#toc2">Configura=E7=E3o</a>
   <ul>
   <li><a href=3D"#toc3">2.0.1. Algumas considera=E7=F5es importantes:</a>
   </li></ul>
 </li><li><a href=3D"#toc4">Divers=E3o</a>
  <ul>
  <li><a href=3D"#toc5">3.1. Iniciando</a>
  </li><li><a href=3D"#toc6">3.2. M=E9todo GET</a>
  </li><li><a href=3D"#toc7">3.3. M=E9todo POST</a>
  </li><li><a href=3D"#toc8">3.4. Upload</a>
  </li><li><a href=3D"#toc9">3.5. CheckBox</a>
  </li><li><a href=3D"#toc10">3.6. Radio Buttons</a>
  </li><li><a href=3D"#toc11">3.7. Contador de Acesso Gen=E9rico</a>
   <ul>
   <li><a href=3D"#toc12">3.7.1. SSI - Server Side Includes</a>
   </li><li><a href=3D"#toc13">3.7.2. Contador</a>
   </li></ul>
  </li><li><a href=3D"#toc14">3.8. Seguran=E7a</a>
   <ul>
   <li><a href=3D"#toc15">3.8.1. Introdu=E7=E3o e Configura=E7=E3o</a>
   </li><li><a href=3D"#toc16">3.8.2. T=E1, e da=ED? Onde est=E1 o CGI em=
 Shell?</a>
   </li></ul>
  </li></ul>
 </li><li><a href=3D"#toc17">LAN  +_+</a>
 </li><li><a href=3D"#toc18">Resum=E3o</a>
 </li></ol>
<p>
</p><hr noshade=3D"noshade" size=3D"1">
<p>
</p><p>
<a name=3D"toc1"></a>
</p><h1>1. Introdu=E7=E3o</h1>
<p>
CGI (Common Gateway Interface) =E9 um servi=E7o server-based o qual adiciona
funcionalidade extra a uma p=E1gina. Esta funcionalidade =E9 fornecida
por um 'pequeno' programa ou 'script' que =E9 executado no servidor onde a
p=E1gina web fica. Estes programas podem ser feitos em diversas linguagens
como Perl, PHP, C, Shell Script, etc.
</p><p>
Como gosto muito de Shell Script resolvi escrever um tutorial b=E1sico
sobre como fazer CGI em Shell. Isto tem v=E1rias vantagens, pois voc=EA pod=
e=20
utilizar v=E1rios comandos do UNIX para ajudar a construir seu script,=20
por exemplo sed, awk, cut, grep, cat, echo, bc, etc. al=E9m dos recursos=20
do pr=F3prio shell.
</p><p>
Ok, como este tutorial n=E3o vai ser muito grande, vamos direto ao ponto.
</p><p>
<a name=3D"toc2"></a>
</p><h1>2. Configura=E7=E3o</h1>
<p>
Como configurar o servidor web Apache para executar CGI ?
</p><p>
CGI =E9 um m=F3dulo do Apache, assim ele precisa ser carregado.
A maioria das distribui=E7=F5es j=E1 vem com o seu <i>httpd.conf</i> config=
urado com
suporte ao m=F3dulo do CGI (mod_cgi), bastando apenas iniciar o Apache.=20
Para se certificar procure e, se for o caso, descomente a seguinte=20
linha no seu <i>httpd.conf</i>:=20
</p><p>
</p><pre>  LoadModule cgi_module /usr/lib/apache/1.3/mod_cgi.so
</pre>
<p>
<b>PS:</b> Note que a terceira coluna pode variar dependendo da vers=E3o do
Apache e da distribui=E7=E3o que voc=EA est=E1 usando.
</p><p>
Existem diversas maneiras de configur=E1-lo:=20
</p><p>
</p><ol>
<li>ScriptAlias
<p>
esta diretiva define um diret=F3rio para o Apache onde ser=E3o armazenados=
 os
scripts CGI. Todos os arquivos que estiverem neste diret=F3rio ser=E3o
interpretados pelo Apache como programas CGI, assim ele tentar=E1 execut=E1=
-los.=20
Adicione ou descomente a seguinte linha no seu arquivo <i>httpd.conf</i>
</p><pre>  ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/=20
</pre>
<p>
</p><p>
O exemplo acima instrui o Apache para que qualquer requisi=E7=E3o come=E7an=
do por
/<i>cgi-bin</i>/ deva ser acessada no diret=F3rio /<i>usr/lib/cgi-bin</i>/=
 e deva
ser tratada como um programa CGI, i.e., ele ir=E1 executar o arquivo
requisitado.
</p><p>
se voc=EA acessar por exemplo <code>http://localhost/cgi-bin/meu_script.cgi=
</code>, o
Apache ir=E1 procurar este arquivo em
/<i>usr/lib/cgi-bin/meu_script.cgi</i> e tentar=E1 execut=E1-lo.
</p><p>
</p></li><li>fora do ScriptAlias
<p>
voc=EA pode especificar um diret=F3rio particular e dar permiss=E3o para a
execu=E7=E3o de CGIs.
</p><pre>  &lt;Directory /home/user/public_html/cgi-bin/&gt;
                  Options +ExecCGI
  &lt;/Directory&gt;
</pre>
<p>
</p><p>
esta diretiva acima permite a execu=E7=E3o de CGIs, mas voc=EA ainda precis=
a=20
avisar o Apache que tipo de arquivos s=E3o estes CGIs. Procure=20
por uma linha igual ou semelhante a esta no seu <i>httpd.conf </i>e descome=
nte.
</p><pre>  AddHandler cgi-script .cgi .sh .pl
</pre>
</li></ol>
OBS: se voc=EA colocar um index.cgi em algum diret=F3rio e quiser que por
default o Apache execute-o, n=E3o se esque=E7a de adicionar esta extens=E3o=
 no
seu <i>DirectoryIndex</i>.
<p>
</p><pre>  &lt;IfModule mod_dir.c&gt;
      DirectoryIndex index.html index.htm index.shtml index.cgi
  &lt;/IfModule&gt;
</pre>
<p>
O Apache ir=E1 procurar pelo index.cgi seguindo a ordem dos argumentos, ou
seja, o index.cgi ser=E1 a =FAltima op=E7=E3o que ele ir=E1 procurar no dir=
et=F3rio.
</p><p>
<a name=3D"toc3"></a>
</p><h3>2.0.1. Algumas considera=E7=F5es importantes:</h3>
<p>
 </p><ul>
 <li>voc=EA n=E3o deve colocar seus scripts no document root do Apache,
porque algu=E9m pode pegar seus scripts, analis=E1-los procurando furos de
seguran=E7a, etc. Al=E9m do mais, o c=F3digo do script n=E3o =E9 o que voc=
=EA quer
mostrar :)  Ent=E3o mantenha-os em /<i>usr/lib/cgi-bin</i> ou algum outro=
 diret=F3rio
fora do document root.
<p>
 </p></li><li>o script precisa ser um execut=E1vel, n=E3o se esque=E7a de=
 dar um <i>chmod</i>
nele. Ah, certifique que o script tem permiss=E3o de execu=E7=E3o para o us=
u=E1rio
que o Apache est=E1 rodando.
 </li></ul>
<a name=3D"toc4"></a>
<h1>3. Divers=E3o</h1>
<a name=3D"toc5"></a>
<h2>3.1. Iniciando</h2>
Assumimos que voc=EA j=E1 tem o seu servidor web configurado para executar
CGI. Agora =E9 hora da divers=E3o :-)
<p>
O b=E1sico que voc=EA precisa saber =E9 que toda a sa=EDda padr=E3o (stdout=
) do seu=20
script vai ser enviada para o browser.
</p><p>
O exemplo mais simples =E9 voc=EA imprimir algo na tela. Vamos ao nosso exe=
mplo:
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D simples.cgi =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/plain"
  echo
  echo -e "
  vamos ver se isto funciona mesmo :-)
 =20
  hmm, parece legal
 =20
  igual ah um shell normal \n&lt;b&gt;tag html&lt;/b&gt;
  "
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Feito isto basta acessar o nosso arquivo.
<a href=3D"http://localhost/cgi-bin/simples.cgi">http://localhost/cgi-bin/s=
imples.cgi</a>
Ah, n=E3o se esque=E7a de colocar permiss=E3o de execu=E7=E3o no arquivo
</p><p>
Ok, ent=E3o percebemos que toda sa=EDda do nosso script =E9 enviada para o
browser, toda a sa=EDda mesmo. Por exemplo, podemos utilizar a sa=EDda de um
comando:=20
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D saida_cmd.cgi=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/plain"
  echo=20
  echo "uname -a"
  echo
  uname -a
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Quando utilizamos CGI o servidor coloca diversas informa=E7=F5es sobre
o cliente e o servidor em vari=E1veis de ambiente. Dentre estas informa=E7=
=F5es
pode-se destacar:
</p><p>
<table align=3D"center" border=3D"0" cellpadding=3D"4">
<tbody><tr>
<td><i>DOCUMENT_ROOT</i></td>
<td>diret=F3rio root dos documentos html</td>
</tr>
<tr>
<td><i>HTTP_ACCEPT</i></td>
<td>quais os content-type suportados pelo browser do cliente</td>
</tr>
<tr>
<td><i>HTTP_HOST</i></td>
<td>nome do host do servidor</td>
</tr>
<tr>
<td><i>HTTP_USER_AGENT</i></td>
<td>o browser do cliente</td>
</tr>
<tr>
<td><i>REMOTE_ADDR</i></td>
<td>IP do cliente</td>
</tr>
<tr>
<td><i>REQUEST_URI</i></td>
<td>p=E1gina requisitada</td>
</tr>
<tr>
<td><i>SERVER_ADDR</i></td>
<td>IP do servidor</td>
</tr>
<tr>
<td><i>SERVER_NAME</i></td>
<td>o server name (configurado no Apache)</td>
</tr>
<tr>
<td><i>SERVER_PORT</i></td>
<td>porta que o servidor est=E1 escutando</td>
</tr>
<tr>
<td><i>SERVER_SOFTWARE</i></td>
<td>sistema operacional e servidor www rodando no server</td>
</tr>
</tbody></table>

</p><p>
Para a lista completa destas vari=E1veis acesse <a href=3D"http://hoohoo.nc=
sa.uiuc.edu/cgi/env.html">http://hoohoo.ncsa.uiuc.edu/cgi/env.html</a>.
</p><p>
O exemplo a seguir mostra todas as vari=E1veis.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D export.cgi =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/plain"
  echo
  echo "
  Informacoes que o servidor coloca em variaveis de ambiente
  Para ver utilizamos o comando set
 =20
  "
  set
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Okay, no protocolo http temos que enviar um cabe=E7alho obrigat=F3rio.=20
O primeiro echo sem string dentro de um script vai avisar o browser para=20
interpretar o que veio antes como cabe=E7alho. Nos exemplos anteriores, a
seguinte linha  <i>content-type: text/plain</i>  informa ao browser
para interpretar o que receber como texto puro. Se o cabe=E7alho n=E3o poss=
uir
nenhuma linha, ou seja, colocarmos somente um echo, ser=E1 utilizado o defa=
ult=20
que normalmente =E9 <i>text/plain</i>.
Este default =E9 configurado no arquivo <i>httpd.conf</i> do Apache na op=
=E7=E3o:
</p><p>
</p><pre>  DefaultType text/plain
</pre>
<p>
Ent=E3o para garantir procure sempre especificar o cabe=E7alho!!
Para enviarmos tags html e o browser interpret=E1-las, temos que utilizar um
cabe=E7alho diferente. Este cabe=E7alho =E9 <i>content-type: text/html</i>
Ent=E3o vamos enviar tags html para deixar nossa sa=EDda mais bonita:
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D sobre.cgi =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo
  echo "
  &lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt; &lt;/he=
ad&gt;
  &lt;body&gt;
  &lt;h1&gt;Algumas informa=E7=F5es sobre a m=E1quina que o CGI est=E1 roda=
ndo:&lt;/h1&gt;
  "
 =20
  echo "&lt;h4&gt;uptime&lt;/h4&gt;"
  echo "&lt;pre&gt;$(uptime)&lt;/pre&gt;"
 =20
  echo "&lt;h4&gt;uname&lt;/h4&gt;"
  echo "&lt;pre&gt;$(uname -a)&lt;/pre&gt;"
 =20
  echo "&lt;h4&gt;/proc/cpuinfo&lt;/h4&gt;"
  echo "&lt;pre&gt;$(cat /proc/cpuinfo)&lt;/pre&gt;"
 =20
  echo "
  &lt;/body&gt;
  &lt;/html&gt;
  "
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Um exemplo mais interessante seria como fazer um contador de acesso.
A cada execu=E7=E3o do script o contador ser=E1 incrementado, n=E3o importa=
ndo se =E9
uma solicita=E7=E3o de reload de um mesmo endere=E7o IP!!
Isto =E9 simples. Veja o exemplo:=20
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D contador.cgi =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo
  echo "&lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt;=
 &lt;/head&gt;"
  echo "&lt;body&gt;"
 =20
  ARQ=3D"/tmp/page.hits"
 =20
  n=3D"$(cat $ARQ 2&gt; /dev/null)" || n=3D0
  echo $((n=3Dn+1)) &gt; "$ARQ"
 =20
  echo "
  &lt;h1&gt;Esta p=E1gina j=E1 foi visualizada: $n vezes&lt;/h1&gt;
  &lt;br&gt;
 =20
  &lt;/body&gt;
  &lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Com o que sabemos at=E9 agora, d=E1 (ops!) para fazer v=E1rios script legai=
s,=20
fazer monitoramento do sistema, de sua rede..., tudo via web.
</p><p>
Agora que j=E1 aprendemos o b=E1sico, queremos interagir com o usu=E1rio.
Neste ponto n=F3s temos um detalhe, pois o nosso script n=E3o pode usar a
entrada padr=E3o (stdin) para receber dados e n=E3o podemos fazer um <i>rea=
d</i> em um
CGI, pois como n=F3s leriamos o que o usu=E1rio digitasse no teclado? :)=20
</p><p>
Para realizar esta intera=E7=E3o existem duas maneiras.=20
</p><p>
</p><ol>
<li>atrav=E9s da URL, utilizando o m=E9todo GET, como por exemplo:
<p>
<code>http://localhost/cgi-bin/script.cgi?user=3Dnobody&amp;profissao=3Dvag=
a</code>
</p><p>
(veremos mais sobre o m=E9todo GET mais adiante)
</p><p>
</p></li><li>utilizando um formul=E1rio HTML. No FORM podemos utilizar dois=
 m=E9todos, o GET
e o POST. No m=E9todo GET, que =E9 o default, os campos de input do FORM s=
=E3o
concatenados a URL. J=E1 no m=E9todo POST, os inputs s=E3o passados interna=
mente do
servidor para o script pela entrada padr=E3o.
</li></ol>
<a name=3D"toc6"></a>
<h2>3.2. M=E9todo GET</h2>
<p>
Usando o m=E9todo GET o nosso script deve pegar os inputs do usu=E1rio
via uma vari=E1vel de ambiente, no caso a <b><i>$QUERY_STRING</i></b>.
Tudo o que vier ap=F3s o caractere '?' na URL ser=E1 colocado naquela vari=
=E1vel.
Os campos de input do FORM s=E3o separados pelo caractere '&amp;' e
possuem a seguinte constru=E7=E3o: <i>name=3Dvalue</i>.
Vamos a um exemplo de um CGI que recebe como entrada um host
que ser=E1 executado no ping.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D ping_get.cgi =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo
  echo "
  &lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt; &lt;/he=
ad&gt;
  &lt;body&gt;
  "
 =20
  echo "&lt;h2&gt;Exemplo de uso do GET&lt;/h2&gt;"
  if [ "$QUERY_STRING" ];then
  	echo "QUERY_STRING   $QUERY_STRING"
  	host=3D"$(echo $QUERY_STRING | sed 's/\(.*=3D\)\(.*\)\(\&amp;.*\)/\2/')"
  	echo "&lt;br&gt;"
  	echo "Disparando o comando ping para o host &lt;b&gt;$host&lt;/b&gt;"
  	echo "&lt;pre&gt;"
  	ping -c5 $host
  	echo "&lt;/pre&gt;"
  	echo "Fim."
  else
  	echo "
  	&lt;form method=3D\"GET\" action=3D\"ping_get.cgi\"&gt;
  	&lt;b&gt;Entre com o nome ou IP do host para o ping:&lt;/b&gt;=20
  	&lt;input size=3D40 name=3Dhost value=3D\"\"&gt;
  	&lt;input type=3Dhidden size=3D40 name=3Dteste value=3D\"nada\"&gt;
  	&lt;/form&gt;"
  fi
 =20
  echo "&lt;/body&gt;"
  echo "&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
<a name=3D"toc7"></a>
</p><h2>3.3. M=E9todo POST</h2>
<p>
No m=E9todo POST as op=E7=F5es do FORM n=E3o s=E3o passadas pela URL, elas=
 s=E3o
passadas internamente do servidor para o CGI. Deste modo, com este
m=E9todo o nosso script deve ler as op=E7=F5es pela entrada padr=E3o. Vamos=
 a um
exemplo em que o CGI envia um mail para algu=E9m atrav=E9s da p=E1gina. Nes=
te
caso, um pouco mais complexo, temos dois arquivos. O primeiro um .html
puro, onde construimos o FORM, e colocamos como op=E7=E3o '<i>action</i>'=
 o nosso
script. A op=E7=E3o action passada no FORM, indica qual script ser=E1 chama=
do
para tratar os dados passados pelo FORM.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D contato.html =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  &lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt; &lt;/he=
ad&gt;
 =20
  &lt;body&gt;
  &lt;form method=3D"post" action=3D"/cgi-bin/contato.cgi"&gt;
  Nome:&lt;br&gt;
  &lt;input type=3D"text" name=3D"name" maxlength=3D"50" size=3D"30"&gt;
  &lt;p&gt;
  E-mail:&lt;br&gt;
  &lt;input type=3D"text" name=3D"address" maxlength=3D"50" size=3D"30"&gt;
  &lt;p&gt;
  Selecione o assunto:
  &lt;select name=3D"subject"&gt;
  &lt;option value=3D"none"&gt;-------------------------
  &lt;option value=3D"venda"&gt;Informa=E7=F5es sobre produto
  &lt;option value=3D"suporte"&gt;Suporte t=E9cnico =20
  &lt;option value=3D"web"&gt;Problema no site
  &lt;/select&gt;
  &lt;p&gt;
  Sua mensagem:&lt;br&gt;
  &lt;textarea name=3D"message" wrap=3D"physical" rows=3D"6" cols=3D"50"&gt;
  &lt;/textarea&gt;
  &lt;p&gt;
  &lt;input type=3D"submit" value=3D"Enviar Mensagem"&gt;
  &lt;input type=3D"reset" value=3D"Limpar"&gt;
  &lt;/form&gt;
 =20
  &lt;/body&gt;
  &lt;/html&gt;
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Agora o nosso script l=EA da entrada padr=E3o e faz o tratamento necess=E1r=
io.
Note que para enviar o mail, podemos utilizar qualquer programa de mail,
por exemplo o mail, sendmail...
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D contato.cgi =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  meu_mail=3D"user@localhost.com.br"
 =20
  echo "content-type: text/html"
  echo
  echo
  echo "&lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt;=
 &lt;/head&gt;"
  echo "&lt;body&gt;"
  VAR=3D$(sed -n '1p')
  echo "$VAR"
  nome=3D$(echo $VAR | sed 's/\(name=3D\)\(.*\)\(\&amp;address=3D.*\)/\2/;s=
/+/ /g')
  mail=3D$(echo $VAR | sed 's/\(.*&amp;address=3D\)\(.*\)\(\&amp;subject=3D=
.*\)/\2/;s/%40/@/')
  subj=3D$(echo $VAR | sed 's/\(.*&amp;subject=3D\)\(.*\)\(\&amp;message=3D=
.*\)/\2/')
  text=3D$(echo $VAR |  sed 's/.*\&amp;message=3D//')
 =20
  echo "&lt;br&gt;
  &lt;br&gt;&lt;b&gt;Nome:&lt;/b&gt; $nome
  &lt;br&gt;&lt;b&gt;mail:&lt;/b&gt; $mail
  &lt;br&gt;&lt;b&gt;Subject:&lt;/b&gt; $subj
  &lt;br&gt;&lt;b&gt;Message:&lt;/b&gt; $text
  &lt;br&gt;"
 =20
  mail -s "Mail from CGI" "$meu_mail" &lt; $(echo -e "
  Nome: $nome=20
  mail: $mail
  Subject: $subj
  Message: $text")
 =20
  echo "&lt;/body&gt;"
  echo "&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Quando o seu servidor web envia os dados do FORM para o seu CGI, ele faz=20
um encode dos dados recebidos. Caracteres alfanum=E9rico s=E3o enviados
normalmente, espa=E7os s=E3o convertidos para o sinal de mais (+), outros
caracteres como tab, aspas s=E3o convertidos para %HH, onde HH s=E3o dois
d=EDgitos hexadecimais representando o c=F3digo ASCII do caractere. Este
processo =E9 chamado de URL encoding.
</p><p>
Tabela para os caracteres mais comuns:
</p><p>
<table align=3D"center" border=3D"1" cellpadding=3D"4">
<tbody><tr>
<th>Caractere</th>
<th>URL Enconded</th>
</tr>
<tr>
<td align=3D"center">\t (tab)</td>
<td align=3D"center">%09</td>
</tr>
<tr>
<td>\n (return)</td>
<td align=3D"center">%0A</td>
</tr>
<tr>
<td align=3D"center">/</td>
<td align=3D"center">%2F</td>
</tr>
<tr>
<td align=3D"center">~</td>
<td align=3D"center">%7E</td>
</tr>
<tr>
<td align=3D"center">:</td>
<td align=3D"center">%3A</td>
</tr>
<tr>
<td align=3D"center">;</td>
<td align=3D"center">%3B</td>
</tr>
<tr>
<td align=3D"center">@</td>
<td align=3D"center">%40</td>
</tr>
<tr>
<td align=3D"center">&amp;</td>
<td align=3D"center">%26</td>
</tr>
</tbody></table>

</p><p>
Aqui v=E3o dois links para fazer e desfazer esta convers=E3o:
</p><ul>
<li><a href=3D"http://www.shelldorado.com/scripts/cmds/urlencode">http://ww=
w.shelldorado.com/scripts/cmds/urlencode</a>
</li><li><a href=3D"http://www.shelldorado.com/scripts/cmds/urldecode">http=
://www.shelldorado.com/scripts/cmds/urldecode</a>
</li></ul>
<a name=3D"toc8"></a>
<h2>3.4. Upload</h2>
Agora que j=E1 sabemos utilizar os m=E9todos GET e POST vamos a um exemplo=
 um
pouco diferente. Vamos supor que precisamos fazer um CGI que permita
o usu=E1rio fazer um upload de um arquivo para o servidor. Aqui utilizamos=
 um
FORM um pouco diferente. Falamos para o FORM utilizar um tipo de codifica=
=E7=E3o
diferente, no caso <i>enctype=3D"multipart/form-data"</i>.
Criamos um HTML normalmente e como op=E7=E3o do <i>action</i> colocamos o=
 nosso script.
<p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D upload.html =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  &lt;html&gt;
  &lt;body&gt;
  &lt;form enctype=3D"multipart/form-data" action=3D"/cgi-bin/upload.cgi"=
 method=3D"post"&gt;
  Enviar arquivo: &lt;input name=3D"userfile" size=3D"30" type=3D"file"&gt;
  &lt;BR&gt;&lt;BR&gt;
  &lt;input type=3D"submit" value=3D"Envia" name=3D"Envia"&gt;
  &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
O nosso script =E9 quase igual a um POST normal. A principal diferen=E7a =
=E9 que
o input para o script n=E3o vem em uma =FAnica linha, e sim em v=E1rias.
Quem faz isto =E9 o <i>enctype=3D"multipart/form-data"</i>.
Vem inclusive o conte=FAdo do arquivo via POST!! Ent=E3o pegamos tudo da en=
trada
padr=E3o. Note que junto com o input vem outras cositas mas =3D8)
Vamos a um exemplo:
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D upload.cgi =3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo
  echo "&lt;html&gt; &lt;head&gt; &lt;title&gt; CGI script &lt;/title&gt;=
 &lt;/head&gt;"
  echo "&lt;body&gt;&lt;pre&gt;"
  # descomente se quiser ver as variaveis de ambiente
  #export
 =20
  # ele separa as varias partes do FORM usando um limite (boundary) que eh
  # diferente a cada execucao. Este limite vem na variavel de ambiente CONT=
ENT_TYPE
  # algo mais ou menos assim
  # CONTENT_TYPE=3D"multipart/form-data; boundary=3D--------------108640073=
8455992438608787998"
  # Aqui pegamos este limite
  boundary=3D$(export | sed '/CONTENT_TYPE/!d;s/^.*dary=3D//;s/.$//')
 =20
  #echo
  #echo "boundary =3D $boundary"
 =20
  # pegamos toda a entrada do POST e colocamos em VAR
  VAR=3D$(sed -n '1,$p')
  # imprimimos o que vem no input
  echo "$VAR"
  echo -e '\n\n'
  echo "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D FIM =3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D"
  echo -e '\n\n'
  # pegamos o nome do arquivo que foi feito o upload
  FILENAME=3D$(echo "$VAR" | sed -n '2!d;s/\(.*filename=3D\"\)\(.*\)\".*$/\=
2/;p')
 =20
  # pegamos somente o conteudo do arquivo do upload
  FILE=3D$(echo "$VAR" | sed -n "1,/$boundary/p" | sed '1,4d;$d')
 =20
  echo "Nome do arquivo : $FILENAME"
  echo
  # imprimimos no browser o conteudo do arquivo
  echo "$FILE" =20
  # redirecionamos o conteudo do arquivo para um arquivo local no server
  # upload feito ;)
  echo "$FILE" | sed '$d' &gt; "/tmp/$FILENAME"=20
 =20
  echo "&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
<a name=3D"toc9"></a>
</p><h2>3.5. CheckBox</h2>
Para relaxar um exemplo mais simples, vamos fazer um CheckBox.
Primeiro criamos uma p=E1gina HTML com o FORM para checkbox normalmente.=20
Vamos utilizar o m=E9todo POST no exemplo.
<p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D checkbox.html=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  &lt;html&gt;&lt;head&gt;&lt;title&gt;distro&lt;/title&gt;&lt;/head&gt;
  &lt;body&gt;
 =20
  &lt;form action=3D"/cgi-bin/checkbox.cgi" method=3D"POST"&gt;
 =20
  &lt;h3&gt;Quais destas distro voce gosta ?&lt;/h3&gt;
  &lt;input type=3D"checkbox" name=3D"debian" value=3D1&gt; Debian&lt;br&gt;
  &lt;input type=3D"checkbox" name=3D"redhat" value=3D1&gt; RedHat&lt;br&gt;
  &lt;input type=3D"checkbox" name=3D"conectiva" value=3D1&gt; Conectiva&lt=
;br&gt;
  &lt;input type=3D"checkbox" name=3D"mandrake" value=3D1&gt; Mandrake&lt;b=
r&gt;
  &lt;input type=3D"submit" value=3D"Enviar"&gt;
  &lt;/form&gt;
 =20
  &lt;/body&gt;
  &lt;/html&gt;
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Pegamos os inputs do FORM na entrada padr=E3o. Eles s=E3o separados por &am=
p;.
Todas as op=E7=F5es que o usu=E1rio selecionar vir=E3o no POST.=20
Ah, n=E3o se esque=E7a, <i>name=3Dvalue</i>. Um exemplo de input que recere=
beremos:
</p><pre>  debian=3D1&amp;conectiva=3D1
</pre>
Assim, sabemos que o usu=E1rio escolheu estas duas op=E7=F5es. Basta fazer o
script.
<p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D checkbox.cgi =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/plain"
  echo=20
  VAR=3D$(sed -n 1p)
  echo "$VAR"
  echo=20
  [ "$VAR" ] || { echo "voce nao gosta de nada";exit; }
  echo "Voce gosta de :"
  echo
  IFS=3D"&amp;"
  for i in `echo "$VAR"`;do
  echo " $(echo $i | cut -d=3D -f1)"
  done
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
<a name=3D"toc10"></a>
</p><h2>3.6. Radio Buttons</h2>
Outro exemplo =E9 o Radio Buttons.
Tamb=E9m utilizaremos o m=E9todo POST aqui.
Criamos um html normalmente.
<p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D radiobuttons.ht=
ml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  &lt;html&gt;&lt;head&gt;&lt;title&gt;distro&lt;/title&gt;&lt;/head&gt;
  &lt;body&gt;
 =20
  &lt;form action=3D"/cgi-bin/radiobuttons.cgi" method=3D"POST"&gt;
 =20
  &lt;h3&gt;Qual sua distro predileta ?&lt;/h3&gt;
  &lt;input type=3D"radio" name=3D"distro" value=3DDebian&gt; Debian&lt;br&=
gt;
  &lt;input type=3D"radio" name=3D"distro" value=3DRedHat&gt; RedHat&lt;br&=
gt;
  &lt;input type=3D"radio" name=3D"distro" value=3DConectiva&gt; Conectiva&=
lt;br&gt;
  &lt;input type=3D"radio" name=3D"distro" value=3DMandrake&gt; Mandrake&lt=
;br&gt;
  &lt;input type=3D"radio" name=3D"distro" value=3Dnone&gt; Nenhuma destas&=
lt;br&gt;
  &lt;input type=3D"submit" value=3D"Enviar"&gt;
  &lt;/form&gt;
 =20
  &lt;/body&gt;
  &lt;/html&gt;
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
O que ser=E1 enviado pelo POST =E9 o input escolhido. Como =E9 Radio Button=
s,
somente uma op=E7=E3o =E9 aceita, assim temos o input: name=3Dvalue, onde=
 name =E9 a
vari=E1vel distro e value =E9 a op=E7=E3o escolhida pelo usu=E1rio. Um exem=
plo =E9:=20
<i>distro=3DDebian</i>
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D radiobuttons.cg=
i =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"=20
  echo=20
  VAR=3D$(sed -n 1p)
  echo "$VAR &lt;br&gt;"
  echo "&lt;br&gt;"
  [ "$VAR" ] || { echo "voce nao gosta de nada";exit; }
 =20
  echo "Sua distro predileta eh: &lt;b&gt;$(echo $VAR | cut -d=3D -f2)&lt;/=
b&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
<a name=3D"toc11"></a>
</p><h2>3.7. Contador de Acesso Gen=E9rico</h2>
<p>
Um dos primeiros exemplos que vimos foi como fazer um contador de acesso
<i>contador.cgi</i>. Aquela implementa=E7=E3o tem um problema de
concorr=EAncia. Se a p=E1gina tiver 2 acessos 'simult=E2neos' ela pode deix=
ar=20
de contabilizar 1 acesso. Vamos imaginar que temos dois acessos a p=E1gina
'ao mesmo tempo'. O fluxo de execu=E7=E3o do CGI do primeiro acesso executa
as seguintes linhas:
</p><p>
</p><pre>  ARQ=3D"/tmp/page.hits"
  n=3D"$(cat $ARQ 2&gt; /dev/null)" || n=3D0
</pre>
<p>
O kernel interrompe a execu=E7=E3o do CGI neste momento e come=E7a a execut=
ar o
CGI do segundo acesso a p=E1gina. O segundo CGI =E9 todo executado, assim,=
 ele
leu o valor que tinha no arquivo /<i>tmp/page.hits</i>, somou 1 e sobrescre=
veu
o arquivo com o novo valor. Agora o kernel volta a executar o primeiro CGI=
 de
onde parou, seguindo nosso algoritmo, o CGI j=E1 tem o valor antigo do
arquivo na vari=E1vel <i>n</i>, assim ele vai para a pr=F3xima instru=E7=E3=
o:
</p><p>
</p><pre>   echo $((n=3Dn+1)) &gt; "$ARQ"
</pre>
<p>
Sobrescreveu o antigo valor. <b>Note</b>: como ele foi interrompido antes da
segunda execu=E7=E3o do CGI, ele estava com o valor antigo em <i>n</i>. Nos=
so
contador perdeu 1 acesso. :/
</p><p>
Para arrumar este problema, vamos aproveitar e incluir um novo t=F3pico aqu=
i.
</p><p>
<a name=3D"toc12"></a>
</p><h3>3.7.1. SSI - Server Side Includes</h3>
<p>
SSI s=E3o diretivas que colocamos em uma p=E1gina HTML pura para que o
servidor avalie quando a p=E1gina for acessada. Assim podemos adiconar
conte=FAdo din=E2mico a p=E1gina sem precisarmos escrever toda ela em CGI.=
 Para
isto basta configurar o seu Apache corretamente. Quem fornece esta op=E7=E3=
o =E9
o m=F3dulo includes (mod_include), simplesmente descomentamos a linha que
carrega este m=F3dulo:
</p><p>
</p><pre>  LoadModule includes_module /usr/lib/apache/1.3/mod_include.so
</pre>
<p>
Exitem duas maneiras de configur=E1-lo:
</p><p>
</p><ol>
<li>atrav=E9s da extens=E3o do arquivo, normalmente .shtml
<p>
</p></li><li>atrav=E9s da op=E7=E3o XBitHack. Esta op=E7=E3o testa se o arq=
uivo HTML (.html)
requisitado tem o bit de execu=E7=E3o setado, se tiver ele executar=E1 o que
tiver usando as suas diretivas. Acrescente a seguinte linha em seu
<i>httpd.conf</i>.
<pre>  XBitHack on
</pre>
</li></ol>
<b>PS</b>: em ambos os casos o arquivo HTML precisa ser execut=E1vel.
<p>
Este t=F3pico est=E1 muito bem documentado nos seguintes endere=E7os:
</p><ul>
<li><a href=3D"http://httpd.apache.org/docs/howto/ssi.html">http://httpd.ap=
ache.org/docs/howto/ssi.html</a>
</li><li><a href=3D"http://httpd.apache.org/docs/mod/mod_include.html">http=
://httpd.apache.org/docs/mod/mod_include.html</a>
</li></ul>
<a name=3D"toc13"></a>
<h3>3.7.2. Contador</h3>
<p>
Para resolver o problema de concorr=EAncia vamos utilizar um <i>named pipe<=
/i>.
Criamos o seguinte script que ser=E1 o daemon que receber=E1 todos os pedid=
os
para incrementar o contador. Note que ele vai ser usado por qualquer
p=E1gina no nosso site que precise de um contador.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D daemon_contador=
.sh=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  PIPE=3D"/tmp/pipe_contador" # arquivo named pipe
  # dir onde serao colocados os arquivos contadores de cada pagina
  DIR=3D"/var/www/contador"	 =20
 =20
  [ -p "$PIPE" ] || mkfifo "$PIPE"
 =20
  while :;do
  	for URL in $(cat &lt; $PIPE);do
  		FILE=3D"$DIR/$(echo $URL | sed 's,.*/,,')"
  		# quando rodar como daemon comente a proxima linha
  		echo "arquivo =3D $FILE"
 =20
  		n=3D"$(cat $FILE 2&gt; /dev/null)" || n=3D0
  		echo $((n=3Dn+1)) &gt; "$FILE"
  	done
  done
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Como s=F3 este script altera os arquivos, n=E3o existe problema de
concorr=EAncia.
</p><p>
Este script ser=E1 um daemon, isto =E9, rodar=E1 em background. Quando uma=
 p=E1gina
sofrer um acesso, ela escrever=E1 a sua URL no arquivo de pipe. Para testar,
execute este comando:
</p><p>
</p><pre>   echo "teste_pagina.html" &gt; /tmp/pipe_contador=20
</pre>
<p>
Em cada p=E1gina que quisermos adicionar o contador acrescentamos a seguinte
linha:
</p><p>
</p><pre>  &lt;!--#exec cmd=3D"echo $REQUEST_URI &gt; /tmp/pipe_contador"--=
&gt;
</pre>
<p>
Note que a vari=E1vel $REQUEST_URI cont=E9m o nome do arquivo que o browser
requisitou.
</p><p>
<b>PS</b>: assim que tiver tempo vou tentar explicar melhor este t=F3pico.=
=20
</p><p>
<a name=3D"toc14"></a>
</p><h2>3.8. Seguran=E7a</h2>
<p>
<a name=3D"toc15"></a>
</p><h3>3.8.1. Introdu=E7=E3o e Configura=E7=E3o</h3>
<p>
Este =E9 um t=F3pico importante quando falamos sobre CGI, principalmente os=
 que t=EAm algum
tipo de intera=E7=E3o com o usu=E1rio. Mas para aumentar um pouco a seguran=
=E7a de
nossos CGIs podemos utilizar a op=E7=E3o <i>AccessFileName</i> do Apache.=
 Ela nos
permite especificar quais usu=E1rio ter=E3o acesso a um determinado diret=
=F3rio.
Por exemplo, podemos especificar quais usu=E1rios ter=E3o acesso aos script=
s em=20
<code>http://localhost/cgi-bin/controle/</code>
</p><p>
Primeiro vamos configurar o Apache. Procure e, se for o caso, descomente a
seguine linha em seu <i>httpd.conf</i>
</p><p>
</p><pre>  AccessFileName .htaccess
</pre>
<p>
Esta op=E7=E3o define para o Apache o nome do arquivo que ter=E1 as informa=
=E7=F5es
sobre o controle de acesso de cada diret=F3rio. Procure e, se for o caso,
descomente as seguintes linhas para n=E3o deixar nenhum usu=E1rio baixar no=
ssos
arquivos de controle de acesso e de usu=E1rios e senhas.
</p><p>
</p><pre>  &lt;Files ~ "^\.ht"&gt;
      Order allow,deny
      Deny from all
  &lt;/Files&gt;
</pre>
<p>
Este pr=F3ximo passo =E9 necess=E1rio porque normalmente a op=E7=E3o <i>All=
owOverride</i>=20
default =E9 <i>None</i>. Assim, para cada diret=F3rio que voc=EA deseja ter=
 este controle,=20
adicione a seguinte linha em seu <i>httpd.conf</i>:
</p><p>
</p><pre>  &lt;Directory /diretorio/que/tera/htaccess/&gt;
      AllowOverride AuthConfig
  &lt;/Directory&gt;
</pre>
<p>
Agora temos o nosso Apache configurado, vamos configurar o nosso <i>.htacce=
ss</i>.
Este arquivo tem a seguinte estrutura:
</p><p>
</p><pre>  AuthName "Acesso Restrito"
  AuthType Basic
  AuthUserFile /PATH/TO/.htpasswd
 =20
  require valid-user
</pre>
<p>
Onde:
</p><p>
<table align=3D"center" border=3D"1" cellpadding=3D"4">
<tbody><tr>
<td align=3D"center">AuthName</td>
<td>mensagem que ir=E1 aparecer quando pedir o username e passwd</td>
</tr>
<tr>
<td align=3D"center">AuthType</td>
<td>normalmente =E9 Basic</td>
</tr>
<tr>
<td align=3D"center">AuthUserFile</td>
<td>o PATH para o arquivo que cont=E9m a lista de user e senha v=E1lido</td>
</tr>
<tr>
<td>require valid-user</td>
<td>especifica que somente usu=E1rios v=E1lidos ter=E3o acesso</td>
</tr>
</tbody></table>

</p><p>
Vamos a um exemplo. Vamos supor que queremos proteger o acesso ao diret=F3r=
io
/<i>usr/lib/cgi-bin/controle</i>. Configuramos o <i>httpd.conf</i> como des=
crito
acima. Depois criamos o seguinte arquivo neste diret=F3rio.
</p><p>
</p><pre>  AuthName "Acesso Restrito"
  AuthType Basic
  AuthUserFile /usr/lib/cgi-bin/controle/.htpasswd
 =20
  require valid-user
</pre>
<p>
Feito isto, criamos o nosso arquivo com os usu=E1rios v=E1lidos.
<b>Importante</b>: os usu=E1rios que vamos criar n=E3o precisam existir na
m=E1quina, i.e., n=E3o tem nenhuma rela=E7=E3o com o arquivo /<i>etc/passwd=
</i>.
Para criar o arquivo utilizamos o comando:=20
</p><p>
</p><pre>  htpasswd -m -c ./.htpasswd user
</pre>
<p>
Ap=F3s criarmos e adicionarmos o primeiro usu=E1rio, basta tirar a op=E7=E3=
o <i>-c</i>
do comando para adicionar novos usu=E1rios no mesmo arquivo. Exemplo:
<i>htpasswd -m ./.htpasswd outro_user</i>
</p><p>
OBS: a cada execu=E7=E3o do comando aparecer=E1 um prompt pedindo para defi=
nir
uma senha para o usu=E1rio. A op=E7=E3o -m serve para utilizar o algoritmo
MD5 modificado pelo Apache. Mais detalhes: <i>man htpasswd</i>
</p><p>
<a name=3D"toc16"></a>
</p><h3>3.8.2. T=E1, e da=ED? Onde est=E1 o CGI em Shell?</h3>
<p>
Calma, isto que vimos =E9 Apache puro. Mas agora vem o pulo do gato :)
Vamos continuar nosso exemplo.
Crie o seguinte arquivo e coloque em /<i>usr/lib/cgi-bin/controle</i>
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D set.cgi =3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/plain"
  echo
  set
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Depois acesse <code>http://localhost/cgi-bin/controle/set.cgi</code>.
Se tudo ocorreu bem, aparecer=E1 uma tela pedindo usu=E1rio e senha. Entre=
 com
um usu=E1rio e senha que voc=EA cadastrou em <i>./.htpasswd</i>.
Ser=E1 mostrado todas as vari=E1veis de ambiente. D=EA uma olhada na vari=
=E1vel
<b><i>REMOTE_USER</i></b>. =C9 o nome do usu=E1rio que fez o login. Agora=
 podemos ter
CGIs onde s=F3 determinados usu=E1rios podem acessar, e dentre estes usu=E1=
rios
s=F3 alguns ter=E3o acesso a certas op=E7=F5es do script, etc.
</p><p>
Um exemplo :) Vamos imaginar que s=F3 determinados usu=E1rios tem acesso ao=
 CGI
de controle sobre a m=E1quina. Ent=E3o configuramos o Apache, criamos o
<i>.htaccess</i> e cadastramos os usu=E1rios v=E1lidos em <i>.htpasswd</i>,=
=20
isto no diret=F3rio /<i>usr/lib/cgi-bin/controle</i>
</p><p>
Criamos o nosso script de controle:
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D controle.cgi =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo "&lt;html&gt;&lt;head&gt;&lt;title&gt;Controle&lt;/title&gt;&lt;/hea=
d&gt;"
  echo "&lt;body&gt;"
 =20
  echo "Voce esta logado como usuario: &lt;b&gt;$REMOTE_USER&lt;/b&gt;&lt;b=
r&gt;"
 =20
  echo "&lt;form action=3D\"/cgi-bin/controle/controle_post.cgi\" method=3D=
\"POST\"&gt;"
   =20
  echo "&lt;h3&gt;Qual destas opera=E7=F5es voce deseja executar ?&lt;/h3&g=
t;"
 =20
  [ "$REMOTE_USER" =3D "gerente" ] &amp;&amp; {
  echo "&lt;input type=3Dradio name=3Dop value=3Dhalt&gt; Desligar m=E1quin=
a&lt;br&gt;"
  echo "&lt;input type=3Dradio name=3Dop value=3Dreboot&gt; Reinicializar&l=
t;br&gt;"; }
 =20
  echo "
  &lt;input type=3Dradio name=3Dop value=3Dw&gt; Ver quem esta logado&lt;br=
&gt;
  &lt;input type=3Dradio name=3Dop value=3Ddf&gt; Ver uso do disco&lt;br&gt;
  &lt;input type=3Dsubmit value=3DEnviar&gt;
  &lt;/form&gt;
   =20
  &lt;/body&gt;
  &lt;/html&gt;"
 =20
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Ok, especificamos que somente o usu=E1rio <i>gerente</i> ter=E1 acesso as=
 op=E7=F5es
de <i>halt</i> e <i>reboot</i>.
Criamos o script que tratar=E1 este input.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D controle_post.c=
gi =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo "&lt;html&gt;&lt;head&gt;&lt;title&gt;Controle&lt;/title&gt;&lt;/hea=
d&gt;"
  echo "&lt;body&gt;"
 =20
  echo "Voce esta logado como usuario: &lt;b&gt;$REMOTE_USER&lt;/b&gt;&lt;b=
r&gt;"
  op=3D$(sed '/./s/^op=3D//')
 =20
  case  "$op"=20
  in
 =20
  	"halt" )
  		echo "desligando a maquina ..."
  		;;
  	"reboot" )
  		echo "reinicializando a maquina ..."
  		;;
  	"w" )
  		echo "Usu=E1rios logado:"
  		echo "&lt;pre&gt;$(who)&lt;/pre&gt;"
  		;;
  	"df" )
  		echo "Disco"
  		echo "&lt;pre&gt;$(df -Th)&lt;/pre&gt;"
  		;;
  	* )
  		echo "opcao invalida&lt;/body&gt;&lt;/html&gt;"
  		exit
  		;;
  esac
  echo "&lt;/body&gt;&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Bom, tudo tranq=FCilo. Script sem problemas. <b>N=C3O</b>
</p><p>
Pois, se algum usu=E1rio olhar o source HTML da p=E1gina
<code>http://localhost/cgi-bin/controle/controle.cgi</code>, ele ver=E1 os=
 inputs do
FORM. Assim, ele sabe que o que =E9 enviado pelo POST no nosso exemplo =E9
<i>op=3Dxx</i>.=20
Ele n=E3o enxergar=E1 as op=E7=F5es <i>halt</i> e <i>reboot</i>, mas ele pe=
rceber=E1 que s=E3o
comandos e que o CGI =E9 para executar algum comando sobre a m=E1quina.
Ent=E3o fizemos o seguinte comando.
</p><p>
</p><pre>  echo "op=3Dhalt" | lynx -dump -post-data -auth=3Duser:senha \
  http://localhost/cgi-bin/controle/controle_post.cgi
</pre>
<p>
<table align=3D"center" border=3D"1" cellpadding=3D"4">
<tbody><tr>
<td>No <i>user:senha</i>, coloque um user e senha v=E1lido, mas use um user=
 diferente de <i>gerente</i></td>
</tr>
</tbody></table>

</p><p>
Note que estamos indo direto a segunda p=E1gina <i>controle_post.cgi</i>.
O lynx pra quem n=E3o sabe =E9 um browser modo texto. No exemplo, ele est=E1
enviando os dados que recebeu da entrada padr=E3o via o m=E9todo POST
para aquela URL.
</p><p>
Como no script controle_post.cgi n=E3o existe nenhum controle de usu=E1rio,=
 o
nosso usu=E1rio !=3D de gerente conseguiu desligar a nossa m=E1quina. :/
</p><p>
Ent=E3o vamos arrumar:
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D controle_post.c=
gi =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo "&lt;html&gt;&lt;head&gt;&lt;title&gt;Controle&lt;/title&gt;&lt;/hea=
d&gt;"
  echo "&lt;body&gt;"
 =20
  echo "Voce esta logado como usuario: &lt;b&gt;$REMOTE_USER&lt;/b&gt;&lt;b=
r&gt;"
  op=3D$(sed '/./s/^op=3D//')
 =20
  case  "$op"=20
  in
 =20
  	"halt" )
  			[ "$REMOTE_USER" !=3D "gerente" ] &amp;&amp; { echo "opcao invalida"
  			set &gt;&gt; "/tmp/CGI_halt_$REMOTE_ADDR"; echo "&lt;/body&gt;&lt;/htm=
l&gt;"; exit; }
  			echo "desligando a maquina ..."
  			;;
  	"reboot" )
  			[ "$REMOTE_USER" !=3D "gerente" ] &amp;&amp; { echo "opcao invalida"
  			set &gt;&gt; "/tmp/CGI_reboot_$REMOTE_ADDR"; echo "&lt;/body&gt;&lt;/h=
tml&gt;"; exit; }
  			echo "reinicializando a maquina ..."
  			;;
  	"w" )
  			echo "Usu=E1rios logado:"
  			echo "&lt;pre&gt;$(who)&lt;/pre&gt;"
  			;;
  	"df" )
  			echo "Disco"
  			echo "&lt;pre&gt;$(df -Th)&lt;/pre&gt;"
  			;;
  	* )
  			echo "opcao invalida&lt;/body&gt;&lt;/html&gt;"
  			exit
  			;;
  esac
  echo "&lt;/body&gt;&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Moral da hist=F3ria: quando utilizar intera=E7=E3o com o usu=E1rio tem que=
 testar
tudo!!! teste, teste, teste. Verifique as opc=F5es, vari=E1veis, etc.
</p><p>
<a name=3D"toc17"></a>
</p><h1>4. LAN  +_+</h1>
<p>
Exemplo pr=E1tico. Vamos monitorar os host de nossa LAN. Saber quais est=E3o
ativos, quais n=E3o respondem e informa=E7=F5es sobre um determinado host.
Este fonte =E9 apenas uma estrutura b=E1sica, mas server para se ter uma id=
=E9ia
do qu=E3o poderoso pode ficar um CGI em Shell.
Crie os seguintes arquivos em /usr/lib/cgi-bin/lan
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D lan.cgi =3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo "&lt;html&gt;"
  echo "&lt;head&gt;"
  echo "&lt;title&gt;Monitoramento da LAN&lt;/title&gt;"
  # Descomente se quiser auto refresh
  #echo "&lt;meta http-equiq=3D\"refresh\" content=3D\"10;url=3D/cgi-bin/la=
n/lan.cgi\"&gt;"
  echo "&lt;/head&gt;"
 =20
  echo "
  &lt;body bgcolor=3Dwhite&gt;
  &lt;div align=3Dright&gt;Usu=E1rio: &lt;b&gt;$REMOTE_USER&lt;/b&gt;&lt;/d=
iv&gt;
  &lt;center&gt;&lt;h2&gt;M=E1quinas da LAN&lt;/h2&gt;
  &lt;form method=3D\"post\" action=3D\"lan_info.cgi\"&gt;
  &lt;table widthborder=3D0 cellpadding=3D2&gt;"
 =20
  # arquivo contendo o nome dos host a monitorar
  FILE_host=3D"host"
  maxcol=3D4
  numcol=3D1
  for host in $(cat "$FILE_host" | sort -g -tl -k2);do
  	[ $numcol =3D 1 ] &amp;&amp; echo "&lt;tr&gt;"
  	# depedendo da versao do ping existe a opcao -w, que especifica quantos
  	# segundo o ping deve esperar por resposta. coloque -w1 para agilizar o
  	# tempo de resposta
  	ping -c1 "$host" &gt; /dev/null 2&gt;&amp;1
 =20
  	if [ $? -eq 0 ];then
  		echo "&lt;td align=3D\"center\"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;im=
g src=3D\"/icons/penguin_on.jpg\" alt=3D\"$host OK\" border=3D0&gt;&lt;/a&g=
t;&lt;/td&gt;"
  		echo "&lt;td&gt;&lt;input type=3Dradio name=3Dhost value=3D\"$host\"&gt=
;&lt;br&gt;$host&lt;/td&gt;"
  	elif [ $? -eq 1 ] ;then
  		echo "&lt;td align=3D\"center\"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;im=
g src=3D\"/icons/penguin_off.jpg\" alt=3D\"Sem reposta da $host\" border=3D=
0&gt;&lt;/a&gt;&lt;/td&gt;"
          echo "&lt;td&gt;&lt;br&gt;$host&lt;/td&gt;"
  	elif [ $? -eq 2 ] ;then=20
  		echo "&lt;td align=3D\"center\"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;im=
g src=3D\"/icons/penguin_off.jpg\" alt=3D\"$host nao existe\" border=3D0&gt=
;&lt;/a&gt;&lt;/td&gt;"
          echo "&lt;td&gt;&lt;br&gt;$host&lt;/td&gt;"
  	fi
 =20
  	[ $numcol =3D 4 ] &amp;&amp; { echo "&lt;/tr&gt;"; numcol=3D1; } || numc=
ol=3D$(($numcol+1))
  done
 =20
  echo "
  &lt;/table&gt;&lt;br&gt;
 =20
  &lt;input type=3Dsubmit name=3D\"botao\" value=3D\"info\"&gt; &amp;nbsp;&=
amp;nbsp;&amp;nbsp;
  &lt;input type=3Dsubmit name=3D\"botao\" value=3D\"processos\"&gt; &amp;n=
bsp;&amp;nbsp;&amp;nbsp;
 =20
  &lt;/form&gt;
  &lt;/center&gt;
  &lt;/body&gt;&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Abaixo o script que receber=E1 os pedidos da p=E1gina principal.
Para buscar informa=E7=F5es nos outros <i>hosts</i> estou utilizando um
<i>rsh</i>. Voc=EA tamb=E9m pode utilizar ssh, =E9 s=F3 trocar.
</p><p>
PS: n=E3o se esque=E7a que para executar o rsh, ele precisa estar configura=
do e
n=E3o pedir senha. Para testar <i>rsh host ls</i>. O usu=E1rio default do=
 Apache
n=E3o tem shell, assim voc=EA precisa rod=E1-lo com um outro usu=E1rio.
</p><p>
</p><pre>  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D lan_info.cgi =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  #!/bin/bash
 =20
  echo "content-type: text/html"
  echo
  echo "&lt;html&gt;
  &lt;head&gt;
  &lt;title&gt;Monitoramento da LAN&lt;/title&gt;&lt;/head&gt;
 =20
  &lt;body bgcolor=3Dwhite&gt;
  &lt;div align=3Dright&gt;Usu=E1rio: &lt;b&gt;$REMOTE_USER&lt;/b&gt;&lt;/d=
iv&gt;"
 =20
  VAR=3D$(sed -n '1p')
  host=3D$(echo "$VAR" | sed 's/^host=3D\(.*\)\&amp;.*$/\1/')
  botao=3D$(echo "$VAR" | cut -d=3D -f3)
 =20
  [ "$host" -a "$botao" ] || { echo "Opcao invalida&lt;/body&gt;&lt;/html&g=
t;";exit; }
 =20
  if [ "$botao" =3D "info" ];then
  	ip=3D$(ping -c1 "$host"  2&gt; /dev/null | sed -n '/^PING/{s/^.*(\([0-9\=
.]\+\)):.*$/\1/;p;}')
  	echo "&lt;center&gt;&lt;h2&gt;Informacoes da maquina: &lt;i&gt;$host&lt;=
/i&gt;&lt;/h2&gt;&lt;/center&gt;"
  	echo "&lt;strong&gt;Nome:&lt;/strong&gt; $host&lt;br&gt;"
  	echo "&lt;strong&gt;IP:&lt;/strong&gt;   $ip&lt;br&gt;"
  	echo "&lt;br&gt;"
 =20
  	saida=3D$(rsh "$host" cat /proc/version)
  	[ "$?" -eq "0" ] &amp;&amp; echo "&lt;strong&gt;Sistema Operacional&lt;/=
strong&gt;&lt;pre&gt;$saida&lt;/pre&gt;"
 =20
  	saida=3D$(rsh "$host" uptime)
  	[ "$?" -eq "0" ] &amp;&amp; echo "&lt;strong&gt;uptime&lt;/strong&gt;&lt=
;pre&gt;$saida&lt;/pre&gt;"
 =20
 =20
  	saida=3D$(rsh "$host" cat /proc/cpuinfo)
  	[ "$?" -eq "0" ] &amp;&amp; echo "&lt;strong&gt;Informacoes da CPU&lt;/s=
trong&gt;&lt;pre&gt;$saida&lt;/pre&gt;"
 =20
  	saida=3D$(rsh "$host" free -ok)
  	[ "$?" -eq "0" ] &amp;&amp; echo "&lt;strong&gt;Informacoes de Memoria&l=
t;/strong&gt;&lt;pre&gt;$saida&lt;/pre&gt;"
  	mem=3D$(rsh $host cat /proc/meminfo)
  	percent=3D`echo "$mem" | sed -n '2p' | awk '{printf("%d",$3*100/$2)}'`
  	used=3D$(echo "$percent*2" | bc); free=3D$(echo "200-$percent*2" | bc)
  	echo "
  	&lt;table border=3D0 cellspacing=3D0 cellpadding=3D2&gt;
  	&lt;tr&gt;
  	&lt;td&gt;&lt;font size=3D\"3\"&gt;0%&lt;/font&gt;&lt;/td&gt;
  	&lt;td align=3Dcenter width=3D$used bgcolor=3Dred&gt;&lt;font size=3D\"3=
\" color=3Dwhite&gt;$percent%&lt;/font&gt;&lt;/td&gt;
  	&lt;td width=3D$free bgcolor=3Dgreen&gt;&lt;font size=3D\"3\"&gt;&amp;nb=
sp;&lt;/font&gt;&lt;/td&gt;
  	&lt;td&gt;&lt;font size=3D\"3\"&gt;100%&lt;/font&gt;&lt;/td&gt;
  	&lt;/tr&gt;
  	&lt;/table&gt;"
  	echo "&lt;br&gt;&lt;br&gt;&lt;strong&gt;Detalhes:&lt;/strong&gt;"
  	echo "&lt;pre&gt;$(echo "$mem" | sed '1,3d')"
  	echo "&lt;br&gt;&lt;br&gt;&lt;/pre&gt;"
 =20
  	echo "&lt;strong&gt;Informacoes de Disco&lt;/strong&gt;&lt;br&gt;"
  	echo "Discos SCSI &lt;br&gt;"
  	echo "&lt;pre&gt;$(rsh "$host" cat /proc/scsi/scsi 2&gt; /dev/null)&lt;/=
pre&gt;"
 =20
  	echo "Discos IDE:&lt;br&gt; "
 =20
  	for i in a b c d; do
  		TEMP=3D$(rsh "$host" "test -L \"/proc/ide/hd$i\" &amp;&amp; echo sim")
  		[ "$TEMP" =3D "sim" ] &amp;&amp; \
  		echo -n "hd$i : $(rsh "$host" cat "/proc/ide/hd$i/{media,model}" | sed=
 'N;s/\n/ /')&lt;br&gt;"=20
  	done
 =20
  	echo "&lt;br&gt;Particoes dos Discos"
  	echo "&lt;pre&gt;$(rsh "$host" cat /proc/partitions)&lt;/pre&gt;"
  	echo "&lt;pre&gt;$(rsh "$host" df -Th)&lt;/pre&gt;"
  	echo "&lt;strong&gt;&lt;i&gt;swap&lt;/i&gt;&lt;/strong&gt;&lt;pre&gt;$(r=
sh "$host" cat /proc/swaps)&lt;/pre&gt;"
 =20
 =20
  elif [ "$botao" =3D "processos" ];then=20
  	saida=3D$(rsh "$host" ps aux)
  	[ "$?" -eq "0" ] &amp;&amp; echo "&lt;strong&gt; Informacoes sobre os pr=
ocessos da \
  	maquina: &lt;i&gt;$host&lt;/i&gt;&lt;/strong&gt;&lt;pre&gt;$saida&lt;/pr=
e&gt;"
  fi
  echo "&lt;/body&gt;&lt;/html&gt;"
  =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
</pre>
<p>
Voc=EA precisa baixar estas duas imagens utilizadas para mostrar se os hosts
est=E3o respondendo ou n=E3o.=20
<table border=3D"0" cellpadding=3D"4">
<tbody><tr>
<td><img src=3D"file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/=
1386028472470_207/1385001845582_358/index_files/penguin_on.jpg" align=3D"mi=
ddle" border=3D"0"></td>
<td><img src=3D"file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/=
1386028472470_207/1385001845582_358/index_files/penguin_off.jpg" align=3D"m=
iddle" border=3D"0"></td>
</tr>
</tbody></table>

</p><p>
<a name=3D"toc18"></a>
</p><h1>5. Resum=E3o</h1>
<b><i>POST &amp; GET</i></b>
<p>
No GET voc=EA pega as op=E7=F5es atrav=E9s da vari=E1vel de ambiente
<b><i>$QUERY_STRING</i></b>. No POST voc=EA pega atrav=E9s da entrada padr=
=E3o, ex:
</p><pre>  VAR=3D$(sed -n '1p')
</pre>
Ap=F3s isto =E9 s=F3 pegar as op=E7=F5es nestas vari=E1veis e fazer o script
necess=E1rio.
<p>
</p><hr noshade=3D"noshade" size=3D"5">
<p>
Bom, com este texto espero ter dado uma vis=E3o geral de como funciona CGI=
 em
Shell Script. Assim que tiver tempo vou procurar incrementar o texto
adicionando novos exemplo, explicando mais os conceitos...=20
</p><p>
Se voc=EA quiser contribuir, me envie um <a href=3D"mailto:thobias@lcp.copp=
e.ufrj.br">mail</a> =3D8)
</p><p>
<table border=3D"1" cellpadding=3D"4">
<tbody><tr>
<td><b>Pessoas que ajudaram</b></td>
</tr>
</tbody></table>

</p><p>
</p><ul>
<li>Silvano B. Dias
</li><li>Aur=E9lio Marinho Jargas
</li><li>Vin=EDcius Della L=EDbera
</li><li>Julio Cezar Neves
</li></ul>
<hr noshade=3D"noshade" size=3D"1">
<p>
This HTML page is <a href=3D"http://txt2tags.sf.net/"><img src=3D"file:///C=
:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/1386028472470_207/1385001=
845582_358/index_files/pwrbytxt2tags-2.png" align=3D"middle" border=3D"0"><=
/a>
(see <a href=3D"http://thobias.org/doc/cgi_shell.t2t">source</a>)
</p><p>
<script src=3D"urn:snapshot-22AB5226:file:///C:/Users/DaLuz/AppData/Local/T=
emp/maftemp-3cd13269/1386028472470_207/1385001845582_358/index_files/urchin=
.js" type=3D"text/javascript">
</script>
<script type=3D"text/javascript"><!--

/* Script removed by snapshot save */

--></script>

<!-- html code generated by txt2tags 1.6 (http://txt2tags.sf.net) -->
<!-- cmdline: txt2tags -\-toc -t html -\-enumtitle cgi_shell.t2t -->

</p><object style=3D"position: absolute; left: 0px; top: 0px;" type=3D"appl=
ication/gas-events-uni" id=3D"bb599ac9-9b78-b6af-fa39-a9baea978ea4" height=
=3D"0" width=3D"0"></object><object style=3D"position: absolute; left: 0px;=
 top: 0px;" type=3D"application/gas-events-cef" id=3D"7b98290b-f82a-a29b-2b=
09-58b57ba89b85" height=3D"0" width=3D"0"></object><object style=3D"positio=
n: absolute; left: 0px; top: 0px;" type=3D"application/gas-events-bb" id=3D=
"9afb5b39-1b99-93a8-0b4a-5995a8a39da2" height=3D"0" width=3D"0"></object></=
body></html>
------=_NextPart_000_0000_6D0A9E5D.23B91C28
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Location: file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/1386028472470_207/1385001845582_358/index_files/penguin_on.jpg

[encoded data, 4408 characters]
mFriYAImYEYifz//2Q==
------=_NextPart_000_0000_6D0A9E5D.23B91C28
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Location: file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/1386028472470_207/1385001845582_358/index_files/penguin_off.jpg

[encoded data, 5168 characters]
qwwweqwbUDBjmLFIuW9rf//Z
------=_NextPart_000_0000_6D0A9E5D.23B91C28
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Location: file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/1386028472470_207/1385001845582_358/index_files/pwrbytxt2tags-2.png

iVBORw0KGgoAAAANSUhEUgAAAHoAAAASAgMAAADpkCJAAAAACVBMVEUAAADAwMD///8Nbde7AAAA
B3RJTUUH0gMTECEFdv3XOQAAABV0RVh0U29mdHdhcmUAWFBhaW50IDIuNi4xXVHhJgAAAMJJREFU
eJyN0jsKwzAMAFChKWjqEUImoVN0DJ269D5GU9EphCehU1ZJWkjpV9h4eJb8hcvXOMMRvsUBTvkU
/tlD9OHk7/KllzMANmb+12cMHkbvRC7OPGbvlszpid2i8rnb0qpLDZWf2KAGNJJh80EbBy4+FjC2
WgHSquTmV7OIXHza8qkmqRHc66voNXhxdZ66au1vKmcuxxATHwXdXMxJtYUEtey51pf99dn+/mg9
/5PLi8+049g7xj/v8+t9f/yPG1CYp8cR/O6lAAAAAElFTkSuQmCC
------=_NextPart_000_0000_6D0A9E5D.23B91C28
Content-Type: text/javascript
Content-Transfer-Encoding: quoted-printable
Content-Location: urn:snapshot-22AB5226:file:///C:/Users/DaLuz/AppData/Local/Temp/maftemp-3cd13269/1386028472470_207/1385001845582_358/index_files/urchin.js

/* Script removed by snapshot save */

------=_NextPart_000_0000_6D0A9E5D.23B91C28--
