Soluzioni compito del 16/07/2012

Esercizio 1

Al solito, l'esercizio di comprensione del codice e' autocontenuto. Eseguite lo script seguente col vostro numero di matricola come argomento per avere la soluzione:

#!/bin/bash

a=0
foo() {
        for i in $* ;
                do echo ${i##7} ;
                a=${#i}+$a ;
        done ;
}

bar() {
        typeset -a b;
        i=$1
        j=0
        while ((${#i}>1)) ; do 
                b[$j]=$(($i%100));
                i=$(($i/100));
                j=1+$j;
                echo $(($j)) $i
        done ;
        echo ${#b[@]}
        foo ${b[*]} ;
}

bar $1
echo $a

Esercizio 2

Il testo chiede di definire un protocollo applicativo per registrazione e invio di messaggi, e di implementare il server che gestisce il sistema di comunicazione.

Il protocollo contiene, naturalmente, due tipi di messaggi: il messaggio di registrazione e quello di invio di testo. Possiamo definire il messaggio di registrazione come “JOIN <#canale>\n”, mentre il messaggio di testo puo' essere preso come default (tutto cio' che non corrisponde ad un altro comando e' inteso come testo da inviare ai client).

Il server deve mantenere una lista di client (identificati dai loro descrittori di file), e associare a ciascun client il canale richiesto o nessun canale prima dell'arrivo del messaggio di registrazione; assumiamo un valore “non associato”, ad esempio:

#define NOCHAN -1

Ai fini della soluzione, la lista puo' essere sostituita da un array, per evitare la complessita' (peraltro non enorme) della creazione dinamica della struttura dati.

Notate che, siccome il client puo' scegliere di cambiare il canale in uso, e' piu' semplice realizzare un server multi-thread o sequenziale che non un server multiprocesso.

Nel caso del server sequenziale (consigliato per semplicita'), si impiega la funzione select per attendere una scrittura su uno o piu' dei file descriptor associati ai client, come visto nell'esempio presentato a lezione.

La differenza rispetto a quel caso sta nel fatto che, in risposta alla lettura di un messaggio “JOIN <#canale>\n” il server deve aggiornare la lista dei client con l'informazione opportuna, mentre per qualunque altra stringa s letta dal descrittore fd, deve svolgere le seguenti operazioni:

for(sender=list_head; 
    sender->fd!=fd && sender!=NULL; 
    curr=sender->next);
if (sender==NULL) error();
for(curr=list_head;
    curr!=NULL;
    curr=curr->next)
  if (curr->chan==sender->chan) 
     write(curr->fd,s, strlen(s));

Notate che sono possibili molte altre soluzioni, questa e' solo quella che mi sembra piu' semplice.

Esercizio 3

  1. seteuid cambia l'uid effettivo (quello che viene impiegato per determinare i permessi); poiche' viene posto a 300 prima di leggere un file che non appartiene all'utente 300 e ha solo permessi di lettura per il proprietario, la lettura fallisce.
  2. Sono differenti (vedete le slide); la prima accetta anche pacchetti con indirizzo sorgente modificato opportunamente.
  3. Dato che i dati sono piccoli, si puo' lasciare una cella vuota per l'identificazione del buffer pieno. Nel secondo caso e' meglio non farlo. Si puo' quindi usare un contatore, o uno degli altri metodi visti nelle esercitazioni.
teaching/pswr/soluzioni_compito_del_16_07_2012.txt · Last modified: 2012/07/18 11:08 by agosta
Recent changes RSS feed Creative Commons License Donate Driven by DokuWiki