%%
%% Dispense corso amministrazione 
%%
%% Copyright (C) 2001-2018 Simone Piccardi and Truelite Srl.
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%%
%% S. Piccardi Sep. 2001
%% 
%% config.tex: configurazioni di base
%%
\chapter{La configurazione dei servizi}
\label{cha:config_services}



\section{Le configurazioni di base}
\label{sec:cfg_file}

In questa sezione tratteremo la gestione generica dei file di configurazione
all'interno di un sistema GNU/Linux, introducendo alcuni concetti validi in
generale per qualunque file di configurazione. Descriveremo poi direttamente i
file di configurazione di alcuni servizi di base, come quelli che controllano
il comportamento delle librerie dinamiche, l'impostazione dei parametri del
kernel e la localizzazione dei programmi.


\subsection{Una panoramica generale}
\label{sec:cfg_general}

A differenza di Windows che tiene tutte le configurazioni in un unico file
binario, il \textsl{registro}, le sole due caratteristiche comuni che potete
trovare nei file di configurazione su un sistema GNU/Linux sono che essi sono
mantenuti, come illustrato in sez.~\ref{sec:file_FHS}, nella directory
\texttt{/etc/} e che sono file di testo. Questo vale in generale per tutti i
file di configurazione, e non è limitato a quelli che tratteremo nel prosieguo
di questa sezione.

La ragione di questa frammentazione dei file di configurazione deriva
dell'architettura del sistema (illustrata in
sez.~\ref{sec:struct_architecture}), per cui tutti i servizi sono forniti da
opportuni programmi, che non è affatto detto siano sempre gli stessi anche per
uno stesso servizio: ad esempio esistono diversi programmi che gestiscono
l'invio e la ricezione della posta elettronica, ma chiaramente se ne
installerà uno solo, e si userà il file di configurazione specifico dello
stesso.

Ciò comporta che i formati dei file di configurazione possano essere anche i
più vari, dipendendo ciascuno dalla sintassi adottata dal relativo programma;
per cui, anche se esistono delle convenzioni generali come ignorare le righe
vuote o considerare il carattere ``\texttt{\#}'' l'inizio di un commento
interno al file, esiste una enorme varietà di formati, ed anche queste
semplici regole non è detto che vengano sempre rispettate.

\itindbeg{keyfile}

Ma anche se non esiste un formato universale, alcuni programmi han finito per
l'adottare formati comuni o simili per i propri file di configurazione. Uno
dei più utilizzati, che per questo vale la pena citare esplicitamente, è
quello dei cosiddetti \textit{keyfile}, una variante del formato dei file INI
di Windows, esteso in genere secondo le \textit{XDG Desktop Entry
  Specification} (vedi
\url{http://standards.freedesktop.org/desktop-entry-spec/latest/}) in cui si
suddivide il file di configurazione in sezioni, introdotte ed identificate da
un nome racchiuso fra parentesi quadre, in cui inserire direttive espresse in
forma di assegnazione \texttt{\textsl{chiave}=\textsl{valore}}. Per i nomi
delle direttive di configurazione si usano solo caratteri alfanumerici, gli
spazi nelle assegnazioni vengono ignorati e normalmente viene fatta
distinzione fra maiuscole e minuscole. Infine, a differenza dei file INI di
Windows e seguendo la tradizione Unix, viene consentito anche l'uso del
carattere ``\texttt{\#}'' oltre al ``\texttt{;}'' come introduzione ad una
riga di commento, ignorando tutto quello che segue.

\itindend{keyfile}

Se da una parte tutta la complessità dovuta alla scelta di avere una directory
contenente centinaia di file di configurazione indipendenti in formati diversi
può spaventare, dall'altra ha il grande vantaggio che le modifiche ad un
singolo file di configurazione non hanno alcun modo di influenzare quelli di
altri programmi.  Il secondo grande vantaggio è che essendo i file di
configurazione dei normali file di testo è possibile effettuare ricerche ed
operazioni complesse con gli ordinari comandi di shell trattati in
sez.~\ref{sec:shell_fileutils}, ed eseguire le operazioni di configurazione
con un editor qualunque.

Un secondo aspetto della configurazione dei servizi di cui bisogna tenere
conto è quello della multi-utenza, molti programmi infatti permettono agli
utenti di scegliere le impostazioni ritenute più appropriate usando un
ulteriore file di configurazione nella loro home directory.  In genere questi
file sono invisibili (iniziano cioè con un ``\texttt{.}'')  ed hanno lo stesso
nome del loro analogo di \texttt{/etc/} valido per tutto il sistema, ma anche
in questo caso ogni programma ha le sue specifiche indicazioni.  Questa è una
forma semplice e pulita di consentire a ciascun utente di personalizzare le
sue scelte senza dover andare a scomodare le impostazioni generali di tutto il
sistema.

È da tenere presente infine che per molti programmi viene fornita anche una
pagina di manuale dei relativi file di configurazione che ne spiega il formato
e le direttive, accessibile usualmente con \texttt{man nomefile}, o nel caso
di omonimia con un comando o una funzione di sistema, con \texttt{man 5
  nomefile} (si ricordi quanto detto in sez.~\ref{sec:documentazione}).


\subsection{La gestione delle librerie condivise}
\label{sec:cfg_dyn_lib}

Una delle funzionalità più importanti per l'esecuzione dei programmi in un
qualunque sistema operativo è quella della gestione delle librerie condivise,
quelle che in Windows vengono chiamate DLL (da \textit{Dinamically Linked
  Library}) e che nei sistemi unix-like sono chiamate \textit{shared object}.
Si tratta del meccanismo che permette di inserire tutto il codice comune usato
dai programmi all'interno di opportune librerie, in modo che non sia
necessario averne una copia all'interno di ciascun programma. Abbiamo anche
visto in sez.~\ref{sec:file_FHS} come ci siano delle directory specifiche,
previste dal \textit{Filesystem Hierarchy Standard}, che devono contenere
queste librerie.

\itindbeg{link-loader}

Per far sì che il codice delle librerie possa essere utilizzato dai singoli
programmi occorre però una apposita infrastruttura. Come accennato anche in
sez.~\ref{sec:shell_scripting}, uno dei compiti fondamentali del sistema,
quello di mettere in esecuzione i programmi, viene realizzato attraverso
l'ausilio del cosiddetto \textit{link-loader}. Questo è un programma speciale,
che non è eseguibile in quanto tale (ed infatti si trova sotto \texttt{/lib}),
si tratta infatti di una sezione di codice che viene utilizzata direttamente
dalla chiamata al sistema che manda in esecuzione un nuovo programma nel
momento in cui questo viene caricato in memoria. 

Oltre alla gestione degli script accennata in sez.~\ref{sec:shell_scripting} è
compito del \textit{link-loader} caricare opportunamente in memoria i
programmi binari,\footnote{in Linux esistono sostanzialmente due formati
  binari, quello chiamato \texttt{a.out}, usato nei kernel delle serie fino
  alla 1.2, attualmente deprecato e totalmente inutilizzato da anni, e il
  formato ELF, usato nelle serie successive.} prima di metterli in
esecuzione. Il nome deriva dal fatto che oltre a caricare il codice
dell'eseguibile il \textit{link-loader} deve anche effettuare il collegamento
delle librerie condivise da questo utilizzate.\footnote{a meno che questo non
  sia stato compilato staticamente, cioè in maniera da includere al suo
  interno anche tutto il codice che altrimenti sarebbe stato disponibile
  attraverso delle librerie condivise, cosa che normalmente non viene mai
  fatta per ragioni di efficienza.} Questo significa che il
\textit{link-loader} dovrà identificare le funzioni di libreria utilizzate da
un programma, caricarle in memoria ed inserire i relativi indirizzi
all'interno del codice, in modo che possano essere invocate.

\itindend{link-loader}

Per verificare quali librerie dinamiche sono necessarie per l'esecuzione di un
programma si può usare il comando \index{comando!\texttt{ldd}} \texttt{ldd},
che stampa sullo \textit{standard output} i nomi delle librerie condivise di
cui esso ha bisogno. Il comando prende come argomento il pathname assoluto del
programma da analizzare e stampa a video il risultato, ad esempio:
\begin{Console}
piccardi@hain:~$ \textbf{ldd /bin/ls}
	linux-gate.so.1 =>  (0xb78d6000)
	libselinux.so.1 => /lib/libselinux.so.1 (0xb78b4000)
	librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb78ab000)
	libacl.so.1 => /lib/libacl.so.1 (0xb78a3000)
	libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb775c000)
	libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7758000)
	/lib/ld-linux.so.2 (0xb78d7000)
	libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb773f000)
	libattr.so.1 => /lib/libattr.so.1 (0xb773a000)
\end{Console}
%$
ci fa vedere le librerie necessarie all'uso di \texttt{ls} (il risultato è
relativo alla versione di \texttt{ls} installata su una Debian Squeeze su
architettura a 32 bit). L'opzione più usata di \texttt{ldd} è \texttt{-v} che
permette di avere una descrizione più dettagliata delle librerie, con le
informazioni relative alle versioni, le altre opzioni sono al solito descritte
nella pagina di manuale del comando.

Si noti come le librerie siano file il cui nome inizia per \texttt{lib} e
termina con l'estensione \texttt{.so}, che sta appunto per \textit{shared
  object}, seguita da un numero che è detto \textit{major version}. Questa è
una delle caratteristiche più utili in un sistema unix-like: le librerie sono
caratterizzate sempre con due numeri di versione, \textit{major} e
\textit{minor}, e la convenzione vuole che le interfacce pubbliche delle
librerie non debbano mai cambiare fintanto che non cambia la \textit{major
  version}. Al solito è soltanto una convenzione, anche se quasi universalmente
rispettata; ogni tanto qualche programmatore anche non più alle prime armi la
viola, con il risultato che programmi che fino ad allora funzionavano
perfettamente si trovano a riportare errori o a terminare improvvisamente.

Con questa architettura si ottengono due risultati di grande rilevanza: il
primo è che si può cambiare tranquillamente la \textit{minor version} di una
libreria senza che i programmi che la usano ne abbiano a risentire, a meno
che, al solito, un programmatore non troppo furbo abbia usato una qualche
funzione interna che non fa parte della interfaccia pubblica, nel qual caso di
nuovo può succedere di tutto. Il secondo è che se si ha bisogno di una
versione vecchia delle librerie si può installare anche quella, e sarà
tranquillamente usabile attraverso la diversa \textit{major version}, senza
nessun conflitto con le versioni più recenti. Questo è il motivo per cui il
problema dei conflitti di versione delle librerie, tristemente noto come
\textit{DLL hell}, è sostanzialmente assente su GNU/Linux.

Dato che il \textit{link-loader} deve essere in grado di determinare quali
sono le librerie che contengono le funzioni richieste da un programma tutte le
volte che questo viene eseguito, per effettuare la ricerca in maniera
efficiente viene utilizzato un apposito file di \textit{cache} in cui sono
state indicizzate tutte le informazioni relative alle funzioni presenti ed
alle librerie in cui esse sono contenute.  Questo file si chiama
\index{configurazione!\texttt{/etc/ld.so.cache}} \texttt{/etc/ld.so.cache} e
viene generato (di norma tutte le volte che si installa una nuova libreria)
con il comando \index{comando!\texttt{ldconfig}} \texttt{ldconfig}.

Il comando \texttt{ldconfig} permette sia di ricostruire la cache che di
ricreare i link all'ultima versione dei file delle librerie; infatti queste
vengono sempre cercate per numero di \textit{major version}, ma la libreria
installata sarà contenuta in un file con una sua specifica \textit{minor
  version}, o in generale, come nell'esempio, con un suo specifico numero di
versione. Perciò quello che si fa è creare un link simbolico dalla versione
cercata alla versione effettiva, e ad esempio avremo che:
\begin{Console}
piccardi@anarres:/lib$ \textbf{ls -l librt*}
-rw-r--r-- 1 root root 30684 Dec 18 00:42 librt-2.11.3.so
lrwxrwxrwx 1 root root    15 Feb  9 12:14 librt.so.1 -> librt-2.11.3.so
\end{Console}
%$
in cui si può notare come una certa versione specifica di una libreria (la
2.11.3) venga rimappata come prima \textit{major version}.

Un'altra delle funzionalità avanzate di \texttt{ldconfig} è che è in grado di
gestire in un unico file di cache, per le architetture che le supportano,
anche diversi formati dei binari e delle relative librerie, come avviene per
gli eseguibili a 32 bit sulle macchine a 64 bit. Se invocato con l'opzione
\texttt{-v} il comando stampa l'elenco di tutte le directory esaminate e delle
librerie usate nella ricostruzione, mentre con \texttt{-N} e \texttt{-X} si
può bloccare rispettivamente la ricostruzione della cache e quella dei link.

In sez.~\ref{sec:file_FHS} abbiamo visto come secondo il \textit{Filesystem
  Hierarchy Standard} le librerie possono essere mantenute in diverse
directory; di default il comando \texttt{ldconfig} esamina soltanto le
directory \texttt{/lib} e \texttt{/usr/lib}. Se ci sono altre librerie
condivise poste in directory diverse, queste possono essere specificate
tramite un opportuno file di configurazione,
\index{configurazione!\texttt{/etc/ld.so.conf}} \texttt{/etc/ld.so.conf}. Il
file contiene una lista tutte le directory che contengono librerie condivise
da far gestire a \texttt{ldconfig}, in genere elencate una per riga (ma la
lista può essere separata da spazi o da ``\texttt{:}'') e supporta anche,
nelle versioni più recenti del comando, l'uso della direttiva
\texttt{include}, per caricare configurazioni analoghe da altri file. Ad
esempio la versione installata su una Debian Squeeze è la seguente:
\begin{FileExample}[label=/etc/ld.so.conf]
include /etc/ld.so.conf.d/*.conf
\end{FileExample}

Se allora si installa una nuova libreria dai sorgenti, questa di norma (vedi
sez.~\ref{sec:install_tarball}) andrà in \texttt{/usr/local/lib}, e se questa
directory non compare in \texttt{/etc/ld.so.conf} o in uno dei file in essa
inclusi,\footnote{nel caso di Debian viene dichiarata in
  \texttt{/etc/ld.so.conf.d/libc.conf}, SuSE ad esempio la aggiunge
  direttamente in questo file.} sarà necessario aggiungerla in questo file e
poi eseguire \texttt{ldconfig} per aggiornare i link alle librerie condivise
disponibili e ricreare la cache, in modo che il linker dinamico possa
utilizzarla.

Il default di \texttt{ldconfig} prevede l'uso di \texttt{/etc/ld.so.conf}, ma
usando l'opzione \texttt{-f} si può specificare un qualunque altro file al suo
posto, mentre con \texttt{-n} si può passare direttamente sulla linea di
comando una lista di directory su cui effettuare la ricerca. Per le altre
opzioni e la documentazione completa si consulti al solito la pagina di
manuale, disponibile con \texttt{man ldconfig}.

Infine, nei casi in cui si vogliano utilizzare solo in forma temporanea delle
librerie condivise, si può ricorrere alla variabile di ambiente
\index{variabili!di~ambiente!\texttt{LD\_LIBRARY\_PATH}}
\texttt{LD\_LIBRARY\_PATH}, in cui passare una lista, nella stessa forma usata
dalla variabile \texttt{PATH} della shell (vedi sez.~\ref{sec:shell_sintax}),
di ulteriori directory separate da ``\texttt{:}'', in cui verrà effettuata la
ricerca di altre librerie, questa volta senza usare l'indicizzazione, per cui
il sistema sarà più lento.

In genere si usa questa variabile quando si sviluppano delle librerie o se si
vuole usare qualche pacchetto sperimentale oppure delle versioni alternative
delle librerie di sistema. Infatti le librerie contenute nelle directory
specificate tramite \texttt{LD\_LIBRARY\_PATH} hanno la precedenza e vengono
utilizzate per prime. In questo modo si può fare uso di librerie sperimentali
senza conseguenze per gli altri programmi e per l'intero sistema, che
continueranno ad usare la versione ordinaria. Si tenga presente infatti che se
si installasse una versione non funzionante di una libreria fondamentale come
la \textsl{glibc}, praticamente tutti i programmi smetterebbero di funzionare.

Un controllo ancora più dettagliato si può avere usando la variabile
\index{variabili!di~ambiente!\texttt{LD\_PRELOAD}} \texttt{LD\_PRELOAD}, che
prende una lista di file (separati da spazi) di singole librerie che verranno
caricate prima di tutte le altre. In questo modo diventa possibile sovrapporsi
alle funzioni di una singola libreria senza dover fare riferimento ad una
directory alternativa. Per motivi di sicurezza, dato che un attaccante
potrebbe utilizzare le proprie funzioni (magari non troppo benevole) al posto
di quelle di sistema, quando si usa questa variabile con programmi
\textit{suid} o \textit{sgid} (vedi sez.~\ref{sec:struct_file_perm}) essa
verrà presa in considerazione solo specificando librerie che siano a loro
volta \textit{suid} o \textit{sgid} ed installate nelle directory standard
\texttt{/lib} e \texttt{/usr/lib}.  Altre variabili di ambiente che
controllano l'uso delle librerie dinamiche sono descritte nella pagina di
manuale del \textit{link-loader}, accessibile con \texttt{man ld.so}.


\subsection{La gestione dei parametri del kernel con \textit{sysctl}}
\label{sec:sysctl_conf}

Una delle funzionalità presenti in tutti i kernel unix-like è la possibilità
di modificare alcuni parametri di comportamento del sistema anche una volta
che questo sia stato avviato. Tradizionalmente questo veniva effettuato
attraverso una opportuna interfaccia a quello che si suole chiamare il sistema
del \textit{sysctl} che veniva gestito attraverso delle apposite
\textit{system call}.\footnote{l'argomento è trattato in dettaglio nella
  sez.~6.2.1 di \cite{GaPiL}.}

L'interfaccia prevede che a ciascun parametro che può essere modificato
corrisponda una chiave che lo identifica. Queste chiavi vengono opportunamente
suddivise in una gerarchia di nomi, in modo da poterle organizzare per
categorie e sottocategorie. La singola chiave viene pertanto identificata
tramite la sua posizione nella gerarchia, che viene espressa con una sorta di
pathname, in cui si prevede che la si indichi con i nomi del percorso che si
deve fare a partire dalle categorie iniziali, separati dal carattere
``\texttt{.}'' anche se, per la evidente analogia con un pathname, i comandi
usati con Linux prendono come separatore anche il carattere ``\texttt{/}''.

L'impostazione di questi parametri viene effettuata tramite il comando
\index{comando!\texttt{sysctl}} \texttt{sysctl}, ed essendo una operazione che
riguarda il comportamento del sistema come tale è riservata
all'amministratore.  Il comando richiede che si specifichi come argomento o il
nome di una chiave, nel qual caso ne stamperà il valore, o una assegnazione
dello stesso nome ad un valore, nel qual caso assegnerà detto valore al
corrispondente parametro del kernel. Questo significa che ad esempio si potrà
leggere il valore corrente di un parametro con:
\begin{Console}
anarres:~# \textbf{sysctl kernel.hostname}
kernel.hostname = anarres
\end{Console}
mentre si potrà assegnarne uno con:
\begin{Console}
anarres:~# \textbf{sysctl net.ipv4.icmp_echo_ignore_broadcasts=1}
net.ipv4.icmp_echo_ignore_broadcasts = 1
\end{Console}

Il comando accetta anche più argomenti, nel qual caso considererà gli stessi
come un elenco, questo comporta che l'assegnazione deve sempre essere eseguita
senza spazi fra il nome della chiave, il carattere ``\texttt{=}'' ed il valore
impostato. Il tipo di valore da assegnare ad una chiave dipende dal tipo di
parametro che si imposta attraverso di essa, ma i più comuni sono dei numeri
interi o delle stringhe. Qualora si debba effettuare una assegnazione con un
valore che contiene dei caratteri interpretabili dalla shell questo può essere
indicato fra virgolette, ma in tal caso occorre specificare l'opzione
\texttt{-w}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Categoria} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{debug} & parametri per il debug.\\
     \texttt{dev}   & parametri dei dispositivi.\\
     \texttt{fs}    & parametri dei filesystem.\\
     \texttt{kernel}& parametri generici del kernel.\\
     \texttt{net}   & parametri della rete.\\
     \texttt{vm}    & parametri della memoria virtuale.\\
    \hline
  \end{tabular}
  \caption{Le principali categorie dei parametri del kernel.}
  \label{tab:sysctl_categories}
\end{table}


In tab.~\ref{tab:sysctl_categories} si sono riportate le principali categorie
dei parametri del kernel, che stanno alla radice della gerarchia delle chiavi.
Un elenco completo di tutte le chiavi disponibili può essere ottenuto
invocando \texttt{sysctl} con l'opzione \texttt{-a}, mentre con l'opzione
\texttt{-e} si dice al comando di ignorare errori dovuti a chiavi non
esistenti. Si può poi usare l'opzione \texttt{-p} per far eseguire
l'impostazione di una serie di valori leggendo una lista di assegnazioni dal
file passato come parametro per l'opzione stessa; se come parametro di
\texttt{-p} non si specifica nulla viene usato come default
\texttt{/etc/sysctl.conf}.  Al solito per i dettagli e l'elenco completo delle
opzioni si consulti la pagina di manuale del comando.

In realtà, come accennato in sez.~\ref{sec:file_FHS}, in tutte le versioni più
recenti di Linux l'uso di un comando dedicato come \texttt{sysctl} non è più
necessario perché tutta la gerarchia delle chiavi di configurazione viene
riproposta direttamente all'interno del filesystem \texttt{/proc}, come
altrettanti veri e propri pathname a partire da \texttt{/proc/sys}. Anzi su
Linux l'interfaccia tradizionale, che prevede una apposita \textit{system
  call}, è stata eliminata nei kernel più recenti, ed anche per poter
utilizzare il comando \texttt{sysctl} è necessario disporre del filesystem
\texttt{/proc}.  Questo significa che si può effettuare una assegnazione come
quella mostrata nel precedente esempio semplicemente con:
\begin{Example}
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
\end{Example}

Il vantaggio di poter effettuare le impostazioni operando direttamente sul
filesystem \texttt{/proc} è che su di esso si possono utilizzare tutti i
comandi per la gestione dei file visti in sez.~\ref{sec:shell_fileutils}. Per
questo motivo il comando \texttt{sysctl} non viene oramai quasi più usato
direttamente per effettuare una impostazione, con l'eventuale eccezione della
configurazione delle eventuali personalizzazioni dei parametri del kernel da
effettuarsi all'avvio del sistema.

A tale scopo infatti viene ancora usato \texttt{sysctl}, che viene invocato
all'interno della procedura di avvio per eseguire le impostazioni previste
dall'amministratore. Queste sono normalmente mantenute nel file
\index{configurazione!\texttt{/etc/sysctl.conf}} \texttt{/etc/sysctl.conf} cui
abbiamo già accennato. Il formato del file prevede la presenza di una
assegnazione per riga, nella stessa forma in cui la si scrive sulla riga di
comando, con la possibilità di inserire commenti precedendoli con il carattere
``\texttt{\#}''.

Nelle distribuzioni più recenti è stato anche previsto l'uso di una directory
\index{configurazione!\texttt{/etc/sysctl.d/}} \texttt{/etc/sysctl.d/}
all'interno della quale inserire singoli file \texttt{.conf} con impostazioni
specifiche in modo da consentire una gestione più flessibile di eventuali
personalizzazioni dei parametri del kernel da parte di singoli pacchetti. I
file seguono la stessa sintassi di \texttt{sysctl.conf}, ma possono avere un
nome qualsiasi.  La directory viene analizzata in fase di avvio,\footnote{con
  Debian veniva fatto dallo script di avvio (vedi
  sez~\ref{sec:struct_sysv_init}) \texttt{/etc/init.d/procps}, con l'uso di
  \texttt{systemd} (vedi sez.~\ref{sec:systemd_upstart}) come programma di
  avvio questo viene fatto direttamente da lui.} e vengono effettuate le
impostazioni contenuti nei vari \texttt{.conf} presenti al suo interno, letti
in ordine alfabetico. Per ultime vengono sempre applicate le configurazioni di
\texttt{/etc/sysctl.conf}.


\subsection{Localizzazione e internazionalizzazione}
\label{sec:localization}

Come accennato in sez.~\ref{sec:shell_sintax} su un sistema GNU/Linux è
presente, a partire dalla libreria fondamentale del sistema (la
\textsl{glibc}), un sistema di supporto per la localizzazione e la
internazionalizzazione che consente di personalizzare in maniera del tutto
generica il funzionamento dei programmi rispetto alla propria lingua e alle
convenzioni riguardo formato di data, ora, valuta, ecc. utilizzate nel proprio
paese.

Spesso si trova riferimento a questo supporto, ad esempio nei pacchetti che
contengono gli eventuali dati ad esso relativi, con le sigle \textit{l10n} e
\textit{i12n} come abbreviazione delle parole inglesi \textit{localization} e
\textit{internationalization} (dove i numeri vanno ad indicare il numero di
lettere intercorrenti). Non è detto infatti che questo sia sempre disponibile
per qualunque lingua, e per alcuni programmi (ad esempio per alcuni ambienti
grafici), viste anche le dimensioni ragguardevoli che può assumere, può essere
necessaria una installazione separata. Questo non è comunque vero per i
comandi e le funzionalità di base (in particolare per la shell ed i vari
comandi dei \texttt{coreutils}) per i quali in genere il supporto è sempre
compreso nella versione installata.

Il supporto per la localizzazione prevede che si possano marcare all'interno
di un programma tutti i messaggi e le stringhe che vengono stampate, così che
queste possano essere tradotte e stampante automaticamente nella lingua
giusta. Oltre a questo vengono fornite opportune funzioni di interfaccia per
modificare l'ordinamento alfabetico e la stampa di alcuni dati, come appunto
orari, date e valute, in modo che i programmi si comportino seguendo le
convenzioni in uso nel proprio paese.

Questo significa, come già illustrato in sez.~\ref{sec:shell_sintax}, che
l'uso della localizzazione non ha impatto soltanto sulla visualizzazione dei
messaggi dei comandi o sulle voci dei menù, o sulla lingua in cui vengono
mostrate le pagine di manuale, ma anche su aspetti più sottili del
comportamento del sistema, come l'ordinamento alfabetico o il significato
degli intervalli di caratteri utilizzati per le espressioni regolari e per il
\textit{filename globbing}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Variabile} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{LANG}        & imposta il valore generale della localizzazione, 
                            che rimane valido per tutti gli aspetti a meno che
                            questi non vengano diversamente specificati
                            tramite una delle variabili \texttt{LC\_*}.\\ 
     \texttt{LC\_COLLATE} & modifica il comportamento delle funzioni di
                            confronto fra stringhe, modificando pertanto
                            l'ordinamento alfabetico e la definizione degli
                            intervalli o le corrispondenze nelle espressioni
                            regolari e nel \textit{filename globbing}.\\  
     \texttt{LC\_CTYPE}   & modifica l'identificazione dei caratteri come
                            maiuscoli e minuscoli e l'interpretazione dei
                            caratteri a byte multipli.\\
     \texttt{LC\_MONETARY}& modifica le modalità con cui vengono stampati i
                            valori numerici che esprimono valori monetari, in
                            particolare l'uso della virgola o del punto per la
                            definizione dei decimali e la stampa del tipo di
                            valuta.\\
     \texttt{LC\_MESSAGES}& modifica la lingua in cui vengono mostrati i
                            messaggi dei programmi, ed anche la forma delle
                            risposte positive e negative.\\
     \texttt{LC\_NUMERIC} & modifica le modalità con cui vengono letti e
                            stampati i numeri, in particolare per l'uso del
                            punto o della virgola per i decimali.\\
     \texttt{LC\_TIME}    & modifica la modalità con cui vengono stampati data
                            ed ora.\\
     \texttt{LC\_ALL}     & imposta il valore per tutte le variabili
                            precedenti, sostituendo eventuali impostazioni
                            eseguite tramite esse.\\
     \texttt{LANGUAGE}    & qualora si sia impostato un valore di
                            \texttt{LANG} che indica una localizzazione
                            diversa dal default, si può usare questa variabile
                            per indicare una lista di priorità delle
                            localizzazioni da usare se quella espressa da
                            \texttt{LANG} non è disponibile, in forma di
                            elenco separato dal carattere ``\texttt{:}'' (ad
                            esempio il valore \texttt{it:fr} mostra il
                            francese se questo è disponibile quando  non lo è
                            l'italiano).\\
    \hline
  \end{tabular}
  \caption{Le variabili di ambiente che controllano il comportamento della
    localizzazione.}
  \label{tab:localization_variables}
\end{table}

Tutte queste funzionalità relative alla localizzazione vengono controllate
attraverso l'uso di una serie di variabili di ambiente che sono riportate,
insieme al loro significato, in tab.~\ref{tab:localization_variables},
maggiori dettagli si possono trovare nella pagina di manuale dedicata
all'argomento, accessibile con \texttt{man 7 locale}.  Abbiamo già incontrato
in sez.~\ref{sec:shell_sintax} una di queste, \texttt{LANG}, che è quella
usata più comunemente in quanto consente di impostare una localizzazione di
default valida in generale, senza dover impostare i singoli aspetti della
localizzazione impostando le singole variabili \texttt{LC\_*} una per una.

La variabile \texttt{LANG} e le varie \texttt{LC\_*} vengono normalmente
inizializzate a seconda della lingua in cui si è installato il
sistema,\footnote{le modalità con cui questo viene realizzato variano da
  distribuzione a distribuzione, Debian ad esempio usa il valore contenuto nel
  file \texttt{/etc/default/locale} negli script di avvio.}  ma si può
verificarne il valore con il comando \index{comando!\texttt{locale}}
\texttt{locale} che ne stampa a video l'impostazione corrente. La
localizzazione di default presente nel codice della \textsl{glibc} e dei
comandi di base (sostanzialmente l'inglese) usa il valore riservato
\texttt{C}; alternativamente, per indicare esplicitamente l'aderenza allo
standard, si può utilizzare il valore \texttt{POSIX}.

È possibile comunque installare anche delle localizzazioni ulteriori, e
passare dall'una all'altra, anche per un singolo aspetto, semplicemente
ridefinendo i valori delle variabili di tab.~\ref{tab:localization_variables}.
Ad esempio si può usare la localizzazione italiana con il valore
\texttt{it\_IT.UTF-8}. Questo già ci mostra il formato generico dei valori
utilizzabili per queste variabili, che riportano in minuscolo il valore
principale della lingua (nel caso \texttt{it}) seguito da un carattere di
sottolineatura e dal valore secondario in maiuscolo (nel caso dell'Italia è di
nuovo \texttt{IT}, ma per la Svizzera italiana sarebbe stato \texttt{CH}), cui
segue, separato da un punto, il nome della codifica dei caratteri (che
nell'esempio è \texttt{UTF-8}, ma sarebbe potuto essere anche qualcosa come
\texttt{ISO-8859-1}).

La lista di questi valori viene in genere mantenuta nel file
\texttt{/etc/locale.alias}, che serve ad avere anche una corrispondenza con
dei nomi più comprensibili per l'utente, il file ha il semplice formato di un
nome per esteso (ad esempio \texttt{Italiano}) seguito dal valore di
localizzazione corrispondente, separato da spazi. Vari servizi, in particolare
quelli che danno accesso all'interfaccia grafica, fanno riferimento a questo
file (o a opportune copie dello stesso), per presentare menù di scelta della
lingua.

Ovviamente perché sia possibile utilizzare una diversa localizzazione occorre
che i relativi dati siano installati. Questo a seconda della distribuzione può
comportare l'installazione di pacchetti aggiuntivi; inoltre dato che in genere
non serve disporre di tutte le localizzazioni possibili, normalmente solo un
sottoinsieme fra quelle esistenti (visualizzabile con l'opzione \texttt{-a} di
\texttt{locale}) viene reso disponibile e può essere utilizzato. 

In genere infatti oltre alla installazione dei pacchetti con i dati, occorre
anche generare, in particolar modo per l'uso delle traduzioni, i file con gli
indici che rendono possibile un uso veloce dei messaggi tradotti. Tutto questo
comporta ovviamente l'uso di spazio disco ulteriore, che può essere
risparmiato quando non necessario.  In tal caso esistono in genere gli
opportuni strumenti per aggiungere o rimuovere le singole localizzazioni
dall'elenco di quelle utilizzabili. Il comando per effettuare questa
operazione è \index{comando!\texttt{locale-gen}} \texttt{locale-gen}, ma le
distribuzioni utilizzano in genere programmi di più alto livello, quando
addirittura non rendono utilizzabili di default tutte le localizzazioni
disponibili.

Si tenga presente inoltre che oltre a lingua e paese a cui fa riferimento,
ciascuna localizzazione è legata anche alla codifica di carattere utilizzata.
In generale infatti, dovendosi poter esprimere le stringhe in tutte le
possibili lingue esistenti, l'uso degli ordinari caratteri ASCII che
originariamente utilizzavano soltanto 7 bit non è sufficiente, in quanto
questi possono esprimere un insieme molto limitato di lettere e numeri (in
sostanza quelli in uso nei paesi anglosassoni). Già per poter utilizzare i
caratteri in uso nelle principali lingue europee infatti sono necessarie delle
estensioni rispetto all'ASCII standard, che aggiungano caratteri ulteriori
come le vocali accentate, il che comporta l'uso di una serie di codifiche più
specifiche come appunto la citata \texttt{ISO-8859-1}, definite sulla base di
una opportuna standardizzazione.\footnote{nel caso si fa riferimento appunto
  allo standard ISO/IEC 8859, ma non tutti hanno aderito da subito allo
  stesso, e ad esempio un noto produttore di sistemi operativi abitualmente
  refrattario all'uso degli standard ha sviluppato anche codifiche alternative
  come quella denominata \texttt{Windows-1252}, che hanno avuto una certa
  diffusione.}

Ma anche così, mantenendo la convenzione per cui ciascun carattere viene
rappresentato da un numero ad 8 bit, si riescono a coprire sostanzialmente
soltanto i caratteri in uso nelle lingue occidentali, tanto che la codifica
\texttt{ISO-8859-1} viene chiamata \textit{Western European}, o anche
\texttt{latin-1}, dato che per le lingue latine dell'Europa centro-orientale
viene usata la codifica \texttt{ISO-8859-2}, detta anche \texttt{latin-2} o
\textit{Central European}.

Per questo già lo standard ISO 8859 prevede numerose codifiche diverse, usate
oltre che per le varie varianti dei caratteri latini, anche per consentire
l'uso di caratteri cirillici o greci, o per l'aggiornamento delle codifiche
con il simbolo dell'euro, non ancora presente all'epoca della definizione
dell'\texttt{ISO-8859-1} e affini. In genere tutte queste codifiche vengono
indicate con il nome \texttt{ISO-8859-N}, dove ``\texttt{N}'' è un numero che
identifica la singola versione.

Ovviamente questa proliferazione di codifiche diverse comporta una notevole
complessità dovendo ad esempio fornire traduzioni con codifiche dei caratteri
sempre diverse e l'impossibilità di rappresentare stringhe in cui siano
presenti caratteri di lingue diverse. Per questo motivo a partire dal 1991 è
stato sviluppato un ulteriore standard, denominato
\textit{Unicode},\footnote{per i fan delle numerazioni lo standard è
  classificato ufficialmente come ISO/IEC 10646.} che consentisse di
rappresentare in un'unica codifica qualunque tipo di caratteri, rinunciando
però alla pretesa di utilizzare un solo byte per carattere. 

Per far questo vengono utilizzate opportune sequenze di valori numerici, e la
forma più utilizzata è quella del citato \texttt{UTF-8}, che prevede codici
composti da uno a quattro byte per singolo carattere mantenendo una
compatibilità, per i caratteri corrispondenti, con il vecchio ASCII. Esistono
però, ancorché usate in maniera inferiore, codifiche alternative come
\texttt{UTF-16} che usa codici composti da una a due parole a 16 bit, o
\texttt{UTF-32} che usa direttamente parole a 32 bit. Ad oggi, vista la minore
complessità di gestione, la gran parte delle distribuzioni tende comunque ad
allinearsi all'uso esclusivo di \texttt{UTF-8}.

Se dal punto di vista del funzionamento dei programmi l'uso della
localizzazione nelle diverse codifiche di caratteri non comporta, una volta
installato il relativo supporto, nessun problema, con i dati, ed in
particolare con i file di testo, i problemi invece sussistono. Questi infatti
possono essere creati su un sistema che usa una certa codifica, e riletti su
uno che ne usa un'altra, con risultati in genere spiacevoli dato che si
troveranno quelli che prima erano normali caratteri trasformati in simboli
strani o in sequenze numeriche di scarso significato.

Per questo motivo è disponibile un apposito programma,
\index{comando!\texttt{iconv}} \texttt{iconv}, che consente di effettuare
conversioni di un file di testo da una codifica di caratteri ad un'altra. Il
comando richiede che si specifichi come parametro per l'opzione \texttt{-f} la
codifica del file da convertire, che deve essere passato come argomento, la
conversione verrà scritta sullo \textit{standard output}, o sul file indicato
con l'opzione \texttt{-o}. Se non si specifica, con l'opzione \texttt{-t}, una
codifica di destinazione, verrà usata quella corrispondente alla
localizzazione in uso.

Per indicare una codifica si deve utilizzare il relativo nome, che è lo stesso
che poi si usa per le variabili di tab.~\ref{tab:localization_variables}, ma
dato che il comando supporta le conversioni da e verso ad una grande quantità
di codifiche diverse, si può ottenere la lista completa di tutti i relativi
identificativi con l'opzione \texttt{-l}. Al solito per i dettagli sul
funzionamento si consulti la pagina di manuale.

Un ultimo aspetto delle problematiche di localizzazione ed
internazionalizzazione è quello dell'uso dell'ora locale. Benché affine alle
altre problematiche appena trattate, la gestione di questo aspetto è
completamente separata, dato che si può essere all'estero, ed usare un fuso
orario diverso da quello del proprio paese d'origine, senza però voler usare
la lingua del posto dove ci si trova, o anche solo aver cambiato fuso, se si
vive in un paese abbastanza grande da averne più di uno.

Come illustrato in sez.~\ref{sec:cmd_time} il kernel opera facendo riferimento
al tempo universale.\footnote{a meno di non aver forzato in fase di
  installazione l'uso dell'ora locale, per compatibilità con sistemi operativi
  mal progettati che han fatto questa scelta; questa è una opzione ormai quasi
  completamente scomparsa e comunque da evitare perché porta ad un uso non
  corretto del sistema: pertanto la ignoreremo totalmente.}  Per poter tener
conto del proprio fuso orario, ed anche della eventuale presenza dell'ora
locale, esiste un apposito supporto, anche questo integrato nelle librerie
fondamentali di sistema, che consente di effettuare la conversione dal tempo
universale all'ora locale in maniera trasparente per l'utente. Questo consente
di far sì che per il kernel il tempo sia sempre crescente in maniera costante,
come è nella realtà, e di evitare salti o buchi nell'orologio. Così se si è
salvato un file da tre ore questo avrà sempre come data di ultima modifica tre
ore fa, anche se nel frattempo ci si è spostati in un paese diverso, si è
cambiato fuso, o è scattata l'ora legale.

\itindbeg{timezone}

Il meccanismo si basa sul concetto di \textit{timezone}, una sorta di
estensione del concetto di fuso orario, che consente di incorporare anche le
eventuali variazioni dovute alle presenze di regolamentazioni locali (come
l'ora legale) che possono variare da paese a paese, e di anno in anno. Il
database viene mantenuto a livello globale tenendo conto delle varie
regolamentazioni in vigore nei vari paesi, e dato che ci sono variazioni
amministrative all'interno dei singoli paesi, le \textit{timezone} sono in
genere indicate con una coppia di nomi del tipo \texttt{Area/Locazione}, dove
per l'area si fa riferimento ad un continente o ad un oceano (con valori come
\texttt{Europe}, \texttt{Asia}, \texttt{Pacific}, ecc.), mentre la locazione
fa riferimento o a una città o a una isola, (con valori come \texttt{Rome},
\texttt{New\_York}, \texttt{Samoa}, ecc.) considerata come il riferimento per
quella zona.

La scelta di evitare l'uso del nome delle nazioni è voluta, sia perché ci sono
nazioni con più di un fuso orario, come gli Stati Uniti o la Russia, sia
perché l'uso dei nomi delle città principali si è rivelato più stabile e meno
equivoco rispetto ai cambiamenti geopolitici. Nel caso dell'Italia ad esempio
si usa \texttt{Europe/Rome}, in cui, come per buona parte dei paesi europei,
si fa riferimento alla capitale.

Ciascuna \textit{timezone} è descritta da un apposito file, chiamato in gergo
\textit{zonefile}, che contiene tutte le informazioni ad essa relative che
consentono di effettuare la conversione dal tempo universale. Si tratta di uno
specifico database (con un formato proprio, per approfondimenti si consulti
\url{http://en.wikipedia.org/wiki/Zoneinfo}) che contiene anche uno storico
dei dati per permettere di effettuare la conversione non solo per il tempo
corrente, ma anche per tutti i tempi passati.  

Il \textit{Filesystem Hierarchy Standard} illustrato in
sez.~\ref{sec:file_FHS} prevede che questi file vengano installati sotto la
directory \texttt{/usr/share/zoneinfo}, in altrettanti file e directory
corrispondenti al nome della \textit{timezone} stessa, che può essere
considerato come un pathname relativo rispetto a \texttt{/usr/share/zoneinfo}.
La \textit{timezone} in uso viene invece impostata tramite il file
\index{configurazione!\texttt{/etc/localtime}} \texttt{/etc/localtime}, che
altro non è che la copia del file della zona scelta preso da
\texttt{/usr/share/zoneinfo}. Questo, nonostante contravvenga la regola di non
usare file binari all'interno di \texttt{/etc}, è dovuto al fatto che la
relativa informazione deve essere disponibile all'avvio, quando non è detto
che \texttt{/usr} sia stata montata, ed è per questo che anche l'uso di un
link simbolico non è una soluzione adeguata.

Uno dei problemi che si riscontrano nella gestione dei fusi orari è che
ciascuna distribuzione usa un suo metodo per impostare la zona di default in
\texttt{/etc/localtime},\footnote{su Debian è ancora presente il vecchio
  comando \texttt{tzconfig}, ma questo è deprecato in favore della
  riconfigurazione del pacchetto dei dati delle \textit{timezone} con (vedi
  sez.~\ref{sec:adv_pkg_debian}) \texttt{dpkg-reconfigure tzdata}, su RedHat
  occorre invece usare il comando dedicato \texttt{system-config-date}.}  in
modo da essere in grado di gestirne l'aggiornamento quando viene installata in
\texttt{/usr/share/zoneinfo} una nuova versione della relativa
\textit{timezone}. Purtroppo questo non è stato standardizzato e modificare a
mano questo file può dar luogo ad inconvenienti.

Qualora si voglia usare una zona diversa si dovrà anzitutto determinare
l'identificativo ad essa associato, per semplificare l'operazione si può usare
il comando \index{comando!\texttt{tzselect}} \texttt{tzselect} che con una
serie di domande richiede prima il continente e poi il proprio paese, ed
infine stampa il valore dell'ora locale nella zona risultante dalle proprie
scelte. Una volta che si sia confermata la correttezza dell'ora ottenuta il
comando stampa il nome della relativa zona ed alcune istruzioni.  In generale
se si vuole effettuare un cambiamento permanente a livello di sistema è
opportuno usare il meccanismo che ciascuna distribuzione mette a disposizione,
perché anche se si può sempre copiare a mano il file da
\texttt{/usr/share/zoneinfo}, questo potrebbe venire sovrascritto da un
aggiornamento o anche da un riavvio.

Il cambiamento della \textit{timezone} a livello di sistema richiede
ovviamente i privilegi di amministratore, ma il singolo utente può effettuare
un cambiamento locale, che coinvolga solo lui, o anche singole applicazioni,
tramite la variabile di ambiente \index{variabili!di~ambiente!\texttt{TZ}}
\texttt{TZ}, assegnando ad essa il nome della \textit{timezone} che vuole
utilizzare, in tal caso le applicazioni faranno riferimento a quest'ultima
invece che a quella di sistema.

\itindend{timezone}


\section{I servizi di base}
\label{sec:base_server}

In questa sezione prenderemo in esame la configurazione di alcuni servizi di
base, presenti fin dalle origini in tutti i sistemi unix-like, come quelli per
l'esecuzione periodica o differita dei comandi, e quelli per la gestione della
registrazione dei messaggi di servizio. Seguendo la filosofia fondamentale di
Unix tutti questi servizi sono realizzati tramite degli appositi programmi,
detti \textsl{demoni} (si ricordi quanto detto in
sez.~\ref{sec:struct_job_control}), che lavorano in background anche quando
nessuno è collegato al sistema ed il cui comportamento viene controllato
attraverso i rispettivi file di configurazione.


\subsection{Il servizio di esecuzione periodica}
\label{sec:crontab}

Una funzionalità importante presente in qualunque sistema operativo è quella
dell'esecuzione di programmi su base periodica, essenziale per compiere tutte
quelle operazioni che devono essere eseguite ad un tempo fissato. Abbiamo già
incontrato due operazioni che vengono gestite in questo modo, come la
creazione del database dei file di \texttt{locate} e l'indicizzazione delle
pagine di manuale, trattate rispettivamente in sez.~\ref{sec:cmd_search} e
\ref{sec:documentazione}.

La gestione dell'esecuzione periodica di programmi per compiere operazioni nel
sistema viene realizzata dal servizio chiamato \textit{cron}, che è stato
implementato attraverso l'uso dell'omonimo demone \index{demone!\texttt{cron}}
\texttt{cron}.  Il demone ha il compito di svegliarsi ogni minuto ed eseguire
ogni programma che è stato programmato per quel momento. 

Il file di configurazione principale di \texttt{cron} è
\index{configurazione!\texttt{/etc/crontab}} \texttt{/etc/crontab} che
contiene l'elenco delle operazioni periodiche generali da eseguire nel
sistema. Il primo file controllato da \texttt{cron} per decidere se c'è da
eseguire una operazione è questo.  In genere si deve intervenire su questo
file solo quando si vuole cambiare uno degli orari a cui le operazioni
prestabilite vengono eseguite o per inserire una nuova operazione periodica.
Oltre a \texttt{/etc/crontab} il programma controlla anche il contenuto della
directory \texttt{/etc/cron.d/} dove i vari pacchetti possono inserire i loro
file per esigenze specifiche, per i quali vale la stessa sintassi di
\texttt{/etc/crontab}.

Il formato del file segue la solita regola di ignorare righe vuote ed
inizianti per ``\texttt{\#}''. Ogni riga deve contenere o una assegnazione di
una variabile di ambiente o la specificazione di una azione periodica.
L'azione viene specificata da una serie di campi separati da spazi o
tabulatori, i primi cinque indicano la periodicità con cui il comando indicato
nell'ultimo campo viene eseguito, il sesto campo indica l'utente per conto del
quale eseguire il comando, che viene scritto nel seguito della riga. La riga
deve essere sempre terminata con un a capo, altrimenti verrà ignorata (si
abbia pertanto attenzione sull'ultima riga del file).

I cinque campi della periodicità indicano rispettivamente: minuto (da 0 a 59),
ora (da 0 a 23), giorno del mese (da 1 a 31), mese dell'anno (da 1 a 12) e
giorno della settimana (da 0 a 7, dove sia 0 che 7 indicano la domenica). Per
quest'ultimo campo sono accettati anche valori tipo Mon, Thu, etc. L'utilizzo
del carattere ``\texttt{*}'' vale da jolly e lo si usa per indicare un valore
qualsiasi. Se il tempo corrente corrisponde a tutti i valori specificati nei
cinque campi il comando viene eseguito.

Il demone \texttt{cron} di GNU/Linux supporta poi alcune estensioni non
presenti in altri sistemi unix-like.\footnote{si tratta del programma
  \textit{vixie-cron}, creato da Paul Vixie, noto anche per essere l'autore di
  \textit{BIND}, il server DNS (vedi sez.~\ref{cha:DNS}) più usato al mondo.}
Si può usare una lista (separata da virgole) per indicare più valori, un
intervallo, specificando gli estremi separati con un ``\texttt{-}''. Infine il
programma supporta la possibilità di specificare periodi personalizzati
attraverso l'uso del carattere jolly abbinato con il carattere ``\texttt{/}''
seguito dal divisore da applicare al valore generico del campo; così ad
esempio usando \texttt{*/2} nel primo campo si intenderà chiedere la
ripetizione del lavoro ogni due minuti.  

