Um Manifesto!

...

  • Increase font size
  • Default font size
  • Decrease font size

Blog

Compartilhando internet pela rede sem fio no linux

E-mail Print PDF
Tutorial de como configurar sua placa de rede sem fio para compartilhar a internet, no linux.

Aqui vou explicar como configurar seu computador/notebook como hotspot wifi, para compartilhar a internet na rede sem fio, com o mínimo de "segurança" WEP apenas.

O Primeiro passo é saber qual a interface que chega a conexão com a internet, no geral se é internet discada, 3G ou se usa o pppoe a interface é ppp0, se a internet chega roteada pela rede é a mesma da interface de rede, eth0 ou outro. Aqui uso internet móvel 3G, então conecta em ppp0.

Temos então que mascarar o encaminhamento de pacotes dessa interface por um nat, usando as regras do iptables. Carregue o módulo de nat, definir a regra e ativar o encaminhamento no sistema, com os seguintes comandos:

# modprobe iptable_nat
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# echo 1 > /proc/sys/net/ipv4/ip_forward

O próximo passo é configurar a rede wifi, com os seguintes comandos:

# ifconfig wlan0 down
# ifconfig wlan0 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255
# ifconfig wlan0 up

Em seguida definimos as caracteristicas da rede sem fio, definindo o nome, o modo ad-hoc, a chave de encriptação e para apenas aceitar com encriptação, os comandos:
# iwconfig wlan0 essid "acer"
# iwconfig wlan0 mode ad-hoc
# iwconfig wlan0 key 's:diogo'
# iwconfig wlan0 key restricted

Para os clientes receberem as configurações devidas você precisará agir como cliente dhcp (ou configurar manualmente a rede nos clientes), você pode instalar o servidor com o seguinte comando:

# aptitude install dhcp3-server

Para configurar o servidor, edite o arquivo /etc/dhcp3/dhcpd.conf, conforme:

ddns-update-style ad-hoc;
option domain-name "home.org";
option domain-name-servers 208.67.222.222, 208.67.220.220;
default-lease-time 600;
max-lease-time 7200;
authoritative;
log-facility local7;
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.10 192.168.0.254;
option routers 192.168.0.1;
option broadcast-address 192.168.0.255;
}

Com o dhcp configurado, basta ativa-lo na interface da rede sem fio.

# dhcp3d wlan0

Agora os clientes podem se conctar a sua rede e navegar na sua internet. Você pode tentar configurar outro meio mais seguro que WEP, mas eu não sei ainda :P e definir regras no dhcp e iptables limitando os MACs e IPs, mas isso fica para próxima.
 

Downgrade de versão no Debian

E-mail Print PDF

Sabe, sou um feliz usuário de Linux. Mesmo tendo um hardware complico, isso melhorou com o tempo.

A história deste post está no primeiro link.

Vou explicar aqui o simples passo-a-passo para fazer o downgrade de versão do debian, sem reinstalar o sistema ou fazer algo mais complicado que o apt-get costumeiro. Se você usa o debian, sabe que pode fazer isso com a consciencia limpa.

O debian tem um sistema de "pinning" para o apt, que permite, entre outras coisas, definir preferencias de versões de pacotes, e vamos usar isso para fazer o downgrade, já que por padrão o apt escolhe os pacotes mais novos.

Primeiro devemos acertar os repositórios desejados, eu estou voltando do unstable(Sid) para o testing(Squeeze), então meu /etc/apt/sources.list ficou assim:

# deb ftp://ftp.br.debian.org/debian/ unstable main contrib non-free 
# deb ftp://ftp.br.debian.org/debian-multimedia/ unstable main

#deb ftp://security.debian.org/ testing/updates main contrib non-free
deb ftp://ftp.br.debian.org/debian/ testing main contrib non-free
deb ftp://ftp.br.debian.org/debian-multimedia/ testing main

#deb http://apt.wicd.net/ sid extras

Eu apenas comentei os "unstable" e adcionei as linhas do "testing".

