From b81e6a00eb42328ad0bdece65fe595a42864faa9 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 26 Jan 2012 19:02:51 +0000 Subject: [PATCH] Conversione funzioni --- filedir.tex | 547 +++++++++++++++++++++++++---------------------- img/fileperm.dia | Bin 1886 -> 1880 bytes 2 files changed, 291 insertions(+), 256 deletions(-) diff --git a/filedir.tex b/filedir.tex index f418163..29abfe2 100644 --- a/filedir.tex +++ b/filedir.tex @@ -5368,7 +5368,7 @@ queste funzioni che prendiamo in esame è \funcd{acl\_init}, il cui prototipo \fdesc{Inizializza un'area di lavoro per una ACL.} } -{La funzione ritorna un puntatore all'area di lavoro in caso di successo e +{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EINVAL}] il valore di \param{count} è negativo. @@ -5381,16 +5381,22 @@ La funzione alloca ed inizializza un'area di memoria che verrà usata per mantenere i dati di una ACL contenente fino ad un massimo di \param{count} voci. La funzione ritorna un valore di tipo \type{acl\_t} da usare in tutte le altre funzioni che operano sulla ACL. La funzione si limita alla allocazione -iniziale e non inserisce nessun valore nella ACL che resta vuota. Si tenga -presente che pur essendo \type{acl\_t} un \index{tipo!opaco} tipo opaco che -identifica ``\textsl{l'oggetto}'' ACL, il valore restituito dalla funzione non -è altro che un puntatore all'area di memoria allocata per i dati richiesti; -pertanto in caso di fallimento verrà restituito un puntatore nullo e si dovrà -confrontare il valore di ritorno della funzione con ``\code{(acl\_t) NULL}''. +iniziale e non inserisce nessun valore nella ACL che resta vuota. + +Si tenga presente che pur essendo \type{acl\_t} un \index{tipo!opaco} tipo +opaco che identifica ``\textsl{l'oggetto}'' ACL, il valore restituito dalla +funzione non è altro che un puntatore all'area di memoria allocata per i dati +richiesti. Pertanto in caso di fallimento verrà restituito un puntatore nullo +e si dovrà, in questa come in tutte le funzioni seguenti che restituiscono un +oggetto di tipo \type{acl\_t}, confrontare il valore di ritorno della funzione +con ``\code{(acl\_t) NULL}''.\footnote{dato che il valore \var{NULL} in questo + caso viene restituito come oggetto di tipo \type{acl\_t}, un confronto del + risultato della funzione con \var{NULL} darebbe un errore di compilazione + per la differenza di tipo.} Una volta che si siano completate le operazioni sui dati di una ACL la memoria -allocata dovrà essere liberata esplicitamente attraverso una chiamata alla -funzione \funcd{acl\_free}, il cui prototipo è: +allocata per un oggetto \type{acl\_t} dovrà essere liberata esplicitamente +attraverso una chiamata alla funzione \funcd{acl\_free}, il cui prototipo è: \begin{funcproto}{ \fhead{sys/types.h} @@ -5400,20 +5406,25 @@ funzione \funcd{acl\_free}, il cui prototipo è: } {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà il valore \errcode{EINVAL} se \param{obj\_p} non è - valido.} + caso \var{errno} assumerà il valore: + \begin{errlist} + \item[\errcode{EINVAL}] \param{obj\_p} non è valido. + \end{errlist} +} \end{funcproto} -Si noti come la funzione richieda come argomento un puntatore di tipo -``\ctyp{void *}'', essa infatti può essere usata non solo per liberare la -memoria allocata per i dati di una ACL, ma anche per quella usata per creare -le stringhe di descrizione testuale delle ACL o per ottenere i valori dei -qualificatori di una voce; pertanto a seconda dei casi occorrerà eseguire un -\textit{cast} a ``\ctyp{void *}'' del tipo di dato di cui si vuole eseguire la -disallocazione. Si tenga presente poi che oltre a \func{acl\_init} esistono -molte altre funzioni che possono allocare memoria per i dati delle ACL, è -pertanto opportuno tenere traccia di tutte queste funzioni perché alla fine -delle operazioni tutta la memoria allocata dovrà essere liberata con +Si noti come la funzione usi come argomento un puntatore di tipo ``\ctyp{void + *}'', essa infatti può essere usata non solo per liberare la memoria +allocata per i dati di una ACL, ma anche per quella usata per creare le +stringhe di descrizione testuale delle ACL o per ottenere i valori dei +qualificatori della una voce di una ACL. + +Pertanto a seconda dei casi occorrerà eseguire un \textit{cast} a ``\ctyp{void + *}'' del tipo di dato di cui si vuole eseguire la disallocazione. Si tenga +presente poi che oltre a \func{acl\_init} ci sono molte altre funzioni che +possono allocare memoria per i dati delle ACL, è pertanto opportuno tenere +traccia di tutte le chiamate a queste funzioni perché alla fine delle +operazioni tutta la memoria allocata dovrà essere liberata con \func{acl\_free}. Una volta che si abbiano a disposizione i dati di una ACL tramite il @@ -5428,8 +5439,8 @@ con la funzione \funcd{acl\_dup}, il cui prototipo è: } {La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo in - caso di successo e \code{(acl\_t)NULL} per un errore, nel qual caso - \var{errno} assumerà assumerà uno dei valori: + caso di successo e \val{NULL} per un errore, nel qual caso \var{errno} + assumerà assumerà uno dei valori: \begin{errlist} \item[\errcode{EINVAL}] l'argomento \param{acl} non è un puntatore valido per una ACL. @@ -5460,7 +5471,7 @@ di permessi ordinari, il prototipo della funzione è: } {La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e - \code{(acl\_t)NULL} per un errore, nel qual caso \var{errno} potra assumere + \val{NULL} per un errore, nel qual caso \var{errno} potra assumere solo il valore \errval{ENOMEM} nel suo significato generico.} \end{funcproto} @@ -5486,7 +5497,7 @@ sono: } {La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e - \code{(acl\_t)NULL} per un errore, nel qual caso \var{errno} assumerà uno + \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati. @@ -5542,7 +5553,7 @@ testuale con la funzione \funcd{acl\_from\_text}, il cui prototipo è: } {La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e - \code{(acl\_t)NULL} per un errore, nel qual caso \var{errno} assumerà uno + \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati. @@ -5565,17 +5576,17 @@ ordinari per la gestione delle ACL (\texttt{getfacl} e \texttt{setfacl}), che prevede due diverse forme, estesa e breve, entrambe supportate da \func{acl\_from\_text}. La forma estesa prevede che sia specificata una voce per riga, nella forma: -\begin{Verbatim} - tipo:qualificatore:permessi -\end{Verbatim} +\begin{Example} +tipo:qualificatore:permessi +\end{Example} dove il tipo può essere uno fra \texttt{user}, \texttt{group}, \texttt{other} e \texttt{mask}. Il qualificatore è presente solo per \texttt{user} e \texttt{group} e indica l'utente o il gruppo a cui la voce si riferisce; i permessi sono espressi con una tripletta di lettere analoga a quella usata per -i permessi dei file.\footnote{vale a dire \texttt{r} per il permesso di - lettura, \texttt{w} per il permesso di scrittura, \texttt{x} per il permesso - di esecuzione (scritti in quest'ordine) e \texttt{-} per l'assenza del - permesso.} +i permessi dei file.\footnote{vale a dire ``\texttt{r}'' per il permesso di + lettura, ``\texttt{w}'' per il permesso di scrittura, ``\texttt{x}'' per il + permesso di esecuzione (scritti in quest'ordine) e ``\texttt{-}'' per + l'assenza del permesso.} Va precisato che i due tipi \texttt{user} e \texttt{group} sono usati rispettivamente per indicare delle voci relative ad utenti e @@ -5620,8 +5631,9 @@ contenente la rappresentazione in forma estesa della ACL passata come argomento, ed alloca automaticamente la memoria necessaria. Questa dovrà poi essere liberata, quando non più necessaria, con \func{acl\_free}. Se nell'argomento \param{len\_p} si passa un valore puntatore ad una variabile -intera in questa verrà restituita la dimensione della stringa con la -rappresentazione testuale (non comprendente il carattere nullo finale). +intera in questa verrà restituita (come \itindex{value~result~argument} +\textit{value result argument}) la dimensione della stringa con la +rappresentazione testuale, non comprendente il carattere nullo finale. La seconda funzione, \funcd{acl\_to\_any\_text}, permette di controllare con dovizia di dettagli la generazione della stringa contenente la @@ -5699,20 +5711,19 @@ disallocato con una chiamata ad \func{acl\_free}. Si tenga presente infine che questa funzione è una estensione specifica di Linux, e non è presente nella bozza dello standard POSIX.1e. -Per quanto utile per la visualizzazione o l'impostazione da comando delle ACL, -la forma testuale non è la più efficiente per poter memorizzare i dati -relativi ad una ACL, ad esempio quando si vuole eseguirne una copia a scopo di -archiviazione. Per questo è stata prevista la possibilità di utilizzare una -rappresentazione delle ACL in una apposita forma binaria contigua e -persistente. È così possibile copiare il valore di una ACL in un buffer e da -questa rappresentazione tornare indietro e generare una ACL. +Per quanto utile per la visualizzazione o l'impostazione da riga di comando +delle ACL, la forma testuale non è la più efficiente per poter memorizzare i +dati relativi ad una ACL, ad esempio quando si vuole eseguirne una copia a +scopo di archiviazione. Per questo è stata prevista la possibilità di +utilizzare una rappresentazione delle ACL in una apposita forma binaria +contigua e persistente. È così possibile copiare il valore di una ACL in un +buffer e da questa rappresentazione tornare indietro e generare una ACL. Lo standard POSIX.1e prevede a tale scopo tre funzioni, la prima e più semplice è \funcd{acl\_size}, che consente di ottenere la dimensione che avrà la citata rappresentazione binaria, in modo da poter allocare per essa un buffer di dimensione sufficiente, il suo prototipo è: - \begin{funcproto}{ \fhead{sys/types.h} \fhead{sys/acl.h} @@ -5729,13 +5740,13 @@ buffer di dimensione sufficiente, il suo prototipo è: } \end{funcproto} - Prima di effettuare la lettura della rappresentazione binaria è sempre necessario allocare un buffer di dimensione sufficiente a contenerla, pertanto prima si dovrà far ricorso a \funcd{acl\_size} per ottenere tale dimensione e poi allocare il buffer con una delle funzioni di sez.~\ref{sec:proc_mem_alloc}. Una volta terminato l'uso della -rappresentazione binaria, il buffer dovrà essere esplicitamente disallocato. +rappresentazione binaria, il buffer dovrà essere esplicitamente disallocato, +in questo caso con \func{free}. La funzione che consente di leggere la rappresentazione binaria di una ACL è \funcd{acl\_copy\_ext}, il cui prototipo è: @@ -5769,26 +5780,24 @@ effetto sulla ACL indicata da \param{acl}. Viceversa se si vuole ripristinare una ACL a partire dalla rappresentazione binaria della stessa disponibile in un buffer si potrà usare la funzione \funcd{acl\_copy\_int}, il cui prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/acl.h} - - \funcdecl{ssize\_t acl\_copy\_int(const void *buf\_p)} - Ripristina la rappresentazione binaria di una ACL. +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/acl.h} +\fdecl{acl\_t acl\_copy\_int(const void *buf\_p)} +\fdesc{.} +} - \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso - di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso - \var{errno} assumerà uno dei valori: +{La funzione ritorna un oggetto di tipo \type{acl\_t} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EINVAL}] il buffer all'indirizzo \param{buf\_p} non contiene una rappresentazione corretta di una ACL. \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare un oggetto \type{acl\_t} per la ACL richiesta. \end{errlist} - } -\end{functions} +\end{funcproto} La funzione in caso di successo alloca autonomamente un oggetto di tipo \type{acl\_t} che viene restituito come valore di ritorno con il contenuto @@ -5801,32 +5810,30 @@ Una volta che si disponga della ACL desiderata, questa potrà essere impostata su un file o una directory. Per impostare una ACL sono disponibili due funzioni; la prima è \funcd{acl\_set\_file}, che opera sia su file che su directory, ed il cui prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/acl.h} - - \funcdecl{int acl\_set\_file(const char *path, acl\_type\_t type, acl\_t - acl)} - Imposta una ACL su un file o una directory. +\begin{funcproto}{ +\fhead{sys/types.} +\fhead{sys/acl.h} +\fdecl{int acl\_set\_file(const char *path, acl\_type\_t type, acl\_t acl)} +\fdesc{Imposta una ACL su un file o una directory.} +} - \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EACCES}] o un generico errore di accesso a \param{path} o il valore di \param{type} specifica una ACL il cui tipo non può essere assegnato a \param{path}. \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type} - ha in valore non corretto. + ha un valore non corretto. \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i dati aggiuntivi della ACL. \item[\errcode{ENOTSUP}] si è cercato di impostare una ACL su un file contenuto in un filesystem che non supporta le ACL. \end{errlist} - ed inoltre \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, - \errval{EROFS}, \errval{EPERM}. -} -\end{functions} + ed inoltre \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR}, + \errval{EPERM}, \errval{EROFS} nel loro significato generico.} +\end{funcproto} La funzione consente di assegnare la ACL contenuta in \param{acl} al file o alla directory indicate dal \textit{pathname} \param{path}, mentre @@ -5843,27 +5850,28 @@ vuota per cancellare la ACL di default associata a default, per i dettagli si ricorra alla pagina di manuale.} La seconda funzione che consente di impostare una ACL è \funcd{acl\_set\_fd}, ed il suo prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/acl.h} - - \funcdecl{int acl\_set\_fd(int fd, acl\_t acl)} - Imposta una ACL su un file descriptor. +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/acl.h} +\fdecl{int acl\_set\_fd(int fd, acl\_t acl)} +\fdesc{Imposta una ACL su un file descriptor.} +} - \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type} - ha in valore non corretto. + \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o ha più voci di + quante se ne possono assegnare al file indicato da \param{fd}. \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i dati aggiuntivi della ACL. \item[\errcode{ENOTSUP}] si è cercato di impostare una ACL su un file contenuto in un filesystem che non supporta le ACL. \end{errlist} - ed inoltre \errval{EBADF}, \errval{EROFS}, \errval{EPERM}. + ed inoltre \errval{EBADF}, \errval{EPERM}, \errval{EROFS} nel loro + significato generico. } -\end{functions} +\end{funcproto} La funzione è del tutto è analoga a \funcd{acl\_set\_file} ma opera esclusivamente sui file identificati tramite un file descriptor. Non dovendo @@ -5879,27 +5887,27 @@ voce direttamente con le funzioni previste dallo standard POSIX.1e. Queste funzioni però sono alquanto macchinose da utilizzare per cui è molto più semplice operare direttamente sulla rappresentazione testuale. Questo è il motivo per non tratteremo nei dettagli dette funzioni, fornendone solo una -descrizione sommaria; chi fosse interessato potrà ricorrere alle pagina di +descrizione sommaria; chi fosse interessato potrà ricorrere alle pagine di manuale. Se si vuole operare direttamente sui contenuti di un oggetto di tipo \type{acl\_t} infatti occorre fare riferimento alle singole voci tramite gli opportuni puntatori di tipo \type{acl\_entry\_t}, che possono essere ottenuti -dalla funzione \funcd{acl\_get\_entry} (per una voce esistente) o dalla -funzione \funcd{acl\_create\_entry} per una voce da aggiungere. Nel caso della +dalla funzione \funcm{acl\_get\_entry} (per una voce esistente) o dalla +funzione \funcm{acl\_create\_entry} per una voce da aggiungere. Nel caso della prima funzione si potrà poi ripetere la lettura per ottenere i puntatori alle singole voci successive alla prima. Una volta ottenuti detti puntatori si potrà operare sui contenuti delle singole -voci; con le funzioni \funcd{acl\_get\_tag\_type}, \funcd{acl\_get\_qualifier}, -\funcd{acl\_get\_permset} si potranno leggere rispettivamente tipo, +voci; con le funzioni \funcm{acl\_get\_tag\_type}, \funcm{acl\_get\_qualifier}, +\funcm{acl\_get\_permset} si potranno leggere rispettivamente tipo, qualificatore e permessi mentre con le corrispondente funzioni -\funcd{acl\_set\_tag\_type}, \funcd{acl\_set\_qualifier}, -\funcd{acl\_set\_permset} si possono impostare i valori; in entrambi i casi +\funcm{acl\_set\_tag\_type}, \funcm{acl\_set\_qualifier}, +\funcm{acl\_set\_permset} si possono impostare i valori; in entrambi i casi vengono utilizzati tipi di dato ad hoc.\footnote{descritti nelle singole pagine di manuale.} Si possono poi copiare i valori di una voce da una ACL -ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con -\funcd{acl\_delete\_entry}. +ad un altra con \funcm{acl\_copy\_entry} o eliminare una voce da una ACL con +\funcm{acl\_delete\_entry}. \itindend{Access~Control~List~(ACL)} @@ -5955,21 +5963,21 @@ dell'\textit{hard limit}. Questi limiti riguardano separatamente sia lo spazio disco (i blocchi) che il numero di file (gli \itindex{inode} \textit{inode}) e devono pertanto essere specificati per entrambe le risorse. -La funzione che consente di controllare tutti i vari aspetti della gestione -delle quote è \funcd{quotactl}, ed il suo prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/quota.h} - - \funcdecl{quotactl(int cmd, const char *dev, int id, caddr\_t addr)} +La funzione di sistema che consente di controllare tutti i vari aspetti della +gestione delle quote è \funcd{quotactl}, ed il suo prototipo è: - Esegue una operazione di controllo sulle quote disco. +\begin{funcproto}{ +\fhead{sys/types.h} +\fhead{sys/quota.h} +\fdecl{int quotactl(int cmd, const char *dev, int id, caddr\_t addr)} +\fdesc{Esegue una operazione di controllo sulle quote disco.} +} - \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EACCES}] il file delle quote non è un file ordinario. - \item[\errcode{EBUSY}] si è richiesto \const{Q\_QUOTAON} ma le quote sono + \item[\errcode{EBUSY}] si è richiesto \const{Q\_QUOTAON}, ma le quote sono già attive. \item[\errcode{EFAULT}] l'indirizzo \param{addr} non è valido. \item[\errcode{EIO}] errore di lettura/scrittura sul file delle quote. @@ -5977,8 +5985,8 @@ delle quote è \funcd{quotactl}, ed il suo prototipo è: superato il limite sul numero di file aperti nel sistema. \item[\errcode{EINVAL}] o \param{cmd} non è un comando valido, o il dispositivo \param{dev} non esiste. - \item[\errcode{ENODEV}] \param{dev} non corrisponde ad un \textit{mount - point} attivo. + \item[\errcode{ENODEV}] \param{dev} non corrisponde ad un + \itindex{mount~point} \textit{mount point} attivo. \item[\errcode{ENOPKG}] il kernel è stato compilato senza supporto per le quote. \item[\errcode{ENOTBLK}] \param{dev} non è un dispositivo a blocchi. @@ -5988,7 +5996,7 @@ delle quote è \funcd{quotactl}, ed il suo prototipo è: filesystem senza quote attivate. \end{errlist} } -\end{functions} +\end{funcproto} La funzione richiede che il filesystem sul quale si vuole operare sia montato con il supporto delle quote abilitato; esso deve essere specificato con il @@ -6002,10 +6010,18 @@ stessa. Il tipo di operazione che si intende effettuare deve essere indicato tramite il primo argomento \param{cmd}, questo in genere viene specificato con l'ausilio della macro \macro{QCMD}: -\begin{functions} - \funcdecl{int QCMD(subcmd,type)} Imposta il comando \param{subcmd} per il - tipo di quote (utente o gruppo) \param{type}. -\end{functions} + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{sys/quota.h} +\fdecl{int \macro{QCMD}(subcmd,type)} +\fdesc{Imposta il comando \param{subcmd} per il tipo di quote (utente o + gruppo) \param{type}.} +} +\end{funcbox} +} + \noindent che consente di specificare, oltre al tipo di operazione, se questa deve applicarsi alle quote utente o alle quote gruppo, nel qual caso \param{type} deve essere rispettivamente \const{USRQUOTA} o @@ -6401,7 +6417,7 @@ in forma di tre diverse maschere binarie,\footnote{il kernel li mantiene, come \texttt{kernel\_cap\_t}; questo era, fino al kernel 2.6.25 definito come intero a 32 bit per un massimo di 32 \textit{capabilities} distinte, attualmente è stato aggiornato ad un vettore in grado di mantenerne fino a - 64.} in cui ciascun bit corrisponde ad una capacità diversa. + 64.} in cui ciascun bit corrisponde ad una capacità diversa. L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui @@ -6967,20 +6983,18 @@ funzioni che permettono rispettivamente di leggere ed impostare i valori dei tre insiemi illustrati in precedenza. Queste due funzioni sono \funcd{capget} e \funcd{capset} e costituiscono l'interfaccia di gestione basso livello; i loro rispettivi prototipi sono: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)} - Legge le \textit{capabilities}. - - \funcdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t - datap)} - Imposta le \textit{capabilities}. +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)} +\fdesc{Legge le \textit{capabilities}.} +\fdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t datap)} +\fdesc{Imposta le \textit{capabilities}.} +} - - \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in caso - di errore, nel qual caso \var{errno} può assumere i valori: - \begin{errlist} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente. \item[\errcode{EPERM}] si è tentato di aggiungere una capacità nell'insieme delle \textit{capabilities} permesse, o di impostare una @@ -6989,9 +7003,10 @@ loro rispettivi prototipi sono: \textit{capability} di un altro processo senza avare \const{CAP\_SETPCAP}. \end{errlist} - ed inoltre \errval{EFAULT} ed \errval{EINVAL}. -} -\end{functions} + ed inoltre \errval{EFAULT} ed \errval{EINVAL} + nel loro significato generico.} +\end{funcproto} + Queste due funzioni prendono come argomenti due tipi di dati dedicati, definiti come puntatori a due strutture specifiche di Linux, illustrate in @@ -7075,17 +7090,18 @@ pertanto non soltanto fornisce le funzioni per modificare e leggere le La prima funzione dell'interfaccia è quella che permette di inizializzare un \textit{capability state}, allocando al contempo la memoria necessaria per i relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{cap\_t cap\_init(void)} - Crea ed inizializza un \textit{capability state}. - - \bodydesc{La funzione ritorna un valore non nullo in caso di successo e - \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà il - valore \errval{ENOMEM}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_init(void)} +\fdesc{Crea ed inizializza un \textit{capability state}.} +} + +{La funzione ritorna un valore non nullo in caso di successo e\val{NULL} per + un errore, nel qual caso \var{errno} potrà assumere solo il valore + \errval{ENOMEM}. +} +\end{funcproto} La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando @@ -7095,16 +7111,18 @@ mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà essere disallocata esplicitamente quando non è più necessaria utilizzando, per questo l'interfaccia fornisce una apposita funzione, \funcd{cap\_free}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_free(void *obj\_d)} - Disalloca la memoria allocata per i dati delle \textit{capabilities}. - - \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_free(void *obj\_d)} +\fdesc{Disalloca la memoria allocata per i dati delle \textit{capabilities}..} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} + La funzione permette di liberare la memoria allocata dalle altre funzioni della libreria sia per un \textit{capability state}, nel qual caso l'argomento @@ -7118,17 +7136,18 @@ fallirà con un errore di \errval{EINVAL}. Infine si può creare una copia di un \textit{capability state} ottenuto in precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{cap\_t cap\_dup(cap\_t cap\_p)} - Duplica un \textit{capability state} restituendone una copia. - - \bodydesc{La funzione ritorna un valore non nullo in caso di successo e - \val{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i - valori \errval{ENOMEM} o \errval{EINVAL}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_dup(cap\_t cap\_p)} +\fdesc{Duplica un \textit{capability state} restituendone una copia.} +} + +{La funzione ritorna un valore non nullo in caso di successo e \val{NULL} per + un errore, nel qual caso \var{errno} assumerà valori \errval{ENOMEM} o + \errval{EINVAL} nel loro significato generico.} +\end{funcproto} + La funzione crea una copia del \textit{capability state} posto all'indirizzo \param{cap\_p} che si è passato come argomento, restituendo il puntatore alla @@ -7142,17 +7161,18 @@ indipendente.\footnote{alla fine delle operazioni si ricordi però di Una seconda classe di funzioni di servizio previste dall'interfaccia sono quelle per la gestione dei dati contenuti all'interno di un \textit{capability state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_clear(cap\_t cap\_p)} - Inizializza un \textit{capability state} cancellando tutte le - \textit{capabilities}. - - \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_clear(cap\_t cap\_p)} +\fdesc{Inizializza un \textit{capability state} cancellando tutte le + \textit{capabilities}.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel \textit{capability state} all'indirizzo \param{cap\_p} passato come argomento, @@ -7181,17 +7201,18 @@ Una variante di \func{cap\_clear} è \funcd{cap\_clear\_flag} che cancella da un \textit{capability state} tutte le \textit{capabilities} di un certo insieme fra quelli di pag.~\pageref{sec:capabilities_set}, il suo prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} +\fdesc{ncella dal \textit{capability state} \param{cap\_p} tutte le + \textit{capabilities} dell'insieme \param{flag}.} +} - Cancella dal \textit{capability state} \param{cap\_p} tutte le - \textit{capabilities} dell'insieme \param{flag}. - - \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. } -\end{functions} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. +} +\end{funcproto} La funzione richiede che si indichi quale degli insiemi si intente cancellare con l'argomento \param{flag}. Questo deve essere specificato con una variabile @@ -7203,15 +7224,17 @@ illustrati in tab.~\ref{tab:cap_set_identifier}. Si possono inoltre confrontare in maniera diretta due diversi \textit{capability state} con la funzione \funcd{cap\_compare}; il suo prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)} - Confronta due \textit{capability state}. - - \bodydesc{La funzione ritorna 0 se i \textit{capability state} sono identici +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)} +\fdesc{Confronta due \textit{capability state}.} +} + +{La funzione ritorna $0$ se i \textit{capability state} sono identici ed un valore positivo se differiscono, non sono previsti errori.} -\end{functions} +\end{funcproto} + La funzione esegue un confronto fra i due \textit{capability state} passati come argomenti e ritorna in un valore intero il risultato, questo è nullo se @@ -7219,10 +7242,17 @@ sono identici o positivo se vi sono delle differenze. Il valore di ritorno della funzione consente inoltre di per ottenere ulteriori informazioni su quali sono gli insiemi di \textit{capabilities} che risultano differenti. Per questo si può infatti usare la apposita macro \macro{CAP\_DIFFERS}: -\begin{functions} - \funcdecl{int CAP\_DIFFERS(value, flag)} Controlla lo stato di eventuali - differenze delle \textit{capabilities} nell'insieme \texttt{flag}. -\end{functions} + +{\centering +\vspace{3pt} +\begin{funcbox}{ +\fhead{sys/capability.h} +\fdecl{int \macro{CAP\_DIFFERS}(value, flag)} +\fdesc{Controlla lo stato di eventuali differenze delle \textit{capabilities} + nell'insieme \texttt{flag}.} +} +\end{funcbox} +} La macro che richiede si passi nell'argomento \texttt{value} il risultato della funzione \func{cap\_compare} e in \texttt{flag} l'indicazione (coi @@ -7235,21 +7265,21 @@ Per la gestione dei singoli valori delle \textit{capabilities} presenti in un \funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono rispettivamente di leggere o impostare il valore di una capacità all'interno in uno dei tre insiemi già citati; i rispettivi prototipi sono: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t flag, cap\_flag\_value\_t *value\_p)} - Legge il valore di una \textit{capability}. +\fdesc{Legge il valore di una \textit{capability}.} +\fdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap, + cap\_value\_t *caps, cap\_flag\_value\_t value)} +\fdesc{Imposta il valore di una \textit{capability}.} +} - \funcdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap, - cap\_value\_t *caps, cap\_flag\_value\_t value)} - Imposta il valore di una \textit{capability}. - - \bodydesc{Le funzioni ritornano 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}. +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} potrà assumere solo il valore \errval{EINVAL}. } -\end{functions} +\end{funcproto} In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al \textit{capability state} su cui operare, mentre l'argomento \param{flag} @@ -7311,19 +7341,18 @@ di un \textit{capability state} e fornisce le opportune funzioni di gestione;\footnote{entrambe erano previste dalla bozza dello standard POSIX.1e.} la prima di queste, che consente di ottenere la rappresentazione testuale, è \funcd{cap\_to\_text}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)} +\fdesc{Genera una visualizzazione testuale delle \textit{capabilities}.} +} - Genera una visualizzazione testuale delle \textit{capabilities}. - - \bodydesc{La funzione ritorna un puntatore alla stringa con la descrizione - delle \textit{capabilities} in caso di successo e \val{NULL} in caso di - errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL} o - \errval{ENOMEM}. - } -\end{functions} +{La funzione ritorna un puntatore alla stringa con la descrizione delle + \textit{capabilities} in caso di successo e \val{NULL} per un errore, nel + qual caso \var{errno} assumerà i valori \errval{EINVAL} o \errval{ENOMEM} + nel loro significato generico.} +\end{funcproto} La funzione ritorna l'indirizzo di una stringa contente la descrizione testuale del contenuto del \textit{capability state} \param{caps} passato come @@ -7383,17 +7412,18 @@ detto processo. Viceversa per passare ottenere un \textit{capability state} dalla sua rappresentazione testuale si può usare \funcd{cap\_from\_text}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{cap\_t cap\_from\_text(const char *string)} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_from\_text(const char *string)} +\fdesc{Crea un \textit{capability state} dalla sua rappresentazione testuale.} +} - Crea un \textit{capability state} dalla sua rappresentazione testuale. +{La funzione ritorna un puntatore valid in caso di successo e \val{NULL} per + un errore, nel qual caso \var{errno} assumerà i valori \errval{EINVAL} o + \errval{ENOMEM} nel loro significato generico.} +\end{funcproto} - \bodydesc{La funzione ritorna un puntatore valido in caso di successo e - \val{NULL} in caso di errore, nel qual caso \var{errno} può assumere i - valori \errval{EINVAL} o \errval{ENOMEM}.} -\end{functions} La funzione restituisce il puntatore ad un \textit{capability state} inizializzato con i valori indicati nella stringa \param{string} che ne @@ -7406,20 +7436,22 @@ convertire i valori delle costanti di tab.~\ref{tab:proc_capabilities} nelle stringhe usate nelle rispettive rappresentazioni e viceversa. Le due funzioni, \funcd{cap\_to\_name} e \funcd{cap\_from\_name}, sono estensioni specifiche di Linux ed i rispettivi prototipi sono: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{char * cap\_to\_name(cap\_value\_t cap)} - \funcdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)} - Convertono le \textit{capabilities} dalle costanti alla rappresentazione - testuale e viceversa. - - \bodydesc{La funzione \func{cap\_to\_name} ritorna un valore diverso da - \val{NULL} in caso di successo e \val{NULL} in caso di errore, mentre - \func{cap\_to\_name} ritorna rispettivamente 0 e $-1$; per entrambe in - caso di errore \var{errno} può assumere i valori \errval{EINVAL} o - \errval{ENOMEM}. } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{char * cap\_to\_name(cap\_value\_t cap)} +\fdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)} + +\fdesc{Convertono le \textit{capabilities} dalle costanti alla rappresentazione + testuale e viceversa.} +} + +{La funzione \func{cap\_to\_name} ritorna un puntatore ad una stringa in caso + di successo e \val{NULL} per un errore, mentre \func{cap\_to\_name} ritorna + $0$ in caso di successo e $-1$ nel qual caso di errore, per entrambe + \var{errno}può assumere i valori \errval{EINVAL} o \errval{ENOMEM}. +} +\end{funcproto} La prima funzione restituisce la stringa (allocata automaticamente e che dovrà essere liberata con \func{cap\_free}) che corrisponde al valore della @@ -7433,16 +7465,18 @@ l'interfaccia di gestione prevede però anche le funzioni per trattare le \textit{capabilities} presenti nei processi. La prima di queste funzioni è \funcd{cap\_get\_proc} che consente la lettura delle \textit{capabilities} del processo corrente, il suo prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{cap\_t cap\_get\_proc(void)} - Legge le \textit{capabilities} del processo corrente. - - \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di - successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può - assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}. } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{cap\_t cap\_get\_proc(void)} +\fdesc{Legge le \textit{capabilities} del processo corrente.} +} + +{La funzione ritorna un valore diverso da \val{NULL} in caso di successo e + \val{NULL} per un errore, nel qual caso \var{errno} assumerà i valori + \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM} nel loro significato + generico.} +\end{funcproto} La funzione legge il valore delle \textit{capabilities} associate al processo da cui viene invocata, restituendo il risultato tramite il puntatore ad un @@ -7456,17 +7490,18 @@ prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t}, ma il valore di ritorno è intero, come si può verificare anche dalla dichiarazione della stessa in \headfile{sys/capability.h}.} è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)} - Legge le \textit{capabilities} del processo indicato da \param{pid}. - - \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, - \errval{EPERM} o \errval{ENOMEM}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int capgetp(pid\_t pid, cap\_t cap\_d)} +\fdesc{Legge le \textit{capabilities} di un processo.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà i valori \errval{EINVAL}, \errval{EPERM} o + \errval{ENOMEM} nel loro significato generico.} +\end{funcproto} + %TODO controllare e correggere i codici di errore!!! La funzione legge il valore delle \textit{capabilities} del processo indicato @@ -7490,17 +7525,17 @@ Infine per impostare le \textit{capabilities} del processo corrente (non esiste una funzione che permetta di cambiare le \textit{capabilities} di un altro processo) si deve usare la funzione \funcd{cap\_set\_proc}, il cui prototipo è: -\begin{functions} - \headdecl{sys/capability.h} - \funcdecl{int cap\_set\_proc(cap\_t cap\_p)} - Imposta le \textit{capabilities} del processo corrente. - - \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di - errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL}, - \errval{EPERM} o \errval{ENOMEM}. - } -\end{functions} +\begin{funcproto}{ +\fhead{sys/capability.h} +\fdecl{int cap\_set\_proc(cap\_t cap\_p)} +\fdesc{Imposta le \textit{capabilities} del processo corrente.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà i valori \errval{EINVAL}, \errval{EPERM} o + \errval{ENOMEM} nel loro significato generico.} +\end{funcproto} La funzione modifica le \textit{capabilities} del processo corrente secondo quanto specificato con l'argomento \param{cap\_p}, posto che questo sia diff --git a/img/fileperm.dia b/img/fileperm.dia index ddb68ada930e9735db36ac78152d89144980779f..8a1c4ff9a1410498d17ba683b584fea1a93fd708 100644 GIT binary patch delta 1879 zcmV-d2dMbo4%iNm7Jv6OrFqe{Yf`KO1`HUmhjq^ZZ8MHmSu!L#iC^~FN6C&Y+mcnA zB3q@$Kmtf$&JpSV`H4Kde8j56^&Z1;~JNoC#@9%@rr@O(& zS;Rl6pLxa?L-iL)UR>Rd9;IA<7>}QypHaNdxlA(@M=O+z@qd3jj`>&>8jtPDPIdu9DekQ)*jon#O51eB$x#=-os48I8AQ#s_xJ z*k1Cvm}G)~Z8nY7Ck(GKy%gE8*~K!=BUMDMmnTIU>=eH%WwxbqRVbO?z5CU9w|S)P zjlHe92W@mB7k@mPN6D!l)i&{_At(wcrK&O9FbJ{l_~f-sE_XMv>n^tIF0<<{%I}wH zCNmz%QTl&8?$Xdg&tOYmsfu zf8M{$hubfB%cUWo%IN9!s?sLu&qMJNfB9qj zd|%UDZGRWn6JflU|JCt8bmKv3({MbHA`-Uoz<&_75f56Gf_Uh0JW$undT> zcs+Qy3KupslxfjW-tieU~sxLyWt$MOrOqa+0>qhyP7>(7J{0)L8R;1CrD5IO znPn(VE1%Lt)_E%K4rhsH+(1EqI)v&uJ=EVfY4931hs$%$tn|cK&k>KKd9o1o->6W`sadylZsk(l z;+xBY;;DS3giVjmNVQKydwaGui$ySx_6AtQ^v^*wJx0UT zF&ggC7!6otiA5O3XnkT)!|q1v=wZm8K)#=-(Vp+iDaoHK^q8;Y>fd1(6lo5Pyb zpGHRC-VVn`_VP^L^DIlBn}1cSZ~HzL$^3i`$k8!p9XM@mwT^r$-5F}aon?CsxOdrk z^L0cww~JF0so4`nD|B0%^^4e#}H3Xagt zFwiglZ-LW?4i}H(pS8QC#_B=nW8!-1Rb*wWABLq{Js$xw+Qs%7iip|mHN_71ut1UW z=G`#G?H-^gAIL#8_&Qj__|L}p??i|Iq&@`}@(oo_%CQ)ybG!ML9U}>(f zGy^Evff5BM^&d)37n^O&LJ1?E?U|(fd3{3C3Xo(ANheYSBz;#TZLVX!7TMikbD@6b R8DHED{s&2jjk>Op001;Xtp)%9 delta 1885 zcmV-j2cr1c4&Dxs7Jv0MrAg}E)hX5i0}2cnuyxM{Z8Nr3Su!L#iC^~FN69zYy2Yl* zR0##7s0HR6k^Y~b$iquMe|cVo!$+E=K^%<@1fVgb(JY<^(PC`;^Zoaap7G^=@Od7P zPyA<*kkyd?MwDis#>SGd^{3J3>FEiC+mx_40b#HKDINVs!hevAc%hMTKNt>+2Ihp3 z?B4z^VJr!z8%Bo_S<$gEC9@xkB;G`GV^?ZlZWf1eGJGWA*!b{}U&d%}W^`t!!S@Pt4R{f@U6+c~*vbAal-ZX`d7)@=|KV5b!|svxH%_*y z9<Na?znpu6H+8>n>F5E>Y_)NGIz!VF?LX z+2u5jLrS8ZSC(w(?S9f33Ax0YswGg1hk&uT<@p~-n7*U}yW7WTyEbwcNic5?+_Mrj zR-S@6TTY&vnhOGG!}H6$y#;p;x9S`|25B%2X;mGAh<^zy;$VK;jrq&(FlYSf*9A4R zvsU{OnS0cx_Vq83#U_~3v_*{PWoj%f_r*qSt$tbVr46&Yb@58iU4&#ylfC(`r4G$bGaZi!k?c+i;x~X*sjfexUT&R;x7XGF8}v7k2IvK z$t+Hya!;bGO64wcx|Az+BtO6c#+Ni$ELnr~+iXwcWKNT|M{kDWHU83N{4}ZPuC~96 ztBEi=$^YhfK%()$wJA9sP!%7o7HT6>Az}}e~rQoX8+Xld0-%NLiHBVAf{L0XP7X*uoE(jE8)X(1?{ zNw=hD(odZ&q^z@r+B;iFceWa}B|b|deSglN|aA1y!Mgs)Xk{ z?7X*ONz|1M5X!WKP@dq$UiQIqZu7{pc4%4laZ#o&JDIPhJ1cjw@b0;0-Ce^nl)9Bq zam1=TW%q{Ti^C=2Wa(YFfEewfN?`pm@w5 z=`t)%k7BA}k@#GbWD=RcKat1+P?JcLs8NBMLw)3sC7vPhB$EgO_e3J@PLoKJs6~UC zMSWzE@SL#h(HScCiExklM2RMmB7YKT4)vcy9V{cj(nn{7JdxR>Jdq}mA`+Q8PxKa8 zq$*dWS@Z^2bHgS~RFx)I%0wC_YB>q>s_u;uy`-EYd7$(V%8gA6eAF`F|#k^jWk* zzXo;Xm5Z;ruaFCvd3t!I7Wj# z8l!0zDPj@SW3)c8sAhK~w#4_LS$A0ODPw*HAKyYg%FY>s_8kV0>)e-p{>^#Ks!t=s zZ*PZVEqh7ACL~GXr+U?j+kc*fG+H#*09_n&)`8R3R_n+o*PWy$JX%)QfG3xoH(y6| zv%5G&5z9SMv_Lm2Kh8uA-7acYb@HfYn`WD4+t122@s;6H$%gV1zz$?H^K&WGkj-r7 zT6Vs;CYvUkCfjS1tu8<2cCoe-1G)V+z?N?AZ5UMbnRe#VZo2$dF;vKfhG0?mSbW&XDynTkmzTx>GKVOknN^#A###Z%3wn z&?q}%e*Ky_^3HMejd9h@-XxDoI@CPsBai$pR(Q(gkp*n?*gdiV>{b6LX3N*@AiW_Zp4F}HFWxyiC#7>zIw$pW=A=y2#V8O; z-s5Lw9KqQb(9Ql@fz^xt774@m+S~H@<+~8s4u2CV+2IHEimjfH|4iJ)t{M!G++8)< z#&#cPTWXv;lS8`?BuWQt5Db0{wtDoZV)R$iq2^H^d1Q96vsOknk5HbE+9L_?^HHAD z4=ODRVM8|hh$5W X`@!x5|5+qtbwBtYb_R;MqmcjrKxnDD -- 2.30.2