Anche la parte conclusiva della linea, con cui si specifica il comando da
eseguire, ha una sua sintassi specifica: anzitutto non è mai possibile
dividere il comando su più linee (cioè non si può usare ``\texttt{\bslash}''
ed andare a capo come si fa con la shell) dato che il carattere di ritorno a
capo viene sempre interpretato come terminazione della riga; la dimensione
massima utilizzabile per indicare il comando è di 998 caratteri.

Inoltre il carattere ``\texttt{\%}'' è riservato; il primo ``\texttt{\%}'' che
viene incontrato viene convertito in un a capo (terminando il comando) e tutto
quello che segue nella riga viene inviato al comando stesso sullo
\textit{standard input}. Se il comando ha bisogno di utilizzare un \texttt{\%}
nei suoi argomenti (un caso tipico è \texttt{date}), questo dovrà essere
indicato in maniera protetta come ``\texttt{\bslash\%}''. Per questo quando si
devono specificare comandi complessi come ultimo campo di un \texttt{crontab}
è preferibile inserirli in uno script ed eseguire direttamente quello. La
descrizione del formato del file, completa di tutti i dettagli è accessibile
con \texttt{man 5 crontab}.

Si tenga presente che siccome il programma specificato nella parte conclusiva
della linea viene eseguito direttamente dal demone \texttt{cron}, non saranno
necessariamente definite le usuali variabili di ambiente presenti normalmente
quando si esegue una shell. In particolare è da tenere presente che il demone
si limita a definire solo alcune di esse ed in particolare per quanto riguarda
\texttt{PATH} questa comprenderà soltanto le directory \texttt{/usr/bin} e
\texttt{/bin}. Altre variabili definite da \texttt{cron} sono \texttt{LOGNAME}
e \texttt{HOME}, che corrisponderanno al nome utente e alla directory
personale dell'utente per conto del quale viene eseguito il programma. 

Per questo motivo se un programma necessita della presenza di valori diversi
da quelli di default, o di altre variabili, occorrerà inserire in testa al
file le relative definizioni. Queste definizioni seguono la stessa sintassi
che si usa nella shell, con la differenza che \texttt{cron} non esegue la
\textit{variable expansion}, per cui non si potrà fare riferimento ad altre
variabili all'interno di una definizione.


Infine un ruolo particolare viene giocato dalla variabile \texttt{MAILTO}, che
indica l'utente a cui inviare per posta elettronica l'eventuale output del
programma posto in esecuzione. Infatti quando \texttt{cron} esegue il comando
questo non è collegato a nessun terminale, e si pone pertanto il problema di
come gestire gli eventuali dati in uscita. La soluzione scelta è stata appunto
quella di inviarli per posta elettronica all'utente per conto del quale è
stato eseguito il comando. Questo a meno che non si sia definita la variabile
\texttt{MAILTO} per indicare un altro destinatario, inoltre se la variabile è
definita, ma vuota, l'invio verrà disabilitato. Questo è il motivo per cui
spesso nei comandi lanciati tramite \texttt{cron} viene eseguita una
redirezione dello \textit{standard output} su \texttt{/dev/null}, in modo da
scartare eventuali dati in uscita.

Un esempio del contenuto del file \texttt{/etc/crontab}, preso dalla versione
installata di default su una Debian Squeeze, è il seguente:
\begin{FileExample}[label=/etc/crontab]
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *  * * * root cd / && run-parts --report /etc/cron.hourly
25 6  * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6  * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6  1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
\end{FileExample}
in cui vengono definite le variabili che indicano quale shell usare ed il path
dei comandi e vengono impostate una serie di operazioni. In questo caso ad
esempio la seconda riga si legge come minuto 25, ore 6, essendo le altre
indicazioni tutti \texttt{*} si intende che giorno del mese, mese e giorno
della settimana sono qualsiasi, allo stesso modo si interpretano le altre
righe.

Con il contenuto mostrato nell'esempio ci saranno allora delle azioni che
vengono eseguite ogni ora al minuto 17, tutti i giorni alle ore 6:25, tutte le
domeniche alle 6:47 e tutti i primi giorni del mese alle 6:52, che vanno a
costituire le operazioni orarie, giornaliere, settimanali e mensili da
eseguire in maniera automatica.  Queste azioni sono eseguite attraverso il
comando \index{comando!\texttt{run-parts}} \texttt{run-parts} il cui scopo è
effettuare l'esecuzione, in ordine alfabetico, degli script presenti nella
directory passata come argomento.

Nel caso gli script sono quelli delle directory elencate nell'esempio, per cui
se non si hanno esigenze particolari non è il caso di intervenire su questo
file ma di aggiungere il proprio script direttamente in
\texttt{/etc/cron.daily/}, \texttt{/etc/cron.weekly/} o
\texttt{/etc/cron.monthly/}. Occorre comunque fare attenzione perché
\texttt{run-parts} non esegue gli script il cui nome contiene caratteri
diversi da lettere maiuscole e minuscole, numeri, il sottolineato ed il
``\texttt{-}'' (per i dettagli sul funzionamento del comando si consulti la
relativa pagina di manuale) per cui è meglio evitare di installare uno script
come \texttt{qualcosa.sh}.

Si noti infine come nel file di \texttt{crontab} mostrato nell'esempio
precedente venga fatto un controllo preventivo della presenza del comando
\index{demone!\texttt{anacron}} \texttt{anacron}. Questo è un sostituto di
\texttt{cron} utilizzato originariamente sulle macchine che non è previsto
siano sempre accese, come le stazioni di lavoro, che si incarica di eseguire
le operazioni periodiche tenendo conto anche del fatto che queste possono non
essere state effettuate in precedenza perché la macchina era spenta.

In Debian se questo programma viene installato è quello a cui viene delegato
il compito anche di eseguire le operazioni giornaliere, settimanali e mensili
illustrate in precedenza e non è necessario l'intervento di
\texttt{cron}. L'installazione di default non prevede la presenza di questo
programma, per cui il comando non sarà presente e verrà eseguito invece
\texttt{run-parts}.

Altre distribuzioni come RedHat installano invece di default questo programma
e delegano direttamente ad esso l'esecuzione delle operazioni
periodiche. Queste sono controllate dal file
\index{configurazione!\texttt{/etc/anacrontab}} \texttt{/etc/anacrontab} che
prevede di nuovo la possibilità di definire delle variabili di ambiente con
una assegnazione con la stessa sintassi della shell. Al solito le righe vuote
e tutto quello che segue un ``\texttt{\#}'' viene ignorato, mentre le righe
restanti servono ad indicare le operazioni da eseguire.

Ciascuna operazione deve essere specificata in una riga con 4 campi separati
da spazi, che indicano rispettivamente: una periodicità di esecuzione (in
numero di giorni), un ritardo iniziale (in numero di minuti), una stringa di
identificazione, ed il comando da eseguire. Il primo campo, che indica la
periodicità, può essere anche espresso in forma simbolica con i nomi
\texttt{monthly}, \texttt{weekly} e \texttt{daily} preceduti dal carattere
``\texttt{@}''. Un esempio di questo file, sempre preso dalla versione
installata su Debian Squeeze, è il seguente:
\begin{FileExample}[label=/etc/anacrontab]
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# These replace cron's entries
1        5       cron.daily       nice run-parts --report /etc/cron.daily
7        10      cron.weekly      nice run-parts --report /etc/cron.weekly
@monthly 15      cron.monthly     nice run-parts --report /etc/cron.monthly
\end{FileExample}

Il funzionamento di \texttt{anacron} prevede che il comando legga la lista
delle operazioni periodiche da \texttt{/etc/anacrontab} e controlli se queste
sono state eseguite nel periodo di tempo indicato nel primo campo. Il
programma infatti mantiene una sua lista interna delle operazioni, in cui
registra anche l'ultima esecuzione effettuata, e se è passato più tempo di
quello richiesto mette in esecuzione il relativo comando dopo il ritardo
indicato dal secondo campo, che viene utilizzato per evitare di lanciare in
contemporanea tutti i comandi relativi alle operazioni scadute.

Il programma legge il file all'avvio e poi resta in esecuzione come demone,
ripetendo le operazioni secondo la periodicità indicata, che però ha come
granularità minima quella dei giorni (viene cioè controllata solo la data e
non l'ora). Questo, fintanto che la macchina è accesa, garantisce la
periodicità nei termini indicati, ma consente, se ad esempio si spegne la
macchina la notte, di eseguire i compiti rimasti sospesi al riavvio successivo
non essendo vincolato, come \texttt{cron}, ad un orario specifico.

Si tenga presente però che a parte gestire le operazioni periodiche in questa
modalità, \texttt{anacron} non costituisce una alternativa a \texttt{cron},
sia per l'impossibilità di usare periodicità su tempi inferiori al giorno sia
per l'impossibilità di indicare orari precisi di esecuzione, che sono
necessari in molti casi. Al solito, per i dettagli sul funzionamento e sulla
configurazione, si consultino le relative pagine di manuale con \texttt{man
  anacron} e \texttt{man anacrontab}.

Oltre ai compiti relativi alla gestione del sistema, e programmati pertanto
dall'amministratore che è l'unico che ha i privilegi per modificare
\texttt{/etc/crontab}, il servizio \textit{cron} è in grado di eseguire anche
operazioni richieste da un singolo utente. L'utente può creare un suo
\textit{crontab} personale tramite il comando \index{comando!\texttt{crontab}}
\texttt{crontab}, in questo caso i file vengono mantenuti in
\texttt{/var/spool/cron/crontabs}, e non sono accessibili direttamente ai
singoli utenti se non appunto attraverso detto comando.

Se si invoca \texttt{crontab} con l'opzione \texttt{-e} questo invocherà
l'editor predefinito con cui scrivere il contenuto del proprio
\textit{crontab} personale. Il default è l'uso di \texttt{vi}, a meno di non
aver impostato diversamente la variabile di ambiente \texttt{EDITOR}. Il
formato delle tabelle di \textit{cron} personali è identico a quello di
\texttt{/etc/crontab}, con l'eccezione dell'assenza del sesto campo, che nel
caso non è necessario dato che l'utente è già ben definito.

Se lanciato senza opzioni \texttt{crontab} prende come argomento un file da
usare come tabella, di cui legge il contenuto, che deve essere nella forma in
cui lo si scriverebbe con l'editor, invece usando ``\texttt{-}'' come nome del
file i dati verranno presi dallo \textit{standard input}.  Con \texttt{-r}
invece si esegue la rimozione completa della tabella corrente, ma si faccia
attenzione nell'uso dato che il comando non chiede conferma.  Infine con
\texttt{-u} si potrà modificare (solo da parte dell'amministratore) la tabella
dell'utente specificato come parametro.

Si può poi vedere la lista delle operazioni programmate usando l'opzione
\texttt{-l}, che scrive sullo \textit{standard output} il contenuto corrente
della tabella \textit{cron} dell'utente.  La versione usata da Debian in
realtà non stampa le righe di commento iniziale che avvisano di non modificare
direttamente il contenuto del \textit{crontab}, in modo da poter riutilizzare
l'output del comando direttamente come input per un successivo \texttt{crontab
  -}.

Si tenga presente che l'amministratore può riservare l'uso del servizio
\textit{cron} solo ad alcuni utenti, creando il file
\index{configurazione!\texttt{/etc/cron.allow}} \texttt{/etc/cron.allow}, nel
quale si devono elencare gli username degli utenti che lo possono usare.  Se
il file non esiste è possibile vietare l'uso del servizio solo ad alcuni
utenti con la creazione del file
\index{configurazione!\texttt{/etc/cron.deny}} \texttt{/etc/cron.deny} che
parimenti dovrà contenere la lista degli username di coloro che non possono
usarlo. In assenza di detti file chiunque può usare il servizio.


\subsection{Il servizio \textit{at}}
\label{sec:cfg_at}

Abbiamo visto nella sezione precedente come si può programmare l'esecuzione
periodica di comandi con \texttt{crontab}, esistono però anche necessità di
avere una esecuzione semplicemente differita, senza che questa debba essere
periodica.  Per provvedere a questo compito esiste un altro servizio, chiamato
\textit{at} dal nome del comando che permette di richiedere l'esecuzione di un
programma ad un tempo successivo. Il servizio comporta diverse modalità di
gestione della esecuzione differita, e vari programmi per la gestione della
stessa.

Il servizio è realizzato dal demone \index{demone!\texttt{atd}} \texttt{atd},
che come \texttt{cron} viene normalmente lanciato dagli script di avvio. Il
demone controlla la presenza nelle code di programmi in attesa di essere
eseguiti, e li manda in esecuzione al tempo stabilito. Il demone può essere
anche lanciato manualmente, e prevede come opzioni \texttt{-b} che permette di
impostare un intervallo di tempo minimo (il default è 60 secondi) fra la messa
in esecuzione di due successivi programmi e \texttt{-l} che permette di
impostare manualmente un limite massimo per il carico della macchina, oltre il
quale non saranno comunque eseguiti i programmi, di default questo è pari a
1.5, ed ha senso cambiarlo solo in caso di macchine multiprocessore.  Al
solito per l'elenco completo delle opzioni si può fare riferimento alla pagina
di manuale.

Il comando di base, che permette di programmare l'esecuzione di un programma
ad un dato momento, è \index{comando!\texttt{at}} \texttt{at}. Il comando
vuole come argomento data ed ora in cui il programma specificato deve essere
messo in esecuzione; il nome di quest'ultimo viene letto dallo
\textit{standard input} ma può essere specificato tramite un file qualunque,
passato come parametro per l'opzione \texttt{-f}. Le altre principali opzioni
sono riportate in tab.~\ref{tab:at_options}, per l'elenco completo si può al
solito consultare la pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{-f}      & indica il file da cui leggere il comando da eseguire.\\
     \texttt{-l}      & stampa la lista dei lavori programmati (equivalente a
                        \texttt{atq}).\\ 
     \texttt{-d \textsl{job}}& rimuove il lavoro con \textit{job id}
                        \texttt{job} (equivalente a \texttt{atrm job}).\\ 
     \texttt{-q \textsl{queue}}& invia il comando sulla coda
                        \texttt{queue}.\footnotemark \\
     \texttt{-m}      & invia un messaggio al completamento del lavoro 
                        programmato anche nel caso non ci siano dati in
                        uscita.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{at}.}
  \label{tab:at_options}
\end{table}

\footnotetext{il servizio \textit{at} prevede l'esistenza di diverse code con
  diverse priorità, queste sono identificate dalle lettere dell'alfabeto
  dall'\texttt{a} alla \texttt{z}; il default prevede che il comando
  \texttt{at} usi la coda ``\texttt{a}'' ed il comando \texttt{batch} la coda
  ``\texttt{b}'', le altre code devono essere indicate esplicitamente ed i
  comandi posti in esse verranno eseguiti con un più alto valore di
  \textit{nice} (cioè con priorità inferiore).}

Il comando supporta una grande varietà di formati per le modalità in cui si
indica la data, fra cui tutti quelli del comando \texttt{date} (vedi
sez.~\ref{sec:cmd_time}), più altre estensioni che permettono di usare anche
specificazioni in forma più \textsl{discorsiva} come \texttt{at 1pm tomorrow};
una descrizione completa delle convenzioni utilizzabili si trova nel file
\texttt{/usr/share/doc/at/timespec}. Una volta completata la programmazione il
programma stampa sul terminale un valore numerico (detto \textit{job id}) che
identifica il lavoro differito programmato dall'utente. Un esempio dell'uso di
\texttt{at} è il seguente:
\begin{Console}
piccardi@anarres:~$ \textbf{at 18:00}
warning: commands will be executed using /bin/sh
at> \textbf{ps aux > ~/listaprocessi.txt}
at> <EOT>
job 1 at Wed Mar 19 18:00:00 2008
\end{Console}
%$

Si tenga presente che la directory di lavoro, la maschera dei permessi e
l'ambiente del comando che verrà lanciato sono quelli presenti al momento in
cui si invoca \texttt{at}, inoltre il comando sarà eseguito usando
\texttt{/bin/sh} come shell. Come per \textit{cron} in caso di presenza di
dati in uscita (sia sullo \textit{standard output} che sullo \textit{standard
  error}) questi verranno inviati all'utente che ha programmato l'esecuzione
con un messaggio di posta elettronica.

Una alternativa ad \texttt{at} per l'esecuzione differita è l'uso del comando
\index{comando!\texttt{batch}} \texttt{batch} (che in realtà è un equivalente
di \texttt{at -b}) che permette di programmare l'esecuzione di un programma
non ad un orario predefinito, ma in base al carico della macchina. Il comando
richiesto cioè verrà posto in esecuzione soltanto quando il carico medio della
macchina scende al di sotto di un certo valore.

Una volta programmata l'esecuzione di un programma (sia con \texttt{at} che
con \texttt{batch}) questo viene messo, per ciascun utente, in una opportuna
coda. Gli utenti possono vedere la lista dei propri programmi in attesa di
esecuzione con il comando \index{comando!\texttt{atq}} \texttt{atq}, mentre
l'amministratore può usare lo stesso comando per vedere la lista di tutti
quanti.  Per ciascun programma \texttt{atq} stampa il valore del \textit{job
  id} ad esso associato e l'orario per cui è stata programmata l'esecuzione,
