Home Corsi Programmazione Linux L'ambiente di sviluppo GNU/Linux

In evidenza

I riflettori della Fiera del Levante si accendono su SMAU Bari 2012

I riflettori della Fiera del Levante si accendono su SMAU Bari 2012

Dal 15 al 16 febbraio nel Nuovo Padiglione della Fiera del Levante, la quarta edizione di Smau sarà dedicata ...
TecnoWorkshop Lucca2011

TecnoWorkshop Lucca2011

Finalmente, e dopo un po' di peripezie siamo riusciti ad organizzare il primo TecnoWorkshop del nostro...
Società Italiana dei Professionisti delle Scienze dell'Informazione

Società Italiana dei Professionisti delle Scienze dell'Informazione

La Società Italiana dei Professionisti delle Scienze dell'Informazione (acronimo SIPSI) è una associazione...
Testata Giornalistica

Testata Giornalistica

Il portale Professionisti e Consulenti ICT - Italia è ora una testata giornalistica a tutti gli effetti...

Bandi di Concorso

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Istruttore informatico L.68/1999 al Comune di Potenza

Concorso pubblico, per esami, per la copertura di n. 2 posti di Istruttore Informatico, categoria C, posizione economica C1, a tempo pieno e indeterminato, con riserva assoluta alle categorie dilavoratori di cui all'art. 1 della legge n. 68/1999 (norme per...

21 Gen 2012 - Letture:70

Senior Business Consultant presso Lombardia Informatica

Selezione per figura Senior Business Consultant presso Lombardia Informatica. Il collaboratore dovrà fornire consulenza strategica e di business sulle tematiche verticali della Socio-Sanità. Requisiti di ammissione: Laurea in Ingegneria, Economia e Commercio o Scienze dell’Informazione; Percorsi di formazione professionale in ambito sanitario e socio-sanitario, su...

11 Gen 2012 - Letture:129

Bando progetto TAG (Toscana Area Giovani) per giovani talenti digitali

UPI Toscana ha indetto un avviso pubblico per la selezione di 20 giovani (2 per ciascuna delle 10 province della Toscana), da impiegare come formatori all'interno del Progetto TAG (Toscana Area Giovani). Il bando è finalizzato a valorizzare al meglio i...

03 Gen 2012 - Letture:136

Avviso pubblico per giovani dottori di ricerca per Uffici di Gabinetto

Avviso pubblico per il conferimento di n. 6 incarichi presso gli Uffici di diretta collaborazione del Ministro dell'istruzione dell'università e della ricerca, per soggetti estranei alla pubblica amministrazione. Ambiti di esperienza e Aree di competenza: Nuovi Media: nuove forma di comunicazione tra...

02 Gen 2012 - Letture:96

Database Administrator in the Information Technology (IT) Department at CERN

E' aperta una posizione nel gruppo di lavoro che fornisce servizi Database e Middleware al CERN, un'organizzazione internazionale che fa fisica delle particelle di stanza a Ginevra, Svizzera. Direttamente dal sito del bando si legge: as Database Administrator in the Database...

12 Dic 2011 - Letture:145

Posto per collaboratore tecnico CROB a Rionero in Vulture (PZ)

Indetto pubblico concorso, per titoli ed esami, per la copertura di un posto di collaboratore tecnico professionale esperto - Ingegnere - Cat. DS presso il centro di riferimento oncologico della Basilicata in Rionero in Vulture (PZ).

22 Nov 2011 - Letture:238

Concorso per operatore tecnico-amministrativo presso l'Autorità Portuale di Cata…

Indetta una pubblica selezione concorsuale per titoli a  n. 1 posto per l'accesso, a tempo indeterminato, nella  Pianta Organica dell'Autorità Portuale di Catania di Operatore esecutivo polifunzionale di settore tecnico/amministrativo, con  inquadramento livello 5° del CCNL dei Lavoratori dei Porti.

21 Nov 2011 - Letture:157

I più attivi

Dati e punteggi dell'ultimo anno

