<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Blog do Fabrício</title>
    <description>Desenvolvedor C#, Java, Javascript e Go que procura sempre acompanhar o mercado que está em constante mutação.
</description>
    <link>https://fgodoy.me/</link>
    <atom:link href="https://fgodoy.me/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 05 Nov 2016 19:02:27 -0200</pubDate>
    <lastBuildDate>Sat, 05 Nov 2016 19:02:27 -0200</lastBuildDate>
    <generator>Jekyll v3.1.6</generator>
    
      <item>
        <title>Entendendo a vulnerabilidade de segurança do JWT</title>
        <description>&lt;div id=&quot;toc&quot; class=&quot;toc&quot;&gt;
&lt;div id=&quot;toctitle&quot;&gt;Table of Contents&lt;/div&gt;
&lt;ul class=&quot;sectlevel1&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;Introdução&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#base-concepts&quot;&gt;Conceitos Iniciais&lt;/a&gt;
&lt;ul class=&quot;sectlevel2&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#hash_checksum&quot;&gt;Hash (Checksum)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#criptografia_simétrica&quot;&gt;Criptografia Simétrica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#criptografia_assimétrica&quot;&gt;Criptografia Assimétrica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assinaturas&quot;&gt;Assinaturas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#json_web_token_jwt&quot;&gt;JSON Web Token (JWT)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#analysis&quot;&gt;Análise das Vulnerabilidades&lt;/a&gt;
&lt;ul class=&quot;sectlevel2&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#algoritmo_nulo&quot;&gt;Algoritmo Nulo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#criptografia_simétrica_vs_assimétrica&quot;&gt;Criptografia Simétrica vs Assimétrica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#recomendações&quot;&gt;Recomendações&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;intro&quot;&gt;Introdução&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Em março de 2015 Tim McLean publicou em um &lt;a href=&quot;https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/&quot;&gt;blog&lt;/a&gt; que após analisar várias
implementações do JSON Web Token (&lt;a href=&quot;https://tools.ietf.org/html/rfc7519&quot;&gt;JWT&lt;/a&gt;) descobriu vulnerabilidades que
permitiam que a etapa de verificação pudesse ser burlada.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;E nesse artigo vamos entender exatamente como essas vulnerabilidades podem ser
exploradas, tanto para auditar uma biblioteca existente quanto para evitar erros
ao utilizar quaisquer bibliotecas existentes.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;base-concepts&quot;&gt;Conceitos Iniciais&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Antes de analisarmos a vulnerabilidade, irei revisar os conceitos básicos
necessários para entender os problemas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;hash_checksum&quot;&gt;Hash (Checksum)&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os algoritmos de soma hash são algoritmos que retornam um resultado de
&lt;strong&gt;comprimento fixo&lt;/strong&gt; independente do tamanho da entrada, e esse resultado é
&lt;strong&gt;quase&lt;/strong&gt; exclusivo para os dados de entrada. Os algoritmos mais conhecidos são:
MD5, SHA-1 e SHA-2.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Como os resultados retornados por tais algoritmos são apenas apenas uma soma dos
dados de entrada não há como inferir os dados de entrada através do resultado.
Esses resultados são muito úteis para verificação de integridade, pois se espera
que qualquer alteração nos dados de entrada os resultados sejam diferentes.&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-none grid-rows spread&quot;&gt;
&lt;caption class=&quot;title&quot;&gt;Tabela 1. Exemplos de Hashes&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33.3333%;&quot;&gt;
&lt;col style=&quot;width: 66.6667%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Mensagem&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Hash&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Oi&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;lxFc&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Olá, como vai?&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;R+bU&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Bem-vindo&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;IB84&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;criptografia_simétrica&quot;&gt;Criptografia Simétrica&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os algoritmos de criptografia simétrica utilizam apenas uma chave para
criptografar um dado qualquer, que pode ser uma mensagem, um arquivo, um pacote
de dados etc. Os algoritmos mais conhecidos são: DES, TripleDES, AES, RC4 e RC5.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A principal vantagem de algoritmos de criptografia simétrica é que são muito
rápidos, o que se traduz em baixa latência e pouco uso de CPU. Já a
principal desvantagem é que por utilizar a mesma chave quanto para criptografar
quanto para descriptografar, essa chave precisa ser compartilhada com o
receptor.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/crypt-sym-alg.png&quot; alt=&quot;Diagrama conceitual&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 1. Envio de Dados com Criptografia Simétrica&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/crypt-sym-alg2.png&quot; alt=&quot;Diagrama conceitual&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 2. Recebimento de Dados com Criptografia Simétrica&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;criptografia_assimétrica&quot;&gt;Criptografia Assimétrica&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os algoritmos de criptografia assimétrica utilizam duas chaves complementares
para criptografar e descriptografar. Uma das chaves é guardada em segredo e não
é revelada ninguém e outra pode ser publicada a qualquer um livremente. Os
algoritmos mais conhecidos são: RSA e ECDSA.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Um grande diferencial dessa classe de algoritmos é que um dado criptografado com
uma chave pode apenas ser descriptografado com outra e vice-versa. Essa
característica permite que estranhos mantenham uma comunicação segura mesmo que
o meio de comunicação não o seja, e além disso, não há a necessidade de um meio
seguro para que a troca de chave ocorra.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Algoritmos de criptografia assimétrica são muito custosos em termos de CPU, por
esse motivo as comunicações, normalmente, os utilizam como meio de troca de
chave simétrica. Diminuindo, assim o tempo e recursos da CPU.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/crypt-asym-alg.png&quot; alt=&quot;Diagrama conceitual&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 3. Envio de Dados com Criptografia Assimétrica&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/crypt-asym-alg2.png&quot; alt=&quot;Diagrama conceitual&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 4. Recebimento de Dados com Criptografia Assimétrica&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;assinaturas&quot;&gt;Assinaturas&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Há também outro uso muito comum para a criptografia assimétrica, além de ser
utilizada para garantir privacidade, também é utilizada em assinaturas para
garantir identidade.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quando Anderson quer enviar um dado sigiloso para Roberta, ele utiliza a chave
pública de Roberta para garantir que apenas Roberta consiga descriptografar o
dado enviado. Entretanto, quando Roberto quer confirmar que um dado foi gerado
por ele, o mesmo pode utilizar a chave privada para criptografar o dado e assim
qualquer um com sua chave pública pode confirmar a identidade descriptografando
o dado.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Apesar de eficaz, criptografar todo o dado para garantir identidade não é muito
usual. O problema é que dependendo da aplicação é um gasto de recursos
desnecessário.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quando queremos apenas confirmar identidade o dado não é privado, pois a chave
pública está disponível a qualquer um, o que permite que os
mesmos acessem os dados. Assim, uma maneira eficiente de alcançar o mesmo
objetivo, com quase a mesma eficiência, é gerar uma soma Hash (Checksum) do dado
e criptografar esse resultado. Então a confirmação de identidade passaria a ser
da seguinte maneira: gerar uma soma Hash do dado recebido, descriptografar a
assinatura recebida e por fim comparar se os resultados são iguais.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/sign-alg.png&quot; alt=&quot;Diagrama conceitual&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 5. Assinatura de Dados com Criptografia Assimétrica&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Por fim existe a possibilidade combinar a garantia de identidade e a garantia de
de privacidade ao mesmo tempo. Para tal basta realizar todo o processo de
assinatura e, antes de enviar os dados, criptografar tudo utilizando a chave
pública do destinatário.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;json_web_token_jwt&quot;&gt;JSON Web Token (JWT)&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O padrão JSON Web Token (&lt;a href=&quot;https://tools.ietf.org/html/rfc7519&quot;&gt;RFC 7519&lt;/a&gt;) define uma maneira segura, compacta e
independente de transmitir informações usando como base objetos &lt;a href=&quot;http://www.json.org/&quot;&gt;JSON&lt;/a&gt;. A
confiabilidade das informações são asseguradas via assinaturas, conforme a
técnica que abordamos na seção anterior.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O padrão JWT permite as informações sejam assinadas tanto com criptografia
simétrica (com o algoritmo HMAC) quanto com criptografia assimétrica (com os
algoritmos RSA e ECDSA).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;JWTs são compactos de uma maneira que permite que os mesmos sejam transmitidos
junto ao cabeçalho de uma requisição HTTP ou até na URL. Adicionalmente, JWTs
são independentes pois os mesmos podem carregar toda informação necessária sem
que seja necessário uma consulta no banco de dados.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os JWTs são muito utilizados no processo de autenticação permitindo que o
processo de autorização de acesso a recursos seja mais rápido e escalável.
Mais rápido porque por ser independente retira da equação o tempo de latência
de acesso ao banco de dados ou outro mecanismo de cache. E mais escalável pois
permite que serviços totalmente independentes compartilhem a mesma autenticação
sem necessitar de comunicação entre os mesmos.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;estrutura&quot;&gt;Estrutura&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A estrutura de um JWT contém três partes separadas por pontos (&lt;code&gt;.&lt;/code&gt;), que são: o
cabeçalho, informação útil e a assinatura.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect4&quot;&gt;
&lt;h5 id=&quot;cabeçalho&quot;&gt;Cabeçalho&lt;/h5&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A implementação mais básica do cabeçalho contém dois campos: um que define o
tipo de token e outro que define o algoritmo utilizado. O tipo de token sempre é
&lt;code&gt;JWT&lt;/code&gt; e o algoritmo é uma combinação de soma Hash com algoritmo de criptografia.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Exemplo de cabeçalho JWT (RSA + SHA-384)&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;alg&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;RS384&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;typ&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;JWT&amp;quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Esse cabeçalho é codificado utilizando o algoritmo &lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;Base64Url&lt;/a&gt;, antes de compor
um JWT.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect4&quot;&gt;
&lt;h5 id=&quot;informação_Útil_payload&quot;&gt;Informação Útil (Payload)&lt;/h5&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Essa parte do JWT contém as afirmações (&lt;em&gt;claims&lt;/em&gt;, em inglês). As afirmações são
confirmações sobre uma entidade, normalmente um usuário, e alguns dados
adicionais.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Há um conjunto de afirmações pré-definidas pelo padrão que são reservadas, como
&lt;code&gt;iss&lt;/code&gt; (emissor), &lt;code&gt;exp&lt;/code&gt; (data de expiração), &lt;code&gt;sub&lt;/code&gt; (entidade), &lt;code&gt;aud&lt;/code&gt;
(destinatário) etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Exemplo de &lt;em&gt;payload&lt;/em&gt; JWT&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;iss&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;accounts.google.com&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;sub&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;110169484474386276334&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;aud&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;iat&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;1433978353&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;exp&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;1433981953&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;email&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;testuser@gmail.com&amp;quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A &lt;em&gt;informação útil&lt;/em&gt; também é codificada utilizando o algoritmo &lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;Base64Url&lt;/a&gt;, antes
de compor a segunda parte do JWT.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect4&quot;&gt;
&lt;h5 id=&quot;assinatura&quot;&gt;Assinatura&lt;/h5&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A assinatura é criada a partir das seguintes informações: cabeçalho codificado
com Base64Url, a &lt;em&gt;informação útil&lt;/em&gt; codificada com Base64Url, uma chave para
criptografia e um algoritmo de soma Hash e criptografia.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Exemplo do algoritmo de assinatura com RSA PKCS#1 e SHA-256&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;// Algoritmo RS256&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;var&lt;/span&gt; hash &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; sha256(
    base64UrlEncode(header) &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt;
    base64UrlEncode(payload));
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;var&lt;/span&gt; signature &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; rsaPKCS1(hash, key);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Da mesma maneira que nas partes anteriores a assinatura também é codificada
utilizando o algoritmo &lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;Base64Url&lt;/a&gt;, antes de compor o JWT.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect4&quot;&gt;
&lt;h5 id=&quot;conclusão&quot;&gt;Conclusão&lt;/h5&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O resultado final são três partes codificadas com &lt;code&gt;Base64Url&lt;/code&gt; e separadas por
pontos. Como demonstrado no exemplo logo abaixo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Exemplo do resultado final de um JWT&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O resultado do exemplo acima foi calculado utilizando os seguintes dados:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Cabeçalho&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;alg&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;HS256&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;typ&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;JWT&amp;quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Informação Útil&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;sub&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;1234567890&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;John Doe&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;admin&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;true&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Assinatura&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;hmacSha256(
    base64UrlEncode(header) &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;+&lt;/span&gt;
    base64UrlEncode(payload),
    &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;secret&amp;quot;&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Você pode realizar testes e colocar esses conceitos em prática no site &lt;a href=&quot;https://jwt.io/&quot;&gt;jwt.io&lt;/a&gt;.
Lá você pode decodificar, verificar e gerar JWTs, tudo online no navegador.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;analysis&quot;&gt;Análise das Vulnerabilidades&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Finalmente irei abordar as vulnerabilidades encontradas nas implementações do
JSON Web Token.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;algoritmo_nulo&quot;&gt;Algoritmo Nulo&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quando um &lt;em&gt;token&lt;/em&gt; precisa ser validado o primeiro passo é determinar o algoritmo
utilizado pelo mesmo, como é indicado pelo campo &lt;code&gt;alg&lt;/code&gt; do cabeçalho.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Isso significa que entramos num dilema, o próprio &lt;em&gt;token&lt;/em&gt; indica qual algoritmo
deve ser utilizado para validar a si próprio. E isso pode ser desastroso,
dependendo da implementação.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No padrão JWT há a opção de algoritmo identificado como &lt;code&gt;none&lt;/code&gt; indicando um
algoritmo nulo, o que significa que não foi utilizado nenhum algoritmo para
gerar uma assinatura para o &lt;em&gt;token&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Exemplo de cabeçalho JWT com algoritmo nulo&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;{
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;alg&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;none&amp;quot;&lt;/span&gt;,
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;&amp;quot;typ&amp;quot;&lt;/span&gt;: &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;JWT&amp;quot;&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O problema é que algumas bibliotecas aceitam &lt;em&gt;tokens&lt;/em&gt; com algoritmo nulo como se
tivessem uma assinatura válida. O que abre uma vulnerabilidade enorme,
permitindo que qualquer atacante possa criar um &lt;em&gt;token&lt;/em&gt; válido.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A maioria das implementações resolveram esse problema rejeitando algoritmos
nulos quando uma chave de criptografia é passada como parâmetro.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;criptografia_simétrica_vs_assimétrica&quot;&gt;Criptografia Simétrica vs Assimétrica&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Aceitar algoritmos nulos não é o real problema, o problema é aceitar que
atacantes controlem o algoritmo de criptografia.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Se a biblioteca aceita que um &lt;em&gt;token&lt;/em&gt; seja validado sem especificar o algoritmo
esperado, outra vulnerabilidade grave é aberta. Exatamente no caso esperarmos
que o &lt;em&gt;token&lt;/em&gt; use uma criptografia assimétrica e o atacante utiliza uma
criptografia simétrica.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://fgodoy.me/images/2016-05-22/jwt-alg.png&quot; alt=&quot;Diagrama de Atividade&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figura 6. Lógica de validação de assinatura JWT&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O problema com essa lógica é que o atacante pode obter a chave pública e assinar
um &lt;em&gt;token&lt;/em&gt; qualquer utilizando um algoritmo simétrico (HMAC) e indicar no
cabeçalho o mesmo algoritmo. Assim quando um recurso protegido utilizar o mesmo
algoritmo e a mesma chave o token será considerado válido, pois a &lt;strong&gt;assinatura
gerada&lt;/strong&gt; será igual a &lt;strong&gt;assinatura do token&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Lembrando que nesse caso como os tokens válidos estão sendo assinados com a
chave privada os mesmos devem ser validados com a chave pública. Por isso o
atacante terá sucesso, pois tem a certeza que o token está sendo validado com a
chave pública.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;recomendações&quot;&gt;Recomendações&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Desenvolvedores deveriam exigir que o algoritmo utilizado para validação seja
passado como parâmetro. Assim garante-se que será utilizado o algoritmo
apropriado para a chave fornecida.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Caso seja necessária a utilização de mais de um algoritmo com chaves diferentes,
a solução é atribuir um identificador para cada chave e indicá-la no campo &lt;code&gt;kid&lt;/code&gt;
do cabeçalho (&lt;em&gt;key identifier&lt;/em&gt;, em inglês). Assim será possível inferir o
algoritmo de acordo com a chave utilizada. Dessa maneira o campo &lt;code&gt;alg&lt;/code&gt; não terá
utilidade alguma além de, talvez, validar se ele indica o algoritmo esperado.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Ao utilizar uma implementação do padrão JWT, você deve auditar de maneira
consistente se ela rejeita efetivamente algoritmos além do esperado. Assim a
possibilidade de sucesso em ataques dessa natureza estarão quase nulos.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sat, 21 May 2016 21:00:00 -0300</pubDate>
        <link>https://fgodoy.me/2016/05/jwt-hole/</link>
        <guid isPermaLink="true">https://fgodoy.me/2016/05/jwt-hole/</guid>
        
        <category>vulnerabilidade</category>
        
        <category>segurança</category>
        
        <category>seguranca</category>
        
        <category>bug</category>
        
        <category>jwt</category>
        
        <category>criptografia</category>
        
        <category>json</category>
        
        
        <category>Programação</category>
        
      </item>
    
      <item>
        <title>Configurações de /proc/sys/net/ipv4/route</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Vou falar um pouco das configurações de roteamento disponíveis em
&lt;em&gt;/proc/sys/net/ipv4/route&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;error_burst&lt;/strong&gt;: Define, em interrupções de timer, o tempo máximo
contabilizado para exibir uma mensagem. O valor predefinido corresponde
a 5 segundos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;error_cost&lt;/strong&gt;: Define, em interrupções de timer, o tempo mínimo para
exibir uma mensagem. O valor predefinido corresponde a 1 segundo.&lt;/p&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os valores predefinidos de &lt;em&gt;error_burst&lt;/em&gt; e &lt;em&gt;error_cost&lt;/em&gt; limitam a uma
mensagem a cada 5 segundos.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;flush&lt;/strong&gt;: Escrever nesse arquivo faz com que o cache de roteamento seja
descartado.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_elasticity&lt;/strong&gt;: É usado para definir o tamanho médio da lista de
rotas, quando excedido a coleta de lixo na tabela de rotas se torna
muito agressiva
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_1&quot; class=&quot;footnote&quot; href=&quot;#_footnote_1&quot; title=&quot;View footnote.&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_interval&lt;/strong&gt;: Define, em segundos, o intervalo entre coletas lixo na
tabela de rotas. Existe uma recomendação para que a coleta não seja
muito frequente pois é uma operação muito pesada
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_2&quot; class=&quot;footnote&quot; href=&quot;#_footnote_2&quot; title=&quot;View footnote.&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_min_interval&lt;/strong&gt;: Obsoleto, usar gc_min_interval_ms
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_3&quot; class=&quot;footnote&quot; href=&quot;#_footnote_3&quot; title=&quot;View footnote.&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_min_interval_ms&lt;/strong&gt;: Define, em milissegundos, o intervalo mínimo
entre coletas
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_4&quot; class=&quot;footnote&quot; href=&quot;#_footnote_4&quot; title=&quot;View footnote.&quot;&gt;4&lt;/a&gt;]&lt;/sup&gt;.
Predefinido em 500 milissegundos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_thresh&lt;/strong&gt;: Define a quantidade mínima de rotas para que rotas
comecem a ser descartadas na coleta de rotas
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_5&quot; class=&quot;footnote&quot; href=&quot;#_footnote_5&quot; title=&quot;View footnote.&quot;&gt;5&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;gc_timeout&lt;/strong&gt;: Define, em segundos, o tempo máximo que uma rota é mantida. A
rota é descartada mesmo se está em uso
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_6&quot; class=&quot;footnote&quot; href=&quot;#_footnote_6&quot; title=&quot;View footnote.&quot;&gt;6&lt;/a&gt;]&lt;/sup&gt;.
Predefinido em 300 segundos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;max_size&lt;/strong&gt;: Define o número máximo de rotas a serem mantidas. As rotas
mais antigas serão descartadas quando o número máximo é alcançado.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;min_adv_mss&lt;/strong&gt;: Define, em bytes, a quantidade mínima de dados pode ser
enviada em um segmento
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_7&quot; class=&quot;footnote&quot; href=&quot;#_footnote_7&quot; title=&quot;View footnote.&quot;&gt;7&lt;/a&gt;]&lt;/sup&gt;.
Predefinido em 256 bytes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;min_pmtu&lt;/strong&gt;: Define, em bytes, o valor mínimo de PMTU permitido. Se o
valor descoberto for menor então o valor mínimo definido aqui prevalece
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_8&quot; class=&quot;footnote&quot; href=&quot;#_footnote_8&quot; title=&quot;View footnote.&quot;&gt;8&lt;/a&gt;]&lt;/sup&gt;.
Predefinido em 552 bytes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;mtu_expires&lt;/strong&gt;: Define, em segundos, o tempo que o PMTU de uma rota é
mantido em cache
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_9&quot; class=&quot;footnote&quot; href=&quot;#_footnote_9&quot; title=&quot;View footnote.&quot;&gt;9&lt;/a&gt;]&lt;/sup&gt;.
Predefinido em 600 segundos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;redirect_load&lt;/strong&gt;: Define um tempo mínimo entre tentativas de
redirecionamentos ICMP, por rota
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_10&quot; class=&quot;footnote&quot; href=&quot;#_footnote_10&quot; title=&quot;View footnote.&quot;&gt;10&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;redirect_number&lt;/strong&gt;: Define o número máximo de redirecionamentos ICMP
ignorados, por rota
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_11&quot; class=&quot;footnote&quot; href=&quot;#_footnote_11&quot; title=&quot;View footnote.&quot;&gt;11&lt;/a&gt;]&lt;/sup&gt;
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_12&quot; class=&quot;footnote&quot; href=&quot;#_footnote_12&quot; title=&quot;View footnote.&quot;&gt;12&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;redirect_silence&lt;/strong&gt;: Define, em interrupções de timer, o tempo máximo
de espera por um redirecionamento ICMP. Após esse tempo é enviada um
novo redirecionamento, mesmo que o mesmo tenha sido ignorado por causa
de &lt;em&gt;redirect_load&lt;/em&gt; ou &lt;em&gt;redirect_number&lt;/em&gt;. Predefinido em 20,48
segundos.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;secret_interval&lt;/strong&gt;: Define, em segundos, o intervalo entre
descarregamento de cache. Predefinido em 600 segundos.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As informações encontradas aqui podem estar incorretas, pois se baseiam
em minhas conclusões.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;referências&quot;&gt;Referências&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Documentação do sistema de arquivos /proc:
&lt;a href=&quot;http://www.linuxinsight.com/proc_sys_net_ipv4_route.html&quot; class=&quot;bare&quot;&gt;http://www.linuxinsight.com/proc_sys_net_ipv4_route.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configurações
do kernel obscuras: &lt;a href=&quot;http://lartc.org/howto/lartc.kernel.obscure.html&quot; class=&quot;bare&quot;&gt;http://lartc.org/howto/lartc.kernel.obscure.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Determinando a quantidade de interrupções de timer:
&lt;a href=&quot;http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&amp;amp;cmd=displayKC&amp;amp;externalId=1005802&quot; class=&quot;bare&quot;&gt;http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&amp;amp;cmd=displayKC&amp;amp;externalId=1005802&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PMTU: &lt;a href=&quot;http://www.netheaven.com/pmtu.html&quot; class=&quot;bare&quot;&gt;http://www.netheaven.com/pmtu.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_1&quot;&gt;
&lt;a href=&quot;#_footnoteref_1&quot;&gt;1&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1178&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1178&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_2&quot;&gt;
&lt;a href=&quot;#_footnoteref_2&quot;&gt;2&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L950&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L950&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_3&quot;&gt;
&lt;a href=&quot;#_footnoteref_3&quot;&gt;3&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L3109&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L3109&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_4&quot;&gt;
&lt;a href=&quot;#_footnoteref_4&quot;&gt;4&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L957&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L957&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_5&quot;&gt;
&lt;a href=&quot;#_footnoteref_5&quot;&gt;5&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L967&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L967&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_6&quot;&gt;
&lt;a href=&quot;#_footnoteref_6&quot;&gt;6&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L842&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L842&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_7&quot;&gt;
&lt;a href=&quot;#_footnoteref_7&quot;&gt;7&lt;/a&gt;. &lt;a href=&quot;http://www.tcpipguide.com/free/t_TCPMaximumSegmentSizeMSSandRelationshiptoIPDatagra.htm&quot; class=&quot;bare&quot;&gt;http://www.tcpipguide.com/free/t_TCPMaximumSegmentSizeMSSandRelationshiptoIPDatagra.htm&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_8&quot;&gt;
&lt;a href=&quot;#_footnoteref_8&quot;&gt;8&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1701&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1701&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_9&quot;&gt;
&lt;a href=&quot;#_footnoteref_9&quot;&gt;9&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1706&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1706&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_10&quot;&gt;
&lt;a href=&quot;#_footnoteref_10&quot;&gt;10&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1557&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1557&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_11&quot;&gt;
&lt;a href=&quot;#_footnoteref_11&quot;&gt;11&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1549&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1549&lt;/a&gt;
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_12&quot;&gt;
&lt;a href=&quot;#_footnoteref_12&quot;&gt;12&lt;/a&gt;. &lt;a href=&quot;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1512&quot; class=&quot;bare&quot;&gt;http://lxr.free-electrons.com/source/net/ipv4/route.c?v=2.6.35#L1512&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Mon, 06 Sep 2010 22:46:08 -0300</pubDate>
        <link>https://fgodoy.me/2010/09/configuracoes-de-proc-sys-net-ipv4-route/</link>
        <guid isPermaLink="true">https://fgodoy.me/2010/09/configuracoes-de-proc-sys-net-ipv4-route/</guid>
        
        <category>advanced</category>
        
        <category>linux</category>
        
        <category>net</category>
        
        <category>proc</category>
        
        <category>route</category>
        
        <category>routing</category>
        
        
        <category>Linha de comando</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>Dividir um PDF com página dupla em dois</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Abaixo publico um código Perl que divide verticalmente cada página em
duas páginas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Um caminho para o arquivo PDF deve ser fornecido como argumento e o
arquivo dividido será criado no mesmo local.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Instale o &lt;a href=&quot;http://search.cpan.org/dist/PDF-API2/&quot;&gt;PDF-API2&lt;/a&gt; (pacote
&lt;strong&gt;libpdf-api2-perl&lt;/strong&gt; no Debian/Ubuntu ou &lt;strong&gt;perl-PDF-API2&lt;/strong&gt; no
RHEL/CentOS/Fedora).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;split_pdf.pl&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;perl&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;#!/usr/bin/env perl&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;use&lt;/span&gt; strict; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;use&lt;/span&gt; warnings;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;use&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;PDF::&lt;/span&gt;API2;

&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$filename&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000&quot;&gt;shift&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;#39;test.pdf&amp;#39;&lt;/span&gt;;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$oldpdf&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;PDF::&lt;/span&gt;API2&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #008000&quot;&gt;open&lt;/span&gt;(&lt;span style=&quot;color: #19177C&quot;&gt;$filename&lt;/span&gt;);
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$newpdf&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000FF; font-weight: bold&quot;&gt;PDF::&lt;/span&gt;API2&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;new&lt;/span&gt;;

&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$page_nb&lt;/span&gt; (&lt;span style=&quot;color: #666666&quot;&gt;1..&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$oldpdf&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;pages) {
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; (&lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);

  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$newpdf&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;importpage(&lt;span style=&quot;color: #19177C&quot;&gt;$oldpdf&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;$page_nb&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;get_mediabox;
  &lt;span style=&quot;color: #19177C&quot;&gt;$cropdata&lt;/span&gt;[&lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;] &lt;span style=&quot;color: #666666&quot;&gt;/=&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;;
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;cropbox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;trimbox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;mediabox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);

  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$newpdf&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;importpage(&lt;span style=&quot;color: #19177C&quot;&gt;$oldpdf&lt;/span&gt;, &lt;span style=&quot;color: #19177C&quot;&gt;$page_nb&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;get_mediabox;
  &lt;span style=&quot;color: #19177C&quot;&gt;$cropdata&lt;/span&gt;[&lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;] &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$cropdata&lt;/span&gt;[&lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;] &lt;span style=&quot;color: #666666&quot;&gt;/&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;;
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;cropbox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;trimbox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);
  &lt;span style=&quot;color: #19177C&quot;&gt;$page&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;mediabox(&lt;span style=&quot;color: #19177C&quot;&gt;@cropdata&lt;/span&gt;);
}

(&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;my&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$newfilename&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #19177C&quot;&gt;$filename&lt;/span&gt;) &lt;span style=&quot;color: #666666&quot;&gt;=~&lt;/span&gt; &lt;span style=&quot;color: #BB6688&quot;&gt;s/(.*)\.(\w+)$/$1.clean.$2/&lt;/span&gt;;
&lt;span style=&quot;color: #19177C&quot;&gt;$newpdf&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;-&amp;gt;&lt;/span&gt;saveas(&lt;span style=&quot;color: #19177C&quot;&gt;$newfilename&lt;/span&gt;);

___END___&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Esse post foi baseado no post em
&lt;a href=&quot;http://snipplr.com/view/18924/split-crop-double-page-pdfs-in-two/&quot; class=&quot;bare&quot;&gt;http://snipplr.com/view/18924/split-crop-double-page-pdfs-in-two/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
        <pubDate>Sat, 17 Jul 2010 23:47:27 -0300</pubDate>
        <link>https://fgodoy.me/2010/07/dividir-pdf/</link>
        <guid isPermaLink="true">https://fgodoy.me/2010/07/dividir-pdf/</guid>
        
        <category>cortar</category>
        
        <category>crop</category>
        
        <category>dividir</category>
        
        <category>double</category>
        
        <category>linux</category>
        
        <category>page</category>
        
        <category>pagina</category>
        
        <category>pdf</category>
        
        <category>split</category>
        
        
        <category>Linha de comando</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>Como criar um repositório Git remoto usando o SSH</title>
        <description>&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Abordarei a criação de um repositório Git remoto usando o SSH num
ambiente Linux.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Não incluirei detalhes da configuração do SSH.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;É necessário que os seguintes pacotes estejam instalados: &lt;strong&gt;git&lt;/strong&gt;,
&lt;strong&gt;openssh-server&lt;/strong&gt; e &lt;strong&gt;openssh-client&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Primeiro configure o SSH editando o arquivo &lt;strong&gt;/etc/ssh/sshd_config&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Eu recomendo algumas configurações
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_1&quot; class=&quot;footnote&quot; href=&quot;#_footnote_1&quot; title=&quot;View footnote.&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;sshd_config&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;Protocol &lt;span style=&quot;color: #666666&quot;&gt;2&lt;/span&gt;    &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Permite apenas a versão 2 do protocolo (mais seguro)&lt;/span&gt;
PermitRootLogin no    &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Não permite login como root&lt;/span&gt;
PasswordAuthentication no    &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Não permite login por senha&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Não esqueça de iniciar ou &lt;strong&gt;reiniciar&lt;/strong&gt; o servidor SSH.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora é necessário criar um usuário para acesso ao Git através do SSH.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Eu recomendo que o nome do usuário seja &lt;strong&gt;git&lt;/strong&gt; e que seja criado com o
seguinte comando
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_2&quot; class=&quot;footnote&quot; href=&quot;#_footnote_2&quot; title=&quot;View footnote.&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;useradd -r -m --shell /usr/bin/git-shell git&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Definindo o shell do usuário para &lt;strong&gt;/usr/bin/git-shell&lt;/strong&gt; o acesso do
usuário será restrito aos comandos do Git
&lt;sup class=&quot;footnote&quot;&gt;[&lt;a id=&quot;_footnoteref_3&quot; class=&quot;footnote&quot; href=&quot;#_footnote_3&quot; title=&quot;View footnote.&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O diretório pessoal do usuário git será criado em &lt;strong&gt;/home/git&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Se você não tem uma chave para o SSH, crie-a com o comando &lt;strong&gt;ssh-keygen&lt;/strong&gt;
(usando seu usuário).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Será criada uma chave pública e privada em &lt;strong&gt;~/.ssh&lt;/strong&gt;, a chave pública
tem o sufixo &lt;strong&gt;.pub&lt;/strong&gt; (nunca compartilhe sua chave privada).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora é necessário adicionar sua chave pública a lista de chaves
autorizadas do usuário &lt;strong&gt;git&lt;/strong&gt;, para isso faça o seguinte:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;mkdir /home/git/.ssh
cat /home/seu_usuario/.ssh/id_rsa.pub &amp;gt;&amp;gt; /home/git/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Supondo que o nome de sua chave pública seja &lt;strong&gt;id_rsa.pub&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora será necessário criar um repositório no diretório pessoal do
usuário &lt;strong&gt;git&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para criar um repositório para o projeto &lt;strong&gt;ProjetoTeste&lt;/strong&gt;, faça o
seguinte:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;mkdir /home/git/ProjetoTeste &lt;span style=&quot;color: #008000&quot;&gt;cd&lt;/span&gt; /home/git/ProjetoTeste git init --bare&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora é necessário garantir que tudo pertença ao usuário git, faça o
seguinte:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #008000&quot;&gt;cd&lt;/span&gt; /home/git chown -R git.git . &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Não esqueça do ponto no final&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Isso é tudo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para clonar o repositório use o seguinte comando:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;git clone git@ip_do_servidor:ProjetoTeste&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_1&quot;&gt;
&lt;a href=&quot;#_footnoteref_1&quot;&gt;1&lt;/a&gt;. &lt;a href=&quot;http://linux.die.net/man/5/sshd_config&quot; class=&quot;bare&quot;&gt;http://linux.die.net/man/5/sshd_config&lt;/a&gt; ou &lt;strong&gt;man 5 sshd_config&lt;/strong&gt;.
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_2&quot;&gt;
&lt;a href=&quot;#_footnoteref_2&quot;&gt;2&lt;/a&gt;. &lt;a href=&quot;http://linux.die.net/man/8/useradd&quot; class=&quot;bare&quot;&gt;http://linux.die.net/man/8/useradd&lt;/a&gt; ou &lt;strong&gt;man 8 useradd&lt;/strong&gt;.
&lt;/div&gt;
&lt;div class=&quot;footnote&quot; id=&quot;_footnote_3&quot;&gt;
&lt;a href=&quot;#_footnoteref_3&quot;&gt;3&lt;/a&gt;. &lt;a href=&quot;http://linux.die.net/man/1/git-shell&quot; class=&quot;bare&quot;&gt;http://linux.die.net/man/1/git-shell&lt;/a&gt; ou &lt;strong&gt;man 1 git-shell&lt;/strong&gt;.
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 15 Nov 2009 00:59:25 -0200</pubDate>
        <link>https://fgodoy.me/2009/11/criar_git_remoto_ssh/</link>
        <guid isPermaLink="true">https://fgodoy.me/2009/11/criar_git_remoto_ssh/</guid>
        
        <category>git</category>
        
        <category>linux</category>
        
        <category>ssh</category>
        
        
        <category>Programação</category>
        
      </item>
    
      <item>
        <title>Internacionalização (I18n) com Autotools</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Explicarei como &lt;em&gt;internacionalizar&lt;/em&gt;, ou seja, tornar um programa
traduzível.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Tomarei como exemplo o projeto hello-world do post anterior.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Você pode baixar o pacote final do projeto do post anterior em
&lt;a href=&quot;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.2.0.tar.gz&quot; class=&quot;bare&quot;&gt;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.2.0.tar.gz&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Será necessário as seguintes ferramentas: intltool e gettext.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Adicione o seguinte código no arquivo configure.ac:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;configure.ac&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for libraries.&lt;/span&gt;
PKG_CHECK_MODULES&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;DEPS&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;,&lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;glib-2.0&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
AC_SUBST&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;DEPS_CFLAGS&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
AC_SUBST&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;DEPS_LIBS&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Internationalization&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;GETTEXT_PACKAGE&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;hello-world &lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
AC_SUBST&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;GETTEXT_PACKAGE&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;(5)&lt;/b&gt;
AC_DEFINE_UNQUOTED&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;GETTEXT_PACKAGE&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;, &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;$GETTEXT_PACKAGE&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;,
 &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;the gettext translation domain&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;6&quot;&gt;&lt;/i&gt;&lt;b&gt;(6)&lt;/b&gt;

AM_GLIB_GNU_GETTEXT &lt;i class=&quot;conum&quot; data-value=&quot;7&quot;&gt;&lt;/i&gt;&lt;b&gt;(7)&lt;/b&gt;
GLIB_DEFINE_LOCALEDIR&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;HELLO_WORLD_LOCALEDIR&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;8&quot;&gt;&lt;/i&gt;&lt;b&gt;(8)&lt;/b&gt;

IT_PROG_INTLTOOL&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;0.35.1&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;9&quot;&gt;&lt;/i&gt;&lt;b&gt;(9)&lt;/b&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Check OS-specific platform&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Procura pela biblioteca &lt;em&gt;glib-2.0&lt;/em&gt; e define as variáveis &lt;em&gt;DEPS_CFLAGS&lt;/em&gt; e
&lt;em&gt;DEPS_LIBS&lt;/em&gt; (detalhes abaixo). Caso a biblioteca não seja encontrada é retornado
um erro.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Faz com que &lt;em&gt;@DEPS_CFLAGS@&lt;/em&gt; ou &lt;em&gt;$(DEPS_CFLAGS)&lt;/em&gt;, nos arquivos de saída do
autoconf, seja substituído pelo valor da variável.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;O mesmo que o comando acima, mas com a variável &lt;em&gt;DEPS_LIBS&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Está sendo definida uma variável local.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;O mesmo que as macros &lt;em&gt;AC_SUBST&lt;/em&gt; acima, mas com a variável
&lt;em&gt;GETTEXT_PACKAGE&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;6&quot;&gt;&lt;/i&gt;&lt;b&gt;6&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Igual a macro &lt;em&gt;AC_DEFINE&lt;/em&gt; com o diferencial de expandir expressões de shell
(ver &quot;Definindo símbolos&quot;). Define, no arquivo &lt;em&gt;config.h&lt;/em&gt;, o símbolo
GETTEXT_PACKAGE com o valor da variável GETTEXT_PACKAGE.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;7&quot;&gt;&lt;/i&gt;&lt;b&gt;7&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Faz verificações se o gettext pode ser usado, define o símbolo
&lt;em&gt;HAVE_GETTEXT&lt;/em&gt; no arquivo &lt;em&gt;config.h&lt;/em&gt; entre outros.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;8&quot;&gt;&lt;/i&gt;&lt;b&gt;8&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Define o nome do símbolo que conterá o caminho do diretório de localização.
É o caminho do diretório de onde os catálogos de mensagens de cada língua será
instalado.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;9&quot;&gt;&lt;/i&gt;&lt;b&gt;9&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Faz verificações se o intltool pode ser usado e define a versão mínima
necessária.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Ainda no arquivo &lt;em&gt;configure.ac&lt;/em&gt; adicione o arquivo &quot;po/Makefile.in&quot; em
&lt;em&gt;AC_CONFIG_FILES&lt;/em&gt;. Desta maneira o arquivo &lt;em&gt;Makefile&lt;/em&gt; que será criado
no diretório &lt;em&gt;po&lt;/em&gt; fará parte da compilação.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;configure.ac&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;AC_CONFIG_FILES&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;Makefile
    src/Makefile
    po/Makefile.in&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para que se possa fazer o uso da biblioteca &lt;em&gt;glib-2.0&lt;/em&gt; é necessário
indicar ao compilador onde achar os arquivos de cabeçalho e os objetos
de ligação. Para isso é necessário modificar o arquivo &lt;em&gt;Makefile.am&lt;/em&gt;
como abaixo:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;bin_PROGRAMS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; hello-world

&lt;span style=&quot;color: #19177C&quot;&gt;hello_world_SOURCES&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; main.cpp
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;if&lt;/span&gt; OS_WIN32
hello_world_SOURCES +&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; windowsdef.h
endif

&lt;span style=&quot;color: #19177C&quot;&gt;hello_world_LDADD&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;$(&lt;/span&gt;DEPS_LIBS&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
&lt;span style=&quot;color: #19177C&quot;&gt;hello_world_CXXFLAGS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;$(&lt;/span&gt;DEPS_CFLAGS&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DEPS_LIBS&lt;/strong&gt; é a variável com os caminhos para os objetos de ligação.
Esses objetos têm a listagem e endereçamento de cada função.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DEPS_CFLAGS&lt;/strong&gt; é a variável com os caminhos para os arquivos de cabeçalho.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Crie o diretório &lt;em&gt;po&lt;/em&gt; no diretório raíz do projeto, este diretório
conterá os catálogos de cada língua.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Crie um arquivo vazio com o nome &lt;em&gt;LINGUAS&lt;/em&gt;, neste arquivo será listado
os códigos de cada idioma com suporte.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Crie um arquivo vazio com o nome &lt;em&gt;POTFILES.in&lt;/em&gt;, neste arquivo será
listado todos os arquivos com mensagens traduzíveis.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No arquivo &lt;em&gt;Makefile.am&lt;/em&gt; do diretório raíz do projeto adicione o
diretório &lt;em&gt;po&lt;/em&gt; em &lt;em&gt;SUBDIRS&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;SUBDIRS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; src po&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;É necessário adicionar os scripts de internacionalização ao pacote de
distribuição, para isso adicione o código  abaixo ao arquivo
&lt;em&gt;Makefile.am&lt;/em&gt; do diretório raíz.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;SUBDIRS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; src po

&lt;span style=&quot;color: #19177C&quot;&gt;INTLTOOL_FILES&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\ &lt;/span&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
 intltool-extract.in &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\&lt;/span&gt;
 intltool-merge.in &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\&lt;/span&gt;
 intltool-update.in

&lt;span style=&quot;color: #19177C&quot;&gt;EXTRA_DIST&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\ &lt;/span&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
 &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;$(&lt;/span&gt;INTLTOOL_FILES&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #19177C&quot;&gt;DISTCLEANFILES&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\ &lt;/span&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
 intltool-extract &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\&lt;/span&gt;
 intltool-merge &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\&lt;/span&gt;
 intltool-update &lt;span style=&quot;color: #BB6622; font-weight: bold&quot;&gt;\&lt;/span&gt;
 po/.intltool-merge-cache&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;INTLTOOL_FILES&lt;/strong&gt; é uma variável com a lista de scripts usados pelo intltool.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;EXTRA_DIST&lt;/strong&gt; define arquivos adicionais que serão adicionados ao
pacote de distribuição.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;DISTCLEANFILES&lt;/strong&gt; define os arquivos adicionais que serão removidos
pelo comando &quot;&lt;em&gt;make distclean&lt;/em&gt;&quot;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para atualizar os scripts com as mudanças execute o comando
&quot;&lt;em&gt;autoreconf&lt;/em&gt;&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para preparar o projeto para o intltool, execute o comando
&quot;&lt;em&gt;intltoolize&lt;/em&gt;&quot; no diretório raíz do projeto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora é necessário inicializar o &lt;em&gt;libintl&lt;/em&gt; e marcar as strings como
traduzíveis. Para isso modifique o arquivo &lt;em&gt;main.cpp&lt;/em&gt; como a seguir:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;main.cpp&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifdef HAVE_CONFIG_H&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;config.h&amp;gt; &lt;/span&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifdef WINNT&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;quot;windowsdef.h&amp;quot;&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;glib/gi18n.h&amp;gt; &lt;/span&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;

&lt;span style=&quot;color: #B00040&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;main&lt;/span&gt;()
{
  &lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;// Gettext initialization&lt;/span&gt;
  setlocale(LC_ALL, &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;); &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
  bindtextdomain(GETTEXT_PACKAGE, HELLO_WORLD_LOCALEDIR); &lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
  bind_textdomain_codeset(GETTEXT_PACKAGE, &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;); &lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;(5)&lt;/b&gt;
  textdomain(GETTEXT_PACKAGE); &lt;i class=&quot;conum&quot; data-value=&quot;6&quot;&gt;&lt;/i&gt;&lt;b&gt;(6)&lt;/b&gt;

  std&lt;span style=&quot;color: #666666&quot;&gt;::&lt;/span&gt;cout &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; _(&lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;) &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style=&quot;color: #666666&quot;&gt;::&lt;/span&gt;endl; &lt;i class=&quot;conum&quot; data-value=&quot;7&quot;&gt;&lt;/i&gt;&lt;b&gt;(7)&lt;/b&gt;
  &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Para usar os símbolos &lt;em&gt;GETTEXT_PACKAGE&lt;/em&gt; e &lt;em&gt;HELLO_WORLD_LOCALEDIR&lt;/em&gt; é
necessário incluir o cabeçalho &lt;em&gt;config.h&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;O cabeçalho &lt;em&gt;gi18n.h&lt;/em&gt; inclui o cabeçalho &lt;em&gt;libintl.h&lt;/em&gt;, que contém as
funções de internacionalização, e define símbolos comumente usados na
internacionalização.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A função &lt;em&gt;setlocale()&lt;/em&gt; define a localização atual que será usada pelo
gettext.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A função &lt;em&gt;bindtextdomain()&lt;/em&gt; define o caminho do catálogo de
&lt;em&gt;GETTEXT_PACKAGE&lt;/em&gt; para &lt;em&gt;HELLO_WORLD_LOCALEDIR&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A função &lt;em&gt;bind_textdomain_codeset()&lt;/em&gt; define a codificação das mensagens
do catálogo de &lt;em&gt;GETTEXT_PACKAGE&lt;/em&gt; para UTF-8.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;6&quot;&gt;&lt;/i&gt;&lt;b&gt;6&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A função &lt;em&gt;textdomain()&lt;/em&gt; define o catálogo de mensagens padrão para
&lt;em&gt;GETTEXT_PACKAGE&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;7&quot;&gt;&lt;/i&gt;&lt;b&gt;7&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;A função &lt;em&gt;_()&lt;/em&gt; é um símbolo que foi definido pelo &lt;em&gt;gi18n.h&lt;/em&gt; que é um
apelido para a função &lt;em&gt;gettext()&lt;/em&gt; do cabeçalho &lt;em&gt;libintl.h&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Agora o projeto está pronto para ser traduzido (localizado).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O pacote final pode ser acessado neste link:
&lt;a href=&quot;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.3.0.tar.gz&quot; class=&quot;bare&quot;&gt;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.3.0.tar.gz&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;referências&quot;&gt;Referências&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Definindo símbolos:
&lt;a href=&quot;http://www.gnu.org/software/hello/manual/autoconf/Defining-Symbols.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/hello/manual/autoconf/Defining-Symbols.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Internacionalização:
&lt;a href=&quot;http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/chapter-internationalization.html&quot; class=&quot;bare&quot;&gt;http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/chapter-internationalization.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;pkg-config: &lt;a href=&quot;http://pkg-config.freedesktop.org/&quot; class=&quot;bare&quot;&gt;http://pkg-config.freedesktop.org/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;setlocale:
&lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/setlocale.html&quot; class=&quot;bare&quot;&gt;http://www.opengroup.org/onlinepubs/009695399/functions/setlocale.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 14 Jun 2009 18:07:52 -0300</pubDate>
        <link>https://fgodoy.me/2009/06/autotools-internacionalizacao-i18n/</link>
        <guid isPermaLink="true">https://fgodoy.me/2009/06/autotools-internacionalizacao-i18n/</guid>
        
        <category>autotools</category>
        
        <category>getlocale</category>
        
        <category>gettext</category>
        
        <category>intltool</category>
        
        <category>intltoolize</category>
        
        <category>libintl</category>
        
        
        <category>Programação</category>
        
      </item>
    
      <item>
        <title>Identificando o ambiente de destino com Autotools</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Explicarei aqui como identificar qual o ambiente de destino de compilação, ou
seja, o ambiente no qual será executado o binário.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para isso tomarei como exemplo o projeto hello-world do post anterior.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Você pode baixar o pacote final do projeto do post anterior em
&lt;a href=&quot;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.1.0.tar.gz&quot; class=&quot;bare&quot;&gt;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.1.0.tar.gz&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No arquivo &lt;em&gt;configure.ac&lt;/em&gt;, é necessário adicionar a seguinte macro:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;configure.ac&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;AM_INIT_AUTOMAKE&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;1.9 -Wall -Werror&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Check build environment&lt;/span&gt;
AC_CANONICAL_HOST

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for programs.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Com essa macro serão criados os arquivos de script &lt;em&gt;config.guess&lt;/em&gt; e &lt;em&gt;config.sub&lt;/em&gt;
que serão usados para identificar o ambiente de destino.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Serão definidas quatro variáveis de ambiente, que são: &lt;em&gt;host&lt;/em&gt;, &lt;em&gt;host_cpu&lt;/em&gt;,
&lt;em&gt;host_vendor&lt;/em&gt;, &lt;em&gt;host_os&lt;/em&gt;. Com essas variáveis é possível condicionar a
compilação para cada ambiente.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Caso o ambiente de destino seja o MinGW de 32 bits para PC, normalmente, a
variável &lt;em&gt;host&lt;/em&gt; teria o valor &lt;em&gt;i686-pc-mingw32&lt;/em&gt; e como consequência as variáveis
&lt;em&gt;host_cpu&lt;/em&gt;, &lt;em&gt;host_vendor&lt;/em&gt; e &lt;em&gt;host_os&lt;/em&gt; teriam os valores &lt;em&gt;i686&lt;/em&gt;, &lt;em&gt;pc&lt;/em&gt; e &lt;em&gt;mingw32&lt;/em&gt;
respectivamente. Assim podemos dizer que &quot;host=$host_cpu-$host_vendor-$host_os&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Criarei uma verificação para definir a variável &lt;em&gt;OS_WIN32&lt;/em&gt; caso a variável
&lt;em&gt;host_os&lt;/em&gt; tenha a palavra &quot;mingw&quot;. Para isso adicionarei o seguinte script no
arquivo &lt;em&gt;configure.ac&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;configure.ac&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# -------------------------------------------------&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Check OS-specific platform&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# -------------------------------------------------&lt;/span&gt;
AC_MSG_CHECKING&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;for&lt;/span&gt; native Win32&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;$host_os&amp;quot;&lt;/span&gt; in
  *mingw*&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #19177C&quot;&gt;iswin32&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;yes
  ;;
  *&lt;span style=&quot;color: #666666&quot;&gt;)&lt;/span&gt;
    &lt;span style=&quot;color: #19177C&quot;&gt;iswin32&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt;no
  ;;
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;esac&lt;/span&gt;
AC_MSG_RESULT&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$iswin32&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;

AM_CONDITIONAL&lt;span style=&quot;color: #666666&quot;&gt;(&lt;/span&gt;OS_WIN32, &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #008000&quot;&gt;test&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;$iswin32&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A macro &lt;em&gt;AC_MSG_CHECKING&lt;/em&gt; faz imprimir na tela a mensagem &quot;checking for native
Win32&amp;#8230;&amp;#8203;&quot; indicando que está sendo feita a verificação por uma característica
específica.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Em seguida é verificada a variável de ambiente pela palavra &quot;mingw&quot;, caso
encontre a variável local &lt;em&gt;iswin32&lt;/em&gt; será definida para o valor &quot;yes&quot;, senão para
o valor &quot;no&quot; (Leia sobre &lt;a href=&quot;http://aurelio.net/shell/&quot;&gt;Bash&lt;/a&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A macro &lt;em&gt;AC_MSG_RESULT&lt;/em&gt; imprime na tela o resultado da última macro
&lt;em&gt;AC_MSG_CHECKING&lt;/em&gt;. Imprime &quot;checking for native Win32&amp;#8230;&amp;#8203; yes&quot;, caso a variável
&lt;em&gt;iswin32&lt;/em&gt; tenha o valor &quot;yes&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A macro &lt;em&gt;AM_CONDITIONAL&lt;/em&gt; de maneira condicional define ou não a variável
&lt;em&gt;OS_WIN32&lt;/em&gt; a qual será compartilhada a todos Makefiles. Caso a variável local
&lt;em&gt;iswin32&lt;/em&gt; tenha o valor &quot;yes&quot; a variável &lt;em&gt;OS_WIN32&lt;/em&gt; será definida.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Adicionarei o seguinte conteúdo no arquivo &lt;em&gt;Makefile.am&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;hello_world_SOURCES&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; main.cpp
&lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;if&lt;/span&gt; OS_WIN32
hello_world_SOURCES +&lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; windowsdef.h
endif&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Assim o arquivo &lt;em&gt;windowsdef.h&lt;/em&gt; só será compilado caso esteja definida a variável
&lt;em&gt;OS_WIN32&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Criarei o arquivo &lt;em&gt;windowsdef.h&lt;/em&gt; com o seguinte conteúdo:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;windowsdef.h&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifndef _WINDOWSDEF_H&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#define _WINDOWSDEF_H&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifdef HAVE_CONFIG_H&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;config.h&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifndef WINVER&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;// Windows Server 2003 with SP1, Windows XP with SP2&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;// See http://msdn.microsoft.com/en-us/library/aa383745.aspx&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#define WINVER 0x0502&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif &lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;/* WINVER */&lt;/span&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;windows.h&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif    &lt;/span&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;/* _WINDOWSDEF_H */&lt;/span&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Definindo a variável &lt;em&gt;WINVER&lt;/em&gt; para o valor &lt;em&gt;0x0502&lt;/em&gt; estaremos limitando o
executável ao Windows XP SP2 ou Windows Server 2003 SP1 no mínimo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Adicionarei o seguinte conteúdo ao arquivo &lt;em&gt;main.cpp&lt;/em&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;main.cpp&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;#ifdef WINNT&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;quot;windowsdef.h&amp;quot;&lt;/span&gt;
&lt;span style=&quot;color: #BC7A00&quot;&gt;#endif&lt;/span&gt;

&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O compilador só referenciará o arquivo windowsdef.h caso a variável WINNT esteja
definida. A variável WINNT é definida automaticamente pelo compilador caso o
mesmo esteja sendo executado em um ambiente do Windows NT.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para consultar as variáveis automaticamente definidas pelo seu compilador
execute o seguinte comando &quot;gcc -E -dM - &amp;lt; /dev/null | sort&quot;, sendo que &quot;| sort&quot;
é para ordenar a saída em ordem alfabética.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Com essas instruções já se tem o básico para construir um programa
multi-plataforma.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O pacote final pode ser acessado neste link:
&lt;a href=&quot;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.2.0.tar.gz&quot; class=&quot;bare&quot;&gt;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.2.0.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;referências&quot;&gt;Referências&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.gnu.org/software/hello/manual/autoconf/Canonicalizing.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/hello/manual/autoconf/Canonicalizing.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.gnu.org/software/hello/manual/autoconf/Printing-Messages.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/hello/manual/autoconf/Printing-Messages.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.gnu.org/software/hello/manual/automake/Usage-of-Conditionals.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/hello/manual/automake/Usage-of-Conditionals.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_03.html&quot; class=&quot;bare&quot;&gt;http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_03.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://git.gnome.org/cgit/gtk+/tree/configure.in#n127&quot; class=&quot;bare&quot;&gt;http://git.gnome.org/cgit/gtk+/tree/configure.in#n127&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://svn.win.tue.nl/viewcvs/MCRL2/trunk/src/configure.ac?rev=808&amp;amp;view=markup&quot; class=&quot;bare&quot;&gt;https://svn.win.tue.nl/viewcvs/MCRL2/trunk/src/configure.ac?rev=808&amp;amp;view=markup&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://www.rtems.com/ml/rtems-users/1998/march/msg00046.html&quot; class=&quot;bare&quot;&gt;http://www.rtems.com/ml/rtems-users/1998/march/msg00046.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 14 Jun 2009 18:07:52 -0300</pubDate>
        <link>https://fgodoy.me/2009/06/identificando-ambiente-de-destino/</link>
        <guid isPermaLink="true">https://fgodoy.me/2009/06/identificando-ambiente-de-destino/</guid>
        
        <category>automake</category>
        
        <category>autotools</category>
        
        <category>mingw</category>
        
        
        <category>Programação</category>
        
      </item>
    
      <item>
        <title>Hello World com Autotools</title>
        <description>&lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para quem não conhece o Autotools, as ferramentas do mesmo têm o principal
objetivo de fazer programas portáveis, possibilitando assim que o programa possa
ser compilado em qualquer ambiente.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Vou explicar como fazer um programa que exibe “Hello World!” no console
configurado com Autotools. Não vou me ater a detalhes, ficando a cargo do leitor
pesquisar detalhadamente sobre as ferramentas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para continuar você precisará ter instalado as seguintes ferramentas: make,
gcc-c++, autoconf e automake. Para Windows você precisará também do MinGW e do
MSYS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Vamos ao projeto:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Primeiramente crie uma pasta para o projeto (&lt;em&gt;hello-world&lt;/em&gt; por exemplo).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Agora crie a pasta src (o nome é sua escolha), ela irá conter o código fonte
do projeto.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Crie o arquivo &lt;em&gt;main.cpp&lt;/em&gt; dentro da pasta &lt;em&gt;src&lt;/em&gt;, como o código abaixo.&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;main.cpp&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span style=&quot;color: #BC7A00&quot;&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #B00040&quot;&gt;int&lt;/span&gt; &lt;span style=&quot;color: #0000FF&quot;&gt;main&lt;/span&gt;()
{
    std&lt;span style=&quot;color: #666666&quot;&gt;::&lt;/span&gt;cout &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #BA2121&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; std&lt;span style=&quot;color: #666666&quot;&gt;::&lt;/span&gt;endl;
    &lt;span style=&quot;color: #008000; font-weight: bold&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;0&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dentro da pasta raíz do projeto crie o arquivo &lt;em&gt;Makefile.am&lt;/em&gt;, com o conteúdo
abaixo.&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;SUBDIRS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; src&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Os arquivos &lt;em&gt;Makefile.am&lt;/em&gt; têm instruções de compilação, mais especificamente,
instruções para o comando &lt;em&gt;make&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No caso deste arquivo, ele indica que deve ser pesquisado o diretório src.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Agora crie outro arquivo &lt;em&gt;Makefile.am&lt;/em&gt; no diretório &lt;em&gt;src&lt;/em&gt;, com o seguinte
conteúdo:&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Makefile.am&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;make&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;bin_PROGRAMS&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; hello-world

&lt;span style=&quot;color: #19177C&quot;&gt;hello_world_SOURCES&lt;/span&gt; &lt;span style=&quot;color: #666666&quot;&gt;=&lt;/span&gt; main.cpp&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A primeira linha indica quais são os nomes dos programa executáveis.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A segunda linha indica quais são os arquivos fontes do programa hello-world.
Observe que todos os caracteres não alfabéticos devem der substituídos por &quot;&lt;em&gt;&quot;,
como em _hello_world&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Agora precisamos criar o arquivo &lt;em&gt;configure.ac&lt;/em&gt; (no diretório raíz do
projeto, daqui em diante iremos trabalhar apenas no diretório raíz), que irá
conter as configurações do projeto, como nome, versão e dependências do projeto
entre outros.&lt;/p&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para criar um arquivo &lt;em&gt;configure.ac&lt;/em&gt; preliminar execute o comando abaixo.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;autoscan&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Serão criados os arquivos &lt;em&gt;configure.scan&lt;/em&gt; e &lt;em&gt;configure.log&lt;/em&gt;, sendo que o
configure.scan é o configure.ac preliminar e o configure.log contém os erros
encontrados.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Renomeie o arquivo &lt;em&gt;configure.scan&lt;/em&gt; para &lt;em&gt;configure.ac&lt;/em&gt;. O arquivo
&lt;em&gt;configure.log&lt;/em&gt; pode ser excluído.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modifique o arquivo configure.ac como abaixo.&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;configure.ac&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;#                                               -*- Autoconf -*-&lt;/span&gt;
&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Process this file with autoconf to produce a configure script.&lt;/span&gt;

AC_PREREQ&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;2.54&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
AC_INIT&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;Hello World&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;, &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;0.1.0&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;, &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;myemail@server.com&lt;span style=&quot;color: #666666&quot;&gt;]&lt;/span&gt;, &lt;span style=&quot;color: #666666&quot;&gt;[&lt;/span&gt;hello-world&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
AC_CONFIG_SRCDIR&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;src&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
AC_CONFIG_HEADERS&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;config.h&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
AM_INIT_AUTOMAKE&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;1.9 -Wall -Werror&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for programs.&lt;/span&gt;
AC_PROG_CXX

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for libraries.&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for header files.&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for typedefs, structures, and compiler characteristics.&lt;/span&gt;

&lt;span style=&quot;color: #408080; font-style: italic&quot;&gt;# Checks for library functions.&lt;/span&gt;

AC_CONFIG_FILES&lt;span style=&quot;color: #666666&quot;&gt;([&lt;/span&gt;Makefile
src/Makefile&lt;span style=&quot;color: #666666&quot;&gt;])&lt;/span&gt;
AC_OUTPUT&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_PREREQ&lt;/strong&gt;: A versão mínima necessária do autoconf, geralmente é a versão 2.54.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_INIT&lt;/strong&gt;: Define o nome e versão do projeto, endereço para relatar erros e o
nome do pacote do projeto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_CONFIG_SRCDIR&lt;/strong&gt;: Define a pasta que contém o código fonte.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_CONFIG_HEADERS&lt;/strong&gt;: Define o nome do arquivo de definições do projeto, é
recomendável deixar o padrão.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AM_INIT_AUTOMAKE&lt;/strong&gt;: É necessário para fazer uso dos &lt;em&gt;Makefile.am&lt;/em&gt;. Define a
versão mínima do &lt;em&gt;automake&lt;/em&gt; e as opções &lt;em&gt;-Wall&lt;/em&gt; e &lt;em&gt;-Werror&lt;/em&gt; definem
respectivamente que devem ser mostrados todos os alertas e que todos os alertas
devem ser tratados como erros.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_PROG_CXX&lt;/strong&gt;: Verifica e exige o compilador C++ para o projeto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_CONFIG_FILES&lt;/strong&gt;: Define os locais dos arquivo &lt;em&gt;Makefile&lt;/em&gt; do projeto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;AC_OUTPUT&lt;/strong&gt;: Macro que executa a saída do &lt;em&gt;autoconf&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;É necessário executar os comandos &lt;em&gt;aclocal&lt;/em&gt;, &lt;em&gt;autoconf&lt;/em&gt;, &lt;em&gt;autoheader&lt;/em&gt; e
&lt;em&gt;automake&lt;/em&gt; para gerar o script de configuração do projeto, mas para facilitar há
o comando &lt;em&gt;autoreconf&lt;/em&gt; que executa todos os comandos necessários.&lt;/p&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Inicialmente iremos executar o comando abaixo para que os arquivos iniciais
necessários sejam criados.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;autoreconf --install&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Serão criados vários arquivos, sendo que o arquivo &lt;em&gt;INSTALL&lt;/em&gt; contém instruções
de instalação e configuração e o arquivo &lt;em&gt;COPYING&lt;/em&gt; contém a licença do programa.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O automake exige os arquivos &lt;em&gt;NEWS&lt;/em&gt;, &lt;em&gt;README&lt;/em&gt;, &lt;em&gt;AUTHORS&lt;/em&gt; e &lt;em&gt;ChangeLog&lt;/em&gt;.
Inicialmente crie-os vazios.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;touch NEWS README AUTHORS ChangeLog&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute o comando &lt;em&gt;autoreconf&lt;/em&gt; e será gerado o script de configuração do
projeto novamente, agora sem erros com o  automake.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute o script &lt;em&gt;./configure&lt;/em&gt; para configurar o projeto.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute o comando &lt;em&gt;make&lt;/em&gt; para compilar o projeto.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Teste o executável do projeto:&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;src/hello-world&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Para criar um pacote do projeto execute o seguinte comando:&lt;/p&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;make dist&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;E será criado um pacote distribuível para outros que queiram compilar o projeto.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Para que além de ser criado o pacote o mesmo seja testado, execute o seguinte
comando:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;pygments highlight&quot;&gt;&lt;code data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color: #19177C&quot;&gt;$ &lt;/span&gt;make distcheck&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Pronto, é isso.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Aqui só é mostrado o básico necessário para começar a usar o Autotools, as
possibilidades vão muito além destas explicadas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;O pacote final pode ser acessado neste link:
&lt;a href=&quot;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.1.0.tar.gz&quot; class=&quot;bare&quot;&gt;http://dl.getdropbox.com/u/1671797/Blog/hello-world-0.1.0.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;referências&quot;&gt;Referências&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Manual do autoconf: &lt;a href=&quot;http://www.gnu.org/software/autoconf/manual/index.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/autoconf/manual/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manual do automake: &lt;a href=&quot;http://www.gnu.org/software/automake/manual/index.html&quot; class=&quot;bare&quot;&gt;http://www.gnu.org/software/automake/manual/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        <pubDate>Sun, 24 May 2009 17:23:36 -0300</pubDate>
        <link>https://fgodoy.me/2009/05/hello-world-com-autotools/</link>
        <guid isPermaLink="true">https://fgodoy.me/2009/05/hello-world-com-autotools/</guid>
        
        <category>autoconf</category>
        
        <category>automake</category>
        
        <category>autoreconf</category>
        
        <category>autoscan</category>
        
        <category>autotools</category>
        
        <category>make</category>
        
        
        <category>Programação</category>
        
      </item>
    
  </channel>
</rss>