Agora vamos configurar o tal "pin", para editar suas preferências do apt e dpkg você pode editar o arquivo /etc/apt/preferences, ou criar um arquivo em /etc/apt/preferences.d/ para cada configuração, no caso para o downgrade para o testing, fiz um assim:

X-comment: Force downgrade to testing.
Package: *
Pin: release a=testing
Pin-Priority: 1100

Veja que facilmente podemos criar outros, para escolher versões especificas de cada pacote, bastando acerta o "pin-priority" para isso.

Após configurado, basta atualizas a lista de pacotes e instala-los:

# dselect update
# aptitude dist-upgrade

E Pronto, seu sistema está "atualizado", é só reiniciar o X, se não mudou o Kernel nem precisa reiniciar. Se você acha que mudou muitos módulos do kernel em uso pode fazer um "depmod" e depois um "modprobe" nos módulos desejados.

Seja feliz com seu sistema "novo" :)

 

Introdução a linguagem Lua, você vai querer aprender também.

E-mail Print PDF

Em busca de uma programação poliglota, e entender as vantagens da cada linguagem oferece, iniciei meus estudos na linguagem Lua.

Histórico 

 Lua é uma linguagem de extensão, criada nos laboratórios da PUC-RJ, com o objetivo de ser simples de ser embarcada. Isso é, ele é extremamente pequena, sucinta, de sintaxe simples, esta presente praticamente em qualquer sistema. É uma verdadeira "write once, run everywhere"(bem mais que java). O pacote de Lua, com documentação, código fonte e exemplos tem cerca de 800KBs, apenas o runtime compilado(no linux) tem 150KBs. São 1700 linhas de código C portável, o mesmo código compila em várias plataformas.  

Roda em Unix, Linux, Windows, e em várias plataformas embarcadas, como celulares e setop boxes, robôs entre outros. Pode ser incluída em qualquer aplicação feita em outra linguagem , com quase nenhum overhead. Para ter melhor noção, um interpretador Lua completo em puro Java (tanto J2ME quanto J2SE), tem cerca de 150KBs. É usada como linguagem de extensão em produtos da Adobe, roda no Android, esta no Ginga (da TVDigital), e é muito usada em Jogos, como o sempre citado World of Warcraft.

E por que não fazer tudo em Lua então? Lua foi pensada em extensão de aplicativos, então a biblioteca básica é bem limitada, não possui as milhares de funções para tudo como teria em Java ou PHP ou Ruby ou Python ou Outra. Seus 150KBs incluem apenas o necessário, muito tem disponível em módulos externos, como os do LuaRocks. Embora seja possível para certas aplicações, mas não é foco.

Enfim, vendido o peixe de Lua. Agora é demonstrar, afinal “Show me the code”.

Exemplos 

Primeiro o essencial, lua é Imperativo, tem funções como cidadão de primeira classe(ah, deu para entender) e tudo é armazenado em tabelas. Tabelas são como arrays, mas são tabelas, depois eu explico. É tipagem dinamica, essencialmente não é orientada a objetos(pode ser simulado), possui escopo e é modular. Vamos ao exemplo.  

  -- rss.test.lua

local xml = dofile("xml.lua")
local sample = "<?xml ?><channel><rss><title>Lua Rock!</title>"
sample = sample .. "<item><title>Item 1</title></item>"
sample = sample .. "<item><title>Item 2</title></item>"
sample = sample .. "</rss></channel>";
local rss = xml.parse_rss(sample)
assert(rss[1].title == "Item 1","Invalid Item 1 title")
assert(rss[2].title == "Item 2","Invalid Item 2 title")
print("rss tests ok")

Esse simples exemplo é o arquivo de testes de uma biblioteca de parser de rss que uso. O uso do modificador "local" indica o escopo mais fechado possível dessa variável. O não uso de "local" implica numa variável "global", visível em toda a aplicação.  

A função "dofile" carrega um arquivo (como se fosse um include), esse arquivo carregado pode retornar uma ou mais variáveis, no caso o xml.lua me retorna uma tabela.

A chamada de função é normal, no caso o xml é uma tabela, e um dos seus índices (parse_rss) é uma função que recebe um argumento e retorna uma tabela.

  Fato interessante sobre tabelas em Lua, é que os índices numéricos começam em 1, e não em 0 como estamos acostumados.

  Em "rss[1].title", eu pego o item de índice 1(o primeiro), da tabela "rss" e o item de índice title dentro desta. No "assert" eu garanto que a expressão retorne True, do contrário levanto o erro no segundo argumento. 

  O arquivo de rss é assim: 

  -- rss.lua
local xml = dofile("utils/xml.lua")
xml.parse_rss = function (str)
local rss = {};
local t = xml.parse(str)
local channel = t[2][1]
for k,v in pairs(channel) do
local label = v['label']
if label == "item" then
local item = {}
for k,v in pairs(v) do
local label = v['label']
if label and v[1] then
item[label] = v[1]
end -- if label and value
end --for pairs in v
table.insert(rss,item)
end -- if is item
end -- for item in channel
return rss
end
return xml

 

Novamente eu carrego um parser xml externo, e na tabela xml eu adcione um índice, o parse_rss. Nesse índice eu ligo uma função, que recebe um argumento. Veja que não tem tipo fixo, eu poderia usar assert para garantir o tipo.

Eu defino então a variável “rss” como uma tabela vazia. Então faço um loop for nos itens retornados pelo parser xml. A função “pairs” retorna as chaves (k) e os valores(v) de uma tabela.

Temos então um IF padrão, nova tabela e mais um for. Então eu uso o “insert”, “table”, que é uma tabela embutida no core do lua. E retorno o RSS, o arquivo então retorna a tabela com as funções.

O parser XML é deveras grande, não vale a pena passa-lo aqui, e isso tudo foi apenas para dar um visão geral na estrutura da sintaxe da linguagem. Vamos agora no passo-a-passo de verdade.

Tutorial 

Em Lua, funções são objetos de primeira classe, então podemos por exemplo ter funções “curried”, como no exemplo abaixo:

  -- curry.lua

function soma(n)
return function(n2)
return n + n2
end
end

local f2 = soma(2)
local soma2e3 = f2(3)
assert(soma2e3 == 5)

 

Podemos levar um pouco alem:

  
-- curry.lua
local somador = function(n)
local soma = n
function f(n2)
if type(n2) == "number" then
soma = soma + n2
return f
else
return soma
end
end
return f
end

local total = somador (1) (2) (3) ()
print(total)

local somador = function (itens)
assert(type(itens) == "table")
local soma = 0;
for k,v in pairs(itens) do
soma = soma + v
end
return soma, #itens
end

local total,n = somador {
1,2,3
}
print(total,n)

local somador = function(```)
local soma = 0;
for k,v in pairs(arg)do
if type(k) == "number" then
soma = soma + v
end
end
return soma
end

local total = somador(1,2,3)
print(total)

 

São as várias formas de fazer a mesma coisa, veja no penúltimo somador uma característica legal, uma função pode retornar mais de uma variável.

Agora que você conhece como fazer funções, loops e condicionais, vamos tratar das tais tabelas.

  --tabelas.lua
local tab = {
"um","dois",
x="3",
y=function() return "hello" end
}
table.insert(tab,"cinco")
table.remove(tab,2)
local final = table.concat(tab," , ") -- apenas numéricos
print(tab[1], tab[2], tab["x"],tab.y,tab["y"](),tab[5],final)

 

Entendeu?

A ultima parte que quero tratar nesse texto é sobre coroutines, que são as “threads” do lua, incluído no core da linguagem, exemplo geral:

  --co.lua
local hello = coroutine.create(function(name)
print ("hello "..name)
end)


coroutine.resume(hello,"diogo")

local hello2 = coroutine.create(function(name)
repeat
print("hello you, "..name)
name = coroutine.yield(name)
until not type(name) == "string"
end)

local h2 = coroutine.resume(hello2,"diogo")
local h3 = coroutine.resume(hello2,"diego")
local h3 = coroutine.resume(hello2)
local h4 = coroutine.resume(hello2)

 

Acho que com esses exemplo já dá para decidir se quer ou não aprender Lua. Caso queira, o melhor lugar é a wiki da documentação de lua.

  Termino com um exemplo de uso real, uma função que realiza uma busca na wikipedia e retorna o resultado, o JSON eu achei na internet, e o http usa o Lua Socket, o wikipedia.lua.  

Last Updated on Monday, 21 September 2009 13:22
 

Game Over: Linux ganhou no Acer 5050!

E-mail Print PDF

Eu tenho um hardware complicado. Meu notebook é um acer 5050 e sempre deu trabalho Linux, mas firme e forte segui com minha saga de suporta-lo 100% no pinguim.

E a pouco tempo essa saga chegou no fim, e é Game Over, com vitória para o usuário, vitória do pinguim!

Basta um kernel recente e o Linux funciona no Acer 5050. Sem truques, sem mágica, sem compilações complicadas com parametros sinistros, agora quando eu quiser atualizar o  kernel, o farei sem medo.

Muito obrigado ao desenvolvedores do Kernel Linux. Tux #win. 

Last Updated on Saturday, 12 September 2009 19:35
 

O Shouter e o TwitterFlow2

E-mail Print PDF

Como disse, o importante é programar. Então como bom nerd e tentando manter o ânimo com projetos pessoais, estou sempre com projetinhos.

Semana passada consegui licenciar com o SHOUTCast(tm) Radio para (re)lançar o Shouter. O Shouter é um player que permite navegar entre as estações de radio online do SHOUTCast(tm) Radio , salvar suas favoritas e ouvi-la, é claro.

Foi um projeto curto, em 2 dias já estava funcional, mais 2 dias estava redondo. Mas demorou quase um mês para licenciar, fora encher de coisas a interface. Mas, enfim, saiu.

E têm também o TwitterFlow, já havia feito o cliente para twitter, mas estava muito insatisfeito com o resultado. Então depois de um tempo resolvi fazer um do zero, ai começou na quinta-feira 3 de setembro o TwitterFlow2, do zero, com o grande diferencial de usar OAuth.

Também já esta online, apesar de estar propenso a muitos erros ainda, e têm bastante o que acertar, mas estou satisfeito com o resultado.

Enfim, é isso. Estou precisando voltar mais ao PHP...

 

Hello World em JavaFX: Faça um streaming com a busca do twitter.

E-mail Print PDF

Não tem HelloWorld mais na moda que o Twitter.

Este artigo sera um tutorial sobre o básico do JavaFX, vai tratar a sintaxe, como construir uma interface básica e acessar um webservice. O Objeto final será um client para busca do twitter, atualizando automaticamente.

Não será um stream propriamente dito pois a API de Streaming do twitter requer autenticação, então para manter mais simples usará atualizações agendas para busca de novos itens. Não vou tratar de nenhuma ferramenta especifica, apenas do código em si, a parte de compilar e rodar fica a cargo da sua IDE. Vamos começar?

O primeiro passo é criar nosso projeto, que se chamará , muito criativamente, Searchr. Vou trabalhar apenas no pacote homônimo, searchr. Vamos primeiro o ponto de entrada na nossa aplicação, que será o Main, então temos o arquivo searchr/Main.fx , lembre-se de configurar sua IDE para usa-lo como ponto inicial.

O primeiro ponto de um aplicativo JavaFx é um objeto “Stage”, cada Stage representa uma janela. É importante notar que a janela é aberta no momento que criamos o Stage, assim que ele é construído. Cada Stage possui então um Scene, que é o conteúdo da janela, aonde vamos colocar nossos elementos gráficos.

O ponto de partida da aplicação é a função “run()”, quando temos o “run” lá criamos nosso stage e iniciamos qualquer outro processo necessário ao inicio da aplicação. Veja como colocamos então uma janela com um texto dentro:

// Main.fx, após imports
var stage: Stage ;
def scene: Scene = Scene {
fill: Color.WHITE
content: [ Text { content: “Hello JavaFx” } ]
}

function run() {
stage = Stage {
title: “Hello JavaFx”
width: 350
height: 500
scene: scene
}
}

Explicando tudo, na sintaxe do javafx temos duas formas de declarar uma variável, como sendo realmente variável ou definitiva, sendo preferível ser definitiva. O formato é então nomeDaVariavel: Tipo.

Temos então a construção de um objeto Scene, veja que na sintaxe declarativa iniciamos cada propriedade no momento da criação do objeto. Nesse caso criei o scene com “fill” branco e um array no conteúdo.

Uma lista é tratada como visto no content do Scene, entre colchetes, com elementos separados por virgula. Criei ainda um texto com conteúdo “Hello JavaFX”. Mais sobre listas mais tarde.

Em seguida declarei um função, nesse caso a principal “run”, aonde começa o programa, quando chega nesse ponto crio a janela que conterá minha UI. Vamos começar a explorar alguns elementos básicos de UI agora.

Minha ideia do aplicativo é extremamente simples, um campo de texto, um botão “Search” e em baixo a lista dos tweets.

Para organizar tudo, criarei um container vertical, o Vbox, e o coloco na cena (Scene). Com conteúdo vazio.

def container: VBox = VBox { spacing: 5, content: [] } ;
def scene: Scene = Scene {
fill: Color.rgb(51,51,51)
content: [ container ]
}

Crio agora a caixa de texto onde vai entrar a busca. E o botão para fazer o busca.

def input: TextBox = TextBox { promptText: “Search...” , action: doSearch, columns: 30};
def button: Button = Button { text: “Search”, action: doSearch };

Veja que temos ai um “action”, aponto ele para uma função “doSearch”, que tem a mesma assinatura que a propriedade “action”, que é uma função sem argumentos e que não retorne nada.

function doSearch(): Void {}

Deixo a função para mais tarde, veja que o tipo de retorno vem depois da declaração. Posso ainda definir assim:

def doSearch = function(): Void {}

Vou colocar esses elementos na mesma linha usando o Hbox, e já o incluo no container vertical.

def searchBar: HBox = HBox { spacing: 5, content: [ input, button] }
def container: VBox = VBox { spacing: 5, content: [ searchBar ] }

Vou declarar agora uma classe para generalizar a interface de cada linha que será o resultado da busca. Será um CustomNode, que é um elemento personalizado.

class SearchLine extends CustomNode {

public-init var profileUrl: String ;
public-init var user: String ;
public-init var text: String;
public var width: Number ;

override function create(): Node {
return HBox {
spacing: 5
content: [
ImageView {
image: Image {
url: profileUrl
, width: 54
, height: 54
, backgroundLoading: true
, placeholder: Image {
url: "{__DIR__}placeholder.png"
width: 54
height: 54
}}
}
Text {
content: “{user}: {text}”
wrappingWidth: bind width – 60
fill: Color.WHITESMOKE
}
]
}
}
}

Temos ai vários elementos para explorar, a declaração da Classe é básica. Temos então os atributos “public-init” que só podem ser alterados na construção do objeto. Width não é public-init pois pode mudar conforme o tamanho da janela mude, você verá mais tarde.

Tenho então que sobreescrever (o override) a função create da classe CustomNode, onde devo retorna o elemento customizado.

Nesse casso fiz uma linha HBox , com uma image e o texto do tweet. Vejam que na imagem defino a URL de onde deve ser carregada, informo para carregar em background, para não travar a UI, e defino uma imagem temporária (placeHolder).

Ai temos algo interessante, uma variável especial __DIR_ indica o diretório do aplicativo. E temos a string. Em Java FX não concatenamos como em Java, mas sim usando a expressão dentro de chaves, como:

def soma = “Soma de {a} + {b} = {a +b}”;

Em seguida temos o elemento texto, novamente com uma string com variáveis, e um limite de largura, aonde haverá quebra automática de linha. E um BIND.

Um bind é uma ligação entre uma variável ou propriedade e uma outra variável ou expressão, assim quando uma muda a outra é atualizada. Quando width mudar, a largura do texto irá acompanhar. Podemos ainda ter casos mais complexo, como expressões e loops, como veremos até o final.

Vamos criar agora o container dos tweets, esse será um pouco mais complexo, pois exibirá apenas parte dos tweets, e terá rolagem, mas isso vai explorar boas partes da linguagem. Então vamos por partes, primeiro a lista em si:

def tweetList: VBox = VBox { spacing: 5 , content: bind for ( tweet in tweets) {
SearchLine{
profileUrl: tweet.profileImage
user: tweet.user
text: tweet.text
width: bind scene.width -15
  } } }

Veja que interessante, eu liguei o conteúdo da lista a um loop, que gera a SearchLine. E garanti que o tamanho do texto vai bater com o tamanho da tela. Vamos definir esses itens faltosos logo:

class Tweet {
public var profileImage :String;
public var user: String ;
public var text: String ;
}
var tweets: Tweet[];

Essa classe vai conter cada tweet, como sendo nosso model. E temos a lista onde armazenamos os tweet achados.

Agora temos um detalhe, que é que não podemos exibir a lista toda por conta do espaço, então criamos um ClipView. Ele funciona contendo o conteúdo, mas exibindo apenas parte dele. Veja:

def clip: ClipView = ClipView {
clipY: 0
clipX: 0
node: tweetList
height: bind scene.height - 30
width: bind scene.width
}

Temos ai nosso ClipView, começando exibindo o começo apenas, contendo o VBox anterior, a altura será sempre o da janela menos 30 (mais ou menos o tamanho da barra de busca), e a largura será o da janela.

Um caso especial sobre o ClipView, é que é pannable. Ou seja, basta “segurar” e arrastar para rolar. Podemos definir ele como “pannable: false” e adcionar um ScrollBar também ou eventos de mouse, mas ai fica para outra oportunidade.

Agora é só inserir o clip no container:

def container: VBox = VBox { translateX: 10, translateY: 5, spacing: 5, content: [ searchBar, clip ] }

Adcionei ainda um posicionamento em X e Y para haver um espaço na janela. Feito a UI, agora é hora de mágica! Vamos ao acesso ao webservice.

Vou usar uma classe chamada AtomTask(podia ser RssTask, FeedTask, ou mesmo genérico HttpRequest), que recupera atom de tempos em tempos. Trabalhamos na função doSearch que definimos antes:

var current: AtomTask ;

function doSearch(): Void {
if(current != null) { current.stop(); }
current = AtomTask {
interval: 1m
location: "http://search.twitter.com/search.atom?q={input.text}"
onFeed: function(feed: Feed) {
delete tweets;
}
onEntry: function(item: Entry) {
insert Tweet {
profileImage: item.links[1].href
text: item.title.text
user: item.authors[0].name
} into tweets ;
}
};
current.start();
input.text = “”;
}

Crio uma variável para conter a Tarefa corrente. Ao fazer a busca, paro a tarefa anterior, e crio uma nova. Defino o intervalo de 1 minuto (é um tipo do JavaFx chamado Duration), a location de acordo com o conteúdo do input.

O evento onFeed é chamado assim que recebemos o Atom, ai eu limpo o array de tweets.

O evento onEntry recebe cada alemento achado no Atom, para cada um eu insiro um novo Tweet no array de tweets.

Em seguida eu inicio a tarefa, e limpo a caixa de texto. Assim como mágica ( #NOT ), o aplicativo está pronto. Agora você pode roda-lo usando webstart, através do jnlp que sua IDE criou(ou não), ou como applet no seu site.

Claro que esta extremamente simples, mas já serve para os principais conceitos do JavaFx, o código final esta no github, no streaming de search de twitter.

Last Updated on Monday, 07 September 2009 20:56
 
  • «
  •  Start 
  •  Prev 
  •  1 
  •  2 
  •  3 
  •  4 
  •  5 
  •  6 
  •  7 
  •  8 
  •  9 
  •  10 
  •  Next 
  •  End 
  • »


Page 1 of 18