ad esempio:
\begin{Console}
piccardi@anarres:~$ \textbf{atq}
1	Wed Mar 19 18:00:00 2008 a piccardi
\end{Console}
%$

Un programma può essere rimosso dalla coda con il comando
\index{comando!\texttt{atrm}} \texttt{atrm}, che prende come argomento il
valore del \textit{job id} ad esso associato. Di nuovo un utente normale può
operare solo sui propri programmi, mentre l'amministratore può operare su
tutti quanti. Infine, come per l'uso del servizio \textit{cron}, è previsto un
controllo degli accessi al servizio \textit{at} attraverso i due file
\texttt{/etc/at.allow} e \texttt{/etc/at.deny}, il cui formato e significato
sono identici a quelli degli analoghi \texttt{cron.allow} e
\texttt{cron.deny}.



\subsection{Il servizio del \textit{syslog}}
\label{sec:syslog.conf}

\itindbeg{syslog}

Il \textit{syslog} è il servizio usato dai demoni che girano in background e
dal kernel stesso quando devono registrare dei messaggi, in inglese infatti si
parla di \textit{log} quando si fa riferimento alla registrazione degli
eventi, come per il giornale di bordo di una nave, o il libro su cui si
annotano le attività giornaliere; il \textit{syslog} serve appunto a tenere il
giornale di bordo di quanto avviene nel vostro sistema.

Come già illustrato in sez.~\ref{sec:struct_proc_property} i demoni devono
essere attivi anche quando nessuno è collegato al sistema, e per questo non
sono associati ad un terminale, non è quindi loro possibile scrivere dei
messaggi di avviso o di errore sullo \textit{standard output} o lo
\textit{standard error}, dato che nessuno li leggerebbe. Per questo motivo
viene fornito (dalla libreria di sistema, la \textsl{glibc}) un servizio di
registrazione a cui i vari programmi che hanno qualcosa da riportare possono
lasciare i loro messaggi.

Il servizio viene chiamato genericamente \textit{syslog}, e la sua gestione
tradizionalmente veniva effettuata dal programma
\index{demone!\texttt{syslogd}} \texttt{syslogd} che si incaricava di
raccogliere questi messaggi e registrarli in maniera opportuna. Oggi quasi
tutte le distribuzioni più importanti (Debian, RedHat, SuSE) sono passate
all'uso di \index{demone!\texttt{rsyslogd}} \texttt{rsyslogd}, una
reimplementazione compatibile con il vecchio \texttt{syslogd} che offre una
serie di estensioni ed un maggior controllo e rimuove la necessità di dover
usare un secondo programma \index{demone!\texttt{klogd}} (\texttt{klogd}) per
raccogliere anche i messaggi del kernel.\footnote{questi sono gestiti in
  maniera diversa da quelli dei programmi, per chi fosse interessato ad
  approfondire i dettagli si rimanda alla sez.~8.1.5 di \cite{GaPiL}.}

Dato che le sue funzionalità sono utilizzate dalla gran parte degli altri
programmi di servizio, in genere il \textit{syslog} viene attivato nelle prime
fasi della procedura di avvio del sistema (tratteremo l'argomento in
sez.~\ref{sec:struct_sysv_init}). In caso di necessità si può comunque
lanciare direttamente \texttt{rsyslogd} dalla riga di comando, ad esempio se
per un qualche motivo il servizio non parte e si vuole capire cosa succede
utilizzando l'opzione \texttt{-d} che lo avvia in modalità di debug, in cui
resta agganciato al terminale e stampa una serie di informazioni relative al
suo funzionamento.

Nella configurazione ordinaria \texttt{rsyslogd} riceve i messaggi inviati
localmente dagli altri programmi, (per i quali viene usato un socket dedicato,
\texttt{/dev/log}) ma è possibile abilitare la ricezione di messaggi anche via
rete da altre macchine. Per il vecchio \texttt{syslogd} questo veniva fatto
lanciandolo con l'opzione \texttt{-r}, per \texttt{rsyslogd} esiste una
apposita direttiva di configurazione, mentre la principale opzione a riga di
comando è \texttt{-c} che indica il livello di compatibilità con
\texttt{syslogd} da adottare, e che se non indicata implica il livello
massimo.

Il vantaggio di \texttt{rsyslogd} è che il programma è stato sviluppato in
maniera modulare, ed è possibile attivare funzionalità aggiuntive, come quella
di gestire direttamente i log del kernel, o di fornire il servizio di
\textit{syslog} via rete, attivando i relativi moduli.  La descrizione
completa del comando e di tutte le opzioni è disponibile nella pagina di
manuale, al solito accessibile con \texttt{man rsyslogd}.

Il file di configurazione che consente di controllare cosa viene registrato ed
in quale modalità è \index{configurazione!\texttt{/etc/rsyslog.conf}}
\texttt{/etc/rsyslog.conf} e supporta la stessa sintassi usata per il file
\index{configurazione!\texttt{/etc/syslog.conf}} \texttt{/etc/syslog.conf} che
veniva usato con \texttt{syslogd}, tanto che è possibile semplicemente copiare
quest'ultimo per riottenere lo stesso comportamento. Entrambi i file seguono
le convenzioni comuni, per cui le linee vuote o che iniziano per
``\texttt{\#}'' vengono ignorate. Tratteremo più avanti le estensioni
specifiche di \texttt{/etc/rsyslog.conf}, che in genere si trovano in testa a
questo file, esaminando per prima la sintassi delle regole utilizzate per la
registrazione (che sono l'unico contenuto di \texttt{/etc/syslog.conf}) che
resta la stessa.


\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Servizio} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{auth}    & servizio identico a \texttt{authpriv}, deprecato.\\ 
    \texttt{authpriv}& messaggi relativi ad autenticazione e sicurezza.\\ 
    \texttt{cron}    & messaggi dei demoni per l'esecuzione differita
                       (\texttt{atd} e \texttt{cron}).\\  
    \texttt{daemon}  & demoni di sistema che non hanno una categoria di
                       servizio a se stante.\\ 
    \texttt{ftp}     & servizio FTP (\textit{File Transfer Protocol}, vedi
                       sez.~\ref{sec:net_ftp}).\\ 
    \texttt{kern}    & messaggi del kernel.\\ 
    \texttt{lpr}     & messaggi dei servizi di stampa.\\ 
    \texttt{mail}    & messaggi dei demoni di gestione della posta
                       elettronica.\\  
    \texttt{mark}    & messaggio di marcatura a uso interno.\\
    \texttt{news}    & messaggi del servizio di gestione di USENET (la rete
                       dei gruppi di discussione).\\ 
    \texttt{security}& sinonimo di \texttt{auth}.\\ 
    \texttt{syslog}  & messaggi interni generati da \texttt{syslogd}.\\ 
    \texttt{user}    & messaggi generici a livello utente.\\ 
    \texttt{uucp}    & messaggi del sistema UUCP (\textit{Unix to Unix CoPy},
                       un meccanismo di comunicazione precedente Internet).\\ 
    \hline
  \end{tabular}
  \caption{I servizi standard in cui sono classificati i messaggi del
    \textit{syslog}.} 
  \label{tab:cfg_syslog_facility}
\end{table}

Ogni regola di registrazione è costituita da una riga divisa in due campi
separati da spazi o tabulatori. Però è possibile comunque spezzare la riga
usando il carattere ``\texttt{\bslash}'' per proteggere, come sulla riga di
comando, un a capo, nel qual caso gli spazi iniziali sulla riga seguente
verranno ignorati, cosa che consente di formattare in maniera più leggibile
regole complesse. Il primo campo è detto \textsl{selettore}, e serve a
selezionare i messaggi per i quali si applica quanto indicato dal secondo,
detto \textsl{azione}. Il \textsl{selettore} supporta a sua volta una sintassi
abbastanza complessa, ma nella sua forma più semplice è costituito da due
parti, il \textsl{servizio} (detto anche \textit{facility}) e la
\textsl{priorità}, separate da un punto.

Il \textsl{servizio} identifica una categoria di servizi di sistema per conto
dei quali si vuole registrare il messaggio e viene specificato tramite una
delle parole chiave riportate in tab.~\ref{tab:cfg_syslog_facility}, dove sono
elencati i servizi standard predefiniti.  Oltre a quelli di
tab.~\ref{tab:cfg_syslog_facility} ci sono una serie di servizi ausiliari,
identificati dalle parole chiave da \texttt{local0} a \texttt{local7}, che
sono lasciati a disposizione dell'utente per un uso non specifico.

Si tenga presente comunque che il \textsl{servizio}, così come la
\textsl{priorità}, sono proprietà generiche definite dal sistema del
\textit{syslog}, che vengono specificate nelle funzioni di registrazione usate
dai programmi ed inserite direttamente nel contenuto dei messaggi, sono
pertanto sempre presenti e completamente indipendenti dallo specifico programma
che si usa per gestire i log.

I valori possibili per specificare una \textsl{priorità} sono indicati in
tab.~\ref{tab:cfg_syslog_priority}, in ordine crescente dalla più bassa alla
più alta. Questi valori identificano l'importanza del messaggio, nel nostro
caso tutti i messaggi di priorità superiore od uguale a quella indicata nella
regola di selezione verranno registrati.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Priorità} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{debug}  & messaggio di debug.\\ 
    \texttt{info}   & messaggio informativo.\\ 
    \texttt{notice} & situazione normale, ma significativa.\\ 
    \texttt{warning}& avvertimento.\\ 
    \texttt{warn}   & sinonimo di \texttt{warning}, deprecato.\\ 
    \texttt{err}    & condizione di errore.\\ 
    \texttt{error}  & sinonimo di \texttt{err}, deprecato.\\ 
    \texttt{crit}   & condizione critica.\\ 
    \texttt{alert}  & si deve intervenire immediatamente.\\ 
    \texttt{emerg}  & il sistema è inusabile.\\ 
    \texttt{panic}  & sinonimo di \texttt{emerg}, deprecato.\\ 
    \hline
  \end{tabular}
  \caption{Le varie priorità dei messaggi del servizio di \textit{syslog}.}
  \label{tab:cfg_syslog_priority}
\end{table}

Oltre a queste parole chiave che identificano servizi e priorità nel file di
configurazione vengono riconosciute alcune estensioni; un asterisco
``\texttt{*}'' seleziona o tutti i servizi o tutte le priorità, mentre la
parola chiave \texttt{none} li esclude tutti. Inoltre usando come separatore
il carattere ``\texttt{,}'' si può elencare una lista di servizi per la stessa
priorità o una lista di priorità per un certo servizio.  Si possono poi
associare più selettori ad una stessa azione separandoli con il carattere
``\texttt{;}''.  Due ulteriori estensioni di questa sintassi sono date dal
carattere ``\texttt{=}'', che permette di registrare solo i messaggi aventi
esattamente quella specifica priorità, e dal carattere ``\texttt{!}'', che
permette di escludere i messaggi di una specifica priorità o servizio.

L'\textsl{azione} specificata come secondo campo serve ad indicare come si
vuole che siano registrati i messaggi. Il caso più comune è quello in cui essi
devono essere scritti su un file (quello che si chiama un \textsl{file di
  log}), che dovrà essere specificato tramite un pathname assoluto. Al nome si
può premettere in maniera opzionale un carattere ``\texttt{-}'' per impedire
che il contenuto del file venga sincronizzato all'arrivo di ogni messaggio,
lasciando spazio per la bufferizzazione degli stessi, in tal caso il demone è
in grado di accorgersi di eventuali ripetizioni di un messaggio precedente e
segnalare queste ultime invece di ripetere tante volte lo stesso messaggio. Si
tenga presente che i messaggi vengono sempre scritti in coda al contenuto
corrente, così da non sovrascrivere messaggi precedenti.

Oltre alla scrittura su file \texttt{rsyslogd} permette di effettuare le
registrazioni in diverse altre modalità. Se si premette un carattere
``\texttt{|}'' al nome di un file si indica che si sta facendo riferimento ad
una fifo (vedi sez.~\ref{sec:struct_file_vfs}) da cui un altro programma potrà
rileggere i dati.  Si può inoltre mandare l'output su una \textit{console}
specificando come file quello di un dispositivo a terminale (ad esempio
\texttt{/dev/tty10}).  Si possono anche mandare i messaggi a liste di utenti,
identificati per username separati da virgole, e questi li riceveranno sui
terminali su cui sono collegati. Infine il carattere ``\texttt{*}'' fa sì che
i messaggi siano inviati a chiunque sia collegato sul sistema.

Una delle caratteristiche più interessanti del \textit{syslog} è che si
possono mandare tutti i messaggi ad una macchina remota. Questo si fa usando
il carattere ``\texttt{@}'' seguito dal nome della macchina di destinazione;
si dovrà specificare cioè l'\textit{hostname} della destinazione o il suo
indirizzo di rete, (qui si da per scontata la conoscenza di questi concetti,
che tratteremo in dettaglio solo al cap.~\ref{cha:networks_base}). Se su
quella macchina è stato predisposto un \texttt{syslogd} abilitato all'ascolto
via rete questo riceverà tutti i messaggi. Si può realizzare così un macchina
dedicata solo a questo servizio, in modo da proteggere i file di log, che
spesso possono contenere informazioni preziose utili in caso di intrusione
(ovviamente detta macchina deve essere ben protetta).

Un esempio per le regole utilizzate nel file \texttt{/etc/rsyslog.conf} è il
seguente estratto, che si è ripreso dal file che viene installato di default
su una Debian Squeeze:
\begin{FileExample}[label=/etc/syslog.conf]
auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
#cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          -/var/log/mail.log
user.*                          -/var/log/user.log

#
# Logging for the mail system.  Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err
...
#
# Some `catch-all' logfiles.
#
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages
#
# Emergencies are sent to everybody logged in.
#
*.emerg                         *
...
\end{FileExample}

In questo caso si noti come tutti i messaggi relativi ai \textit{servizi}
\texttt{auth} e \texttt{authpriv}, \texttt{daemon}, \texttt{kern},
\texttt{lpr}, \texttt{mail}, \texttt{user} e \texttt{uucp} vengano salvati su
singoli file, mentre sul file \texttt{syslog} vengono mandati tutti i messaggi
eccettuati quelli relativi ad \texttt{auth} e \texttt{authpriv}.  Inoltre sono
trattati a parte i messaggi relativi al sistema di posta, dove per ciascuna
priorità viene usato un file diverso.

Vengono poi definiti alcuni file di log per i messaggi generici, come
\texttt{messages} in cui si richiede l'invio dei messaggi solo delle priorità
\texttt{info}, \texttt{notice} e \texttt{warn} escludendo una serie di servizi
i cui messaggi sono archiviati altrove. Infine si noti come le emergenze (fra
queste ci sono ad esempio i messaggi di avviso dello spegnimento del sistema)
vengano stampate su tutti i terminali attivi.

Come accennato oltre alle regole di registrazione riportate nel precedente
esempio, \texttt{rsyslogd} supporta delle ulteriori direttive specifiche per
controllare le funzionalità aggiuntive non presenti nel vecchio
\texttt{syslogd}, che si riconoscono in quanto iniziano tutte con il carattere
``\texttt{\$}'' e prevedono una parola chiave seguita da un valore separato da
spazi. Queste possono anche essere assenti, nel qual caso il valore di default
consente di riottenere un comportamento compatibile con quello di
\texttt{syslogd}.

In particolare si possono attivare i moduli che forniscono il supporto per
queste funzionalità con la direttiva \texttt{\$ModLoad} seguita dal nome del
modulo da caricare, il default prevede che siano attivi i moduli
\texttt{imuxsock} per la ricezione dei messaggi locali e \texttt{imklog} per
la ricezione dei messaggi del kernel. Se si vuole abilitare la ricezione dei
messaggi via rete (equivalente alla opzione \texttt{-r} di \texttt{syslogd})
occorre abilitare anche il modulo \texttt{imudp}.\footnote{la ricezione di
  default avviene con il protocollo UDP sulla porta 514, ma questa può essere
  cambiata con la direttiva \texttt{\$UDPServerRun}, per le spiegazioni su
  protocolli e porte ed i concetti relativi alla rete, che si son dati per
  acquisiti, si faccia riferimento a sez.~\ref{sec:net_tcp_ip}.}


\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Priorità} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{\$ModLoad}       & carica un modulo di estensione.\\ 
    \texttt{\$FileOwner}     & imposta il proprietario dei file creati.\\ 
    \texttt{\$FileGroup}     & imposta il gruppo dei file creati.\\ 
    \texttt{\$FileCreateMode}& imposta i permessi per i file creati.\\ 
    \texttt{\$DirCreateMode} & imposta i permessi per le directory create.\\ 
    \texttt{\$Umask}         & imposta la \textit{umask} per la creazione dei
                               file.\\  
    \texttt{\$IncludeConfig} & include ulteriori file di configurazione
                               (supporta la sintassi del \textit{filename
                                 globbing}).\\  
    \hline
  \end{tabular}
  \caption{Le principali direttive specifiche di \texttt{rsyslogd}.}
  \label{tab:rsyslogd_directives}
\end{table}

Altre direttive sono quelle che consentono di indicare le modalità con cui
vengono creati i file di log, o di includere altri file di configurazione a
partire da una directory (in genere \texttt{/etc/rsyslog.d/}) usate in genere
dai singoli pacchetti per fornire configurazioni specifiche. Un elenco delle
altre principali direttive è illustrato in tab.~\ref{tab:rsyslogd_directives}.