Giovanna Casamassima Giovanna Casamassima
46 articoli
11,965 punti totali
Rodolfo Giometti Rodolfo Giometti
47 articoli
7,544 punti totali
Vittorio D'Aversa Vittorio D'Aversa
33 articoli
2,871 punti totali
Fabio Bronzini Fabio Bronzini
13 articoli
0,654 punti totali
Fulvio Lucchetti Fulvio Lucchetti
11 articoli
0,539 punti totali

Ci hanno visitato

Oggi:1362
Ieri:2464
Totali (14/04/09):910772

I nostri numeri

Articoli pubblicati: 518
Iscritti al portale: 667
Iscritti all'Elenco: 175
Iscritti ML Discussioni: 331
Iscritti ML Articoli: 28
Iscritti ML Lavoro: 165
 
L'ambiente di sviluppo GNU/Linux Stampa E-mail
(3 voti, media 3.67 di 5)
Area Corsi - Programmazione Linux
Scritto da Rodolfo Giometti   
Mercoledì 30 Settembre 2009 15:57
Articolo letto 1684 volte

Questa dispensa vuole illustrare alcuni aspetti che riguardano l'ambiente di sviluppo in un sistema UNIX in generale e GNU/Linux in particolare, in modo da presentare al lettore diverse soluzioni e/o spunti di approfondimento.

Si presenteranno non solo gli strumenti di sviluppo fondamentali ma anche alcuni suggerimenti sui sistemi di aiuto alla programmazione (e non solo), sulla documentazione e il reperimento delle informazione e su alcune tecniche di debugging.

Gli strumenti di aiuto

Quando abbiamo a che fare con un sistema complesso come un sistema UNIX è fondamentale conoscere e saper utilizzare gli strumenti di aiuto, questo perché tali strumenti ci permettono di avere informazioni su:

  • i comandi di sistema disponibili;
  • i file di configurazione dei vari programmi installati;
  • i prototipi e il funzionamento delle funzioni (soprattutto quelle in C);
  • ecc.

In ogni sistema UNIX è presente il comando man, con il quale è possibile avere una serie di informazioni riguardanti l'utilizzo di tutti i comandi, la sintassi e le opzioni dei file di configurazione del sistema, i prototipi e la semantica delle funzioni di programmazione per più linguaggi, ecc..

Riporto un esempio dell'output del comando:

$ man man
MAN(1) Manual pager utils MAN(1)

NAME
man - an interface to the on-line reference manuals

SYNOPSIS
man [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L
locale] [-m system[,...]] [-M path] [-S list] [-e extension] [-i|-I]
[--regex|--wildcard] [--names-only] [-a] [-u] [-P pager] [-r prompt]
[-7] [-E encoding] [--no-hyphenation] [-p string] [-t] [-T[device]]
[-H[browser]] [-X[dpi]] [-Z] [[section] page ...] ...
man -k [apropos options] regexp ...
man -f [whatis options] page ...
man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L
locale] [-P pager] [-r prompt] [-7] [-E encoding] [-p string] [-t]
[-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...
man -w|-W [-C file] [-d] [-D] page ...
man -c [-C file] [-d] [-D] page ...
man [-hV]

DESCRIPTION
man is the system’s manual pager. Each page argument given to man is
normally the name of a program, utility or function. The manual page
associated with each of these arguments is then found and displayed. A
section, if provided, will direct man to look only in that section of
the manual. The default action is to search in all of the available
sections, following a pre-defined order and to show only the first page
found, even if page exists in several sections.

Nei sistemi GNU/Linux esiste però anche un altro comando per ottenere aiuto, e molto più potente di man: il comando info. Con info è possibile avere on-line il manuale di tutta una serie di pacchetti software a cominciare da gcc, make, gdb, ld, ecc.. In pratica il manuale del prodotto software è distribuito insieme ad esso in forma elettronica.

In più se abbiamo il sorgente texinfo del nostro manuale (e, di solito, questo viene sempre fatto nel mondo del software libero) possiamo ottenerne anche una in formato HTML, PDF, PS, ecc., quindi è possibile perfino stamparlo.

Documentazione

Purtroppo (o per fortuna) non esiste molta documentazione sulla programmazione all'interno del kernel in rete, ecco perché il mezzo migliore per capire come funzionano le cose in Linux è di leggerne il codice sorgente!
altUse the source, Luke!

Esistono comunque, per chi si trova in difficoltà o non ha tempo di studiarsi il codice da solo, una serie di risorse alternative:

  • Siti in rete: LWN.net, LKML.org

alt

  • Libri specilistici: Linux Device Driver, Understanding the Linux Kernel, Linux Kernel in a Nutshell

alt alt alt

  • Consulenti specializzati.

alt

 

I tool di compilazione

Il compilatore

Il codice di Linux è scritto in C, quindi per poterci lavorare occorre un compilatore, Ie il compilatore utilizzato è il gcc (GNU C compiler).

Non so se il codice di Linux possa essere compilato anche con altri compilatori (personalmente non ne sono a conoscenza), ma poiché il codice utilizza molte delle caratteristiche specifiche del gcc e quest'ultimo è pure reperibile gratuitamente in rete, di fatto il gcc è il solo compilatore che conviene utilizzare (per non parlare poi della sue qualità).

Come è noto un compilatore C è formato da più componenti (cpp, cc1, eventualmente as e lo stesso ld), e gcc non è diverso, e alle volte può essere utile arrestare la compilazione subito dopo l'esecuzione di uno di questi stadi intermedi per esigenze di debugging.

Per far questo, direttamente dalle pagine di man del gcc si legge:

-c      Compile or assemble the source files, but do not
        link. The compiler output is an object file corre-
­        sponding to each source file.
-S      Stop after the stage of compilation proper; do not
        assemble. The output is an assembler code file for
        each non-assembler input file specified.
-E      Stop after the preprocessing stage; do not run the
        compiler proper. The output is preprocessed source
        code, which is sent to the standard output.
-dM     Tell the preprocessor to output only a list of the
        macro definitions that are in effect at the end of
        preprocessing. Used with the `-E' option.

Il linker

Come intuibile (e già accennato) il linker utilizzato è ld (GNU linker). Verrà utilizzato per collegare (linkare) tra loro i vari moduli che compongono il nostro codice di nucleo.

Il linker, però, lo si può utilizzare anche insieme a speciali direttive (chiamate ld-script) per fare in modo di rilocare a piacere il codice di nucleo. Direttamente dalle pagine di info di ld:

The main purpose of the linker script is to describe how the
sections in the input files should be mapped into the output file, and
to control the memory layout of the output file. Most linker scripts
do nothing more than this. However, when necessary, the linker script
can also direct the linker to perform many other operations, using the
commands described below.

The linker always uses a linker script. If you do not supply one
yourself, the linker will use a default script that is compiled into the
linker executable. You can use the `--verbose' command line option to
display the default linker script. Certain command line options, such
as `-r' or `-N', will affect the default linker script.

make e i makefile

Il tool di gestione della compilazione utilizzato è make (GNU make).

Senza voler entrare nel dettaglio di funzionamento di make, ci basti sapere che questo tool ci aiuta nella gestione della fase di compilazione. In particolare si occuperà lui di dare icomandi giusti, e nella sequenza corretta, affinché il compilatore e il linker generino il codice corretto.

In particolare ci permetterà di gestire facilmente ed in maniera efficiente i parametri di configurazione della nostra applicazione. Quando si realizza una nuova applicazione che (si spera) andrà a far parte del codice standard di Linux, questo strumento risulta allora fondamentale e dovrà inoltre essere configurato insieme all'applicazione di configurazione del kernel chiamata menuconfig (il nome non e proprio quello ma passatemi il termine n.d.a.).

Questa applicazione riesce a determinare il come un certo progetto (insieme di file) va compilato a seconda delle istruzioni che gli vengono impartite in file speciali denominati makefile. In un makefile (che di solito si chiama Makefile) si specificano le dipendenze tra i vari file che compongono il progetto e i comandi da eseguire per ottenere il risultato finale. Direttamente dalle pagine di info di make:

The GNU `make' utility automatically determines which pieces of a
large program need to be recompiled, and issues the commands to
recompile them.

Riporto di seguito un semplice makefile per compilare un modulo del nucleo:

TARGET = module.o
CFLAGS += -Wall -O -D__KERNEL__ -DMODULE

$(TARGET) : $(TARGET:.o=.c)
        $(CC) $(CFLAGS) -c $^

Un makefile può anche essere molto più complesso se gli si richiedono di eseguire diverse operazioni (come ad esempio eseguire delle operazioni di installazione del codice appena compilato o di ripulire il progetto dai file generati dal compilatore); ad esempio con il seguente makefile:

TARGET = timer.o

KERNELDIR = /usr/src/linux
INCLUDEDIR = $(KERNELDIR)/include
override CFLAGS += -Wall -O -D__KERNEL__ -DMODULE -I$(INCLUDEDIR)

$(TARGET) : $(TARGET:.o=.c)
        $(CC) $(CFLAGS) -c $^

.PHONY : clean
clean :
        rm -f $(TARGET)

si può usare il comando seguente per generare un codice oggetto:

$ make KERNELDIR=/usr/src/linux-2.4.18
cc -Wall -O -I/usr/src/linux-2.4.18/include -D__KERNEL__ -DMODULE -c timer.c

E questo per cancellare il file appena generato, ripulendo così la directory del progetto per una eventuale distribuzione del pacchetto software;

$ make clean
rm -f timer.o

Se vogliamo invece produrre del codice che si (spera) verrà inserito nella distribuzione standard del codice di Linux, occorre allora modificare non solo il/i Makefile del kernel ma anche il processo di configurazione del kernel stesso (menuconfig), modificando i file Kconfig (nel 2.4 si chiamavano Kconfig.in).
I file Kconfig vengono poi letti dai vari comandi di configurazione standard del nucleo:

  • make config     - solo testo
  • make menuconfig - solo testo ma utilizzando la libreria ncurses
  • make xconfig    - grafico

Riporto di seguito un esempio di file Kconfig:

#
# PPS support configuration
#

menu "PPS support"

config PPS
tristate "PPS support"
depends on EXPERIMENTAL
help
  PPS (Pulse Per Second) is a special pulse provided by some GPS
  antennae. Userland can use it to get a high-precision time
  reference.

  Some antennae's PPS signals are connected with the CD (Carrier
  Detect) pin of the serial line they use to communicate with the
  host. In this case use the SERIAL_LINE client support.

  Some antennae's PPS signals are connected with some special host
  inputs so you have to enable the corresponding client support.

  To compile this driver as a module, choose M here: the module
  will be called pps_core.ko.

config PPS_DEBUG
bool "PPS debugging messages"
depends on PPS
help
  Say Y here if you want the PPS support to produce a bunch of debug
  messages to the system log. Select this if you are having a
  problem with PPS support and want to see more of what is going on.

source drivers/pps/clients/Kconfig

endmenu

I Makefile del kernel 2.6 sono stati molto potenziati rispetto a quelli del 2.4 in modo da semplificare al massimo la definzione delle operazioni di compilazione dei vari sottosistemi/moduli del kernel; il tutto poi in modo del tutto trasparente al programmatore. Ad esempio la definizione di file oggetto composti da più di un file sorgente è molto semplificata così come lo è la definizione di eventuali flag di compilazione:

#
# Makefile for the PPS core.
#

pps_core-y := pps.o kapi.o sysfs.o
obj-$(CONFIG_PPS) := pps_core.o
obj-y += clients/

ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG

Il debugging

strace

Per le operazioni di debugging si possono scegliere diversi strumenti che operano nello spazio utente, come il gdb (The GNU Debugger) e/o strace. Esistono poi anche altre tecniche di debugging come, ad esempio, l'uso delle printk() e del proc filesystem ma che non vedremo ora.

L'uso del gdb è poco usato (almeno io non lo reputo molto efficiente e portabile), mentre l'uso di strace è decisamente più versatile. Ma cosa è strace? Non è altro che una applicazione che permette di vedere tutte le chiamate di sistema che un processo fa durante la sua esecuzione. Risulta allora evidente come esso sia molto utile per testare le varie chiamate di sistema che, scrivendo ad esempio un driver, dovremo necessariamente implementare.

Dalle pagine di man di strace:

STRACE(1) STRACE(1)

NAME
strace - trace system calls and signals

SYNOPSIS
strace [ -dffhiqrtttTvxx ] [ -acolumn ] [ -eexpr ] ... [ -ofile ] [
-ppid ] ... [ -sstrsize ] [ -uusername ] [ -Evar=val ] ... [ -Evar ]
... [ command [ arg ... ] ]

strace -c [ -eexpr ] ... [ -Ooverhead ] [ -Ssortby ] [ command [ arg
... ] ]

DESCRIPTION
In the simplest case strace runs the specified command until it exits.
It intercepts and records the system calls which are called by a pro-
cess and the signals which are received by a process. The name of each
system call, its arguments and its return value are printed on standard
error or to the file specified with the -o option.

strace is a useful diagnostic, instructional, and debugging tool. Sys-
tem administrators, diagnosticians and trouble-shooters will find it
invaluable for solving problems with programs for which the source is
not readily available since they do not need to be recompiled in order
to trace them.
Students, hackers and the overly-curious will find that
a great deal can be learned about a system and its system calls by
tracing even ordinary programs. And programmers will find that since
system calls and signals are events that happen at the user/kernel
interface, a close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.

Each line in the trace contains the system call name, followed by its
arguments in parentheses and its return value. An example from strac-
ing the command ``cat /dev/null'' is:

open("/dev/null", O_RDONLY) = 3

Errors (typically a return value of -1) have the errno symbol and error
string appended.

open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

Naturalmente strace da solo non può bastare per effettuare complesse operazioni di debug del codice di nucleo, si usano anche altre tecniche, alcune anche molto «banali» che prevedono l'uso delle funzione di nucleo printk() come accennato prima, oppure l'utilizzare i normali strumenti di manipolazione dei file presenti in ogni sistema UNIX per stimolare il codice di nucleo.

Strumenti per la manipolazione dei file

L'ambiente UNIX è caratterizzato dal possedere l'astrazione file, la possibilità cioè, di considerare ogni dispositivo come se fosse un file; questo concetto è molto potente perché ci permette di utilizzare uno stesso strumento su entità fisicamente molto differenti. In una macchina UNIX quindi qualsiasi cosa viene vista come un file: il video, la tastiera, la memoria, i dischi, ecc..

Questo concetto ci permette quindi di utilizzare uno stesso programma per copiare un file in un altro, come per copiare il contenuto di un disco in un file o in unaltro disco. Ad esempio per copiare il contenuto di un disco su di un altro si può dare il comando:

$ cat /dev/hda > /dev/hdb

Poiché un dispositivo è visto come un file, è facile capire come anche il comando cat possa essere usato per stimolare un dispositivo.

cat

Questo comando, di solito, si usa per leggere il contenuto di un file ma durante lo sviluppo di un driver può essere anche usato per testare i metodi open(), close(), read() e write(). Con il comando cat posso quindi scrivere o leggere dati da e nel mio dispositivo. Ecco come posso, ad esempio, scattare una foto da un frame grabber mappato sul file /dev/framegrabber:

$ cat /dev/framegrabber > mypic

dd

Questo comando è molto interessante perché permette di utilizzare/testare anche il metodo lseek(). In pratica si può usare per andare a leggere zone diverse di un dispositivo senza dover necessariamente partire dalla posizione 0. Sempre considerando il framegrabber di prima possiamo, ad esempio, leggere la quarta immagine (sempre che il dispositivo preveda questa caratteristica e che la dimensione delle immagine sia di 64Kb) usando il comando:

$ dd if=/dev/framegrabber of=mypic bs=64K count=1 skip=3

Strumenti per la gestione dei pacchetti di rete

L'unico aspetto che non può essere inserito nell'astrazione file, è la rete. Il sottosistema di rete, proprio di tutti i sistemi UNIX, non soddisfa totalmente l'astrazione file. In questo caso quindi, per gestire e/o visualizzare i pacchetti che due o più macchine di scambiano via rete, dobbiamo usare strumenti specifici per tale scopo.

ping, route e tcpdump

Con il comando ping è possibile generare dei pacchetti verso un dato host contenenti pattern specifici.

NAME
ping, ping6 - send ICMP ECHO_REQUEST to network hosts

SYNOPSIS
ping  [-LRUbdfnqrvVaAB]  [-c count] [-i interval] [-l preload] [-p pat-
tern] [-s packetsize] [-t ttl] [-w deadline] [-F flowlabel] [-I  inter-
face] [-M hint] [-Q tos] [-S sndbuf] [-T timestamp option] [-W timeout]
[hop ...] destination

DESCRIPTION
ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to elicit
an  ICMP  ECHO_RESPONSE from a host or gateway.  ECHO_REQUEST datagrams
(``pings'') have an IP and ICMP header, followed by  a  struct  timeval
and  then  an  arbitrary  number  of ``pad'' bytes used to fill out the
packet.

OPTIONS
-f     Flood ping. For  every  ECHO_REQUEST  sent  a  period  ``.''  is
       printed,  while  for  ever  ECHO_REPLY  received  a backspace is
       printed.  This provides a rapid display of how many packets  are
       being  dropped.   If  interval is not given, it sets interval to
       zero and outputs packets as fast as they come back or  one  hun-
       dred  times  per second, whichever is more.  Only the super-user
       may use this option with zero interval.
-p pattern
       You  may  specify  up to 16 ``pad'' bytes to fill out the packet
       you send.  This is useful for diagnosing data-dependent problems
       in  a network.  For example, -p ff will cause the sent packet to
       be filled with all ones.

Con il comando route è possibile, invece, dire al sistema su quale interfaccia di rete indirizzare i pacchetti per la spedizione.

Ad esempio, per aggiungere una rotta di default verso il gateway uso il comando:

$ route add default gw 192.168.32.10

mentre per visualizzare dove il sistema mi invierà i vari pacchetti uso:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.100.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr1
192.168.32.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
0.0.0.0         192.168.32.10   0.0.0.0         UG    100    0        0 eth0

In questo modo saprò che tutti i pacchetti della sottorete 192.168.122.0/24 verranno spediti all'interfaccia virbr0.

Con il comando tcpdump, in fine, è possibile monitorare tutti i pacchetti che passano su di un collegamento di rete.

Il comando tcpdump è particolarmente interessante perché ci permette di sapere se il nostro sistema ha effettivamente inviato il pacchetto o no.

Ad esempio possiamo tenere sotto controllo l'invio o la ricezione di pacchetti di rete da parte del computer denominato computer1 tramite il comando:

$ tcpdump host computer1

Volendo filtrare solo una data porta (ad esempio la 80) basterà scrivere:

$ tcpdump host computer1 and port 80

 


Questa dispensa del corso Programmazione Linux è opera di Rodolfo Giometti (Copyright © 2003-2010) ed è rilasciata dall'autore «as is» (così com'è) e distribuita sotto licenza Creative Commons Attribuzione – Condividi allo stesso modo 2.5 Italia.

 

Aggiungi commento

Prima di pubblicare un tuo commento assicurati che:

  • sia in tema e contribuisca alla discussione in corso.

  • non abbia contenuto razzista o sessista.

  • non sia offensivo, calunnioso o diffamante.


La redazione con i controlli a campione si riserva di cancellare qualsiasi contenuto ingiurioso, volgare o illegale.


Nota bene: se non sei registrato il tuo commento verrà moderato e quindi non pubblicato immediatamente. Se, invece, sei registrato al portale e hai fatto login verrà visualizzato subito.


Codice di sicurezza
Aggiorna

 

In primo piano

Simons Voss: un mondo senza chiavi

Simons Voss: un mondo senza chiavi

Il sistema di gestione e di controllo degli accessi 3060 si presenta come un’alternativa con enormi vantaggi...
Pubblicità mirata dei prodotti

Pubblicità mirata dei prodotti

Hai un prodotto o un servizio da pubblicizzare? Fallo su consulenti-ict.it! Pubblicizzare un prodotto...
Recensioni sul Portale

Recensioni sul Portale

Hai un prodotto hardware/software o un libro riguardante uno dei temi dell'ICT? Vuoi farlo conoscere...

Ultime dal Forum

Visualizza Topic »

Eventi

Non ci sono eventi in programma
Febbraio 2012
D L M M G V S
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 1 2 3
Marzo 2012
D L M M G V S
26 27 28 29 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Sondaggi

busyCaricamento Sondaggio...

Ultimi Commenti