Infine qualora si voglia poter utilizzare il sistema di \textit{syslog} dalla
shell (ad esempio all'interno di uno script) si può utilizzare il comando
\index{comando!\texttt{logger}} \texttt{logger}, che consente di registrare un
messaggio. Il comando prende come argomento il testo del messaggio, e di
default questo verrà registrato sul servizio \texttt{user} con priorità
\texttt{notice}, si può però usare l'opzione \texttt{-p} per impostare una
diversa priorità (o servizio) che prende un parametro nella forma
\texttt{\textsl{servizio}.\textsl{priorità}}. Per tutti i dettagli sul comando
e le altre opzioni si consulti al solito la pagina di manuale.

Benché \texttt{rsyslogd} sia il principale sostituto del vecchio
\texttt{syslogd}, esistono delle alternative, una di queste, che ha ottenuto
una certo successo è \texttt{syslog-ng}, che supporta anche una serie di
estensioni del formato e la registrazione di alcuni dati strutturati, ma la
sua incompatibilità con le configurazioni del precedente \texttt{syslogd} lo
rende meno diffuso. Inoltre con il passaggio come nuovo programma di avvio a
\texttt{systemd} (vedi sez.~\ref{sec:systemd_upstart}) alcune distribuzioni
stanno iniziando ad adottare come default \texttt{journald}, il sistema di
registrazione integrato in \texttt{systemd}.

La scelta in tal caso è molto controversa, in quanto \texttt{journald} salva i
dati su un file binario che può essere riletto solo con l'apposito programma
\texttt{journalctl}, su cui torneremo in
sez.~\ref{sec:systemd_upstart}. Questa scelta consente di salvare molte più
informazioni rispetto al \textit{syslog}, (in particolare i dati relativi ad
utenti e privilegi associati ai processi) sulle quali è possibile effettuare
ricerche e selezioni, offrendo funzionalità non disponibili nel sistema
tradizionale. D'altra parte espone a problemi di accesso ai dati sia perché la
stabilità del formato non è garantita, per cui non è detto sia semplice
accedere a vecchie registrazioni, sia perché non è garantita l'integrità delle
registrazioni ed in caso di corruzione del file si possono perdere
informazioni. Per questo motivo è opportuno usare \texttt{journald} come
intermediario, per sfruttarne le funzionalità avanzate, ed inoltrare comunque
i log (cosa che il programma supporta) ad un demone di \textit{syslog}
tradizionale.



\subsection{Il sistema di rotazione dei file di log}
\label{sec:logrotate}

I file di log sono una risorsa di grande valore in quanto i messaggi
provenienti dai vari servizi che vi sono registrati possono essere di
importanza fondamentale per capire le ragioni di eventuali malfunzionamenti.
Il problema è che \texttt{rsyslogd}, come abbiamo appena detto, scrive sempre
in modalità \textit{append}, aggiungendo i nuovi messaggi in coda ai file, ma
il problema si pone anche in quei casi, come avviene per i demoni di rete più
complessi, in cui i file di log vengono scritti direttamente dal singolo
programma.  Questo significa che la dimensione di questi ultimi tende a
crescere indefinitamente e si rischia così che la partizione su cui risiede la
directory \texttt{/var/log} si riempia.

Per risolvere questo problema, e semplificare la gestione dei file di log, è
stato creato un apposito programma, \index{comando!\texttt{logrotate}}
\texttt{logrotate}, che lanciato su base periodica gestisce la
``\textsl{rotazione}'' dei file di log effettuando operazioni come la loro
compressione, la rimozione delle versioni troppo vecchie, e l'invio di
messaggi di avviso all'amministratore per posta elettronica.

Il comando deve essere lanciato specificando come argomento un file di
configurazione che specifica le modalità di rotazione. Se si usa l'opzione
\texttt{-v} il comando stamperà una serie di messaggi durante le operazioni di
rotazione. L'opzione \texttt{-d} permette di eseguire il comando in modalità
di \textit{debug} (ed implica \texttt{-v}), mentre l'opzione \texttt{-f} forza
il comando ad eseguire una rotazione anche quando questa non è in programma.
Al solito per l'elenco completo delle opzioni si può fare riferimento alla
pagina di manuale.

Il formato del file di configurazione prevede la presenza di una direttiva per
riga.  Queste possono essere specificate direttamente nel file e vengono prese
come impostazioni globali da applicare in maniera generica a tutti i file. È
poi possibile indicare delle opzioni specifiche per un singolo file scrivendo
al posto di una direttiva il pathname assoluto di quest'ultimo, seguito da un
blocco delimitato da parentesi graffe contenente le direttive da applicargli,
specificate sempre una per riga. Infine, come per gli altri file di
configurazione, le linee vuote o che iniziano per ``\texttt{\#}'' vengono
ignorate.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{daily}   & effettua una rotazione giornaliera.\\ 
    \texttt{weekly}  & effettua una rotazione settimanale, un file viene
                       ruotato se è passata più di una settimana dall'ultima
                       rotazione.\\  
    \texttt{monthly} & effettua una rotazione mensile, i file vengono ruotati
                       la prima volta che il comando viene eseguito in un
                       certo mese.\\ 
    \texttt{size}    & effettua la rotazione al superamento di una certa
                       dimensione da parte del file di log (invece che su un
                       periodo temporale); richiede che si specifichi la
                       dimensione come argomento (supporta i suffissi
                       \texttt{k}, \texttt{M} e \texttt{G}).\\  
    \texttt{rotate}  & specifica il numero di copie (da passare come
                       argomento) dei file di log che devono essere
                       mantenute in una successione di rotazioni.\\  
    \texttt{include} & legge i file passati come parametri, o se
                       trattasi di directory, tutti i file presenti
                       all'interno di questa che non abbiano nel nome una
                       delle estensioni vietate (indicate tramite la direttiva
                       \texttt{tabooext}).\\  
    \texttt{create}  & crea un nuovo file di log vuoto immediatamente
                       dopo aver eseguito la rotazione del precedente
                       assegnandogli un insieme di permessi, un proprietario
                       ed un gruppo proprietario, che devono essere
                       specificati come argomenti.\\ 
    \texttt{tabooext}& permette di definire una lista di estensioni e
                       caratteri vietati nei nomi dei file da includere con
                       la direttiva \texttt{include}; questi devono essere
                       passati come lista separata da virgole. Un carattere
                       \texttt{+} indica di aggiungere la lista ai caratteri
                       già esclusi, di default questi sono \texttt{.rpmorig},
                       \texttt{.rpmsave}, \texttt{.dpkg-dist},
                       \texttt{.dpkg-old}, \texttt{.dpkg-new},
                       \texttt{.disabled}, \texttt{,v}, \texttt{.swp},
                       \texttt{.rpmnew}, e \verb|~|.\\ 
    \texttt{compress}& comprime le vecchie versioni dei file di log usando
                       \texttt{gzip}.\\  
    \texttt{missingok}&se il file di log è assente non dà errori. \\
    \texttt{prerotate}&prima di effettuare la rotazione esegue tutti i comandi
                       inseriti nelle linee seguenti la direttiva fino a
                       quando non incontra una direttiva \texttt{endscript}. \\
    \texttt{postrotate}&dopo aver effettuato la rotazione esegue tutti i
                       comandi inseriti nelle linee seguenti la direttiva fino
                       a quando non incontra una direttiva
                       \texttt{endscript}. \\ 
    \texttt{endscript}&termina una direttiva \texttt{postrotate} o
                       \texttt{prerotate}.\\
    \hline
  \end{tabular}
  \caption{Le principali direttive usate nel file di configurazione di
    \texttt{logrotate}.} 
  \label{tab:cfg_logrotate_conf}
\end{table}

Una direttiva particolare è \texttt{include} che permette di includere altri
file all'interno della configurazione. Il suo uso più interessante è però
quello in cui viene usata per includere una directory. In tal caso infatti
vengono inclusi tutti i file in essa contenuti a parte quelli con alcuni
caratteri o con certe estensioni che li identificano come copie, definibili
con la direttiva \texttt{tabooext} (vedi tab.~\ref{tab:cfg_logrotate_conf}).
Questo consente ad ogni servizio che gestisce autonomamente i suoi file di log
di usare un suo file di configurazione per \texttt{logrotate} con delle
impostazioni personalizzate, semplicemente scrivendolo in una directory
comune.

Altre due direttive particolari sono \texttt{prerotate} e \texttt{postrotate},
che consentono di eseguire una serie di comandi prima e dopo la rotazione. In
genere le si usano per fermare prima, o far ripartire poi, i servizi di cui si
vogliono ruotare i file di log (o per eseguire compiti analoghi). Entrambe le
direttive prevedono che vengano eseguiti i comandi inseriti nelle righe ad
esse seguenti, fino a quando non si incontra la direttiva \texttt{endscript}.

Si ricordi infatti quanto detto in sez.~\ref{sec:struct_filesystem_arch}
riguardo la cancellazione dei file: un programma attivo fa riferimento in
maniera diretta ai file che ha aperto, cosa che vale anche per i file di log,
con i file descriptor, per cui anche se si cancella o rinomina il file su
disco il programma, usando il file descriptor, continuerà a scrivere sul file
originale usando l'\textit{inode}. Per questo motivo in genere è necessario
prima fermare il programma e poi farlo ripartire, oppure dirgli esplicitamente
di chiudere i file di log, cosa che alcuni programmi fanno se gli si manda un
apposito segnale (in genere \texttt{SIGHUP}), così che al riavvio (o alla
riapertura degli stessi) vada a scrivere sulla nuova versione.

La rotazione di un file può essere specificata sia per intervalli temporali
(con le direttive \texttt{daily}, \texttt{weekly} e \texttt{monthly}) che
sulla base del superamento di una certa dimensione (con la direttiva
\texttt{size}). Quando il comando viene invocato viene controllato se la
condizione è soddisfatta e solo in questo caso (a meno di non aver specificato
l'opzione \texttt{-f}) la rotazione viene eseguita. Le altre principali
direttive sono riportate in tab.~\ref{tab:cfg_logrotate_conf}, la descrizione
completa di tutte le direttive e del loro significato si trova nella pagina di
manuale del comando, accessibile con \texttt{man logrotate}.

Benché sia possibile lanciare il comando a mano, gran parte delle
distribuzioni invocano \texttt{logrotate} fra le operazioni giornaliere
eseguite da \texttt{cron}.  In quasi tutti i casi negli script viene usato
come standard il file di configurazione
\index{configurazione!\texttt{/etc/logrotate.conf}}
\texttt{/etc/logrotate.conf} mentre ulteriori file di configurazione di
singoli servizi sono mantenuti nella directory \texttt{/etc/logrotate.d/}.

In genere si mettono in \texttt{logrotate.conf} solo alcune opzioni generali,
le opzioni specifiche per ciascun servizio vengono messe nella directory
\texttt{/etc/logrotate.d/}.  In questo modo un pacchetto di installazione di
un qualunque programma che ha bisogno di produrre dei log e ruotarli può
inserire in questa directory un opportuno file di configurazione.  Il
contenuto della directory viene poi incluso tramite una direttiva
\texttt{include} presente in \texttt{logrotate.conf} così che non ci sia
necessità di modificare quest'ultimo ogni volta che si installa o disinstalla
un pacchetto software.

Un esempio del contenuto di \texttt{/etc/logrotate.conf}, tratto dalla
versione installata di default su una Debian Squeeze, è il seguente, i
commenti spiegano in maniera molto chiara il significato delle varie opzioni:
\begin{FileExample}[label=/etc/logrotate.conf]
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp or btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
}  

/var/log/btmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}
       
# system-specific logs may be configured here
\end{FileExample}

In questo esempio si richiede di ruotare i file settimanalmente e di mantenere
quattro copie degli stessi. Poi si dice di leggere tutto il contenuto della
directory \texttt{/etc/logrotate.d} per ulteriori configurazioni, infine si
cambiano le impostazioni di default per i due file \texttt{/var/log/wtmp} e
\texttt{/var/log/btmp} che non fanno riferimento a nessun pacchetto
(contengono i dati delle sessioni degli utenti) per i quali si richiede una
rotazione mensile invece che settimanale.

\itindend{syslog}



\section{L'\textit{X Window System}}
\label{sec:cfg_Xwindow}

In questa sezione tratteremo le problematiche principali relative all'uso e
alla gestione di base dell'interfaccia grafica nei sistemi Unix. In
particolare approfondiremo le caratteristiche principali dell'\textit{X Window
  System}, l'infrastruttura che fornisce l'interfaccia grafica, di come
gestirlo e come configurarlo, con una breve panoramica finale sui programmi
per l'accessibilità.


\subsection{Introduzione a \textit{X Window}}
\label{sec:Xwindow_intro}

Benché in realtà esistano diverse alternative per la realizzazione di
applicazioni in ambiente grafico, sia attraverso l'uso diretto del
\textit{framebuffer} o dell'hardware video, sia attraverso opportuni
\textit{toolkit} grafici, sia attraverso sistemi a finestre alternativi (che
non hanno mai avuto una diffusione significativa), sia attraverso una
reimplementazione ed estensione come \textit{Wayland}
(\url{http://wayland.freedesktop.org/}), a tutt'oggi le interfacce grafiche
normalmente utilizzate in un sistema GNU/Linux (ed in generale in un qualunque
sistema Unix) si basano tutte sull'\textit{X Window System}, nome spesso
abbreviato in \textit{X11}, dalla versione finale del protocollo o ancora più
brevemente in ``\textit{X}''.

Il fatto che esistano delle alternative complete per l'uso dell'interfaccia
grafica ci mette immediatamente di fronte ad una delle principali differenze
che c'è fra un sistema unix-like come GNU/Linux ed altri sistemi operativi:
l'interfaccia grafica non fa parte del kernel, e non ha nessuna caratteristica
privilegiata, ma viene eseguita da un programma in user space come un
qualunque altro programma. Tutto il sistema grafico in sostanza non è che un
altro strato che viene posto sopra il kernel, che può essere tranquillamente
sostituito da uno strato diverso, e che può anche essere eliminato tutte le
volte che non serve (ad esempio sui server).

Il punto critico è che in realtà il programma che implementa questa
interfaccia a lungo ha richiesto un accesso diretto all'hardware della scheda
grafica tramite degli appositi \textsl{agganci} forniti dal kernel e questo è
stato causa di instabilità con l'uso di schede grafiche per le quali i driver
di supporto erano sperimentali (o proprietari).  Inoltre questa architettura
comportava una serie di problemi, fra cui quello di dover eseguire il cuore
l'interfaccia grafica con privilegi amministrativi, per cui nelle versioni più
recenti del kernel una serie di funzionalità che prima facevano parte di
\textit{X Window} sono state portate all'interno del kernel e sono state
definite delle interfacce più controllate per l'uso delle schede grafiche, che
consentono anche una migliore interazione con le altre funzionalità che erano
già gestite dal kernel, come la console virtuale.

L'interfaccia grafica di \textit{X Window System} nasce a metà degli anni '80
con il progetto \textit{Athena} al MIT. L'intento era di fornire un ambiente
grafico per i sistemi UNIX, e costituisce una delle prime interfacce grafiche
realizzate su un sistema operativo. La caratteristica principale di
\textit{X}, che a tutt'oggi lo distingue dalle interfacce grafiche presenti in
altri sistemi operativi, è che oltre a fornire le usuali funzionalità per
disegnare finestre ed altri elementi grafici su uno schermo, il sistema è
completamente trasparente rispetto alla rete. Questo significa che \textit{X
  Window} è in grado di operare allo stesso modo sia in locale,
interfacciandosi direttamente all'hardware grafico della macchina su cui si
sta operando, sia in rete, inviando attraverso di essa le informazioni per
disegnare la grafica di una applicazione su una macchina remota.

\begin{figure}[htb]
  \centering
  \includegraphics[width=11cm]{images/X11-schema}
  \caption{Schema di funzionamento del protocollo X11}
  \label{fig:X11_protocol}
\end{figure}

L'architettura di \textit{X Window} infatti definisce una relazione
\textit{client-server}, illustrata sommariamente in
fig.~\ref{fig:X11_protocol} fra una applicazione ed il suo \textit{display},
fornendo una serie di funzioni di libreria (tramite le \textit{Xlib}) che
separano completamente l'applicazione (detta per questo \textit{X-client}) dal
programma che si incaricherà di disegnarne le finestre
(l'\textit{X-server}). È questa separazione che consente di definire un
protocollo di comunicazione (l'\textit{X protocol}), fra client e server, che
rende l'intera interfaccia trasparente rispetto alla rete.

Si tenga presente però che in questa architettura client e server hanno
posizione invertita rispetto al solito. Infatti di solito è il client che
viene eseguito localmente per interrogare un server remoto, che fornisce delle
risposte. In questo caso sono dei client remoti (le applicazioni
\textit{X-client}) che inviano le informazioni al server locale
(l'\textit{X-server}) perché questo ne disegni le finestre sulla propria
macchina.

Fino a qualche anno fa la versione dell'\textit{X Window System} più
utilizzata su GNU/Linux era XFree86 nato dal porting su PC del codice
originale. Questo infatti è sempre stato rilasciato con licenza libera e da
sempre sono esistite diverse realizzazioni,\footnote{un progetto interessante
  ad esempio è \textit{TinyX}, una versione ottimizzata per il minor consumo
  possibile di risorse, da utilizzare nei sistemi embedded.}  infatti la
\textsl{licenza X11}, che venne creata per questo progetto e poi utilizzata in
seguito anche per molti altri, è una licenza non-\textit{copyleft} che
consentiva ai vari distributori di sistemi unix-like di realizzare le proprie
versioni proprietarie. Anche XFree86 aveva adottato questa licenza, ma
dall'inizio del 2004, avendo effettuato un cambiamento di licenza che lo
rendeva incompatibile con la GPL, la sua diffusione si è progressivamente
ridotta fino alla completa scomparsa. Ma già prima di allora c'erano state
parecchie critiche alla gestione del progetto, ed in particolare alla scarsa
apertura nell'accettare contributi esterni, e nel restare legati ad una
costruzione monolitica dell'insieme del server e delle librerie, che rendeva
poco flessibile lo sviluppo.

Il cambiamento di licenza è stata l'occasione che ha fatto sì che questo
malcontento desse luogo all'avvio di un progetto di sviluppo alternativo.
Negli anni precedenti infatti si era avuta una significativa conversione
dell'\textit{X-Consortium} (il titolare dei diritti dell'implementazione
originale di \textit{X Window}) da consorzio di industrie a fondazione aperta
anche alla partecipazione diretta di singole persone.  Ne sono così entrati a
far parte i principali sviluppatori che non erano d'accordo con il cambio di
licenza e la gestione del progetto XFree86, e si è ripartiti dall'ultima
versione di quest'ultimo rilasciata con la licenza originale, per la creazione
delle nuove versioni del server X dell'\textit{X-Consortium}, quello che oggi
va sotto il nome di \textit{X.org} (si veda
\href{http://www.x.org/}{\texttt{http://www.x.org/}}).

Il cambio di gestione del progetto ha avuto un notevole effetto di rilancio
dello sviluppo di \textit{X Window}; in particolare nel Dicembre 2005 è stata
creata, dopo più di dieci anni, una nuova \textit{major release} del
protocollo, la X11R7, che oltre ad introdurre una serie di estensioni, è stata
la prima con una separazione delle varie componenti (server, librerie, driver
delle schede grafiche) per consentire uno sviluppo più rapido e flessibile. Ad
oggi sono già state rilasciate varie versioni del server con il nome
\textit{X.org}, che è quello adottato ormai universalmente da tutte le
distribuzioni di GNU/Linux.

% L'unica distribuzione con ancora una certa diffusione che continua
% ad usare la vecchia versione di XFree86 è Debian Sarge.\footnote{la
%   transizione è avvenuta durante la fase di rilascio di Sarge, per cui non era
%   possibile fare il passaggio, in realtà comunque anche in Sarge viene usata
%   una versione di XFree86 sviluppata internamente da Debian su cui sono stati
%   inseriti molti aggiornamenti; già con la nuova versione stabile Etch anche
%   Debian è passata a \textit{X.org}.}


\subsection{La configurazione del server X}
\label{sec:cfg_Xserver}

Il primo passo per utilizzare l'interfaccia grafica su GNU/Linux è configurare
il server X sulla propria macchina, perché questo possa disegnare le finestre
e ricevere i dati da tastiera e mouse (oltre che dai client). Tutte le
distribuzioni mantengono i vari file di configurazione dell'\textit{X Window
  System} in una directory ad essi dedicata, sotto \texttt{/etc/X11}, e con
\textit{X.org} il file di configurazione del server X è
\index{configurazione!\texttt{/etc/X11/xorg.conf}} \texttt{xorg.conf}.

% Fino alla versione 3 di XFree86 il primo passo era quello di identificare la
% propria scheda grafica e installare il pacchetto con il relativo server X in
% grado di parlare con essa.  A partire dalla versione 4 il supporto delle varie
% schede è stato modularizzato, ed il pacchetto che contiene il server è uno
% solo. Con \textit{X.org} il supporto è sempre modulare; perciò faremo sempre
% riferimento alla configurazione secondo questa modalità.

% Tutte le distribuzioni mantengono i vari file di configurazione dell'\textit{X
%   Window System} in una directory ad essi dedicata, sotto \texttt{/etc/X11}.
% La configurazione del server in XFree86 è governata dal file
% \texttt{XF86Config}, il formato di questo file è stato modificato a partire
% dalla versione 4, per cui nelle distribuzioni si può trovare al suo posto il
% file \index{configurazione!\texttt{/etc/X11/XF86Config-4}}
% \texttt{XF86Config-4}.  Usando XFree86 con versioni successive alla 3 il
% server X in genere cerca prima quest'ultimo e se non lo trova ricorre al
% precedente.  Se invece si usa \textit{X.org} il file di configurazione è
% sempre \index{configurazione!\texttt{/etc/X11/xorg.conf}} \texttt{xorg.conf},
% che usa la stessa sintassi del precedente. Dato che quest'ultimo è ormai
% diventato il più diffuso, nel seguito faremo principalmente riferimento ad
% esso.

Configurare il server X significa fornirgli un file di configurazione
adeguato, che lo metta in grado di utilizzare l'hardware necessario. Fino a
qualche anno fa questo veniva fatto automaticamente all'interno della
procedura di installazione del sistema, in genere attraverso un opportuno
programma in grado di determinare automaticamente i parametri necessari e
generare il file sulla base dell'hardware della macchina. 

A partire dalla versione 7.2 di \textit{X.org} il server X è in grado di
auto-configurarsi completamente e funzionare nella maggior parte dei casi
anche senza avere un file di configurazione, utilizzando i default ritenuti
appropriati secondo quanto rilevato nell'hardware. Questo significa che in
genere il suddetto file \texttt{xorg.conf} non è neanche più presente e deve
essere creato solo in quei rari casi in cui il meccanismo di
autoconfigurazione non funziona o in cui si vogliono modificare i default. 

In questo caso si deve tener presente che, oltre a quelle relative
all'hardware, la configurazione manuale necessita anche di altri parametri,
come le informazioni relative ai font per il disegno dei caratteri o ai nomi
dei colori, che però in genere sono predeterminate dall'installazione dei
relativi pacchetti e vengono impostate automaticamente. Si può comunque
generare uno scheletro del file di configurazione lanciando il server con
\texttt{X -configure}.

Le informazioni usate nella configurazione del server X sono quelle che
riguardano le varie componenti utilizzate dallo stesso, e cioè mouse,
tastiera, scheda video e monitor.  Si tenga presente che fin dalla sua nascita
X11 ha sempre supportato la presenza di schermi multipli, e che nelle versioni
recenti sono presenti pure le varie estensioni che permettono di
``\textsl{spalmare}'' un desktop su più schermi.

% Per la creazione della configurazione praticamente ogni distribuzione ha
% creato un suo programma dedicato;\footnote{su Debian basta usare
%   \texttt{dpkg-reconfigure} (vedi sez.~\ref{sec:adv_pkg_debian}) sul pacchetto
%   del server X, \texttt{xserver-xfree86} o \texttt{xserver-xorg} a seconda di
%   quale versione è in uso.} con il pacchetto XFree86 comunque vengono anche
% forniti direttamente due programmi di configurazione,
% \index{comando!\texttt{xf86cfg}} \texttt{xf86cfg} che opera ad interfaccia
% grafica e \index{comando!\texttt{xf86config}} \texttt{xf86config} che opera a
% linea di comando;\footnote{nella versione 3.0 di Xfree86 c'era pure il comando
%   \index{comando!\texttt{XF86Setup}} \texttt{XF86Setup}, che forniva una
%   interfaccia testuale semigrafica, oggi questo programma non viene più
%   utilizzato.} nel caso si usi \textit{X.org} esistono gli equivalenti
% \index{comando!\texttt{xorgcfg}} \texttt{xorgcfg} e
% \index{comando!\texttt{xorgconfig}} \texttt{xorgconfig}.  Questi programmi,
% una volta inseriti i dati dell'hardware, permettono di generare
% automaticamente il file di configurazione. Essi vengono utilizzati sempre meno
% dato che le capacità di auto-configurazione del server migliorano
% continuamente, e già adesso si può generare uno scheletro del file di
% configurazione lanciando il server con \texttt{X -configure}.

Il file di configurazione del server X è diviso in varie sezioni; ciascuna
sezione inizia con la parola chiave \texttt{Section} seguita dal nome che la
identifica, ed è conclusa dalla parola chiave \texttt{EndSection}. All'interno
di queste sezioni dovranno poi essere specificate le opzioni ed i valori delle
configurazioni (dipendenti dal tipo di sezione); la sintassi generica di una
sezione sarà pertanto analoga a qualcosa come:
\begin{Verbatim}[samepage=true]
    Section  "SectionName"
        SectionEntry
        ...
    EndSection
\end{Verbatim}

I nomi delle principali sezioni sono riportati in
tab.~\ref{tab:Xorg_Section}, l'elenco completo può essere trovato nella
rispettiva pagina di manuale (la sintassi del file di configurazione è
identica per XFree86 e \textit{X.org}).  Le sezioni hanno poi una loro
gerarchia; alcune di esse devono essere necessariamente specificate, e quelle
di livello più alto possono usare valori definiti in quelle di livello più
basso.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Nome} & \textbf{Contenuto} \\
    \hline
    \hline
    \texttt{Files}      & indica i pathname di file o directory contenenti 
                          informazioni usate dal server come le directory dei
                          font o i file con le descrizioni dei colori.\\ 
    \texttt{ServerFlags}& indica le opzioni generali che controllano 
                          globalmente il comportamento del server, di norma
                          non viene utilizzato e valgono i valori di default
                          delle stesse.\\ 
    \texttt{Module}     & indica i moduli aggiuntivi che devono essere
                          caricati dinamicamente (e che forniscono estensioni
                          come le accelerazioni 3D e il rendering dei font
                          truetype). \\ 
    \texttt{InputDevice}& contiene la descrizione di un dispositivo di input
                          (mouse, tastiera, tavoletta grafica, ecc.); ne deve
                          essere specificata una per singolo dispositivo.\\ 
    \texttt{Device}     & contiene le informazioni di configurazione di una
                          scheda grafica, ne deve essere specificata una per
                          ogni scheda disponibile.\\ 
    \texttt{Monitor}    & contiene le informazioni di descrizione di un
                          monitor, ne deve essere specificata una per
                          ogni monitor disponibile.\\ 
    \texttt{Modes}      & contiene la descrizione di una modalità video 
                          (corrisponde a specificare risoluzione, frequenza di
                          refresh e profondità di colore).\\ 
    \texttt{Screen}     & contiene la definizione di uno \textsl{schermo}, 
                          combinando una scheda video ed un monitor.\\ 
    \texttt{ServerLayout}&contiene la configurazione generale del server.\\ 
    \texttt{DRI}        & contiene le specifiche per il \textit{Direct
                          Rendering Interface} un'interfaccia diretta
                          alle accelerazioni hardware delle schede grafiche.\\ 
    \hline
  \end{tabular}
  \caption{I nomi delle varie sezioni del file di configurazione del server X.}
  \label{tab:Xorg_Section}
\end{table}

Al livello più alto c'è la sezione \texttt{ServerLayout}, che serve a
collegare insieme i dispositivi di ingresso e di uscita che vengono usati dal
server in una sessione X11. Un singolo dispositivo di ingresso deve essere
descritto in una sezione \texttt{InputDevice}, mentre i dispositivi di uscita
devono essere collegati in una sezione \texttt{Screen}, che comprende una
sezione \texttt{Device} che descrive una scheda video ed una sezione
\texttt{Monitor} che descrive il monitor ad essa collegato, queste possono
essere anche più di una se ci sono più monitor collegati alla stessa
scheda. Le altre sezioni sono invece indipendenti.

Ciascuna sezione comprende una serie di direttive, proprie della sezione, che
vanno espresse su una singola riga. Queste sono introdotte da una parola
chiave seguita da uno o più valori, che hanno un formato comune per tutte le
sezioni e possono essere di tre tipi diversi: numeri interi, numeri reali e
stringhe. Gli interi si possono esprimere sia in forma decimale che
esadecimale (apponendo il suffisso \texttt{0x}), le stringhe devono sempre
essere comprese fra virgolette.

Inoltre per tutte le sezioni esiste la direttiva generica \texttt{Options} che
specifica il valore di una opzione; questa richiede sempre due argomenti di
tipo stringa, il primo dei quali specifica il nome dell'opzione ed il secondo
il valore.  La stringa che specifica quest'ultimo viene poi interpretata ed il
suo contenuto viene classificato in altrettanti tipi di valore, i numeri
(reali o interi, secondo il formato visto per gli argomenti generici) verranno
interpretati come tali, le parole chiave \texttt{yes}/\texttt{no},
\texttt{on}/\texttt{off}, \texttt{true}/\texttt{false} esprimeranno invece dei
valori logici, mentre aggiungendo ad un numero uno dei suffissi \texttt{Hz},
\texttt{kHz}, \texttt{MHz}, ecc. si potranno specificare delle frequenze; il
resto verrà interpretato come stringa (l'elenco completo dei tipi di valori è
comunque riportato nella pagina di manuale). Inoltre usando il prefisso
\texttt{No} nello scrivere il nome di una opzione si specificherà per essa
direttamente un valore logico pari a \texttt{no}, \texttt{off} o
\texttt{false}.

Tratteremo qui solo le principali sezioni, indicando le principali direttive
previste per ciascuna di esse; al solito per l'elenco completo si può fare
riferimento alla pagina di manuale.  La prima che prendiamo in esame è la
sezione \texttt{Files}, che contiene la definizione di una serie di pathname
che riguardano i file e le directory utilizzate dal server. È in questa
sezione che si indica dove si trovano le risorse (ad esempio i font) necessari
per il funzionamento del server.  Le direttive possibili sono le seguenti:
\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{FontPath}] specifica una lista di directory, separate da
  virgole, in cui si trovano i font usati dal server. Si può usare la
  direttiva più volte, e le relative directory verranno unite insieme. La
  direttiva richiede o un pathname assoluto ad una directory, o
  l'identificatore di un \textit{font server},\footnote{il font server è un
    servizio fornito dal programma \texttt{xfs} che permette di mantenere i
    font su una singola macchina, e distribuirli via rete ad altre, in modo da
    diminuire lo spazio disco necessario all'installazione del server o
    consentire l'utilizzo di font ai cosiddetti \textit{dumb terminal} non
    dotati di disco; veniva utilizzato, prima del supporto diretto del
    rendering dei font \textit{TrueType}, per generare automaticamente da
    questi ultimi dei font compatibili con il server X allora in uso.}
  \index{demone!\texttt{xfs}} nella forma:
\begin{Verbatim}
         <trans>/<hostname>:<port-number>
\end{Verbatim}
  dove \texttt{trans} indica la modalità di connessione (e vale \texttt{unix}
  per i socket locali e \texttt{tcp} per un collegamento remoto), 
  \texttt{hostname} indica il nome della macchina cui si collega e
  \texttt{port} la porta. Un esempio tipico è:
\begin{Verbatim}
         FontPath        "unix/:7100"
\end{Verbatim}
  che indica il fontserver sulla macchina locale.
  
\item[\texttt{RgbPath}] indica il pathname del file contenente il database dei
  colori RGB, qualora non specificato viene utilizzato il valore di default
  che è \texttt{/usr/lib/X11/rgb}. A partire dalla versione 7.0 infatti non
  viene più utilizzata la gerarchia separata \texttt{X11R6} cui si è accennato
  in sez.~\ref{sec:file_FHS} e le versioni più recenti di \textit{X.org}
  inoltre installano il file in \texttt{/usr/share/X11/}.% ; in precedenza il
  % file era sotto \texttt{/usr/X11R6/lib/X11/rgb} (il nome del file è comunque
  % \texttt{rgb.txt}, con il \texttt{.txt} che viene sottinteso).

\item[\texttt{ModulePath}] indica il pathname delle directory in cui verranno
  cercati i moduli binari che forniscono le estensioni del server. Come per la
  direttiva \texttt{FontPath} si possono specificare più directory usando più
  istanze della direttiva. Qualora non sia specificato nulla viene usata di
  default la directory \texttt{/usr/lib/xorg/modules/}.
\end{basedescript}

La gestione dei font all'interno di \textit{X window} merita qualche dettaglio
in più, l'uso della direttiva \texttt{FontPath} da sola infatti non è
sufficiente, essa infatti serve ad indicare al server dove si sono installati
font, ma questa installazione deve essere stata effettuata in maniera
adeguata. In generale il tipo di font utilizzabile dipende dalla versione di
server utilizzata ma tutte le versioni di \textit{X.org} supportano l'uso
generico di font sia \textit{Type 1} che \textit{TrueType}. Il server però
oltre ai file che contengono i caratteri dei font ha necessità di conoscere
anche le informazioni relative al nome dei font stessi, alle loro dimensioni,
al tipo (normale, grassetto, corsivo, ecc.), così che questi possano poi
essere utilizzati e referenziati al suo interno.

Per questo una volta installati i file dei font devono essere costruite anche
tutte le informazioni necessarie al server. Un tempo questo doveva essere
fatto attraverso degli opportuni programmi di utilità: una volta installati i
file dei font in una directory, occorreva creare le informazioni di gestione
con programmi come \index{comando!\texttt{mkfontdir}} \texttt{mkfontdir} o
\index{comando!\texttt{ttmkfontdir}} \texttt{ttmkfontdir}.

Con \textit{X.org} tutto questo non è più necessario e le informazioni
relative ai font vengono gestite automaticamente tramite la libreria
\texttt{fontconfig}. Questa viene controllata da una serie di file in
\texttt{/etc/fonts}: la configurazione generale viene mantenuta nel file
\index{configurazione!\texttt{/etc/fonts/fonts.conf}}
\texttt{/etc/fonts/fonts.conf}, ma eventuali personalizzazioni devono essere
inserite in \index{configurazione!\texttt{/etc/fonts/local.conf}}
\texttt{/etc/fonts/local.conf} che viene mantenuto in caso di aggiornamento; i
singoli utenti possono inserire le proprie in
\index{configurazione!\texttt{.fonts.conf}} \texttt{\~/.fonts.conf}. Tutti
questi file sono in formato \index{XML} XML,\footnote{\textit{eXtendible
    Markup Language}, un linguaggio formale basato su marcatori.} e se ne può
trovare una descrizione dettagliata nella pagina di manuale, accessibile con
\texttt{man fonts.conf}.

La sezione \texttt{ServerFlags} permette di impostare alcune opzioni generali
relative al server, essa contiene solo direttive di tipo \texttt{Options} e
normalmente è vuota. La sezione \texttt{Module} è usata per specificare quali
moduli di estensione del server devono essere caricati. In genere prevede solo
la direttiva \texttt{Load} seguita dal nome del modulo; questo è lo stesso del
file corrispondente che si deve trovare all'interno del percorso indicato con
\texttt{ModulePath}, tolto il \texttt{lib} iniziale e l'estensione. L'unica
formulazione alternativa è usare una sintassi del tipo:
\begin{Verbatim}
    SubSection "extmod"
       Option  "omit XFree86-DGA"
    EndSubSection
\end{Verbatim}
dove il nome del modulo è lo stesso e la direttiva \texttt{Option} viene
utilizzata per passare dei parametri al modulo.

La sezione \texttt{InputDevice} serve a specificare le caratteristiche di un
singolo dispositivo di input, e normalmente se ne hanno almeno due, una per la
tastiera e l'altra per il mouse, ma se ne possono specificare anche di più, in
caso di presenza di più tastiere (caso non molto comune) o di più mouse (caso
comune invece con i portatili, cui in genere si usa un mouse USB da affiancare
al touchpad, o con l'uso di tavolette grafiche). Ogni sezione viene
specificata nel formato:
\begin{Verbatim}
    Section "InputDevice"
        Identifier "nome"
        Driver     "dispositivo"
        Option     "..."
        ...
    EndSection
\end{Verbatim}
dove devono sempre essere specificate sia la direttiva \texttt{Identifier},
che indica un nome con cui fare riferimento al dispositivo nelle altre
sezioni, che la direttiva \texttt{Driver}, che ne specifica il tipo.

In particolare \texttt{Driver} permette di indicare se il dispositivo in
questione viene usato per il puntamento (con il valore \texttt{mouse}) o per
l'immissione di dati (con il valore \texttt{keyboard}) facendo riferimento al
caso più comune di entrambe le tipologie.  Le restanti direttive sono tutte da
specificare nella forma di opzioni, le principali delle quali sono:
\begin{basedescript}{\desclabelwidth{2.9cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{CorePointer}] di valore booleano; se viene impostata indica che
  il relativo dispositivo viene considerato come il mouse principale.
\item[\texttt{CoreKeyboard}] di valore booleano; se viene impostata indica che
  il relativo dispositivo viene considerato come la tastiera principale.
\item[\texttt{Device}] indica il file di dispositivo da utilizzare per
  accedere al relativo dispositivo.
\item[\texttt{SendCoreEvents}] invia gli eventi relativi ad un altro
  dispositivo come se fossero generati dal dispositivo principale (lo si usa
  sui portatili per abbinare gli eventi di un eventuale mouse USB a quelli del
  touchpad).
\item[\texttt{XkbModel}] indica, nel caso di una tastiera, il modello (ad
  esempio \texttt{pc105} per una tastiera da PC a 105 tasti).
\item[\texttt{XkbLayout}] indica, nel caso di una tastiera, la disposizione
  dei tasti, e corrisponde in genere al nome della relativa localizzazione
  (con valori come \texttt{us}, \texttt{it}, \texttt{fr}, \texttt{de}, ecc.)
\item[\texttt{Protocol}] indica nel caso di un mouse, il protocollo utilizzato
  (i più comuni sono \texttt{PS/2} per i mouse ordinari e \texttt{ImPS/2} per
  quelli dotati di rotellina).
\end{basedescript}

La sezione \texttt{Device} serve a specificare le caratteristiche di una
scheda grafica, e ne deve esistere almeno una (ma se ne possono avere diverse
in caso di presenza di più schede grafiche). Il suo formato è identico a
quello visto in precedenza per \texttt{InputDevice}, e prevede le due
direttive obbligatorie \texttt{Identifier} e \texttt{Driver}, dove
quest'ultima indica il nome del modulo associato al driver che gestisce la
relativa scheda grafica.

Il resto della sezione prevede come nel caso precedente solo delle direttive
\texttt{Option}, buona parte delle quali sono specifiche del driver della
scheda grafica utilizzato e sono descritte nella relativa pagina di manuale,
cui si accede nella sezione 4 usando il nome del driver stesso. Alcune opzioni
generiche, valide per tutti i driver, sono tuttavia specificate direttamente
nella pagina di manuale del file di configurazione.

La sezione \texttt{Monitor} serve ad indicare le caratteristiche di un
monitor, e ne deve essere presente almeno una. Il formato generale della
sezione è del tipo:
\begin{Verbatim}
    Section "Monitor"
        Identifier "nome monitor"
        direttiva  valore
        ...
    EndSection
\end{Verbatim}
dove come nei casi precedenti \texttt{Identifier} specifica una stringa
identificativa del monitor (che può essere qualunque) ed è obbligatoria; le
restanti direttive servono a specificare le caratteristiche del monitor, le
principali sono:
\begin{basedescript}{\desclabelwidth{2.8cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{VendorName}] stringa che identifica la marca del monitor.
\item[\texttt{ModelName}] stringa che identifica il modello del monitor.
\item[\texttt{HorizSync}] indica la frequenza o l'intervallo di frequenze di
  sincronia orizzontale supportato dal monitor (la frequenza di sincronia
  orizzontale è la frequenza a cui il monitor può spostare il fascio che
  disegna una riga orizzontale).  Può essere indicato come singola lista di
  valori separati da virgole o come intervallo separato da un meno, e se non
  specificata con uno degli indicatori illustrati in precedenza è supposto
  essere espressa in kHz.
\item[\texttt{VertRefresh}] indica la frequenza o l'intervallo di frequenze di
  aggiornamento verticale supportato dal monitor (è la frequenza con cui può
  essere ridisegnato l'intero schermo). Come per \texttt{HorizSync} può essere
  indicato sia come singola lista di valori che come intervallo, espresso di
  default in Hz. Questo valore viene usato dal server X per determinare se una
  modalità video è compatibile con il monitor.
\item[\texttt{Mode}] è una direttiva speciale da scriversi su più linee
  (chiuse da una direttiva \texttt{EndMode}) che permette di specificare una
  \textsl{modalità video} (in sostanza l'insieme dei parametri che imposta la
  risoluzione dello schermo e la frequenza di aggiornamento dello stesso) cui
  viene dato il nome passato come argomento, mentre i valori da usare in
  termini di risoluzione e frequenze di aggiornamento vengono specificati
  nelle righe successive (per la sintassi si consulti la pagina di manuale).
\item[\texttt{Modeline}] è una forma alternativa della direttiva \texttt{Mode}
  che permette di scrivere gli stessi dati che definiscono una modalità video
  su di un'unica riga, per chi fosse interessato una buona guida con tutti i
  dettagli storici sul funzionamento ed il significato delle
  \textit{Modelines} è nel \textit{XFree86 Video Timings HOWTO}.  Come per la
  precedente \texttt{Mode} non viene usata se non quando si voglia definire
  una modalità personalizzata o quando, cosa che ormai non avviene
  praticamente mai, il riconoscimento automatico non ha successo.
\end{basedescript}

I valori per \texttt{HorizSync} e \texttt{VertRefresh} sono critici per l'uso
del monitor, in quanto sbagliandoli è possibile mandare fuori sincronia lo
stesso con il risultato di non vedere più nulla. I monitor recenti supportano
adeguati meccanismi per notificare alle applicazioni questi ed altri dati, ed
il server X provvede ad impostarli sempre in maniera automatica, per cui
questi, che una volta erano i parametri più critici da impostare, ed andavano
cercati fra le specifiche dei monitor o in una qualche oscura pagina del
libretto di istruzione, oggi non vengono più toccati.

%  Nelle versioni più recenti dei monitor viene implementato un meccanismo
% di notifica delle risoluzioni supportate chiamato DDC (\textit{Display Data
%   Channel}) il cui uso è supportato di default da Xorg a partire dalla
% versione 6.8, esiste altresì un meccanismo di notifica detto EDID che
% consente di richiedere le informazioni direttamente al monitor. 

% Grazie a questi meccanismi ormai non è più necessario dover cercare i valori
% di \texttt{HorizSync} e \texttt{VertRefresh} su una qualche oscura pagina del
% manuale del monitor (sempre che si siano scomodati a scriverceli) e impostare
% una modalità video manualmente, ma l'impostazione è del tutto
% automatica. Inoltre i dati di EDID possono essere letti tramite il programma
% \texttt{get-edid} il cui output può essere trasformato direttamente nella
% corretta sezione \texttt{Monitor} pronta per l'inclusione nel file di
% configurazione, mandandolo in \textit{pipe} al comando
% \texttt{parse-edid}.\footnote{nel caso di Debian per poter utilizzare questi
%   comandi occorrerà installare il pacchetto \texttt{read-edid}.}

Gli altri parametri critici sono i valori delle modalità video espressi con
\texttt{Mode} o \texttt{Modeline}, che se sbagliati di nuovo possono mandare
il monitor fuori sincronia.  Come accennato però queste direttive non sono più
utilizzate, in quanto i valori corretti delle modalità video vengono ricavati
automaticamente dalla scheda grafica che già dispone di tutti i modi standard
VESA, che vengono utilizzati in base alle informazioni ottenute dal monitor o
dalla risoluzione impostata dalla direttiva \texttt{Modes} nella sezione
\texttt{Screen}.

% Se però si dovesse effettuare una configurazione manuale può essere di aiuto
% il programma \index{comando!\texttt{xvidtune}} \texttt{xvidtune}. Questo è un
% programma ad interfaccia grafica che deve essere lanciato a server X avviato
% che rileva la modalità video in uso e ne mostra i parametri su una finestra,
% consentendo di modificarli.  Una delle funzionalità del programma è proprio
% quella che consente, una volta effettuate le modifiche ed aver verificato che
% funzionano, di stampare a video la riga da inserire come parametro della
% direttiva \texttt{Modeline}. 

% L'uso di valori sbagliati per una modalità video può mandare fuori sincronia
% il monitor, con la spiacevole conseguenza di non vedere più nulla,
% \texttt{xvidtune} comunque consente di provare le nuove impostazioni e riporta
% automaticamente il server alla configurazione di partenza dopo pochi secondi,
% consentendo un recupero anche in caso di errore. Dato che oggi questo tipo di
% impostazione è spesso gestita automaticamente a basso livello direttamente dal
% kernel, il programma non è più in grado di effettuare le modifiche ed il suo
% uso si limita a mostrare i valori correnti.

Una volta definite le schede video ed i monitor presenti, questi vanno
collegati fra loro oltre che con il cavo tramite una apposita sezione
\texttt{Screen} che identifica l'insieme dei due, e definisce le
caratteristiche dello ``\textsl{schermo}'' che verrà utilizzato dal server X.
Il formato generale di questa sezione è il seguente:
\begin{Verbatim}
    Section "Screen"
        Identifier "name"
        Device     "device id"
        Monitor    "monitor id"
        direttive
        ...
        SubSection "Display"
           voci
           ...
        EndSubSection
        ...
    EndSection
\end{Verbatim}
di nuovo la direttiva \texttt{Identifier} serve a fornire una stringa che
identifica lo schermo in questione, ed è obbligatoria come le due
\texttt{Device} e \texttt{Monitor} che servono a specificare la scheda video
ed il monitor collegati allo schermo, che prendono come argomento
l'identificatore utilizzato in una delle sezioni omonime. Viene spesso
utilizzata anche la direttiva \texttt{DefaultDepth} che indica la profondità
di colore (in numero di bit) da utilizzare di default per lo schermo quando si
hanno più sottosezioni di tipo \texttt{Display}.

È inoltre obbligatoria la presenza di almeno una sottosezione \texttt{Display}
che specifichi la profondità di colore (tramite la direttiva \texttt{Depth},
obbligatoriamente presente) e l'indicazione di una (o più) modalità video con
la direttiva \texttt{Modes}, che prende un elenco di nomi (separati da spazi)
fra quelli predefiniti nello standard VESA o indicati da una precedente
direttiva \texttt{Mode} o \texttt{Modeline} presente nella corrispondente
sezione \texttt{Monitor}. Uno schermo infatti può essere utilizzato a diverse
profondità di colore, diverse risoluzioni e diverse frequenze di aggiornamento
a seconda delle caratteristiche della scheda video e del monitor, e qualora
si specifichino più modi, è pure possibile passare al volo dall'uno all'altro
una volta avviato il server con la combinazione di tasti \texttt{C-M-+} e
\texttt{C-M-{}-}.

Infine la sezione \texttt{ServerLayout} serve ad ottenere una configurazione
completa collegando uno o più schermi (definiti in altrettante sezioni
\texttt{Screen}) con uno o più dispositivi di input (definiti in altrettante
sezioni \texttt{InputDevice}). Di nuovo ne deve essere presente almeno una,
nella forma generica:
\begin{Verbatim}
    Section "ServerLayout"
        Identifier   "nome"
        Screen       "screen id"
        ...
        InputDevice  "input device id"
        ...
        opzioni
        ...
    EndSection
\end{Verbatim}
di nuovo \texttt{Identifier} indica una stringa di identificazione, mentre
\texttt{Screen} e \texttt{InputDevice} servono a referenziare quali schermi e
dispositivi di input inserire nel layout, usando l'identificatore specificato
nelle omonime sezioni.


\subsection{L'avvio di una sessione di lavoro sotto X}
\label{sec:cfg_xserver_start}

Le modalità per attivare una sessione di lavoro usando l'interfaccia grafica
fornite da \textit{X Window} sono sostanzialmente due, quella che prevede
l'avvio del server X e di tutto l'ambiente grafico da \textit{console}, che
oggi però non viene praticamente mai usata, e quella che prevede il login
direttamente dall'ambiente grafico, che in questo caso viene attivato
direttamente nella procedura di avvio (tramite gli opportuni script) insieme
al programma di gestione del login.

Il programma per avviare una sessione grafica a partire dalla \textit{console}
è \index{comando!\texttt{xinit}} \texttt{xinit}, che si usa soltanto quando
non si può o non si vuole lanciare il server X nella fase di avvio del
sistema, o in ambienti in cui si abbia la necessità di utilizzare diverse
versioni del server X, ad esempio se, avendo più schede e più monitor, si
volesse usare XFree86 per una scheda e X.org per l'altra. Dato che, come
illustrato in sez.~\ref{sec:Xwindow_intro}, per l'uso dell'interfaccia grafica
occorre disporre sia del server X che degli opportuni programmi client che la
realizzano, \texttt{xinit} ha la particolare caratteristica di suddividere gli
argomenti che gli vengono passati in due sezioni, separate dalla sequenza
``\texttt{-{}-}''.

La prima sezione è quella che indica il programma da eseguire come client del
server X ed i rispettivi argomenti. Essa deve iniziare con il nome del
programma, che deve essere specificato con un pathname esplicito in forma
assoluta o relativa, deve cioè essere nella forma ``\texttt{/path/to/prog}'' o
``\texttt{./prog}'', altrimenti l'intera sezione sarà considerata come
costituita soltanto dagli argomenti da passare al programma usato di
default. In genere si usa come programma un opportuno script di avvio sessione
che lancia tutti i programmi necessari a realizzare la stessa.

La seconda sezione indica invece quale deve essere il programma da usare come
server X, e deve essere specificata in maniera analoga alla prima, vale a dire
che se non si usa al suo inizio un pathname esplicito la sezione viene
considerata come costituita esclusivamente dagli argomenti da passare al
server. In genere non la si usa quasi mai (per cui la sequenza
``\texttt{-{}-}'' viene omessa e si passa a \texttt{xinit} solo la prima
sezione) se non per specificare qualche argomento alternativo al server X. In
generale infatti non ci sono motivi per cambiare il default usato da
\texttt{xinit} che è l'esecuzione del server X con il comando ``\texttt{X
  :0}'', dove \texttt{:0} indica l'uso del primo \textit{display} disponibile
(torneremo sul concetto di \textit{display} in sez.~\ref{sec:X_client}).

Una volta invocato, \texttt{xinit} prima mette in esecuzione il server X e poi
esegue il programma client specificato nella prima sezione, che a questo punto
potrà lanciare la sessione grafica. Quando detto programma termina,
\texttt{xinit} si incarica di chiudere la sessione grafica terminando anche il
server X.  Si tenga presente che questo avviene anche se nel frattempo ci sono
altri programmi che usano X che sono ancora attivi, lanciati per esempio dal
client specificato nella prima sezione.

Se non si specifica nulla sulla riga di comando all'avvio della sessione
\texttt{xinit} cercherà nella home dell'utente il file
\index{configurazione!\texttt{.xinitrc}} \texttt{.xinitrc} e lo eseguirà come
se fosse uno script di shell, terminando la sessione (e fermando il server X)
solo alla conclusione dell'esecuzione del contenuto di \texttt{.xinitrc}.  Non
è necessario che il file sia eseguibile (né che inizi con \texttt{\#!/bin/sh})
se esiste viene lanciato come programma client, nella forma \texttt{sh \tild
  /.xinitrc}.
 
Questo consente di utilizzare \texttt{.xinitrc} per inizializzare il proprio
ambiente grafico, chiamando al suo interno tutti i programmi che si intendono
lanciare. In assenza di uno \texttt{.xinitrc} creato dell'utente,
\texttt{xinit} eseguirà il programma \index{comando!\texttt{xterm}}
\texttt{xterm}, un semplice emulatore di terminale che si limita a riprodurre
dentro una finestra un'interfaccia a terminale del tutto analoga a quella che
si trova sulla \textit{console}.

Se si utilizza questa funzionalità occorre però considerare che i programmi
eseguiti tramite \texttt{.xinitrc} vengono avviati in sequenza: se si vuole
che vengano eseguiti in maniera concorrente occorrerà lanciarli tutti in
background, altrimenti fino alla terminazione di uno di essi non partirà il
successivo. Questo per tutti tranne l'ultimo, altrimenti l'esecuzione di
\texttt{.xinitrc} proseguirebbe con la conclusione dello script, e la
conseguente terminazione della sessione. Per questo motivo in genere si lancia
sempre per ultimo un \textit{window manager} o un \textit{session manager}
(vedi sez.~\ref{sec:X_client}).

Normalmente \texttt{xinit} non viene mai eseguito direttamente, e per avviare
una sessione grafica da \textit{console} si usa invece
\index{comando!\texttt{startx}} \texttt{startx}. Quest'ultimo non è altro che
uno script di shell che esegue \texttt{xinit} fornendogli dei default
opportuni, integrandosi con le impostazioni scelte dalla propria distribuzione
in modo da utilizzare gli eventuali \textit{window manager} o \textit{session
  manager} che sono stati predisposti come default.

Il comando si esegue in genere senza argomenti, se presente utilizza anch'esso
il file \texttt{.xinitrc}, ma se questo è assente viene eseguita una
inizializzazione di default, identica per tutto il sistema, sulla base del
contenuto del file \index{configurazione!\texttt{/etc/X11/xinit/xinitrc}}
\texttt{/etc/X11/xinit/xinitrc}. Il risultato dipende da quello che è stato
impostato dalla vostra distribuzione come sessione grafica di default, ad
esempio nel caso di Debian detto file fa a sua volta riferimento a quanto
indicato in \texttt{/etc/X11/Xsession}.  Oltre al comportamento standard si
possono passare degli argomenti sulla riga di comando anche a \texttt{startx},
con lo stesso formato illustrato in precedenza per \texttt{xinit}, nel qual
caso si avrà anche lo stesso comportamento di quest'ultimo; ad esempio per
lanciare dalla \textit{console} una sessione in cui si usi soltanto un
terminale si potrà usare:
\begin{Example}
startx /usr/bin/xterm -title "Terminale di prova" -geometry 80x25
\end{Example}

Infine, essendo il server X un programma come gli altri, è sempre possibile
lanciarne più istanze in contemporanea. In tal caso è possibile distinguere a
quale istanza fare riferimento in base al cosiddetto numero di
\textit{display} (tratteremo i dettagli di questa caratteristica all'inizio di
sez.~\ref{sec:X_client}). All'avvio del server di norma viene utilizzato il
primo numero di \textit{display} disponibile, cioè zero.  Sia \texttt{xinit}
che \texttt{startx} consentono di lanciare ulteriori istanze del server X, ma
in tal caso occorre specificare un numero di display diverso, che andrà
passato come argomento aggiuntivo. In tal caso si tratta di specificare solo
questo come argomento aggiuntivo dopo la sequenza ``\texttt{-{}-}'', ed il
valore di \textit{display} indicato andrà a soprassedere quello di default.
Così se si vuole lanciare una seconda istanza del server X che utilizzi il
display 1 si dovrà eseguire il comando:
\begin{Example}
startx -- :1
\end{Example}

La seconda modalità di avvio del server X è quella eseguita attraverso
l'impiego di un \itindex{login~manager} \textit{login manager} grafico. In
genere perché questo avvenga dovrà essere stata opportunamente configurata la
procedura di avvio (vedi sez.~\ref{sec:struct_sysv_init}) per lanciare
automaticamente detto programma. Questo ormai viene fatto nelle installazioni
di default di praticamente tutte le distribuzioni, tranne il caso in cui si
sia fatta la scelta esplicita di non installare l'interfaccia grafica.

Un \itindex{login~manager} \textit{login manager} è semplicemente un programma
che lancia il server X e poi si incarica di mostrare all'utente il cosiddetto
\itindex{greeter} \textit{greeter}, una finestra di login (grafica) su cui
questo può autenticarsi per entrare nel sistema ed eseguire una
\textsl{sessione} di lavoro. In realtà il compito di un
\itindex{login~manager} \textit{login manager} è un po' più complesso, infatti
è possibile sfruttare la trasparenza sulla rete del protocollo X11 per
eseguire la stessa procedura di autenticazione e di avvio di una sessione di
lavoro in modalità remota, cosa che richiede il supporto di un apposito
protocollo, l'XDMCP (\textit{X Display Manager Control Protocol}).

Questa funzionalità consente di presentare anche su macchine remote, che a
questo punto assumeranno il compito di fare da semplici \textsl{terminali} per
la sessione, la stessa finestra di login.  In questo modo è possibile
centralizzare le applicazioni grafiche su un unico server su cui esse saranno
eseguite, e riutilizzare macchine dotate anche di scarse risorse hardware,
che non sarebbero in grado di sopportare il carico di tutta l'interfaccia
grafica, solo per il disegno delle finestre attraverso l'installazione del
solo server X.

Nella distribuzione classica di \textit{X Window}, quella distribuita con
l'implementazione di riferimento dell'X-server, il programma che implementa il
\textit{login manager} è \index{demone!\texttt{xdm}} \texttt{xdm}.  Il
programma ha una interfaccia molto spartana, ma è ampiamente configurabile in
quanto il suo comportamento viene governato da una serie di script di shell e
dall'impostazione delle opportune ``\textsl{risorse}'' (le
``\textsl{risorse}'' di \textit{X Window} sono trattate in
sez.~\ref{sec:X_client}); questo ne complica la configurazione in quanto i
vari aspetti del suo funzionamento sono controllati tramite molteplici file.

%%
%% ### OBSOLETE BEGIN ###
%% Materiale obsoleto per XDM
%%
\ifx\obsoletesection\undefined

\relax
\else

Il file di configurazione principale di \texttt{xdm} è
\index{configurazione!\texttt{/etc/X11/xdm/xdm-config}}
\texttt{/etc/X11/xdm/xdm-config}, ma si può usare un file diverso indicandolo
con l'opzione \texttt{-config}. In questo file vengono indicati i vari script
e gli ulteriori file che servono a controllare il programma. Il file usa il
formato delle risorse di \textit{X Window} (che tratteremo in
sez.~\ref{sec:X_client}), un estratto del suo contenuto, tratto dalla versione
installata su una Debian Etch, è il seguente:
\begin{FileExample}[label=/etc/X11/xdm/xdm-config]
DisplayManager.errorLogFile:    /var/log/xdm.log
DisplayManager.pidFile:         /var/run/xdm.pid
DisplayManager.keyFile:         /etc/X11/xdm/xdm-keys
DisplayManager.servers:         /etc/X11/xdm/Xservers
DisplayManager.accessFile:      /etc/X11/xdm/Xaccess
DisplayManager.authDir:         /var/lib/xdm
DisplayManager*resources:       /etc/X11/xdm/Xresources
DisplayManager.willing:         su nobody -c /etc/X11/xdm/Xwilling
...
\end{FileExample}

Le versioni di \texttt{xdm} usate su Linux onorano inoltre anche una serie di
opzioni che consentono di controllare alcune caratteristiche dell'avvio e
della terminazione del servizio, da indicare tramite l'ulteriore file
\index{configurazione!\texttt{/etc/X11/xdm/xdm.options}}
\texttt{/etc/X11/xdm/xdm.options}, anche se tecnicamente questo file, più che
dal programma \texttt{xdm} in quanto tale, viene utilizzato dai vari script ad
esso associati nella pacchettizzazione, con cui se ne controllano avvio e
terminazione. 

Questo file ha un formato molto semplice, in cui viene specificata una opzione
per riga (al solito le righe vuote e quelle che iniziano per ``\texttt{\#}''
vengono ignorate). I valori possibili sono riportati nella pagina di manuale
(accessibile con \texttt{man xdm.options}), e possono essere specificati o
direttamente, se si vuole abilitare l'opzione, o con il prefisso
``\texttt{no-}'' se la si vuole disabilitare, un esempio del contenuto di
questo file (ripreso da una Debian Etch) è il seguente:
\begin{FileExample}[label=/etc/X11/xdm/xdm.options]
no-ignore-nologin
no-restart-on-upgrade
no-start-on-install
use-sessreg
\end{FileExample}

Oltre a questi due file, la configurazione di \texttt{xdm} utilizza anche gli
ulteriori file indicati da \texttt{xdm-config}. Nel seguito vi faremo
riferimento così come sono specificati nell'esempio riportato in precedenza,
in cui sono posti tutti sotto \texttt{/etc/X11/xdm/}. Questi possono essere
cambiati sia intervenendo sul contenuto di \texttt{xdm-config} che indicandoli
direttamente tramite le corrispondenti opzioni a riga di comando
nell'invocazione di \texttt{xdm} (per i dettagli si consulti la pagina di
manuale con \texttt{man xdm}).

Come tutti i \itindex{login~manager} \textit{Display Manager} \texttt{xdm}
prevede le modalità di funzionamento locale e remoto. Nel primo caso vengono
utilizzate le istanze del server X specificate nel file \texttt{Xservers},
dove una per riga vengono indicate le istanze da far partire e le relative
opzioni.  Un esempio del contenuto di questo file (al solito preso da una
Debian Etch) è il seguente:
\begin{FileExample}[label=Xservers]
:0 local /usr/bin/X :0 vt7 -dpi 100 -nolisten tcp
\end{FileExample}
in questo caso si è richiesto ad \texttt{xdm} di lanciare una istanza locale
del server X (referenziato dal relativo pathname) sul display \texttt{0}, da
associare alla settima \textit{console} virtuale, utilizzando le opzioni
specificate di seguito.

Una delle caratteristiche dell'esecuzione della interfaccia grafica infatti è
che ogni sessione di X può essere associata ad una \textit{console} virtuale,
e ci si può portare su una diversa \textit{console} virtuale (abbandonando la
sessione grafica corrente) con la combinazione di tasti \texttt{C-M-FN} (con
``\texttt{N}'' corrispondente alla relativa \textit{console}). Come vedremo in
sez.~\ref{sec:struct_sysv_init} la gran parte delle distribuzioni associa le
prime sei console virtuali al programma \texttt{getty} che fornisce l'accesso
al sistema in modalità testuale. Con l'indicazione \texttt{vt7} dell'esempio
precedente si indica di associare alla settima \textit{console} virtuale il
passaggio alla sessione grafica stessa.  Qualora si creino più istanze di X si
potranno associare ad altre \textit{console} virtuali, così da passare
dall'una all'altra con analoghe combinazioni di tasti.

La modalità di funzionamento remoto viene invece controllata dal file
\texttt{Xaccess}, dove si possono specificare sia l'elenco dei server per i
quali fornire una sessione remota, sia le modalità in cui lo stesso
\texttt{xdm} si pone in ascolto per consentire ad altri una sessione remota
usando il server locale. Il formato del file è descritto in dettaglio nella
sezione ``\textit{XDMCP ACCESS CONTROL}'' della pagina di manuale di
\texttt{xdm}.

Le risorse che controllano le varie componenti di \texttt{xdm} sono invece
impostate dal contenuto del file \texttt{Xresources}; è qui che si possono
impostare le proprietà della finestra di login (associate alla risorsa
\texttt{xlogin}), quelle del programma di selezione delle sessioni remote
(associate alla risorsa \texttt{Chooser}) e delle altre componenti che
eventualmente si sono eseguite (come la \textit{console} di X, il cursore,
ecc.). Per una descrizione dettagliata si faccia riferimento al solito alla
pagina di manuale.

Inoltre è possibile utilizzare lo script \texttt{Xsetup} (le versioni meno
recenti usavano \texttt{Xsetup\_0}) per eseguire operazioni di impostazione
preliminare prima che venga mostrata la finestra di login; in questo modo si
può ad esempio modificare l'apparenza dello schermo, impostare colori o
lanciare altri programmi da far comparire insieme alla finestra di login, come
un orologio o il programma per visualizzare i messaggi della \textit{console}.

Una volta terminata con successo la procedura di autenticazione di un
utente,\footnote{in tutte le distribuzioni moderne \texttt{xdm} supporta
  pienamente PAM (vedi sez.~\ref{sec:cfg_user_PAM}), e non sono previste
  particolari configurazioni da eseguire al riguardo.} \texttt{xdm} esegue lo
script \texttt{Xstartup} per inizializzare la sessione, e se questo ha
successo il successivo \texttt{Xsession}, che tipicamente usa il file
\index{configurazione!\texttt{.xsession}} \texttt{.xsession} nella home
directory dell'utente come analogo di \texttt{.xinit} per lanciare la
\textsl{sessione} grafica dell'utente; se questo non esiste viene lanciata una
sessione di default utilizzando
\index{configurazione!\texttt{/etc/X11/Xsession}} \texttt{/etc/X11/Xsession}.

I file \texttt{.xinit} e \texttt{.xsession} hanno lo stesso scopo e
significato, tanto che in Debian la configurazione di default fa sì che sia
usato quest'ultimo anche quando si lancia l'ambiente grafico da
\textit{console} con \texttt{startx}; entrambi contengono cioè i programmi da
lanciare per gestire la sessione grafica. Come nel caso di \texttt{startx}
quando il programma che gestisce la sessione termina, \texttt{xdm} esegue un
reset dell'X-server con lo script \texttt{Xreset} e ripresenta la schermata di
login iniziale.

%%
%% ### OBSOLETE END ###
%% Materiale obsoleto xdm
%%
\fi

Benché \texttt{xdm}, per il suo legame diretto con il sistema di \textit{X
  Window}, sia disponibile in maniera praticamente universale, resta alquanto
primitivo per cui la gran parte delle distribuzioni GNU/Linux recenti hanno
adottato dei \textit{login manager} alternativi. Due dei più diffusi sono GDM
(lo \textit{Gnome Display Manager}) che fa parte del desktop Gnome e KDM (il
\textit{KDE Display Manager}) che fa parte del desktop KDE. Entrambi offrono
una grafica molto più accattivante di \texttt{xdm} ed un sistema di
configurazione molto più avanzato (e semplice da usare).

Infatti benché entrambi non necessitino della presenza dei rispettivi ambienti
desktop e possano essere usati indipendentemente, vengono solitamente
installati in corrispondenza a questi. Il grande vantaggio di entrambi è che,
pur essendo controllati da un file di configurazione testuale, è possibile
controllarli e modificarne alcune impostazioni con un apposito programma ad
interfaccia grafica, che permette di attivare e controllare le loro
funzionalità senza dover modificare a mano i file di configurazione.

Nel caso di GDM a partire dalla versione 2.22 il programma è stato riscritto e
suddiviso in due parti, il demone \index{demone!\texttt{gdm}} \texttt{gdm}
vero e proprio che lancia il server X ed esegue le operazioni di accesso e di
creazione della sessione di lavoro ed il \textit{greeter}, che è
l'applicazione grafica che visualizza la finestra di accesso (ed i relativi
accessori) ed il cui compito è sostanzialmente quello di autenticare l'utente
prima dell'accesso e che viene configurata a parte con il sistema di
\textit{gconf} di Gnome.\footnote{vale a dire con una specie di riedizione del
  ``registro'' di Windows, che per quanto sia stata realizzata in maniera più
  sana, facendo ricorso a file di testo in XML, rende comunque quasi
  obbligatorio il ricorso ad un apposito programma (ad esempio
  \texttt{gconf-editor}) per modificare le chiavi di configurazione onde
  evitare di perdersi in una marea di tag.}

Il file di configurazione principale di GDM è
\index{configurazione!\texttt{/etc/gdm/gdm.conf}} \texttt{/etc/gdm/gdm.conf};
il file ha il formato in stile dei \textit{keyfile}, che abbiamo brevemente
illustrato in sez.~\ref{sec:cfg_general}. Il file prevede una serie di
sezioni, le principali delle quali sono elencate in
tab.~\ref{tab:gdm_gdm.conf}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Nome} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{[daemon]}  & contiene le direttive di controllo generali del
                         demone \texttt{gdm}, come i nomi di file directory e
                         comandi utilizzati, utente e gruppo per conto del
                         quale eseguire i programmi come il \textit{greeter},
                         ecc. In genere è vuota mantenendo tutti i valori ai
                         rispettivi default.\\ 
    \texttt{[security]}& contiene le opzioni per la gestione della sicurezza,
                         a volte vi si imposta \texttt{AllowRoot=true} per 
                         consentire all'amministratore di eseguire il login
                         grafico, ma si tratta di una scelta da evitare nella
                         maniera più assoluta, visto che sono
                         disponibili numerose alternative per lanciare
                         programmi ad interfaccia grafica con privilegi di
                         amministratore senza dover far girare un intero
                         ambiente desktop, non pensato a questo scopo, per
                         conto dello stesso.\\
    \texttt{[xdmcp]}   & contiene la direttive per gestire il login grafico da
                         remoto con il protocollo \textit{XDMCP}, se lo si
                         vuole abilitare occorre impostare la direttiva
                         \texttt{enable=true}, le altre direttive non vengono
                         in genere usate essendo ragionevoli i valori di
                         default.\\
    \hline
  \end{tabular}
  \caption{Nomi delle principali sezioni di \texttt{gdm.conf}.} 
  \label{tab:gdm_gdm.conf}
\end{table}

Insieme a \texttt{gdm.conf} il programma utilizza anche una serie di altri
file e directory (riportati in tab.~\ref{tab:gdm_config_files}) posti sempre
in \texttt{/etc/gdm}, che consentono una personalizzazione molto dettagliata
di tutta la procedura di accesso, è comunque possibile avviare il demone
richiedendo con le opportune opzioni a riga di comando l'uso un altro file di
configurazione o di una directory diversa da \texttt{/etc/gdm}. Le directory
elencate nella prima parte di tab.~\ref{tab:gdm_config_files} consentono di
far eseguire a \texttt{gdm} uno specifico script per ciascuna delle varie fasi
di gestione della sessione, secondo quanto illustrato nella tabella stessa. Si
tenga presente che gli script in questione, anche quelli relativi alla
sessione, vengono eseguiti con privilegi amministrativi e non per conto
dell'utente, il cui nome viene passato nella variabile di ambiente
\texttt{USER}.

Tutti gli script presenti in queste directory seguono uno stesso schema di
nomi, che consente di eseguire script diversi a seconda del \textit{display}
su cui è stato lanciato il server X. Infatti se \texttt{gdm} trova uno script
corrispondente al numero di \textit{display} questo verrà eseguito nel
relativo punto della sequenza, altrimenti verrà eseguito, se presente, lo
script \texttt{Default}. Un caso particolare resta il contenuto della
directory \texttt{Init}, che viene utilizzato anche per effettuare login
remoti con XDMCP, attivati dalla presenza dello script \texttt{Init/XDMCP}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Nome} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{Init/}         & contiene gli script da eseguire immediatamente
                             dopo l'avvio del server X e prima del lancio del
                             \textit{greeter}, in genere vengono usati per
                             lanciare programmi che si vogliono eseguire
                             durante la schermata di accesso o per effettuare
                             eventuali inizializzazioni prima della
                             stessa.\\  
    \texttt{PostLogin/}    & contiene gli script da eseguire immediatamente
                             dopo l'autenticazione dell'utente, prima che
                             venga eseguita qualunque operazione di
                             inizializzazione della sessione, usati ad
                             esempio per impostare proprietà della stessa, come
                             la home dell'utente.\\ 
    \texttt{PreSession/}   & contiene gli script da eseguire immediatamente
                             prima dell'avvio della sessione finale, in genere
                             per mantenere informazioni di contabilità .\\
    \texttt{PostSession/}  & contiene gli script da eseguire alla chiusura di 
                             una sessione di lavoro.\\ 
    \hline
    \texttt{modules/}      & contiene le configurazioni usate dai moduli che
                             forniscono il supporto per le funzionalità di
                             accessibilità (vedi
                             sez.~\ref{sec:accessibility}).\\   
    \texttt{locale.alias}  & file contenente la lista delle localizzazioni
                             disponibili (vedi sez.~\ref{sec:localization}).\\ 
    \texttt{Xsession}      & indica lo script utilizzato per avviare la
                             sessione, che viene eseguito dopo gli script
                             della directory \texttt{PreSession/} per conto
                             dell'utente.\\  
    \texttt{XKeepsCrashing}& indica lo script eseguito quando l'avvio del
                             server X fallisce, viene in genere usato per
                             invocare il programma di configurazione del
                             server X.\\
    \hline
  \end{tabular}
  \caption{I file in \texttt{/etc/gdm} che controllano \texttt{gdm}.}
  \label{tab:gdm_config_files}
\end{table}

Come avvenuto per Gnome anche l'ambiente grafico KDE ha sviluppato un suo
\textit{Display Manager}, \index{demone!\texttt{kdm}} \texttt{kdm}, che
fornisce funzionalità simili. In questo caso la configurazione viene mantenuta
nella sottodirectory \texttt{kdm} delle configurazioni di KDE, vale a dire, a
seconda della versione di KDE usata, \texttt{/etc/kde3/kdm} o
\texttt{/etc/kde4/kdm}.  Il file di configurazione principale è
\index{configurazione!\texttt{/etc/kde4/kdm/kdmrc}} \texttt{kdmrc}, che di
nuovo usa il formato dei \textit{keyfile} descritto in
sez.~\ref{sec:cfg_general}.

Oltre alle direttive delle tre sezioni generali, riportate in
tab.~\ref{tab:kdm_kdmrc}, \texttt{kdmrc} può contenere configurazioni
specifiche da eseguire per ciascuna istanza del server X che viene lanciata
(associate al relativo \textit{display}) da mettere in altrettante sezioni
dedicate nella forma \texttt{[X-*-Core]} e \texttt{[X-*-Greeter]}, dove al
posto dell'asterisco deve essere indicato il nome del \textit{display} (come
indicato in sez.~\ref{sec:X_client}) e della classe di risorse da configurare.
Per una trattazione completa della sintassi di questo file si rimanda alla
lettura della documentazione ufficiale consultabile su
\url{http://docs.kde.org/stable/en/kde-workspace/kdm/index.html}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Nome} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{[General]} & contiene le direttive di controllo generali del
                         demone \texttt{kdm}.\\ 
    \texttt{[Xdmcp]}   & contiene le direttive di controllo per fornire il
                         login grafico da remoto con il protocollo
                         \textit{XDMCP}.\\  
    \texttt{[Shutdown]}& contiene le direttive relative ai programmi da usare
                         per gestire il riavvio ed il fermo macchina da
                         \texttt{kdm}.\\ 
    \hline
  \end{tabular}
  \caption{Nomi delle principali sezioni di \texttt{kdmrc}.} 
  \label{tab:kdm_kdmrc}
\end{table}

Oltre al file \texttt{kdmrc} nella directory di configurazione vengono
mantenuti una serie di altri file: ad esempio per lanciare il demone viene
usato dallo script di avvio il file \texttt{kdm.option}, con lo stesso
significato e formato dell'analogo di XDM. Inoltre nella stessa directory
vengono mantenuti gli script \texttt{Xsetup}, \texttt{Xstartup},
\texttt{Xsession}, ecc. anch'essi con lo stesso significato degli analoghi di
XDM. In particolare \texttt{Xsetup} viene lanciato dopo l'avvio del server X
prima di far partire il \textit{greeter} per operare sulla finestra di
accesso, \texttt{Xstartup} quando l'utente si è autenticato prima lanciare la
sessione per predisporre la sessione, mentre \texttt{Xsession} viene usato per
avviare la sessione.

Ai due precedenti si affianca, adottato da Ubuntu che è la distribuzione
desktop più diffusa, \index{demone!\texttt{lightdm}} \texttt{lightdm}, un
altro \textit{display manager} nato per essere completamente svincolato
rispetto all'ambiente grafico sottostante, la cui interfaccia viene disegnata
a partire da del semplice codice HTML. Il vantaggio è il non dipendere da
nessun toolkit grafico specifico ed avere quindi una base di codice nettamente
più ridotta, pur fornendo le stesse funzionalità di GDM, mentre il
\textit{greeter} può essere realizzato con qualunque ambiente grafico,
rendendo possibile installare solo le librerie grafiche di quell'ambiente.

Il programma viene controllato dal file di configurazione
\index{configurazione!\texttt{/etc/lightdm/lightdm.conf}}
\texttt{/etc/lightdm/lightdm.conf}, che di nuovo segue il formato dei
\textit{keyfile} descritto in sez.~\ref{sec:cfg_general}. A questo si
aggiungono, se presenti, eventuali file
\texttt{/etc/lightdm/lightdm.conf.d/*.conf} in modo da consentire ad altri
pacchetti software l'installazione di configurazioni specifiche senza toccare
la configurazione principale; si tenga comunque presente che
\texttt{lightdm.conf} ha la precedenza su questi ultimi.

Il file prevede 4 sezioni principali, riportate in
tab.~\ref{tab:lightdm.conf}, in genere le ultime due sono, per una
installazione normale di una stazione di lavoro personale, vuote, ma
consentono di attivare le sessioni grafiche remote o tramite il protocollo
XDMCP citato precedentemente, o tramite il protocollo VNC. 

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Nome} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{[LightDM]}     & configurazioni generali di \texttt{lightdm}.\\ 
    \texttt{[SeatDefaults]}& configurazioni relative alla sessione di lavoro
                             per la \textsl{postazione} generica.\\ 
    \texttt{[XDMCPServer]} & configurazioni per fornire una sessione di lavoro
                             remota con il protocollo XDMCP.\\ 
    \texttt{[VNCServer]}   & configurazioni per fornire una sessione di lavoro
                             remota con il protocollo VNC.\\ 
    \texttt{[Seat:\textsl{N}]}& configurazioni specifiche alla sessione di
                                lavoro lanciata sull'\texttt{\textsl{N}}-sima
                                \textsl{postazione}.\\  
    \hline
  \end{tabular}
  \caption{Nomi delle principali sezioni di \texttt{lightdm.conf}.} 
  \label{tab:lightdm.conf}
\end{table}

La prima sezione, \texttt{LightDM}, contiene le direttive di configurazione
generali del programma: ad esempio con \texttt{greeter-user} si imposta
l'utente per conto del quale verrà eseguito il \textit{greeter} (il default è
\texttt{lightdm}). In genere non viene utilizzata non essendovi necessità di
cambiare i valori di default. La sezione più importante è
\texttt{SeatDefaults} che imposta le caratteristiche di una \textsl{postazione
  di lavoro} (il cosiddetto \textit{seat}) generica, mentre si possono
indicare impostazioni specifiche per le singole postazioni (corrispondenti ad
altrettanti \textit{display} di X) con altrettante sezioni nella forma
\texttt{Seat:\textsl{N}}.


\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Nome} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{greeter-session} & indica il programma da lanciare come
                               \textit{greeter} (ad esempio 
                               \texttt{unity-greeter}, o
                               \texttt{lightdm-gtk-greeter}).\\ 
    \texttt{user-session}    & indica quale sessione grafica far partire fra
                               quelle eventualmente disponibili.\\
    \texttt{allow-guest}     & consente di creare una sessione di lavoro per
                               un ospite, senza autenticazione.\\
    \texttt{greeter-show-manual-login}& indica se il \textit{greeter} deve
                                     offrire un manuale di ausilio per le
                                     opzioni di login.\\ 
    \texttt{greeter-hide-users}& indica al \textit{greeter} di non
                               mostrare l'elenco degli utenti.\\  
%    \texttt{guest-session}   & .\\ 
    \texttt{display-setup-script}  & script eseguito all'avvio del server X.\\
    \texttt{greeter-setup-script}  & script eseguito all'avvio del
                                     \textit{greeter}.\\ 
    \texttt{session-setup-script}  & script eseguito al lancio della sessione.\\
    \texttt{display-cleanup-script}& script eseguito alla chiusura del server
                                     X.\\ 
    \texttt{greeter-cleanup-script}& script eseguito all'uscita dal
                                     \textit{greeter}.\\ 
    \texttt{session-cleanup-script}& script eseguito all'uscita dalla
                                     sessione.\\ 
    \hline
  \end{tabular}
  \caption{Principali direttive della sezione \texttt{[SeatDefaults]} di \texttt{lightdm.conf}.} 
  \label{tab:lightdm_seatdefaults}
\end{table}

É nella sezione \texttt{SeatDefaults} che si imposta quale programma
lanciare come \textit{greeter} (con la direttiva \texttt{greeter-session}),
cosa usare come sessione grafica di default per gli utenti (con la direttiva
\texttt{user-session}), e gli eventuali script da lanciare nelle varie fasi di
accesso al sistema (con le direttive \texttt{*-setup-script}) o di uscita
dallo stesso (con le direttive \texttt{*-cleanup-script}). Si sono riportate
in tab.~\ref{tab:lightdm_seatdefaults} le principali direttive disponibili per
questa sezione.




\subsection{L'uso di X Window dal lato client}
\label{sec:X_client}

Come accennato in sez.~\ref{sec:Xwindow_intro} qualunque programma che usi
l'interfaccia grafica tramite le \textit{Xlib} lo fa agendo come client per un
server X che poi si incaricherà di disegnare sullo schermo da lui gestito gli
elementi grafici indicati dall'applicazione. Per il client si pone allora il
problema di come sapere a quale istanza del server X deve fare riferimento.

Per risolvere questo problema ogni server X è identificato tramite quello che
viene chiamato il suo ``\textit{display name}''.  Considerando che il
protocollo X11 è nato per essere usato anche via rete, il server X a cui il
client deve rivolgersi potrebbe anche essere remoto; per questo motivo il
\textit{display name} viene espresso nella sua forma più generica con un
identificativo del tipo:
\begin{Console}
nomehost:\textsl{Nd}.\textsl{Ns}
\end{Console}
dove \texttt{nomehost} è il nome della eventuale macchina remota, che può
essere espresso sia con un indirizzo IP che con un nome a
dominio,\footnote{tratteremo in dettaglio questi argomenti, qui dati per
  scontati, in sez.~\ref{cha:networks_base}.}  mentre ``\texttt{\textsl{Nd}}''
è un numero intero, detto \textit{display number}, che corrisponde all'istanza
del server lanciata (quello da passare nell'esempio di avvio del server X, che
abbiamo illustrato in sez.~\ref{sec:cfg_xserver_start}). Dato che il server X
supporta anche la possibilità di utilizzare in contemporanea più schermi
(facendo riferimento alla stessa tastiera e allo stesso mouse), si può anche
scegliere uno schermo specifico con il numero ``\texttt{\textsl{Ns}}'', detto
\textit{screen number}.

Sia \texttt{\textsl{Nd}} che \texttt{\textsl{Ns}} sono numeri che, salvo
indicazioni contrarie, vengono allocati dinamicamente per grandezza crescente
a partire da zero. Se non si specifica il numero di schermo si suppone che ce
ne sia uno solo. Se invece non si specifica il nome della macchina si intende
dire che il server X è attivo in locale, e verrà utilizzata la modalità più
efficiente per comunicare con lui che passa attraverso l'uso di un socket
locale (in genere è \texttt{/tmp/.X11-unix/X\textsl{N}}, dove
``\texttt{\textsl{N}}'' corrisponde al numero di \textit{display}).

Il valore del \textit{display name} viene mantenuto nella forma appena
illustrata (senza l'indicazione dell'\textit{hostname}, se si lavora in
locale) in una apposita variabile di ambiente,
\index{variabili!di~ambiente!\texttt{DISPLAY}} \texttt{DISPLAY}, che è quella
che viene usata dalle \textit{Xlib} per identificare il server X con cui
l'applicazione deve parlare.  Molte applicazioni accettano una opzione
\texttt{-display} sulla riga di comando con cui si può specificare un
\textit{display name} alternativo, altrimenti viene usato il valore della
variabile di ambiente \texttt{DISPLAY}.  Quando si avvia una sessione grafica
locale è cura della procedura di inizializzazione della sessione definire in
maniera automatica questa variabile, in modo da renderla disponibile per tutti
i programmi che si utilizzeranno al suo interno; se non viene impostata
qualunque client fallirà con errore del tipo: ``\textit{Can't open display}''.

Finora abbiamo parlato della capacità del protocollo di poter essere
utilizzato via rete, ma nella configurazione di default di un server X questa
capacità viene usualmente disabilitata. Il protocollo X11 infatti di base
supporta un meccanismo di sicurezza piuttosto debole, con una autenticazione
del client basata sull'uso di un cookie di sessione, che ciascun client deve
presentare al server per poter avere accesso. I client lo ottengono
utilizzando il contenuto del file indicato dalla variabile di ambiente
\index{variabili!di~ambiente!\texttt{XAUTHORITY}} \texttt{XAUTHORITY}.  Nel
caso di una sessione locale il cookie di sessione viene mantenuto di solito
nel file \texttt{.Xauthority} nella home dell'utente che ha messo in
esecuzione il server X. Il cookie, questo file, e la variabile
\texttt{XAUTHORITY}, vengono creati al momento dell'avvio della sessione
grafica.

Il problema è che una volta che si è ottenuto l'accesso al server non esistono
meccanismi di limitazione o controllo, e si può compiere su di esso qualunque
operazione; questo significa ad esempio che si può creare una finestra
trasparente che copre tutto lo schermo e farle intercettare tutti i dati in
ingresso (comprese eventuali password immesse su una emulazione di terminale).
Fintanto che l'accesso è locale questo non costituisce un problema, in quanto
il file \texttt{.Xauthority} non è accessibile dagli altri utenti, ma se si
abilita la comunicazione via rete questo, essendo trasmesso in chiaro, può
essere facilmente intercettato e riutilizzato da terzi per garantirsi un
accesso completo al server X.  Anche se in teoria c'è la possibilità di
utilizzare meccanismi più complessi, come cookie cifrati con chiavi DES
condivise o appoggiarsi a \textit{Kerberos} (per i dettagli si consulti la
pagina di manuale accessibile con \texttt{man Xsecurity}), ma questo complica
notevolmente la configurazione e perciò normalmente non viene usato.

Per questo motivo il default adottato quasi universalmente è quello di
utilizzare il server X soltanto in locale, a meno di non operare su reti
chiuse e molto controllate (ad esempio quelle di un aula). Questo significa
che su molte distribuzioni il server X viene lanciato con l'opzione
\texttt{-nolisten tcp} (su Debian questa impostazione è usata in
\texttt{/etc/X11/xinit/xserverrc}), opzione che deve essere rimossa se si
vuole poter utilizzare il server via rete. Una volta messo in esecuzione il
server in ascolto sulla rete, occorre poi consentire l'accesso al server X da
parte dei client.\footnote{il protocollo X11 utilizza per la comunicazione via
  rete le porte TCP (porte e protocolli di rete sono trattati in
  sez.~\ref{sec:net_tcp_ip}) a partire dalla 6000, ne viene utilizzata una per
  ciascun display attivo, il cui valore si ottiene sommando a 6000 il numero
  di display.}

Un client infatti per poter parlare con il server deve presentare il cookie di
sessione, ma questo è presente solo sulla macchina su cui si è avviato il
server, è pertanto necessario fornire questa informazione ai client sulla
macchina remota da cui si collega, dato che i client usano di default il file
indicato da \texttt{XAUTHORITY}, che essendo su un macchina diversa non potrà
indicare un cookie di sessione valido.

Per modificare le modalità con cui il server autorizza i client all'accesso
esiste un apposito programma, \index{comando!\texttt{xauth}} \texttt{xauth},
che permette, eseguendolo sul server, di estrarre il cookie della sessione
locale, e di reimportarlo, eseguendolo sul client, in quella remota (per i
dettagli sul comando ed un esempio di come usarlo si consulti la rispettiva
pagina di manuale).  Dato che anche con questo procedimento si ha comunque il
trasferimento dei dati via rete in chiaro, pertanto senza ottenere un livello
di sicurezza significativo, in genere si preferisce utilizzare un meccanismo
di accesso ancora più elementare, ma più semplice da usare, che si basa sul
consentire l'accesso al server solo in base alla provenienza delle connessioni
da una determinata macchina.

Anche in questo caso l'accesso deve essere abilitato in maniera esplicita; per
questo viene utilizzato l'apposito comando \index{comando!\texttt{xhost}}
\texttt{xhost}, che indica al server X quali sono le macchine da cui accettare
connessioni via rete senza richiedere nessun cookie di sessione.  Il comando
prende come argomento il nome (o l'indirizzo di rete) della macchina a cui si
vuole consentire l'accesso, preceduto opzionalmente dal carattere
``\texttt{+}'' per indicare che esso sarà aggiunto alla lista delle macchine
consentite, mentre se vi si appone il carattere ``\texttt{-}'' il nome verrà
tolto dalla lista. Si può consentire l'accesso o rimuoverlo in maniera
generica utilizzando i suddetti caratteri senza farli seguire da nessun nome,
in sostanza con \texttt{xhost +} chiunque potrà inviare finestre sulla nostra
macchina. Se infine si esegue il comando senza specificare nulla verrà
stampata la lista delle macchine autorizzate.

Dato che alla fine, anche a causa della notevole quantità di banda richiesta,
l'uso del protocollo X11 in remoto avviene quasi esclusivamente su reti
locali, l'operazione che tradizionalmente si effettua per ottenere l'invio
delle finestre da una macchina remota alla propria è quella in cui prima si
definisce sulla macchina remota su cui gira il client un opportuno valore per
la variabile \texttt{DISPLAY} che indichi la propria macchina come
destinazione (ad esempio con qualcosa del tipo \texttt{DISPLAY=serverhost:0})
mentre su quest'ultima si dovrà consentire l'accesso da parte dei client sulla
macchina remota, eseguendo un comando del tipo \texttt{xhost
  +clienthost}. Vedremo in sez.~\ref{sec:ssh_forwarding} come sia possibile
usare questa funzionalità in maniera sicura con \texttt{ssh}, senza la
necessità di nessuna di queste operazioni.

Un'altra funzionalità di \textit{X Window} è quella di fornire un meccanismo
generico per impostare le preferenze relative all'ambiente grafico di ciascuna
applicazione, tramite quelle che vengono chiamate \textsl{risorse}. Il
vantaggio di questa funzionalità sta nel fatto che i valori di queste
\textsl{risorse} vengono mantenuti sul server, in un database interno,
evitando così di doverle specificare separatamente per ciascun client. È
possibile inoltre, quando si vogliono personalizzare le preferenze relative
alle singole applicazioni grafiche, caricare direttamente sul server valori
diversi, senza dover con questo andare a modificare le impostazioni sui
client.

Il valore di una risorsa è sempre specificato tramite una stringa; le risorse
poi possono a loro volta contenere altre risorse, il che comporta una
organizzazione strutturata su una gerarchia ad albero in cui ogni nodo è
identificato dal nome della risorsa, i singoli nodi sono separati dal
carattere ``\texttt{.}''  e che ha come radice il nome del programma a cui la
risorsa fa riferimento spesso scritto con la prima lettera
maiuscola.\footnote{le \textsl{risorse} si chiamano così in quanto
  corrispondono effettivamente a delle strutture dati che a loro volta possono
  contenere altre strutture dati, i campi di una di queste strutture
  identificano cioè un possibile valore o una ulteriore risorsa; ciascun
  programma definisce quali strutture vuole utilizzare per il controllo del
  suo aspetto grafico (il colore delle finestre, dello sfondo, il titolo della
  finestra, ecc.); il valore viene associato ad un campo della risorsa stessa
  con un certo nome, per cui viene naturale accedere all'insieme di strutture
  e sottostrutture attraverso una gerarchia ad albero.} Esiste inoltre tutta
una serie di risorse generiche, come quelle relative ai colori di sfondo, i
caratteri, ecc. che possono venire applicate ai singoli elementi grafici di un
programma, consentendo così una configurabilità estremamente dettagliata.

In genere per le risorse di ciascuna applicazione vengono mantenute delle
impostazioni generali in un file a questo dedicato, che in fase di
installazione viene posto in una directory comune (nelle distribuzioni recenti
\texttt{/etc/X11/app-defaults/}) con il nome stesso della risorsa. I singoli
utenti però possono cambiare a piacere questi valori tramite l'uso del file
\index{configurazione!\texttt{.Xresources}} \texttt{.Xresources} nella propria
home directory, nel quale specificare i valori che all'avvio del server
andranno a soprassedere quelli di default.  Se poi si vogliono cambiare gli
stessi valori una volta avviato il server si può usare il comando
\index{comando!\texttt{xrdb}} \texttt{xrdb} che prende come argomento il file
in cui sono stati scritti i nuovi valori che saranno caricati immediatamente.
Un esempio di un file di configurazione delle risorse può essere il seguente:
\begin{FileExample}[label=.Xresources]
... 
emacs*Background: DarkSlateGray
emacs*Foreground: Wheat
emacs*pointerColor: LightSteelBlue
emacs*cursorColor: LightSteelBlue
emacs*bitmapIcon: on
!emacs*font: fixed
emacs*font: -misc-fixed-*-*-*-*-15-*-75-75-*-*-iso8859-*
emacs.geometry: 80x28
emacs*BorderColor: DarkSlateGray
emacs*fringe.Background: DarkSlateGray
...
\end{FileExample}
in cui si modificano le impostazioni dell'editor \texttt{emacs} relative ai
colori di sfondo e primo piano, si specifica la geometria iniziale ecc. Si
noti come la sintassi preveda una riga in cui si specifica il nome della
risorsa terminato da ``\texttt{:}'', cui segue la stringa che assegna il
valore. Si noti anche come il nome della risorsa possa contenere il carattere
jolly ``\texttt{*}'' che assume lo stesso significato che avrebbe se si
specificasse un pathname.\footnote{cioè applica il valore a tutte le risorse
  che corrispondono alla stringa in cui nella gerarchia l'asterisco è
  sostituito da un nome qualunque.} Infine si tenga presente che il carattere
``\texttt{!}'' serve ad introdurre una riga di commento.

\itindbeg{window~manager} 

Se le risorse permettono di controllare i vari parametri interni relativi
all'aspetto grafico delle singole applicazioni, quello che contraddistingue
l'interfaccia grafica è la capacità di poter eseguire vari programmi in
contemporanea, ciascuno nella sua finestra. Come però ci si potrà rendere
conto lanciando una sessione X con un singolo programma (come nell'esempio di
\texttt{startx} visto in sez.~\ref{sec:cfg_xserver_start}), gli X-client si
limitano solo a disegnare il contenuto interno alle rispettive finestre. Il
posizionamento delle stesse, il loro spostamento, il passaggio dall'una
all'altra, ecc. devono essere invece gestiti a parte e farlo non è compito dei
singoli programmi. Per questo per poter usare davvero un'interfaccia grafica è
necessario avere almeno un altro programma che esegua questi compiti
specifici: quello che viene chiamato un \textit{window manager}, e che assume
un po' quello che è il ruolo della shell nella riga di comando (lanciare altri
comandi e passare dall'uno all'altro).

Senza un \textit{window manager} infatti si avrebbe la grafica ma non la
possibilità di spostare, nascondere, ridimensionare le finestre, o di passare
dall'una all'altra. È il \textit{window manager} che si cura di tutti questi
compiti: del disegno degli elementi grafici di contorno, della gestione dello
spostamento attraverso l'uso del mouse, del ridimensionamento e della
selezione delle finestre. Un compito fondamentale infatti, quando si hanno più
finestre da gestire, è appunto quello della selezione di quella che viene
\textsl{messa a fuoco}, quella cioè cui verranno inviati tutti gli eventi in
ingresso (ad esempio quello che si scrive sulla tastiera), che è un po'
l'equivalente del processo in \textit{foreground} visto in
sez.~\ref{sec:struct_job_control}.

Per usare con profitto una sessione grafica tutto quello che serve è un
\textit{window manager}, molti di questi infatti gestiscono anche la presenza
di un menu o di una barra direttamente sullo schermo (o eventuali altri
elementi di contorno), usando i quali è possibile lanciare altre applicazioni
o avere informazioni sul sistema. I più comuni, tuttora in ampio uso da parte
di coloro che sono abituati alla loro interfaccia e non necessitano di
funzionalità più avanzate, sono \textit{Window Maker}, \textit{ICEwm},
\textit{fvwm}, \textit{blackbox}, ecc.

\itindend{window~manager} 

Le interfacce grafiche moderne vanno però al di là della semplice gestione
delle finestre arrivando a definire una infrastruttura che consenta operazioni
come il cosiddetto \textit{drag and drop}, in cui si possono passare elementi
o dati da una finestra ad un altra (e cioè da una applicazione ad un
altra). Per fare questo un \textit{window manager} non basta, il passo
successivo è allora quello dell'uso di un \textit{desktop environment}, cioè
di una infrastruttura (completa di meccanismi di intercomunicazione) che
definisca non solo la gestione delle finestre, ma tutto un insieme di elementi
(come oggetti grafici comuni e meccanismi di intercomunicazione) che porta
appunto ad un ambiente grafico integrato, analogo a quello che si trova su
altri sistemi operativi come MacOS o Windows.


%%
%% INIZIO: Sezione specifica per LPI
%%
\ifx\lpispecificsection\undefined

\relax
\else

\subsection{Programmi per l'accessibilità}
\label{sec:accessibility}

Benché non necessariamente legati all'uso dell'interfaccia grafica, ed in
certi casi anzi totalmente slegati, come quelli indirizzati all'uso da parte
di persone non vedenti, tratteremo in questa ultima sezione i programmi
realizzati per rispondere alle esigenze di accessibilità in quanto la gran
parte degli stessi fanno parte o sono strettamente legati agli ambienti
desktop. 

Le tecnologie legate alla accessibilità sono diverse, in quanto sono anche
diverse le tipologie di disabilità alle quali cercano di fornire una
risposta. Una prima serie di programmi, per lo più integrati con gli ambienti
desktop (come GNOME e KDE) sono quelli che consentono di modificare le
modalità di utilizzo di tastiera e mouse per le persone con problemi di
mobilità.

In entrambi i casi i programmi di configurazione dell'ambiente consentono di
modificare il comportamento standard della tastiera per persone con difficoltà
motorie, ed in particolare si possono trovare configurazioni specifiche per:
\begin{itemize*}
\item bloccare la ripetizione dell'immissione di un carattere quando si
  mantiene un tasto premuto a lungo;
\item ignorare pressioni multiple ravvicinate;
\item simulare la pressione contemporanea di due tasti usando la permanenza
  della pressione dei tasti modificatori (\textit{shift}, \textit{alt},
  \textit{ctrl}, ecc.);
\item modificare la velocità di spostamento del mouse;
\item modificare le tempistiche delle pressioni dei tasti del mouse;
\item simulare i click con la pressione in un'area;
\end{itemize*}
ed in particolare si possono impostare per ciascuna di queste funzionalità i
tempi di risposta ed attesa, in modo da adattarle alle esigenze specifiche di
una persona, che possono variare in ragione della diversità delle sue
difficoltà motorie.

Inoltre per le persone in grado di usare soltanto un mouse o un dispositivo di
puntamento esistono diversi programmi per utilizzare una tastiera virtuale
presentata sullo schermo, su cui simulare l'uso della tastiera con la
pressione dei tasti effettuata tramite il mouse. Fra questi uno dei più
sofisticati è \texttt{gok} (acronimo di \textit{GNOME On-screen Keyboard}) che
consente una emulazione molto dettagliata di tutte le funzionalità di una
tastiera ordinaria, e si integra anche con il Desktop offrendo scorciatoie e
``\textit{gestures}'' per l'uso del menù e delle barre.

Una seconda serie di programmi sono previsti per coloro che hanno difficoltà
visive. Ad esempio tutti gli ambienti Desktop prevedono la possibilità per gli
utenti di usare programmi di ingrandimento per lo schermo (ad esempio
\texttt{kmag} per KDE) e di modificare le dimensioni dei font dei caratteri
per aumentare la visibilità.  Esistono inoltre specifici temi grafici ad alto
contrasto per gli ambienti grafici, per favorire chi ha difficoltà visive
nelle differenze di colori o di luce.

A questi programmi si affiancano, rivolti specificamente ai non vedenti,
alcuni programmi di sintesi vocale. Fra questi spicca \texttt{emacspeak},
sviluppato da un non vedente, inizialmente nato come un lettore di schermo per
l'editor \texttt{emacs} (con il quale offre una integrazione molto stretta) ma
in grado di trasformare l'editor in una sorta di ``desktop audio'',
effettuando non soltanto la lettura dello schermo, ma anche la restituzione
audio delle azioni compiute, la rilettura automatica di quanto scritto e la
vocalizzazione dell'inserzione dei caratteri. 

Sempre rivolto ai non vedenti è \texttt{brltty}, un demone che consente di
redirigere l'output di una console su una barra Braille (un dispositivo in
grado di generare i caratteri Braille su una superficie), per restituire una
rappresentazione tattile dello stesso, che supporta anche la sintesi vocale,
lo scorrimento all'indietro e l'uso di più terminali virtuali.

Infine nello sviluppo del desktop GNOME tutta una serie di funzionalità
relative alle tecnologie di assistenza per l'accesso delle persone non vedenti
sono state integrate tramite ORCA (il nome deriva dal porsi come alternativa
al proprietario JAWS) presente nella distribuzione ufficiale di questo
ambiente desktop fino dalla versione 2.16. Il programma si appoggia alla
interfaccia AT-SPI (\textit{Assistive Technology Service Provider Interface}),
un toolkit che consente di fornire servizi di accessibilità alle applicazioni
che lo utilizzano.

Con ORCA è possibile abilitare tutta una serie di tecnologie di assistenza che
vanno ben oltre le originali funzionalità di \textit{screen reader}, con l'uso
della sintesi vocale per le varie azioni su desktop, l'integrazione con le
barre Braille, la definizione di effetti sonori e combinazioni di tasti per
consentire anche a chi non vede di orientarsi all'interno delle applicazioni.


%%
%% FINE: Sezione specifica per LPI
%%
\fi

\section{Il sistema di stampa}
\label{sec:print_printing}

Tratteremo in questa sezione la configurazione delle stampanti sotto
GNU/Linux; dopo una introduzione generale sulla gestione generica della stampa
vedremo in particolare la configurazione secondo il sistema tradizionale del
\textit{Line Printing Daemon} di BSD e la nuova architettura del
\textit{Common Unix Printing System}.


\subsection{Introduzione generale}
\label{sec:print_intro}

Mantenendo la filosofia progettuale di Unix per cui \textit{tutto è un file},
è facile immaginarsi che la prima e più immediata modalità di stampa sia
quella di inviare il file da stampare direttamente al dispositivo associato
alla stampante.  Questo è senz'altro possibile, ma si scontra con una serie di
problemi che lo rendono altamente sconsigliabile; il primo è che non esiste un
dispositivo univoco che identifichi una stampante, questa può essere infatti
agganciata ai dispositivi più vari (e molte stampanti ne supportano più di
uno), come la parallela, la seriale, una porta USB, ecc. In ciascuno di questi
casi il file andrebbe inviato sul relativo dispositivo (ad esempio nel caso di
stampante su porta parallela, a \texttt{/dev/lp0}).

Tutto questo non costituirebbe di per sé un grosso problema, basterebbe
identificare il dispositivo specifico indicandolo tramite un link simbolico
con un nome generico che vi faccia riferimento. Il problema più importante è
invece quello relativo al contenuto del file da stampare; un tempo quando si
stampavano solo file di testo senza formattazioni il problema non c'era, oggi
però si stampano file con contenuti grafici e con formattazioni complesse e
font diversi.

Per questo in genere le stampanti moderne prevedono un loro linguaggio di
stampa come il PostScript (alcune ne supportano anche più di uno), che
permette di ottenere i risultati voluti. Questo significa che anche un
semplice file di testo deve essere opportunamente \textsl{trattato} prima di
essere inviato alla stampante. Inoltre se, come accade spesso, i programmi
generano le stampe in un formato (principalmente il PostScript) e la stampante
non lo capisce, questo dovrà essere opportunamente tradotto.

Il terzo problema è quello di essere in presenza di un sistema operativo
multiutente e multitasking; il che comporta che con l'accesso diretto si
possono avere più processi che scrivono in contemporanea sul dispositivo della
stampante, coi relativi dati che si mescolano fra di loro dando luogo a
risultati tutt'altro che piacevoli nella stampa finale.

Per questa serie di motivi in genere il dispositivo della stampante non è mai
accessibile direttamente ai singoli utenti, ma viene gestito attraverso un
opportuno \textit{sistema di stampa} che si incarica di risolvere questi
problemi. In generale quello che succede è che l'accesso alla stampante è
regolato attraverso un opportuno demone, che è l'unico che ci scrive, le
stampe vengono richieste inviando i file da stampare al suddetto demone, che
si incarica di eseguire tutte le operazioni necessarie (comprese le eventuali
conversioni di formato) e di garantire un accesso corretto senza
sovrapposizioni.

Una delle caratteristiche fondamentali dei sistemi di stampa in ambiente
unix-like è quella delle \textsl{code}, le stampe cioè non vengono mai
eseguite direttamente, ma immesse, tramite un opportuno comando, su una coda
di stampa dalla quale poi verranno prelevate (in genere dal demone di cui
sopra) ed opportunamente inviate sulla stampante secondo lo schema illustrato
in fig.~\ref{fig:print_general_structure}.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=11cm]{images/print_struct}
  \caption{Schema generico del funzionamento del sistema di stampa.}
  \label{fig:print_general_structure}
\end{figure}

Il vantaggio di questo sistema è che la gestione della coda può essere eseguita
indipendentemente dalla gestione della stampante, ad esempio diventa possibile
inviare la stampa su una coda remota se è previsto un opportuno meccanismo di
comunicazione. Lo stesso concetto di stampa remota può essere realizzato in
maniera alternativa usando una coda locale ed usando direttamente il demone di
stampa per inviare i file ad un altro demone remoto. 

Inoltre con lo schema di fig.~\ref{fig:print_general_structure} nell'eseguire
l'invio dei file dalla coda di stampa alla stampante il demone di stampa può
eseguire tutte le operazioni necessarie (realizzate in genere attraverso
quelli che si chiamano \textsl{filtri di stampa}) per convertire il contenuto
del file da stampare in un formato che la stampante è in grado di comprendere.

Infine l'uso di questa architettura permette anche di utilizzare più code di
stampa per la stessa stampante; questo consente ad esempio di utilizzare code
diverse (con filtri diversi) a seconda del tipo di file che si vuole stampare,
o con diversi privilegi o priorità. Benché la terminologia usata finora faccia
riferimento all'architettura classica ereditata da BSD (che vedremo
sommariamente in sez.~\ref{sec:print_LPD}) i concetti e la filosofia generale
di funzionamento restano gli stessi anche con la più recente architettura di
CUPS.


\subsection{Il \textit{Common Unix Printing System}}
\label{sec:print_CUPS}

Benché continuino ad esistere altri programmi per la gestione del sistema di
stampa (torneremo sulla compatibilità con il vecchio sistema di BSD in
sez.~\ref{sec:print_LPD}) oggi questa viene effettuata quasi esclusivamente
tramite CUPS (acronimo di \textit{Common Unix Printing System}).

A differenza dei programmi usati nelle prime versioni di Unix, nati in un
periodo in cui le stampanti erano sempre collegate fisicamente alle singole
macchine e venivano utilizzate per lo più solo localmente, CUPS è stato creato
nell'era di Internet, con stampanti che possono operare direttamente sulla
rete, e per questo fornisce anche tutta l'interfaccia di gestione via
rete,\footnote{i concetti relativi a indirizzi, porte, protocolli, ed in
  generale tutto quanto riguarda gli argomenti relativi alla rete citati in
  questa sezione vengono assunti come noti, per la trattazione degli stessi si
  rimanda a quanto verrà illustrato nel capitolo \ref{cha:networks_base}.}
tramite apposito servizio con cui si comunica usando una variante del
protocollo HTTP su una porta dedicata (il default è la 631). Rispetto al
protocollo HTTP ordinario un server CUPS prevede però una comunicazione con
caratteristiche specifiche, che sono state standardizzate
nell'\href{http://www.ietf.org/rfc/rfc3239.txt}{RFC~3239} in cui è definito il
protocollo IPP (acronimo di \textit{Internet Printing Protocol}).

L'uso di un protocollo di rete che è basato su HTTP ha il grande vantaggio che
con CUPS buona parte dell'amministrazione del sistema di stampa, come la
creazione il controllo e la rimozione di stampe e code di stampa o la
configurazione delle stampanti, può essere eseguita direttamente tramite un
browser qualunque, che basterà puntare sulla porta 631 della macchina da
amministrare. Questa resta la modalità principale di utilizzo del sistema,
anche se è possibile usare degli opportuni comandi di shell per eseguire gli
stessi compiti.

Il servizio è fornito da un demone, \index{demone!\texttt{cupsd}}
\texttt{cupsd}, controllato da un file di configurazione, \texttt{cupsd.conf},
che di norma viene installato in \texttt{/etc/cups}. Questo file configura il
servizio nel suo insieme, dato che come accennato la gestione di stampanti,
code e stampe avviene attraverso l'interfaccia che il servizio stesso mette a
disposizione.  Il formato del file è simile a quello del file di
configurazione del web server Apache (il server web più diffuso), la maggior
parte sono una serie di direttive elementari nella forma:
\begin{Example}
NomeDirettiva argomento
\end{Example}
dove il nome della direttiva è composto da normali caratteri, e il successivo
argomento viene specificato di seguito come valore separato da uno o più spazi
il cui formato dipende dalla direttiva stessa.  Al solito le righe vuote o
inizianti per un ``\texttt{\#}'' vengono ignorate.

Ad esempio con la direttiva \texttt{Port} si può specificare la porta su cui
il servizio si pone in ascolto (il default è la 631), mentre con la direttiva
\texttt{Listen} si può indicare esplicitamente un indirizzo IP o anche un
socket locale. Inoltre una delle caratteristiche più interessanti di CUPS è la
sua capacità di riconoscere automaticamente le stampanti presenti su una rete,
con il cosiddetto \textit{browsing}.

Questa funzionalità è attivata di default (ma può essere disattivata
impostando ad \texttt{off} la direttiva \texttt{Browsing}) e può essere
controllata con la direttiva \texttt{BrowseAddress} per indicare l'indirizzo
di \textit{broadcast} (vedi sez.~\ref{sec:net_ip_addr}) cui inviare le
richieste di riconoscimento.  Normalmente tutte le richieste vengono
accettate, ma con le direttive \texttt{BrowseAllow} e \texttt{BrowseDeny} si
possono indicare quali sono le macchine (o le reti) le cui richieste vengono
accettate o rifiutate.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{AccessLog}    & il file su cui vengono registrati gli
                            accessi; richiede come valore il nome del file o la
                            parola chiave \texttt{syslog} che invia le
                            informazioni all'omonimo servizio.\\ 
    \texttt{BrowseAddress}& indirizzo di \texttt{broadcast} cui inviare le
                            richieste di riconoscimento. \\
    \texttt{BrowseAllow}  & indirizzo o rete da cui accettare le richieste di
                            riconoscimento.\\
    \texttt{BrowseDeny}   & indirizzo o rete da cui non accettare le richieste 
                            di riconoscimento.\\
    \texttt{Browsing}     & abilita o disabilita il riconoscimento automatico
                            delle stampanti presenti (prende i valori
                            \texttt{on} o \texttt{off}).\\
    \texttt{DataDir}      & la directory dove sono mantenuti i dati di CUPS.\\
%    \texttt{DefaultCharset}&il set di caratteri di default.\\
    \texttt{DocumentRoot} & la directory radice per i documenti HTTP (come la
                            documentazione) che vengono messi a disposizione
                            attraverso l'interfaccia.\\
    \texttt{ErrorLog}     & il file su cui vengono registrati gli
                            errori; richiede come valore il nome del file o la
                            parola chiave \texttt{syslog} che invia le
                            informazioni all'omonimo servizio.\\ 
    \texttt{Group}        & gruppo per conto del quale viene eseguito
                            \texttt{cupsd} (di default \texttt{lpadmin}).\\ 
    \texttt{Include}      & permette di includere un altro file nella 
                            configurazione.\\
    \texttt{Listen}       & consente di specificare completamente l'indirizzo
                            IP su cui il server si pone in ascolto nella forma
                            \texttt{address:port} (o \texttt{/path/name} in
                            caso di socket locale).\\ 
    \texttt{LogLevel}     & livello dei messaggi da parte del demone.\\
    \texttt{PageLog}      & il file su cui vengono registrati i dati
                            sulle pagine stampate; richiede come valore il
                            nome del file o la parola chiave \texttt{syslog}
                            che invia le informazioni all'omonimo servizio.\\ 
    \texttt{Port}         & specifica la porta su cui si pone in ascolto il  
                            demone \texttt{cupsd} (il default è 631).\\
    \texttt{Printcap}     & specifica su quale file riprodurre un file
                            \texttt{printcap} che faccia da sostituto per 
                            \texttt{/etc/printcap} per i programmi che
                            necessitano di quest'ultimo per riconoscere le code
                            di stampa.\\ 
    \texttt{ServerRoot}   & specifica la directory radice per il demone
                            \texttt{cupsd}, di default è \texttt{/etc/cups}.\\
    \texttt{SystemGroup}  & specifica il gruppo (o i gruppi, se si indica un
                            elenco separato da spazi) i cui utenti avranno
                            i privilegi amministrativi sul sistema (su Debian
                            viene usato \texttt{lpadmin}).\\
    \texttt{TempDir}      & la directory in cui inserire i file temporanei, in
                            sostanza lo \textit{spool} di stampa (di default
                            è \texttt{/var/spool/cups/tmp}).\\
    \texttt{User}         & utente per conto del quale viene eseguito
                            \texttt{cupsd} (di default \texttt{lp}).\\
    \texttt{MaxCopies}    & numero massimo di copie che un utente può
                            richiedere, il valore 0 significa nessun limite,
                            il default è 100.\\
    \texttt{MaxJobs}      & numero massimo di stampe in coda, il valore 0
                            significa nessun limite, il default è 500.\\ 
    \texttt{MaxJobsPerUser}&numero massimo di stampe per utente, il 
                            default è 0 e significa nessun limite.\\
%    \texttt{WebInterface} & indica se abilitare l'interfaccia via web.\\
    \hline
  \end{tabular}
  \caption{Principali direttive per il file \texttt{/etc/cups/cupsd.conf}.}  
  \label{tab:print_cups_conf}
\end{table}

In tab.~\ref{tab:print_cups_conf} sono riportate le direttive di base più
importanti di \index{configurazione!\texttt{/etc/cups/cupsd.conf}}
\texttt{/etc/cups/cupsd.conf}, per l'elenco completo con una descrizione
sommaria si può fare riferimento alla pagina di manuale. Inoltre le
distribuzioni normalmente installano una versione predefinita di questo file
in cui tutte le opzioni (anche quelle non attivate esplicitamente) sono
abbondantemente commentate.  Per una documentazione completa invece si può
fare riferimento ai manuali on-line direttamente accessibili attraverso
l'interfaccia del sistema (un altro dei vantaggi di avere un protocollo basato
su HTTP) o reperibili su \url{http://www.cups.org/}.

Oltre alle direttive appena illustrate, che usano la sintassi elementare in
cui si esprime un argomento con un valore ad una parola chiave, il formato di
\texttt{cupsd.conf} prevede la presenza di direttive con una sintassi più
complessa, che vengono chiamate \textsl{contenitori} (o \textit{container}) in
quanto in genere consentono al loro interno altre direttive.

In particolare sono queste le direttive usate per effettuare il controllo
degli accessi all'interfaccia di rete fornita da \texttt{cupsd}, con cui è
possibile gestire il controllo del sistema di stampa attraverso il protocollo
IPP.  Queste direttive, che in genere vengono raggruppate in coda al file (ma
possono essere inserite in qualunque posizione), hanno una forma diversa:
\begin{Example}
<DirettivaContenitore argomento>
  DirettivaNormale1 argomento1
  DirettivaNormale2 argomento2
  ...
</DirettivaContenitore>
\end{Example}

La più comune di queste direttive è \texttt{Location}, nel qual caso il
relativo argomento assume sempre l'aspetto di un pathname, o più precisamente
una URI.\footnote{per una trattazione del significato delle URI e delle URL si
  rimanda alla sezione 1.1.2 di \cite{WebServ}.} Questa direttiva viene in
genere utilizzata per il controllo di accesso, poiché l'accesso alle varie
funzionalità del sistema di stampa via IPP avviene tramite indirizzi web, e
viene gerarchizzato in una struttura ad albero analoga a quella dei file, ed
espressa appunto con dei ``\textsl{percorsi}'' a partire da una radice
``\texttt{/}'' avendo accesso alla quale si diventa in grado di compiere
qualunque operazione.

Specificando un percorso a partire dalla radice si potrà accedere ad una
classe di operazioni, sempre più specifica via via che si scende nella
gerarchia, per la quale si potranno impostare le regole di accesso. I
principali percorsi utilizzabili come argomento di \texttt{Location} sono
illustrati in tab.~\ref{tab:print_cups_access_path}, insieme alle operazioni
cui si accede attraverso di essi; per l'elenco completo si può fare
riferimento alla documentazione in linea di CUPS.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Percorso} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{/}             & accesso a tutte le operazioni.\\
    \texttt{/admin}        & accesso operazioni amministrative (creazione,
                             cancellazione, impostazione e avvio delle
                             stampanti e delle code).\\ 
    \texttt{/admin/conf}   & accesso ai file di configurazione.\\ 
    \texttt{/classes}      & accesso alle operazioni sulle classi.\\
    \texttt{/classes/name} & accesso alle operazioni sulla classe
                             \texttt{name}.\\ 
    \texttt{/jobs}         & accesso alle operazioni sulle stampe.\\
    \texttt{/printers}     & accesso alle operazioni sulle stampanti.\\
    \texttt{/printers/name}& accesso alle operazioni sulla stampante 
                             \texttt{name}.\\
    \hline
  \end{tabular}
  \caption{I \textsl{percorsi} per l'accesso alla gestione delle operazioni
    usabili come argomento di \texttt{Location}.}  
  \label{tab:print_cups_access_path}
\end{table}

Una volta che con la scelta di un percorso nella direttiva container
\texttt{Location} si sia definito a quale classe di operazioni si vuole che
siano applicate le regole di accesso, queste ultime devono essere specificate
da altrettante direttive poste all'interno del
``\textsl{contenitore}''. Questo viene fatto attraverso una serie di ulteriori
direttive, specifiche per l'indicazione di regole di accesso, che hanno una
sintassi identica alle direttive elementari viste in precedenza, ma che sono
utilizzabili solo all'interno del ``\textsl{contenitore}''.

Una direttiva \texttt{Location} prevede sempre la presenza di una direttiva
\texttt{Order} che definisce la politica di accesso, che per chiarezza si pone
in genere come prima direttiva al suo interno. Se l'accesso è consentito per
default si utilizza il valore \texttt{Deny,Allow}, mentre se è vietato per
default si utilizza il valore \texttt{Allow,Deny}.  Alla direttiva
\texttt{Order} devono poi seguire successive direttive \texttt{Deny} o
\texttt{Allow} per indicare rispettivamente le macchine a cui vietare o
consentire esplicitamente gli accessi, e direttive come \texttt{AuthType} e
\texttt{AuthClass} per indicare le eventuali modalità di autenticazione. I
valori utilizzabili per queste direttive sono riportati in
tab.~\ref{tab:print_cups_access_directive}, in cui sono illustrate le
principali direttive di accesso, per una descrizione più dettagliata di tutte
le direttive e della relativa sintassi si può fare nuovamente riferimento alla
documentazione di CUPS.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Direttiva} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{Order}     & definisce la modalità con cui vengono gestite le
                         autorizzazioni con le direttive \texttt{Deny} e
                         \texttt{Allow}, prende come valori:
                         \texttt{Deny,Allow} in cui si accettano tutte le 
                         richieste eccetto quelle negate da una direttiva
                         \texttt{Deny} e \texttt{Allow,Deny} in cui si
                         accettano solo le richieste consentite con una
                         direttiva \texttt{Allow}.\\
    % \texttt{AuthClass} & definisce il livello di autenticazione richiesto,
    %                      prende come valori: \texttt{Anonymous} che
    %                      disabilita l'autenticazione, \texttt{User} che
    %                      richiede utente e password, \texttt{System} che
    %                      inoltre richiede che l'utente appartenga al gruppo
    %                      \texttt{sys} (o a quello specificato con la direttiva
    %                      \texttt{SystemGroup}), \texttt{Group} che richiede
    %                      che l'utente appartenga al gruppo definito dalla
    %                      direttiva \texttt{AuthGroupName}.\\ %deprecato
    \texttt{AuthType}  & definisce le modalità di autenticazione, prende 
                         come valori: \texttt{None} che non effettua 
                         nessuna autenticazione, \texttt{Basic} che
                         effettua l'autenticazione usando le credenziali
                         standard della macchina, \texttt{Digest} e
                         \texttt{BasicDigest} che utilizza le credenziali
                         specifiche memorizzate in
                         \texttt{/etc/cups/passwd.md5}.\\ 
    \texttt{Allow}     & consente l'accesso: prende come valore l'indirizzo
                         IP di una singola macchina o di una rete (in
                         notazione CIDR, vedi sez.~\ref{sec:net_ip_addr}) o un
                         nome a dominio (consentendo notazioni del tipo
                         \texttt{*.dominio.it} o \texttt{.dominio.it} per
                         indicare tutti le macchine in un dominio) o la parola
                         chiave \texttt{All}.\footnotemark\\ 
    \texttt{Deny}      & nega l'accesso, usa gli stessi valori 
                         appena descritti per \texttt{Allow}.\\
    \texttt{Encryption}& abilita la cifratura della connessione, prende come
                         valori: \texttt{Never}, \texttt{IfRequested} e 
                         \texttt{Required}, il cui significato è
                         autoesplicativo.\\
    \texttt{Require}   & richiede un accesso autenticato (che verrà effettuato
                         secondo la modalità indicata da
                         \texttt{AuthType}) consentendo di specificare i
                         soggetti che possono usare tale accesso, sia in forma
                         di lista di utenti, da far seguire alla parola chiave
                         \texttt{user}, sia indicando un gruppo, con la parola
                         chiave \texttt{group}; il gruppo può essere indicato
                         indicato anche con \texttt{user} con la sintassi
                         \texttt{@\textsl{nome}} che si può utilizzare anche
                         per indicare i valori predefiniti \texttt{@OWNER}, che
                         indica il proprietario di un lavoro di stampa, e
                         \texttt{@SYSTEM} che indica il gruppo impostato
                         dalla direttiva \texttt{SystemGroup}.\\
    \hline
  \end{tabular}
  \caption{Le direttive di accesso usate in all'interno di una
    \texttt{Location}.}
  \label{tab:print_cups_access_directive}
\end{table}


Un esempio del contenuto di \texttt{/etc/cups/cupsd.conf}, estratto (togliendo
i commenti) dalla versione installata con il pacchetto \texttt{cupsys} su una
Debian Squeeze, è il seguente:
\begin{FileExample}[label=/etc/cups/cupsd.conf]
LogLevel warn
MaxLogSize 0
SystemGroup lpadmin
Listen localhost:631
Listen /var/run/cups/cups.sock
Browsing On
BrowseOrder allow,deny
BrowseAllow all
BrowseLocalProtocols CUPS dnssd
DefaultAuthType Basic
<Location />
  Order allow,deny
</Location>
<Location /admin>
  Order allow,deny
</Location>
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
</Location>
...
\end{FileExample}

Si noti come nella configurazione di \texttt{cupsd.conf} non vi sia nessuna
traccia di dati relativi alle stampanti. Queste infatti sono mantenute in un
file a parte, \texttt{printers.conf}, ma in genere il contenuto di questo file
viene gestito da \texttt{cupsd}, che ne genera e modifica il contenuto sia
attraverso i comandi che con l'interfaccia di gestione via web. Questo
comporta anche che il file non deve essere modificato manualmente fintanto che
il programma è attivo. 

Il formato del file mantiene le caratteristiche di base di
\texttt{cupsd.conf}, ma in questo caso le direttive sono diverse. La
principale è la direttiva container \texttt{Printer} che definisce una
stampante logica, al cui interno vanno poi inserite le direttive che ne
controllano l'uso.  

Oltre alla configurazione lato server è possibile specificare una
configurazione generale sul lato client (per tutti i programmi cioè che si
appoggiano a CUPS per la stampa), che viene mantenuta a livello di sistema nel
file \texttt{/etc/cups/client.conf}, e può essere personalizzata dal singolo
utente in un file \texttt{.cupsrc} nella propria home directory. 

In genere le direttive principali che si utilizzano in detti file sono
\texttt{ServerName} che prende come valore il nome della macchina cui
rivolgersi come server di stampa e \texttt{Encryption} che prende gli stessi
valori della omonima vista in tab.~\ref{tab:print_cups_access_directive} per
il server, che indica la modalità con cui eseguire una eventuale cifratura
della connessione.


\subsection{I comandi di gestione per CUPS}
\label{sec:print_CUPS_CLI}

Come accennato anche se la gran parte della gestione e della configurazione
del sistema di stampa viene gestita attraverso l'interfaccia web fornita da
CUPS è comunque possibile utilizzare anche una serie di comandi di shell; il
primo di questi è \index{comando!\texttt{lpadmin}} \texttt{lpadmin}, che è
quello che si può utilizzare per definire le proprietà generali delle
stampanti presenti nel sistema. 

Il concetto di base è quello di definire delle \textsl{stampanti logiche},
chiamate così in quanto se ne possono associare più di una ad una stessa
stampante fisica. Si tratta in sostanza della reimplementazione del concetto
di coda di stampa visto in sez.~\ref{sec:print_intro}. Alle stampanti logiche
si deve fare sempre riferimento con l'opzione \texttt{-p} seguita dal nome. In
pratica tutte le invocazioni di \texttt{lpadmin} richiedono l'uso di questa
opzione, tranne il caso in cui si usi al suo posto \texttt{-x} che richiede la
cancellazione di una stampante logica.

Per creare una stampante logica oltre ad identificarla con \texttt{-p}
occorrerà anche definire con quale dispositivo vi si accede, cosa che si fa
attraverso l'opzione \texttt{-v}; questa prende come argomento quello che la
documentazione chiama un \textit{device-URI}, cioè una stringa nella forma di
un indirizzo simile a quello di un sito web, che indica con quale modalità è
possibile raggiungere la stampante stessa (se sulla porta parallela, seriale,
USB, o via rete secondo vari protocolli di comunicazione), un breve elenco di
possibili valori è riportato in tab.~\ref{tab:print_cups_device_URI}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Nome} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{ipp://remote.printer.ip} & stampante di rete raggiungibile con
                                       protocollo IPP.\\
    \texttt{smb://remote.printer.ip} & stampante di rete windows raggiungibile
                                       tramite Samba.\\
    \texttt{lpd://remote.printer.ip} & stampante di rete raggiungibile con 
                                       protocollo LPD.\\
    \texttt{parallel:/dev/lp0}       & stampante locale sulla porta 
                                       parallela.\\
    \texttt{usb:/dev/lp0}            &  stampante locale su porta USB.\\
    \texttt{serial:/dev/ttyS0}       &  stampante locale su porta seriale.\\
    \hline
  \end{tabular}
  \caption{Le diverse possibili specificazioni per gli indirizzi del
    dispositivo associato ad una stampante (\textit{device-URI}).}  
  \label{tab:print_cups_device_URI}
\end{table}

Oltre a definire come si può parlare con la stampante è necessario anche
specificare quale ``\textsl{linguaggio}'' usare, questo si fa con l'opzione
\texttt{-P} che associa alla stampante logica il relativo file PPD
(\textit{PostScript Printer Description}) che ne descrive le capacità; questo
è un po' l'equivalente del filtro di stampa, in quanto serve a definire quali
sono le modalità con cui alla fine i file vengono stampati.

Una delle caratteristiche più interessanti di CUPS è quella di permettere di
definire delle \textsl{classi} di stampanti, in sostanza una classe definisce
un gruppo di stampanti che può essere trattato come un insieme, così che
indicando di stampare su quella classe la stampa viene effettuata su una delle
stampanti che ne fanno parte.  La definizione delle classi viene fatta tramite
le opzioni \texttt{-c} e \texttt{-r} di \texttt{lpadmin} che permettono
rispettivamente di inserire o eliminare una stampante dalla classe passata
come argomento; se una classe non esiste viene creata all'inserimento della
prima stampante, se si elimina l'ultima stampante la classe viene cancellata.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{-p \textsl{stampante}}& indica la stampante logica su cui si sta
                                    operando.\\ 
    \texttt{-x \textsl{stampante}}& rimuove una stampante logica.\\
    \texttt{-d \textsl{stampante}}& imposta la stampante come stampante di
                                    default.\\  
    \texttt{-c \textsl{classe}}   & inserisce in una classe una stampante
                                    logica.\\  
    \texttt{-r \textsl{classe}}   & rimuove una stampante logica da una
                                    classe.\\ 
    \texttt{-v \textsl{URI}}      & indica il dispositivo da usare per parlare
                                    con la stampante (secondo il formato
                                    illustrato in
                                    tab.~\ref{tab:print_cups_device_URI}).\\
    \texttt{-P \textsl{file.ppd}} & definisce il file di descrizione della
                                    stampante da utilizzare.\\
    \texttt{-E}                   & abilita una stampante rendendola
                                    disponibile per la stampa.\\
    \texttt{-h \textsl{host}}     & indica il server CUPS remoto su cui far 
                                    operare il comando.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{lpadmin}.}  
  \label{tab:print_cups_lpadmin_opt}
\end{table}

Le principali opzioni del comando sono riportate in
tab.~\ref{tab:print_cups_lpadmin_opt}; al solito si può fare riferimento alla
pagina di manuale o alla documentazione di CUPS per un elenco completo e per
la descrizione dettagliata.

Una volta definita una stampante logica questa può essere abilitata o
disabilitata alla stampa rispettivamente con i comandi
\index{comando!\texttt{cupsenable}} \texttt{cupsenable} e
\index{comando!\texttt{cupsdisable}} \texttt{cupsdisable} che prendono come
argomento il nome della stessa; entrambi i comandi prevedono l'uso
dell'opzione \texttt{-h} per indicare un server remoto. Inoltre
\texttt{cupsdisable} supporta l'opzione \texttt{-c} che permette di rimuovere
tutte le stampe pendenti dalla stampante disabilitata, e \texttt{-r} che
prende come argomento una stringa in cui descrivere le motivazioni per cui la
stampante è stata disabilitata (che sarà riportata dai comandi diagnostici).

Si tenga presente comunque che abilitare o disabilitare una stampante logica
significa sostanzialmente abilitare o disabilitare l'esecuzione delle stampe
su di essa, e che questa è una operazione diversa rispetto a quella di
accettare o rifiutare l'immissione di nuove stampe sulla relativa coda; questa
seconda operazione viene fatta invece con i comandi
\index{comando!\texttt{cupsaccept}} \texttt{cupsaccept} e
\index{comando!\texttt{cupsreject}} \texttt{cupsreject}, che di nuovo
richiedono come argomento il nome della stampante; come per
\texttt{cupsdisable} anche \texttt{cupsreject} supporta l'opzione \texttt{-r}
con lo stesso significato.

Il comando per richiedere una stampa è invece \index{comando!\texttt{lp}}
\texttt{lp},\footnote{anche se CUPS supporta un sistema di compatibilità
  all'indietro con il protocollo tradizionale di BSD che consente l'uso del
  comando \texttt{lpr}, con la sintassi illustrata in
  sez.~\ref{sec:print_LPD}.} che prende come argomento il file da stampare, e
lo invia sulla stampante di default, riportando a video l'identificatore
associato alla stampa richiesta.  Le stampe infatti sono chiamate, seguendo la
nomenclatura inglese, \textsl{job}, in particolare i comandi di gestione fanno
riferimento a questi identificativi come ai \textit{job ID} e riportano il
numero di stampe correnti come numero di \textsl{job}.

Qualora si debba indicare una stampante specifica al posto di quella di
default si deve usare l'opzione \texttt{-d} che prende come parametro il nome
della stampante o della classe cui inviare il lavoro di stampa, mentre se si
vuole stampare utilizzando uno specifico server CUPS remoto occorre
specificarne l'indirizzo come parametro dell'opzione \texttt{-h} (nella forma
\texttt{host:porta}).

Questa, insieme alle altre opzioni riportate nella prima parte di
tab.~\ref{tab:print_cups_lp_opt}) è una delle opzioni generiche che
controllano la modalità di collegamento al server che sono disponibili in
generale per tutti i comandi client, compresi i precedenti comandi di
controllo delle code, ed i comandi per le statistiche e le informazioni che
vedremo più avanti.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{-E}               & forza una comunicazione cifrata col server.\\
    \texttt{-h \textsl{host}} & specifica il server CUPS remoto cui inviare
                                la stampa.\\ 
    \texttt{-U \textsl{user}} & indica un utente con cui collegarsi al server.\\
    \hline
    \texttt{-d \textsl{dest}} & specifica la stampante o la classe da usare.\\
    \texttt{-i \textsl{job}}  & specifica la stampa su cui operare, indicata
                                per \textit{job ID}.\\
    \texttt{-n \textsl{N}}    & specifica il numero di copie da stampare.\\
    \texttt{-o \textsl{opts}} & passa una o più opzioni per la stampante,
                                indicate come una stringa contenente una lista
                                di assegnazioni nella forma
                                \texttt{nome=valore} separate da spazi (i
                                valori dipendono dalla stampante specifica).\\  
    \texttt{-q \textsl{N}}    & specifica una priorità (valore numerico fra 
                                1 e 100).\\ 
    \texttt{-H \textsl{when}} & specifica quando eseguire una stampa:
                                \texttt{hold} la blocca indefinitamente, un
                                tempo in formato \texttt{HH:MM} la blocca ad
                                allora, \texttt{resume} la avvia
                                immediatamente e \texttt{restart} riesegue una
                                stampa completata (gli ultimi due valori
                                richiedono l'uso di \texttt{-i} per
                                identificare la stampa cui si fa
                                riferimento).\\ 
    \texttt{-P \textsl{pages}}& specifica quali pagine stampare (passati come
                                lista separate da virgole o intervalli
                                separati da un ``\texttt{-}'').\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{lp}.}  
  \label{tab:print_cups_lp_opt}
\end{table}

Altre due opzioni utili sono \texttt{-n}, che permette di specificare il
numero di copie da stampare e \texttt{-q}, che permette di impostare una
priorità (un numero da 1 a 100, con valore di default pari a 50). Le opzioni
principali sono riportate in tab.~\ref{tab:print_cups_lp_opt}, per l'elenco
completo ed i dettagli si può fare riferimento alla pagina di manuale.

Per cancellare una stampa si può invece usare il comando
\index{comando!\texttt{cancel}} \texttt{cancel}, che prende come argomento
l'identificatore della stampa, o, se specificato con l'opzione \texttt{-a},
una stampante o una classe, nel qual caso saranno cancellate tutte le stampe
presenti su di essa. Il comando supporta anche l'opzione \texttt{-h} con lo
stesso significato di \texttt{lp}; al solito per i dettagli si faccia
riferimento alla pagina di manuale.

Infine per ottenere informazioni riguardo il sistema di stampa ci sono alcuni
comandi ulteriori. Il primo è \index{comando!\texttt{lpinfo}} \texttt{lpinfo}
che permette di vedere i dispositivi fisici ed i supporti per le stampanti
disponibili all'interno di CUPS. Il comando richiede una delle opzioni
\texttt{-v} o \texttt{-m} per stampare rispettivamente la lista dei
dispositivi utilizzabili e quella delle stampanti supportate. Ad esempio se si
vuole ottenere una lista dei dispositivi visibili da riutilizzare con
l'opzione \texttt{-v} di \texttt{lpadmin} si può eseguire il comando:
\begin{Console}
hain:~# \textbf{lpinfo -v}
network http
network ipp
network lpd
direct parallel:/dev/lp0
direct usb:/dev/usb/lp0
...
direct usb:/dev/usb/lp15
network smb
\end{Console}

Oltre a quelle indicate il comando prevede le opzioni per il collegamento
verso il server illustrate nella prima parte di
tab.~\ref{tab:print_cups_lp_opt}, ed una serie di altre opzioni per
selezionare in maniera più dettagliata i risultati riportati, per le quali al
solito si rimanda alla consultazione della pagina di manuale.

Il secondo comando è \index{comando!\texttt{lpstat}} \texttt{lpstat}, che
riporta le informazioni relative alle singole stampanti, classi e stampe
attive. Anche questo comando supporta le opzioni per il collegamento
illustrate nella prima parte di tab.~\ref{tab:print_cups_lp_opt}. 

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{-c \textsl{[class]}}& elenca le classi e le stampanti che ne fanno
                                  parte, limitandosi alla eventuale classe
                                  indicata.\\
    \texttt{-p \textsl{[dest]}} & riporta lo stato di una stampante, 
                                  eventualmente limitandosi a quella indicata.\\
    \texttt{-a \textsl{[queue]}}& riporta lo stato di una coda, eventualmente 
                                  limitandosi a quella indicata.\\
    \texttt{-o \textsl{[dest]}} & riporta l'elenco dei lavori di stampa, 
                                  limitandosi alla eventuale destinazione
                                  indicata.\\  
    \texttt{-W \textsl{jobs}}   & specifica quali lavori di stampa riportare
                                  negli elenchi, prevede tre valori di
                                  significato evidente: \texttt{all},
                                  \texttt{completed} e \texttt{non-completed}
                                  (il default).\\
    \texttt{-l} & esegue un elenco generico dei dati di stampanti, classi e
                  lavori di stampa.\\ 
    \texttt{-d} & indica la attuale stampante di default.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni specifiche del comando \texttt{lpstat}.}  
  \label{tab:cups_lpstat_opt}
\end{table}

L'opzione \texttt{-c} richiede la stampa delle informazioni relative ad una
classe (o a tutte se non si specifica quale classe), l'opzione \texttt{-a}
riporta lo stato di una coda (e delle eventuali stampe in attesa), mentre
l'opzione \texttt{-p} riporta lo stato di una stampante; entrambe richiedono
il nome di una stampante logica da interrogare, e riportano lo stato di tutte
quelle definite se questa non viene specificata. Si sono riportate in
tab.~\ref{tab:cups_lpstat_opt} le opzioni principali del comando. Ulteriori
dettagli e l'elenco completo delle opzioni si trovano al solito sulla pagina
di manuale.

Il terzo comando è \index{comando!\texttt{lpoptions}} \texttt{lpoptions} che
permette di consultare e modificare opzioni e default relativi alle
stampanti. Come i precedenti riconosce le opzioni di collegamento illustrate
nella prima parte di tab.~\ref{tab:print_cups_lp_opt}, se usato con la sola
opzione \texttt{-l} stampa le opzioni relative alla stampante di default, ma
se ne può scegliere una qualunque specificando il relativo nome con l'opzione
\texttt{-p}.  Indicando un nome con l'opzione \texttt{-d} si imposta invece
una nuova stampante di default.

Lo scopo principale del comando è però impostare le opzioni delle stampanti, i
cui valori dipendono dalle singole stampanti e che non è possibile elencare
qui. L'impostazione di un valore si può fare con l'opzione \texttt{-o} con cui
si possono inserire o modificare i valori delle opzioni nella forma
\texttt{opzione=valore}, mentre con \texttt{-r} seguito dal nome dell'opzione
si può rimuovere quest'ultima dalla configurazione della stampante.


\subsection{Il sistema di stampa in stile BSD}
\label{sec:print_LPD}

Benché oggi non sia praticamente più usato, fino a qualche anno fa, prima
dell'avvento di CUPS, il sistema di stampa più diffuso in ambiente Unix era
quello sviluppato per BSD, e tutt'ora distribuito insieme a questo sistema
operativo.  Di questo è disponibile una versione anche GNU/Linux, ma il suo
funzionamento è stato a lungo difettoso ed il numero di stampanti supportate è
limitato. Per questo esso veniva in genere sostituito da una reimplementazione
alternativa sviluppata indipendentemente, LPRng, che pur mantenendo la stessa
interfaccia e le stesse funzionalità, supportava diverse estensioni e molte
più stampanti.


%%
%% OBSOLETE
%%
% Noi faremo riferimento solo a LPRng, che a lungo è stato uno dei sistemi di
% stampa di uso più comuni nelle distribuzioni GNU/Linux; l'altro, che lo sta
% soppiantando in maniera ormai quasi completa, è CUPS, che tratteremo in
% sez.~\ref{sec:print_CUPS}. Ignoreremo completamente l'implementazione
% originale di BSD, facendo riferimento al tutto con il nome del

Oggi nessuna delle due varianti viene più utilizzata per gestire le stampanti,
essendo entrambe nettamente inferiori, sia in termini di funzionalità che di
stampanti utilizzabili, a CUPS. Esiste però, per supportare i programmi che
ancora fanno riferimento alla vecchia interfaccia, un layer di compatibilità
fornito dallo stesso CUPS,\footnote{nel caso di Debian questo viene fornito
  dal pacchetto \texttt{cups-bsd} (o \texttt{cupsys-bsd} per le versioni più
  vecchie).} che consente di implementare la vecchia interfaccia del
protocollo LPD (acronimo di \textit{Line Printer Daemon}) standardizzata
nell'\href{http://www.ietf.org/rfc/rfc1179.txt}{RFC~1179}.

Il cuore del sistema di stampa in stile BSD è infatti costituito dal demone di
stampa \texttt{lpd} (da cui deriva il nome del protocollo) che si incarica sia
della gestione delle code che dell'invio dei dati alle stampanti. Il
protocollo LPD prevede che il demone possa essere contattato anche via rete
(da un altro demone o direttamente da un client) per eseguire la stampa in
remoto.  Nel caso di CUPS il demone viene sostituito da un apposito programma
di emulazione, \texttt{cups-lpd} che viene normalmente lanciato a richiesta da
programmi come \texttt{inetd} o \texttt{xinetd} (vedi sez.~\ref{sec:net_inetd}
e sez.~\ref{sec:net_xinetd}) per ricevere le connessioni dai client e
reinviare i dati a CUPS.

Oltre al server \texttt{lpd} il sistema di stampa in stile BSD prevede poi una
serie di programmi client usati per l'immissione delle stampe nelle code e per
la gestione di queste ultime. Anche questi sono stati rimpiazzati da opportuni
sostituti dal funzionamento identico, ma che inviano invece la stampa ad un
server CUPS, e sono questi quelli che tratteremo dato che sono gli unici che
ancora hanno una applicazione pratica in quanto gli script ed i programmi
scritti quando ancora CUPS non era in auge possono fare ricorso ad essi.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-P \textsl{dest}} & indica la coda su cui stampare.\\ 
    \texttt{-h} & inibisce la stampa di una pagina di intestazione.\\
    \texttt{-\# \textsl{N}}   & specifica il numero di copie da stampare. \\
    % cambiato in lpr di CUPS
    % \texttt{-C \textsl{prio}} & specifica la priorità della \textsl{stampa},
    %                             identificata da una lettera maiuscola da
    %                             ``\texttt{A}'' (più bassa) a 
    %               ``\texttt{Z}'' (più alta), da passare come parametro. \\
    \texttt{-J \textsl{nome}} & associa alla stampa un nome in modo che questo
                                venga stampato nell'intestazione (quando
                                questa è prevista).\\
    \texttt{-m \textsl{mail}} & richiede l'invio di una email all'indirizzo
                                specificato qualora la stampa fallisca.\\ 
    \texttt{-U \textsl{user}} & permette di specificare l'utente per conto del
                                quale eseguire la stampa (utilizzabile solo
                                dall'amministratore).\\ 
    \hline
  \end{tabular}
  \caption{Le principali opzioni del comando \texttt{lpr}.}
  \label{tab:print_lpr_options}
\end{table}

Il più rilevante di questi programmi è \index{comando!\texttt{lpr}}
\texttt{lpr}, con cui si può richiedere la stampa di un file. Il comando
prende come argomenti i file da stampare e se non si specifica nulla viene
usato lo \textit{standard input}. Una volta messa in coda una serie di stampe
il comando riporta sullo \textit{standard output} un numero identificativo per
ciascuna di esse che potrà essere usato con gli altri comandi per fare
riferimento alle stesse.

L'opzione principale di \texttt{lpr} è \texttt{-P} che permette di indicare su
quale coda di stampa inviare il file da stampare. Se non la si specifica viene
usato, se definito, il valore di una delle variabili
\index{variabili!di~ambiente!\texttt{PRINTER}} \texttt{PRINTER},
\index{variabili!di~ambiente!\texttt{LPDEST}} \texttt{LPDEST} o la stampante
di default di sistema o quella indicata per l'utente con \texttt{lpoptions}.
Un'altra opzione utile è \texttt{-h} che inibisce la stampa di eventuali
pagine iniziali per le code in cui questa è prevista e \texttt{-\#} che
richiede la stampa di un certo numero di copie; le altre opzioni principali
sono riportate in tab.~\ref{tab:print_lpr_options}, per l'elenco completo al
solito si faccia riferimento alla pagina di manuale.

% OBSOLETE roba di LPR-ng
% , \texttt{NPRINTER} o \texttt{NGPRINTER}, oppure la stampante
% di default, che è la prima definita in \texttt{/etc/printcap}.\footnote{questo
%   è il file che contiene la definizione delle stampanti nel sistema di BSD,
%   con CUPS il file è auto-generato, e la prima riga corrisponde alla stampante
%   usata.} 


Per la gestione delle stampe sono disponibili una serie di comandi per
controllare lo stato della coda ed eseguirvi delle operazioni, il primo di
questi è \index{comando!\texttt{lpq}} \texttt{lpq}, che permette di esaminare
lo stato della coda. Se invocato senza argomenti esso stampa la lista delle
stampe presenti, con il formato:
\begin{Console}
parker:/root# \textbf{lpq}
Printer: rlp@parker 'Remote printer entry' (dest epson@davis)
 Queue: no printable jobs in queue
 Server: no server active
 Status: job 'root@parker+648' saved at 16:48:21.800
 Rank   Owner/ID                  Class Job Files                 Size Time
done   root@parker+648              A   648 /root/iptables        2748 16:48:21
epson is ready and printing
root: active                            [job 543 localhost]
        /root/iptables                          3072 bytes
\end{Console}
altrimenti si può specificare come argomento il numero identificativo della
stampa (quello riportato nella colonna \texttt{Job}) ed il comando riporterà
solo le informazioni ad essa relative.

Di default il comando esegue la ricerca delle stampe sulla coda di default, a
meno di non usare l'opzione \texttt{-P} per selezionare una coda specifica. Si
può usare l'opzione \texttt{-a} per fare eseguire la ricerca su tutte le code.
Per le altre opzioni e per una descrizione dettagliata si può fare riferimento
alla pagina di manuale.
 
Una volta creata una stampa, la si potrà eliminare dalla coda con il comando
\index{comando!\texttt{lprm}} \texttt{lprm}. Questo prende come argomenti la
lista delle stampe da rimuovere che possono essere indicate tramite il loro
identificativo (quello stampato da \texttt{lpr} o riportato da \texttt{lpq}),
mentre l'uso dell'argomento ``\texttt{-}'' seleziona tutte le stampe presenti,
se invece non si specifica nulla viene selezionata la prima che può essere
rimossa.  Di nuovo il comando opera sulla coda di default a meno di non usare
l'opzione \texttt{-P} per specificarne un'altra o l'opzione \texttt{-a} per
indicare di operare su tutte le code.

%% OBSOLETE riferisce a lprm di lpr-ng
%  Entrambe le forme supportano l'utilizzo dei caratteri jolly del
% \textit{filename globbing} (vedi
% sez.~\ref{sec:shell_sintax}).% L'uso della parola chiave \texttt{all}
% seleziona tutte le stampe presenti,\footnote{questa è una caratteristica della
%   versione di \texttt{lprm} del pacchetto \texttt{lpr-ng}, il pacchetto
%   originale del demone di stampa di BSD non supporta questa opzione, al suo
%   posto invece si deve usare semplicemente l'argomento ``\texttt{-}'', che
%   seleziona tutte le stampe di un utente, o, se usato dall'amministratore, del
%   sistema.} mentre se non si specifica nulla viene selezionata la prima che
% può essere rimossa.  


L'uso di \texttt{lprm} serve a richiedere la cancellazione delle stampe
selezionate, ma un utente potrà rimuovere solo quelle per i quali ha il
permesso; con l'opzione \texttt{-U} si può richiedere, se si è
l'amministratore, di operare a nome di un altro utente. Per le altre opzioni
ed i dettagli di funzionamento del programma si faccia riferimento alla pagina
di manuale.

% Chiude la lista dei programmi ausiliari \index{comando!\texttt{lpc}}
% \texttt{lpc}, che serve per controllare lo stato del sistema di stampa. Il
% programma prende come argomenti un comando seguito da eventuali parametri per
% lo stesso. Come i precedenti esso opera sulla coda di default a meno di non
% usare l'opzione \texttt{-P} per specificarne un'altra o l'opzione \texttt{-a}
% per indicarle tutte.

% Se non si specificano argomenti il programma si porta su una linea di comando
% interna, da cui questi possono essere specificati. Di questi nella versione
% installata da CUPS è disponibile soltanto un sottoinsieme limitato, ma la
% lista di tutti quelli disponibili si può stampare con \texttt{help}; con
% \texttt{status} invece si può ottenere la stampa dello stato della coda e
% relativa stampante associata.


%%
%% ### OBSOLETE BEGIN ###
%% Materiale obsoleto per sistema di stampa in stile BSD, 
%% non includere nelle nuove versioni
%%
\ifx\obsoletesection\undefined

\relax
\else

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Comando} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{disable}& disabilita l'immissione di stampe su una coda di stampa;
                      prende come argomento il nome della coda o \texttt{all}
                      per indicare tutte le code.\\
    \texttt{down}   & disabilita sia l'immissione di nuove stampe in coda che
                      la stampa di quelle presenti; prende come argomento il 
                      nome della coda o \texttt{all} per indicare tutte le
                      code.\\ 
    \texttt{enable} & abilita l'immissione di nuove stampe su una coda di
                      stampa; prende come argomento il nome della coda o 
                      \texttt{all} per indicare tutte le code.\\
    \texttt{exit}   & esce dal programma.\\
    \texttt{hold}   & sospende la stampa (su una stampante o per una singola 
                      stampa); prende come argomento il nome della stampante ed
                      eventualmente l'identificatore del job. \\
    \texttt{holdall}& sospende automaticamente tutte le nuove stampe, 
                      che vengono accodate ma non stampate; prende come
                      argomento il nome della coda o \texttt{all} per indicare
                      tutte le code.\\ 
    \texttt{move}   & sposta una stampa da una coda ad un'altra; prende come
                      argomenti la coda di origine, l'identificativo della
                      stampa e la coda di destinazione.\\
    \texttt{release}& sblocca la sospensione della stampa per una coda o una
                      stampa specifica; prende come argomento il nome della
                      coda ed eventualmente l'identificatore della stampa.\\ 
    \texttt{start}  & avvia una stampante, è utilizzato principalmente quando
                      un demone termina lasciando dei job sulla coda per
                      riavviarlo; prende come argomento il nome della coda o
                      \texttt{all} per indicare tutte le code. \\
    \texttt{status} & riporta lo stato di una coda e relativa stampante;
                      prende come argomento il nome della coda o \texttt{all}
                      per indicare tutte le code.\\
    \texttt{stop}   & blocca ogni ulteriore stampa dopo il completamento della
                      stampa corrente; prende come argomento il nome della
                      coda o \texttt{all} per indicare tutte le code.\\
    \texttt{topq}   & sposta le stampe selezionate in cima alla coda di stampa;
                      prende come argomento il nome della coda seguito dalla
                      lista degli identificativi delle stampe. \\
    \texttt{up}     & abilita sia l'immissione nella coda che la stampa;
                      prende come argomento il nome della coda o \texttt{all}
                      per indicare tutte le code. \\
    \hline
  \end{tabular}
  \caption{I principali comandi di \texttt{lpc}.}
  \label{tab:print_lpc_command}
\end{table}

Nel caso si sia installata invece la versione originale si può fermare la
stampa con l'uso del comando \texttt{stop} e farla ripartire con
\texttt{start}. Si può invece bloccare l'immissione di stampe su una coda con
\texttt{disable} e riabilitarla con \texttt{enable}.  L'elenco dei principali
comandi di \texttt{lpc} è riportato in tab.~\ref{tab:print_lpc_command}, ed al
solito l'elenco completo ed i dettagli sono nella pagina di manuale.  Un
esempio di risultato di questo comando è il seguente:
\begin{Verbatim}[fontsize=\footnotesize,%frame=single,samepage=true,
  xleftmargin=1cm,xrightmargin=1.5cm]
parker:/var/log# lpc status
Printer: rlp@parker 'Remote printer entry' (dest epson@davis)
 Queue: no printable jobs in queue
 Server: no server active
 Status: job 'root@parker+648' saved at 16:48:21.800
 Rank   Owner/ID                  Class Job Files                 Size Time
epson is ready
no entries
\end{Verbatim}



\subsection{La configurazione della stampa con LPRng}
\label{sec:print_lpd_conf}

Come accennato il principale programma di un sistema di stampa in stile BSD è
il demone \index{demone!\texttt{lpd}} \texttt{lpd}, che gestisce l'invio dei
file dalla coda di stampa alla stampante; il demone però è in grado anche di
gestire la eventuale ricezione di richieste di stampa via rete (da un altro
demone o direttamente da un client), e permette perciò di trasformare una
qualunque stampante presente sulla propria macchina in una stampante di rete.

Pertanto la configurazione della stampante su una macchina che usa questo
sistema consiste nel configurare opportunamente \texttt{lpd}.  Nel nostro caso
esamineremo la configurazione soffermandoci specificamente sul caso
particolare di LPRng, in cui è prevista la presenza di una serie di file di
configurazione per i vari compiti eseguiti dal demone.

Il primo file di configurazione è
\index{configurazione!\texttt{/etc/printcap}} \texttt{/etc/printcap}, che
viene usato da tutti i demoni di stampa in stile BSD.  Il file contiene la
definizione delle code di stampa con la assegnazione delle stampanti e degli
eventuali filtri ad esse associate. Il file è composto da una serie di
blocchi, uno per ciascuna coda che si intende utilizzare. Ciascun blocco è
composto da una serie di campi separati dal carattere ``\texttt{:}'', un
blocco può essere scritto su più righe terminando ciascuna di esse con la
barra rovescia ``\texttt{\bslash}'' come si fa per la shell;\footnote{in
  realtà con LPRng questo non è necessario, ma è meglio farlo per
  compatibilità.} si tenga conto che l'ultimo campo deve essere anch'esso
terminato col carattere ``\texttt{:}''. Al solito righe vuote e tutto quello
che segue il carattere ``\texttt{\#}'' viene ignorato.

Il primo campo indica il nome della coda di stampa, esso può riportare più
nomi (per una migliore identificazione della stampante associata) separati con
la barra verticale ``\texttt{|}''. Tutti gli altri campi, che controllano le
caratteristiche della coda e della stampante associata, possono essere
specificati in ordine qualsiasi, ciascun campo inizia sempre per un
identificativo di due caratteri,\footnote{questo vale in realtà per il demone
  originario di BSD, con LPRng esistono alcune estensioni che prevedono l'uso
  di indicativi di dimensione qualunque.} seguito da una assegnazione con un
``\texttt{=}'' se il suo valore è una stringa o con un ``\texttt{\#}'' se il
valore è numerico; un terzo tipo di campi ha valore logico, nel qual caso si
usa semplicemente la presenza del rispettivo identificativo.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Campo} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{if} & \textit{input filter}, indica il filtro da applicare a
                  tutti i file immessi sulla coda prima di inviarli alla
                  stampante, è quello che permette le conversioni di
                  formato, prende come valore il pathname al programma da
                  usare come filtro, che deve leggere i dati dallo
                  \textit{standard input} e riemettere il risultato del
                  filtraggio sullo \textit{standard output}.\\
%   \texttt{lf} & \\
    \texttt{lf} & \textit{log file}, file su cui vengono registrati tutti gli
                  errori del sistema, prende come valore un pathname. \\
    \texttt{af} & \textit{account file}, file su cui viene registrato il  
                  rendiconto delle pagine stampate, prende come valore un
                  pathname.\\
    \texttt{lp} & \textit{line printer}, file di
                  dispositivo su cui è situata la stampante (o la \textit{fifo}
                  cui può essere inviato il file da stampare), prende come
                  valore il relativo pathname.\\ 
    \texttt{mx} & dimensione massima della pagina da stampare, da specificare
                  in byte come valore numerico. \\
    \texttt{pl} & \textit{page length}, lunghezza della pagina in righe, da 
                  specificare come valore numerico. \\
    \texttt{pw} & \textit{page width}, larghezza della pagina in caratteri, da 
                  specificare come valore numerico. \\
    \texttt{rm} & \textit{remote machine}, nome della macchina remota cui 
                  inviare le stampe, da specificare come stringa contenente
                  l'\textit{hostname} o l'indirizzo IP (in notazione dotted
                  decimal).\footnotemark\\
    \texttt{rp} & \textit{remote printer}, nome della coda di stampa su una
                  macchina remota, da specificare come stringa.\\
    \texttt{sd} & \textit{spool directory}, nome della directory dove vengono
                  mantenuti i file da stampare presenti nella coda. \\
    \texttt{sh} & \textit{suppress header}, sopprime la stampa delle 
                  intestazioni, è un valore logico.\\
    \hline
  \end{tabular}
  \caption{I principali campi di \texttt{/etc/printcap}.}
  \label{tab:print_printcap_fields}
\end{table}

\footnotetext{indirizzi IP e nomi verranno trattati in
  sez.~\ref{cha:networks_base}.}

Di questi campi è fondamentale specificare sempre \texttt{sd} che indica la
\textit{spool directory}, cioè la directory su cui verranno appoggiati
temporaneamente i file da stampare; se la stampante è locale deve essere
specificato il campo \texttt{lp} che indica quale dispositivo usare; se invece
la stampante è remota si deve specificare un campo \texttt{rm} (da
\textit{remote machine}) per indicare l'\textit{hostname} del computer (o
l'indirizzo IP) su cui essa si trova ed il campo \texttt{rp} (da
\textit{remote printer}) per indicare il nome (cioè la coda di stampa) con cui
essa è identificata dal demone LPD presente su quel sistema. I principali
campi di \texttt{/etc/printcap} sono riportati in
tab.~\ref{tab:print_printcap_fields}, al solito per l'elenco completo ed i
dettagli si può fare riferimento alla pagina di manuale, un esempio di questo
file è il seguente, che definisce una stampante remota:

\begin{Verbatim}[xleftmargin=1cm,xrightmargin=1.5cm]
  lp:\
	:sd=/var/spool/lpd/hpremote:\
	:lp=:mx#0:sh:\
        :rm=printserver:rp=lp:\
\end{Verbatim}

Una importanza particolare è poi rivestita dal campo \texttt{if}, che con
\textit{LPRng} viene normalmente sostituito dal più generico
\texttt{filter}.\footnote{in realtà il sistema di stampa di BSD prevede vari
  campi di controllo per i filtri, che vengono applicati a seconda del
  ``\textsl{formato}'' del file da stampare come indicato dal comando di
  stampa (con \texttt{lpr} si hanno le relative opzioni, per i dettagli si
  consulti la pagina di manuale).}  Questo campo indica un apposito programma
cui in ingresso vengono passati i file da stampare e che restituisce in uscita
quanto verrà inviato alla stampante, agendo appunto da \textit{filtro}.  Un
esempio di applicazione di filtri è l'uso del programma
\texttt{gs}\footnote{il nome del comando sta per \textit{GhostScript}, ed il
  programma in realtà è solo parte di una suite che realizza un intero sistema
  di conversione dei file postscript verso praticamente qualunque altro
  formato: ad esempio la conversione verso \textit{X11} consente di
  visualizzare i file postscript a video.} per convertire un file in
postscript generato da un programma nel formato specifico di una stampante,
così da poter stampare postscript anche su una vecchia stampante ad aghi.

Altri filtri possono essere programmi come \texttt{a2ps}, \texttt{enscript} e
\texttt{mpage} che eseguono la conversione da file testo a postscript, e
consentono di stampare (con formattazioni anche complesse) semplici file di
testo su stampanti postscript. In generale l'uso di un filtro è necessario per
convertire i dati di un file ad un formato che la stampante è in grado di
capire, il filtro cioè viene a costituire il \textit{driver} della stampante. 

Per questo motivo la parte probabilmente più complessa della configurazione di
una stampante con LPR è quella di trovare qual'è il filtro che consente di
stampare su di essa in maniera corretta. A tale scopo esistono dei progetti
che forniscono filtri da utilizzare per i vari tipi di stampante. I due
progetti principali sono \textit{APSfilter}
(\href{http://www.apsfilter.org/}{\texttt{http://www.apsfilter.org/}}) e
\textit{magicfilter}
(\href{http://www.pell.portland.or.us/~orc/Code/magicfilter/}
{\texttt{http://www.pell.portland.or.us/~orc/Code/magicfilter/}}), in entrambi
i casi si tratta di selezionare il filtro che corrisponde al proprio modello
di stampante,\footnote{è possibile che ne esistano diversi, in quanto alcune
  stampanti possono essere pilotate con linguaggi di stampa diversa, o
  supportare diverse modalità di stampa.} ed impostarlo come argomento per il
campo \texttt{if}. Nel caso di \textit{magicfilter} viene anche fornito un
programma di configurazione, \texttt{magicfilterconfig}, che esegue una
impostazione richiedendo i parametri sulla \textit{console}.

%% 
%% Vecchio limite, è obsoleta pure la parte precedente
%%
%% ### OBSOLETE BEGIN ###
%% Materiale obsoleto per LPR-ng, non includere nelle nuove versioni
%%
%\ifx\obsoletesection\undefined

%\relax
%\else

Nel caso di LPRng il demone \texttt{lpd} viene controllato anche da altri due
file di configurazione, usualmente mantenuti, insieme a tutti gli altri file
del sistema, in \texttt{/etc/lprng}. Il primo file,
\index{configurazione!\texttt{/etc/lprng/lpd.conf}} \texttt{lpd.conf}, contiene
la configurazione generale del demone, ma dato che tutti i valori sono ad un
default corretto, di norma questo non deve essere modificato.

Si può usare questo file per specificare valori di default validi in generale
per i parametri di \texttt{/etc/printcap}, ma la sintassi prevede che il file
contenga l'assegnazione di un parametro per ogni riga (al solito righe vuote e
tutto quello che inizia per ``\texttt{\#}'' viene ignorato) anziché separati
da ``\texttt{:}''. I parametri hanno gli stessi nomi usati in
\texttt{/etc/printcap}, e l'assegnazione, oltre alle modalità previste per
quest'ultimo, prevede anche quella di utilizzare il carattere ``\verb|@|'' per
identificare un valore logico.

Il file permette inoltre di specificare una serie di configurazioni generali
del demone usando delle opportune direttive che non corrispondono a nessun
parametro di \texttt{printcap}, ad esempio con la direttiva \texttt{lockfile}
si specifica la locazione del file di lock utilizzato per indicare la presenza
di un demone che gira nel sistema, con \texttt{printcap\_path} si indica la
posizione di default del file \texttt{printcap}, mentre con la direttiva
\texttt{include} si possono includere altri file. Al solito si rimanda alla
pagina di manuale, accessibile con \texttt{man lpd.conf}, per i dettagli e
l'elenco completo delle direttive.

Il secondo file di configurazione di \texttt{lpd} è 
\index{configurazione!\texttt{/etc/lprng/lpd.perms}} \texttt{lpd.perms} che
viene utilizzato per il controllo degli accessi. Questa è la più grossa
differenza con il sistema di stampa di BSD classico, questo infatti utilizza
semplicemente il file \texttt{/etc/hosts.lpd} (alternativamente viene usato,
se presente, anche \texttt{host.equiv}) per indicare le macchine da cui è
consentito collegarsi per stampare da remoto, mentre con LPRng nessuno di
questi file viene utilizzato.

Al solito righe vuote e tutto quello che segue un ``\texttt{\#}'' viene
ignorato, se si deve usare quest'ultimo carattere in una configurazione lo si
deve pertanto proteggere con una barra inversa ``\texttt{\bslash}''. Il file
contiene una serie di direttive tutte nella forma:
\begin{Verbatim}
ACCEPT [[not] chiave = valore[,valore]* ]*
REJECT [[not] chiave = valore[,valore]* ]*
DEFAULT ACCEPT
DEFAULT REJECT
\end{Verbatim}
dove con le parentesi quadre seguite dall'asterisco si intende che una
combinazione può essere ripetuta più volte (per specificare ulteriori
condizioni).

Le direttive \texttt{REJECT} e \texttt{ACCEPT} specificano, come il nome rende
evidente, se accettare o meno un certo accesso sulla base della condizione
espressa di seguito; il controllo dei permessi viene fatto usando un insieme
di chiavi il cui valore viene confrontato con quanto specificato nel file,
l'uso della direttiva \texttt{DEFAULT} serve a stabilire cosa succede quando
non sono state specificate condizioni.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{P}& capacità di inviare alla stampante il contenuto della coda.\\
    \texttt{R}& richiesta di \texttt{lpr} da una macchina remota.\\
    \texttt{C}& richiesta di controllo remoto tramite \texttt{lpc}.\\
    \texttt{M}& richiesta di rimozione di una stampa tramite \texttt{lprm}.\\
    \texttt{Q}& richiesta di elencazione delle stampe tramite \texttt{lpq}.\\
    \texttt{S}& richiesta dello stato dello spool di stampa con \texttt{lpc}.\\
    \texttt{U}& operazione amministrativa di un utente.\\
    \texttt{X}& connessione remota.\\
    \hline
  \end{tabular}
  \caption{Valori del campo \texttt{SERVICE} in \texttt{lpd.perms}.}
  \label{tab:print_service_values}
\end{table}

La chiave più importante è \texttt{SERVICE}, che permette di classificare il
\textsl{tipo} di richiesta di accesso, quando non la si specifica si intende
applicare la condizione seguente a qualunque tipo di accesso; questa può
prendere uno o più dei valori identificati da una lettera; i valori possibili
ed il relativo significato sono riportati in
tab.~\ref{tab:print_service_values}.  Tutte le chiavi partono con un valore
nullo, ma ad ogni richiesta di accesso alcune di esse (a seconda del tipo di
accesso) vengono inizializzate con i valori relativi ai parametri della
richiesta, che poi saranno confrontati con le condizioni indicate all'interno
di \texttt{lpd.perms}. In tab.~\ref{tab:print_lpd_perms_key} si sono riportate
le principali chiavi ed il relativo significato, per un elenco dettagliato si
può fare riferimento alla pagina di manuale accessibile con \texttt{man
  lpd.perms}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{REMOTEHOST}& lista degli IP da cui accettare connessioni remote
                         (indicato alternativamente come \texttt{REMOTEIP}).\\
    \texttt{REMOTEPORT}& porta da cui viene effettuata la connessione
                         (indicata alternativamente come \texttt{PORT}).\\
    \texttt{REMOTEUSER}& utente da cui proviene la richiesta di accesso.\\
    \texttt{SERVER}    & vera quando la richiesta è locale.\\
    \texttt{LPC}       & per le richieste di controllo specifica quali dei
                         comandi di \texttt{lpc} possono essere eseguiti.\\
    \texttt{PRINTER}   & nome della stampante (o meglio della coda) cui viene
                         richiesto l'accesso.\\
    \texttt{USER}      & utente cui appartiene la stampa richiesta (definita
                         per le operazioni su stampe esistenti).\\
    \texttt{HOST}      & macchina da cui è stato inserito la stampa richiesta 
                         (definita per le operazioni su stampe esistenti).\\
    \texttt{SAMEUSER}  & la richiesta proviene dallo stesso utente cui
                         appartiene la stampa (definita per le operazioni su 
                         stampe esistenti).\\
    \texttt{SAMEHOST}  & la richiesta proviene dalla stessa macchina da cui
                         è stato inserito la stampa (definita per le 
                         operazioni su stampe esistenti).\\
    \texttt{FORWARD}   & equivalente a \texttt{NOT SAMEHOST}.\\
    \hline
  \end{tabular}
  \caption{Principali chiavi per le restrizioni di accesso in
    \texttt{lpd.perms}.} 
  \label{tab:print_lpd_perms_key}
\end{table}

Il file esprime sempre un elenco di condizioni, che vengono controllate
sequenzialmente, quando una di queste viene verificata gli ulteriori controlli
vengono evitati.  Un esempio di \texttt{lpd.perms}, estratto
dalla versione installata su una Debian Sid, è il seguente:
\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm,xrightmargin=1.5cm]
REJECT NOT SERVER
ACCEPT SERVICE=C SERVER REMOTEUSER=root
ACCEPT SERVICE=C LPC=lpd,status,printcap
REJECT SERVICE=C
ACCEPT SERVICE=M SAMEHOST SAMEUSER
ACCEPT SERVICE=M SERVER REMOTEUSER=root
REJECT SERVICE=M
REJECT SERVICE=R FORWARD
DEFAULT ACCEPT
\end{Verbatim}

In questo caso la configurazione si apre vietando ogni accesso che non sia
locale. Dopo di che viene consentito, con le regole per il servizio
``\texttt{C}'', solo all'amministratore di controllare il demone con
\texttt{lpc} in maniera completa, mentre per chiunque altro viene consentito
(con la direttiva \texttt{LPC}) di utilizzare solo i comandi in essa elencati.
Per quanto riguarda invece la capacità di cancellare un file (il servizio
``\texttt{M}'') lo si permette solo a richieste provenienti dallo stesso
utente e dalla stessa macchina, o in maniera generica all'amministratore. Si
elimina poi possibilità di connettersi da qualunque altra macchina che non sia
quella locale.

%%
%% ### OBSOLETE END ###
%% Materiale obsoleto per LPR-ng, non includere nelle nuove versioni
%%
\fi


% LocalWords:  fstab mtab Windows ls total drwxr sez dev anacrontab replace
% LocalWords:  root Aug GNUstep rw Feb Muttrc adduser conf adjtime shell DLL
% LocalWords:  home nomefile Dinamically Linked Library like shared object ldd
% LocalWords:  Filesystem Hierarchy loader pathname major version hell cache LD
% LocalWords:  ldconfig librt Oct lrwxrwxrwx lib linker Sid PATH Name all'MIT
% LocalWords:  glibc Service Switch DNS NIS Information LDAP Lightweight Access
% LocalWords:  Protocol Solaris Example configuration of functionality If you
% LocalWords:  have the and packages installed try info libc for dns sysctl fs
% LocalWords:  information about this anarres vm echo files l'XDMCP dell'X call
% LocalWords:  tab username Group localization internationalization LANG LC UTF
% LocalWords:  aliases MAC address libnss ldap getty PAM ppc hostname kernel as
% LocalWords:  RedHat issue telnet ssh message RETRIES MOTD tty consoles Same
% LocalWords:  above but these only occur with devfs devices vc troff catN cron
% LocalWords:  whatis apropos mandb manpath config MANDATORY MAP bin sbin pm rc
% LocalWords:  SECTION perl local autoexec bat DOS run parts bashrc bash chsh
% LocalWords:  profile FTP updatedb tmp filesystem CDROM sets variables which
% LocalWords:  used filesystems pruned from PRUNEFS NFS nfs afs proc smbfs iso
% LocalWords:  autofs ncpfs devpts ftpfs mfs sysfs paths PRUNEPATHS amd alex at
% LocalWords:  sfs netpaths added find LOCALUSER nobody priority higher number
% LocalWords:  means lower is to usually NICE source spool log Mon Thu nice
% LocalWords:  vixie Paul bind crontab Sarge system wide Unlike any other don't
% LocalWords:  command install new when edit also has field that crontabs dom
% LocalWords:  mon dow report anacron atd tomorrow atq atrm allow deny syslog
% LocalWords:  syslogd auth authpriv daemon ftp Transfer kern lpr mark news err
% LocalWords:  USENET security uucp UUCP CoPy debug notice warning warn error
% LocalWords:  crit alert emerg panic fifo Logging Split it easy write if CTYPE
% LocalWords:  scripts logfiles Emergencies sent everybody logged autpriv POSIX
% LocalWords:  messages shutdown logrotate daily weekly monthly size tabooext
% LocalWords:  rpmorig rpmsave dpkg dist old disabled swp rpmnew compress gzip
% LocalWords:  missingok see details keep weeks worth backlogs empty after ones
% LocalWords:  rotating uncomment want your compressed RPM rotation into own XF
% LocalWords:  wtmp btmp them here utmp specific logs may configured fig UDP
% LocalWords:  Window framebuffer toolkit MacOS Athena client Xlib org COLLATE
% LocalWords:  protocol XFree rendering truetype Consortium live cfg NUMERIC
% LocalWords:  configure Section EndSection ServerFlags Modes MONETARY CH IEC
% LocalWords:  Module InputDevice Device refresh Screen ServerLayout DRI Direct
% LocalWords:  Interface Options yes off true Hz kHz MHz FontPath xfs dumb tcp
% LocalWords:  socket port fontserver RgbPath RGB ModulePath Load path Option
% LocalWords:  USB touchpad Identifier keyboard CorePointer CoreKeyboard pc us
% LocalWords:  SendCoreEvents XkbModel XkbLayout PS ImPS Matrox mga EndMode
% LocalWords:  VendorName ModelName HorizSync VertRefresh VESA EDID get edid
% LocalWords:  read DefaultDepth Depth Ctrl layout startx xinit xinitrc window
% LocalWords:  session xterm Manger Control xdm xlogin Xstartup European latin
% LocalWords:  Xsession xsession reset Xreset gdm kdm KDE sottostrutture xrdb
% LocalWords:  Xresources emacs DarkSlateGray Foreground Wheat pointerColor BSD
% LocalWords:  LightSteelBlue cursorColor bitmapIcon fixed misc geometry fringe
% LocalWords:  BorderColor foreground Maker ICEwm blackbox drag line Printing
% LocalWords:  common PostScript multitasking porting CUPS LPD RFC rsyslogd
% LocalWords:  printer lpd job LPDEST NPRINTER NGPRINTER lpq printer dest l'UTC
% LocalWords:  Queue printable jobs queue active saved Rank owner class central
% LocalWords:  done epson ready printing localhost bytes lprm filename globbing
% LocalWords:  all lpc disable enable exit hold holdall move topq entries sd lp
% LocalWords:  rm machine l'hostname rp filter lf af pl pw width sh fvwm URL
% LocalWords:  dotted decimal suppress header printcap lockfile lock perms host
% LocalWords:  equiv REJECT ACCEPT REMOTEHOST REMOTEIP REMOTEPORT REMOTEUSER HH
% LocalWords:  SAMEUSER SAMEHOST FORWARD NOT IPP cupsd browsing BrowseAddress
% LocalWords:  broadcast BrowseAllow BrowseDeny AccessLog DataDir DocumentRoot
% LocalWords:  DefaultCharset ErrorLog lpadmin LogLevel PageLog ServerRoot name
% LocalWords:  TempDir MaxCopies MaxJobs MaxJobsPerUser Location admin classes
% LocalWords:  printers Order AuthClass Anonymous sys SystemGroup AuthGroupName
% LocalWords:  AuthType Basic Digest BasicDigest CIDR Encryption Never Required
% LocalWords:  IfRequested cupsys notused cupsrc ServerName device windows PPD
% LocalWords:  Description ppd reject accept resume restart cancel lpinfo hain
% LocalWords:  ipp direct smb lpstat Pluggable Authentication xorg xfree Etch
% LocalWords:  reconfigure xserver xorgcfg xorgconfig title nomehost Ndisplay
% LocalWords:  Nscreen displayname PRELOAD suid sgid ld Modules length Unicode
% LocalWords:  runlevel prunefs prunepaths localuser prerotate HOWTO  keyfile
% LocalWords:  endscript postrotate Modeline Modelines Timings Apple dall'UTC
% LocalWords:  xvidtune TinyX embedded Setup rgb txt Nd Ns screen cookie xhost
% LocalWords:  nolisten LOGNAME variable expansion MAILTO commands will using
% LocalWords:  executed ps aux Wed cap append sull' SectionName SectionEntry vt
% LocalWords:  TrueType Type mkfontdir ttmkfontdir fontconfig fonts eXtendible
% LocalWords:  Markup Language SubSection extmod omit DGA EndSubSection DDC dpi
% LocalWords:  Channel DisplayManager errorLogFile pidFile keyFile servers Fn
% LocalWords:  accessFile authDir resources willing options ignore nologin DES
% LocalWords:  upgrade sessreg Xservers Xaccess XDMCP Chooser Xsetup Can't page
% LocalWords:  Kerberos Xsecurity Xauthority xauth serverhost clienthost gs not
% LocalWords:  environment GhostScript postscript enscript mpage APSfilter prog
% LocalWords:  magicfilter magicfilterconfig NomeDirettiva Listen inode init TZ
% LocalWords:  nell' iconv timezone Europe Pacific Rome zonefile usr tzconfig
% LocalWords:  tzdata tzselect logger facility layer bsd cups inetd xinetd
% LocalWords:  greeter gconf PostLogin PreSession PostSession modules acpi
% LocalWords:  XKeepsCrashing alternatives apt Nov Apr completion Squeeze tag
% LocalWords:  SuSE coreutils fields ini AllowRoot xdmcp kdmrc general option
% LocalWords:  printserver klogd ModLoad imuxsock imklog imudp UDPServerRun
% LocalWords:  FileOwner FileGroup FileCreateMode DirCreateMode umask SIGHUP
% LocalWords:  IncludeConfig LPRng descriptor Wayland group cupsenable gok
% LocalWords:  cupsdisable cupsaccept cupsreject completed lpoptions gestures
% LocalWords:  emacspeak brltty XDG systemd Ubuntu lightdm HTML VNC unity ELF
%  LocalWords:  guest manual hide users setup cleanup shift reader pages seat
%  LocalWords:  journald journalctl


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "corso"
%%% End:
