From: Simone Piccardi Date: Tue, 29 Apr 2003 15:33:39 +0000 (+0000) Subject: Corretti i commenti ai listati in una forma piu' leggibile (spero). X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=d47f15496fa85c8ec22edcde608f2665ec5b95ae Corretti i commenti ai listati in una forma piu' leggibile (spero). Proseguito nella revisione dei nomi dei programmi. Inseriti gli opportuni link all'IETF per tutti gli RFC --- diff --git a/elemtcp.tex b/elemtcp.tex index c57bbcf..b074cb0 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -9,7 +9,7 @@ %% License". %% \chapter{Socket TCP} -\label{cha:elem_TCP_sock} +\label{cha:TCP_socket} In questo capitolo iniziamo ad approfondire la conoscenza dei socket TCP, iniziando con una descrizione delle principali caratteristiche del @@ -1108,7 +1108,6 @@ scritti nella struttura puntata da \param{name}. Si tenga presente che se si utilizzato un buffer troppo piccolo per \param{name} l'indirizzo risulterà troncato. - La funzione si usa tutte le volte che si vuole avere l'indirizzo locale di un socket; ad esempio può essere usata da un client (che usualmente non chiama \func{bind}) per ottenere numero IP e porta locale associati al socket @@ -1146,7 +1145,8 @@ restituisce l'indirizzo remoto del socket, cio capo della connessione. Ci si può chiedere a cosa serva questa funzione dato che dal lato client l'indirizzo remoto è sempre noto quando si esegue la \func{connect} mentre dal lato server si possono usare, come vedremo in -\figref{fig:TCP_cunc_serv_code}, i valori di ritorno di \func{accept}. +\figref{fig:TCP_daytime_cunc_server_code}, i valori di ritorno di +\func{accept}. Il fatto è che in generale quest'ultimo caso non è sempre possibile. In particolare questo avviene quando il server, invece di gestire la connessione @@ -1299,11 +1299,12 @@ nell'\href{http://www.ietf.org/rfc/rfc0867.txt}{RFC~867}, che restituisce l'ora locale della macchina a cui si effettua la richiesta, e che è assegnato alla porta 13. -In \figref{fig:TCP_cli_code} è riportata la sezione principale del codice del -nostro client. Il sorgente completo del programma (\file{TCP_daytime.c}, che -comprende il trattamento delle opzioni ed una funzione per stampare un -messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e -può essere compilato su una qualunque macchina GNU/Linux. +In \figref{fig:TCP_daytime_client_code} è riportata la sezione principale del +codice del nostro client. Il sorgente completo del programma +(\file{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una +funzione per stampare un messaggio di aiuto) è allegato alla guida nella +sezione dei codici sorgente e può essere compilato su una qualunque macchina +GNU/Linux. \begin{figure}[!htb] \footnotesize \centering @@ -1350,9 +1351,10 @@ ritorna (\texttt{\small 31}). Completata con successo la connessione il passo successivo (\texttt{\small 34--40}) è leggere la data dal socket; il protocollo prevede che il server -invii sempre una stringa alfanumerica di 26 caratteri, nella forma giorno -della settimana, mese, ora minuto e secondo, anno, seguita dai caratteri di -terminazione \verb|\r\n|, cioè qualcosa del tipo: +invii sempre una stringa alfanumerica, il formato della stringa non è +specificato dallo standard, per cui noi useremo il formato usato dalla +funzione \func{ctime}, seguito dai caratteri di terminazione \verb|\r\n|, cioè +qualcosa del tipo: \begin{verbatim} Wed Apr 4 00:53:00 2001\r\n \end{verbatim} @@ -1399,7 +1401,7 @@ elementare, che sia anche in grado di rispondere al precedente client. Come primo esempio realizzeremo un server iterativo, in grado di fornire una sola risposta alla volta. Il codice del programma è nuovamente mostrato in \figref{fig:TCP_daytime_iter_server_code}, il sorgente completo -(\file{TCP_iter_daytimed.c}) è allegato insieme agli altri file degli esempi. +(\file{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli esempi. \begin{figure}[!htbp] \footnotesize \centering @@ -1477,36 +1479,37 @@ non \subsection{Un server \textit{daytime} concorrente} \label{sec:TCP_daytime_cunc_server} -Il server \texttt{daytime} dell'esempio in \secref{sec:TCP_daytime_client} è un -tipico esempio di server iterativo, in cui viene servita una richiesta alla -volta; in generale però, specie se il servizio è più complesso e comporta uno -scambio di dati più sostanzioso di quello in questione, non è opportuno -bloccare un server nel servizio di un client per volta; per questo si ricorre -alle capacità di multitasking del sistema. +Il server \texttt{daytime} dell'esempio in +\secref{sec:TCP_daytime_iter_server} è un tipico esempio di server iterativo, +in cui viene servita una richiesta alla volta; in generale però, specie se il +servizio è più complesso e comporta uno scambio di dati più sostanzioso di +quello in questione, non è opportuno bloccare un server nel servizio di un +client per volta; per questo si ricorre alle capacità di multitasking del +sistema. Come accennato anche in \secref{sec:proc_gen} una delle modalità più comuni di funzionamento da parte dei server è quella di usare la funzione \func{fork} per creare, ad ogni richiesta da parte di un client, un processo figlio che si incarichi della gestione della comunicazione. Si è allora riscritto il server -\texttt{daytime} dell'esempio precedente in forma concorrente, inserendo anche +\textit{daytime} dell'esempio precedente in forma concorrente, inserendo anche una opzione per la stampa degli indirizzi delle connessioni ricevute. -In \figref{fig:TCP_cunc_serv_code} è mostrato un estratto del codice, in cui -si sono tralasciati il trattamento delle opzioni e le parti rimaste invariate -rispetto al precedente esempio (cioè tutta la parte riguardante l'apertura -passiva del socket). Al solito il sorgente completo del server, nel file -\file{ElemDaytimeTCPCuncServ.c}, è allegato insieme ai sorgenti degli altri -esempi. +In \figref{fig:TCP_daytime_cunc_server_code} è mostrato un estratto del +codice, in cui si sono tralasciati il trattamento delle opzioni e le parti +rimaste invariate rispetto al precedente esempio (cioè tutta la parte +riguardante l'apertura passiva del socket). Al solito il sorgente completo del +server, nel file \file{TCP\_cunc\_daytimed.c}, è allegato insieme ai sorgenti +degli altri esempi. \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} - \includecodesample{listati/ElemDaytimeTCPCuncServ.c} + \includecodesample{listati/TCP_cunc_daytimed.c} \end{minipage} \normalsize \caption{Esempio di codice di un server concorrente elementare per il servizio daytime.} - \label{fig:TCP_cunc_serv_code} + \label{fig:TCP_daytime_cunc_server_code} \end{figure} Stavolta (\texttt{\small 21--25}) la funzione \func{accept} è chiamata @@ -1577,6 +1580,7 @@ torneremo su questo pi complessi. + \section{Un esempio più completo: il servizio \textit{echo}} \label{sec:TCP_echo_application} @@ -1587,54 +1591,58 @@ un po' pi le direzioni, implementando il servizio standard \textit{echo}, così come definito dall'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~862}. -Si è scelto di usare questo servizio, seguendo l'esempio di \cite{UNP1}, -perché costituisce il prototipo ideale di una generica applicazione di rete in -cui un server risponde alle richieste di un client; nel caso di una -applicazione più complessa si potrà avere in più una elaborazione dell'input -del client da parte del server nel fornire le risposte in uscita. +Si è scelto, seguendo l'esempio di \cite{UNP1}, di usare questo servizio, che +si limita a restituire in uscita quanto immesso in ingresso, perché nonostante +la sua estrema semplicità costituisce il prototipo ideale di una generica +applicazione di rete in cui un server risponde alle richieste di un client; +nel caso di una applicazione più complessa si potrà avere in più una +elaborazione dell'input del client da parte del server nel fornire le risposte +in uscita. -Ci limiteremo ad un esempio elementare, che usi solo le funzioni di base, ma -prenderemo in esame, oltre al comportamento in condizioni normali, anche tutti -i possibili scenari particolari (errori, sconnessione della rete, crash del -client o del server durante la connessione) che possono avere luogo durante -l'impiego di un'applicazione di rete. +Ci limiteremo per ora ad una implementazione elementare, che usi solo le +funzioni di base, ma prenderemo in esame, oltre al comportamento in condizioni +normali, anche tutti i possibili scenari particolari (errori, sconnessione +della rete, crash del client o del server durante la connessione) che possono +avere luogo durante l'impiego di un'applicazione di rete, partendo da una +versione primitiva che dovrà essere rimaneggiata di volta in volta per poter +tenere conto di tutte le evenienze che si possono manifestare nella vita reale +di un'applicazione di rete, fino ad arrivare ad un'implementazione completa. -Partiremo da un'implementazione elementare che dovrà essere rimaneggiata di -volta in volta per poter tenere conto di tutte le evenienze che si possono -manifestare nella vita reale di un'applicazione di rete, fino ad arrivare ad -un'implementazione completa. \subsection{Il client: prima versione} \label{sec:TCP_echo_client} -Il codice del client è riportato in \figref{fig:TCPsimpl_client_elem}, anche -esso ricalca la struttura del precedente client per il servizio -\texttt{daytime} (vedi \secref{sec:TCP_daytime_client}) ma, come per il -server, lo si è diviso in due parti, inserendo la parte relativa alle -operazioni specifiche previste per il protocollo \textit{echo} in una funzione -a parte. +Il codice della prima versione client per il servizio \textit{echo} è +riportato in \figref{fig:TCP_echo_client_1}. Esso ricalca la struttura del +precedente client per il servizio \textit{daytime} (vedi +\secref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27}) è +sostanzialmente identica, a parte l'uso di una porta diversa. \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15.6 cm} - \includecodesample{listati/EchoServerWrong.c} + \includecodesample{listati/TCP_echo_client.c} \end{minipage} \normalsize \caption{Codice della prima versione del client \textit{echo}.} - \label{fig:TCPsimpl_client_elem} + \label{fig:TCP_echo_client_1} \end{figure} -La funzione \code{main} si occupa della creazione del socket e della -connessione (linee \texttt{\small 10--27}) secondo la stessa modalità spiegata -in \secref{sec:TCP_daytime_client}, il client si connette sulla porta 7 -all'indirizzo specificato dalla linea di comando (a cui si è aggiunta una -elementare gestione delle opzioni non riportata in figura). - -Completata la connessione, al ritorno di \func{connect}, la funzione -\code{ClientEcho}, riportata in \figref{fig:TCPsimpl_client_echo_sub}, si -preoccupa di gestire la comunicazione, leggendo una riga alla volta dallo -\file{stdin}, scrivendola sul socket e ristampando su \file{stdout} quanto -ricevuto in risposta dal server. +Al solito si è tralasciata la sezione relativa alla gestione delle opzioni a +riga di comando; una volta dichiarate le variabili, si prosegue +(\texttt{\small 10--13}) con della creazione del socket, la preparazione +(\texttt{\small 14--17}) la struttura per l'indirizzo, con la relativa +conversione (\texttt{\small 18--22}) di quanto specificato a riga di comando. + +A questo punto (\texttt{\small 23--27}) si può eseguire la connessione al +server secondo la stessa modalità usata in \secref{sec:TCP_daytime_client}. +Completata la connessione, al ritorno di \func{connect}, si usa la funzione +\code{ClientEcho}, il cui codice è riportato in +\figref{fig:TCPsimpl_client_echo_sub}. Questa si preoccupa di gestire tutta la +comunicazione, leggendo una riga alla volta dallo standard input \file{stdin}, +scrivendola sul socket e ristampando su \file{stdout} quanto ricevuto in +risposta dal server. Al ritorno dalla funzione (\texttt{\small 30--31}) anche +il programma termina. \begin{figure}[!htb] \footnotesize \centering @@ -1647,27 +1655,28 @@ ricevuto in risposta dal server. \label{fig:TCPsimpl_client_echo_sub} \end{figure} -La funzione utilizza due buffer per gestire i dati inviati e letti sul socket -(\texttt{\small 3}). La comunicazione viene gestita all'interno di un ciclo -(linee \texttt{\small 5--10}), i dati da inviare sulla connessione vengono -presi dallo \file{stdin} usando la funzione \func{fgets} che legge una -linea di testo (terminata da un \texttt{CR} e fino al massimo di -\const{MAXLINE} caratteri) e la salva sul buffer di invio, la funzione -\func{FullWrite} (\texttt{\small 3}) scrive detti dati sul socket (gestendo -l'invio multiplo qualora una singola \func{write} non basti, come spiegato -in \secref{sec:sock_io_behav}). +La funzione \code{ClientEcho} utilizza due buffer (\texttt{\small 3}) per +gestire i dati inviati e letti sul socket. La comunicazione viene gestita +all'interno di un ciclo (\texttt{\small 5--10}), i dati da inviare sulla +connessione vengono presi dallo \file{stdin} usando la funzione \func{fgets}, +trattata in \secref{sec:file_line_io}, che legge una linea di testo (terminata +da un \texttt{CR} e fino al massimo di \const{MAXLINE} caratteri) e la salva +sul buffer di invio, la funzione \func{FullWrite}, già vista in +\figref{fig:sock_FullWrite_code}, scrive (\texttt{\small 6}) i dati sul socket +(gestendo l'invio multiplo qualora una singola \func{write} non basti, come +spiegato in \secref{sec:sock_io_behav}). -I dati che vengono riletti indietro con una \func{FullRead} sul buffer di -ricezione e viene inserita la terminazione della stringa (\texttt{\small - 7--8}) e per poter usare la funzione \func{fputs} per scriverli su -\file{stdout}. +I dati vengono riletti indietro (\texttt{\small 7}) con una \func{FullRead} +sul buffer di ricezione e viene inserita (\texttt{\small 8}) la terminazione +della stringa e per poter usare (\texttt{\small 9}) la funzione \func{fputs} +per scriverli su \file{stdout}. -Un end of file inviato su \file{stdin} causa il ritorno di \func{fgets} -con un puntatore nullo e l'uscita dal ciclo, al che la subroutine ritorna ed -il client esce. +Un end-of-file inviato su \file{stdin} (ad esempio con la pressione di +\texttt{C-d}) causa il ritorno di \func{fgets} con un puntatore nullo e la +conseguente uscita dal ciclo, al che la subroutine ritorna ed il client esce. -\subsection{La struttura del server} +\subsection{Il server: prima versione} \label{sec:TCPsimp_server_main} Il servizio \textit{echo} è uno dei servizi standard solitamente provvisti @@ -1705,7 +1714,7 @@ nel precedente esempio esaminato in \secref{sec:TCP_daytime_cunc_server}. La struttura di questa prima versione del server è sostanzialmente identica a quella dell'esempio citato, ed ad esso si applicano le considerazioni fatte in \secref{sec:TCP_daytime_cunc_server}. Le uniche differenze rispetto -all'esempio in \figref{fig:TCP_daytime_iter_server_code} sono che in questo +all'esempio in \figref{fig:TCP_daytime_cunc_server_code} sono che in questo caso per il socket in ascolto viene usata la porta 7 e che tutta la gestione della comunicazione è delegata alla funzione \code{ServEcho}. % Per ogni connessione viene creato un diff --git a/listati/ComputeValues.c b/listati/ComputeValues.c index bc11c28..e3c61f1 100644 --- a/listati/ComputeValues.c +++ b/listati/ComputeValues.c @@ -2,7 +2,7 @@ int ComputeValues(struct dirent * direntry) { struct stat data; - stat(direntry->d_name, &data); /* get stat data */ + stat(direntry->d_name, &data); /* get stat data */ shmptr->tot_size += data.st_size; shmptr->tot_files++; if (S_ISREG(data.st_mode)) shmptr->tot_regular++; diff --git a/listati/DirMonitor.c b/listati/DirMonitor.c index edd5bb9..65173c8 100644 --- a/listati/DirMonitor.c +++ b/listati/DirMonitor.c @@ -17,33 +17,33 @@ int main(int argc, char *argv[]) { int i, pause = 10; ... - if ((argc - optind) != 1) { /* There must be remaing parameters */ + if ((argc - optind) != 1) { /* There must be remaing parameters */ printf("Wrong number of arguments %d\n", argc - optind); usage(); } - if (chdir(argv[1])) { /* chdir to be sure dir exist */ + if (chdir(argv[1])) { /* chdir to be sure dir exist */ perror("Cannot find directory to monitor"); } - Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ + Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ Signal(SIGINT, HandSIGTERM); Signal(SIGQUIT, HandSIGTERM); - key = ftok("~/gapil/sources/DirMonitor.c", 1); /* define a key */ - shmptr = ShmCreate(key, 4096, 0666, 0); /* get a shared memory segment */ + key = ftok("~/gapil/sources/DirMonitor.c", 1); /* define a key */ + shmptr = ShmCreate(key, 4096, 0666, 0); /* get a shared memory segment */ if (!shmptr) { perror("Cannot create shared memory"); exit(1); } - if ((mutex = MutexCreate(key)) == -1) { /* get a Mutex */ + if ((mutex = MutexCreate(key)) == -1) { /* get a Mutex */ perror("Cannot create mutex"); exit(1); } /* main loop, monitor directory properties each 10 sec */ - daemon(1, 0); /* demonize process, staying in monitored dir */ + daemon(1, 0); /* demonize process, staying in monitored dir */ while (1) { - MutexLock(mutex); /* lock shared memory */ - memset(shmptr, 0, sizeof(struct DirProp)); /* erase previous data */ - DirScan(argv[1], ComputeValues); /* execute scan */ - MutexUnlock(mutex); /* unlock shared memory */ - sleep(pause); /* sleep until next watch */ + MutexLock(mutex); /* lock shared memory */ + memset(shmptr, 0, sizeof(struct DirProp)); /* erase previous data */ + DirScan(argv[1], ComputeValues); /* execute scan */ + MutexUnlock(mutex); /* unlock shared memory */ + sleep(pause); /* sleep until next watch */ } } diff --git a/listati/DirScan.c b/listati/DirScan.c index 725b524..b54b15d 100644 --- a/listati/DirScan.c +++ b/listati/DirScan.c @@ -15,17 +15,17 @@ int DirScan(char * dirname, int(*compute)(struct dirent *)) DIR * dir; struct dirent *direntry; - if ( (dir = opendir(dirname)) == NULL) { /* oper directory */ - printf("Opening %s\n", dirname); /* on error print messages */ - perror("Cannot open directory"); /* and then return */ + if ( (dir = opendir(dirname)) == NULL) { /* open directory */ + printf("Opening %s\n", dirname); /* on error print messages */ + perror("Cannot open directory"); /* and then return */ return -1; } - fd = dirfd(dir); /* get file descriptor */ - fchdir(fd); /* change directory */ + fd = dirfd(dir); /* get file descriptor */ + fchdir(fd); /* change directory */ /* loop on directory entries */ - while ( (direntry = readdir(dir)) != NULL) { /* read entry */ - if (compute(direntry)) { /* execute function on it */ - return -1; /* on error return */ + while ( (direntry = readdir(dir)) != NULL) { /* read entry */ + if (compute(direntry)) { /* execute function on it */ + return -1; /* on error return */ } } closedir(dir); diff --git a/listati/EchoServerWrong.c b/listati/EchoServerWrong.c deleted file mode 100644 index f9a67b6..0000000 --- a/listati/EchoServerWrong.c +++ /dev/null @@ -1,32 +0,0 @@ -int main(int argc, char *argv[]) -{ -/* - * Variables definition - */ - int sock_fd, i; - struct sockaddr_in serv_add; - ... - /* create socket */ - if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - return -1; - } - /* initialize address */ - memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(7); /* echo port is 7 */ - /* build address using inet_pton */ - if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) { - perror("Address creation error"); - return -1; - } - /* extablish connection */ - if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("Connection error"); - return -1; - } - /* read daytime from server */ - ClientEcho(stdin, sock_fd); - /* normal exit */ - return 0; -} diff --git a/listati/ElemDaytimeTCPCuncServ.c b/listati/ElemDaytimeTCPCuncServ.c deleted file mode 100644 index 9af8cc7..0000000 --- a/listati/ElemDaytimeTCPCuncServ.c +++ /dev/null @@ -1,52 +0,0 @@ -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utililites */ -#include /* socket library */ -#include /* include standard I/O library */ -#include - -int main(int argc, char *argv[]) -{ - int list_fd, conn_fd; - int i; - struct sockaddr_in serv_add, client; - char buffer[MAXLINE]; - socklen_t len; - time_t timeval; - pid_t pid; - int logging=0; - ... - /* write daytime to client */ - while (1) { - if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) - <0 ) { - perror("accept error"); - exit(-1); - } - /* fork to handle connection */ - if ( (pid = fork()) < 0 ){ - perror("fork error"); - exit(-1); - } - if (pid == 0) { /* child */ - close(list_fd); - timeval = time(NULL); - snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); - if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { - perror("write error"); - exit(-1); - } - if (logging) { - inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer)); - printf("Request from host %s, port %d\n", buffer, - ntohs(client.sin_port)); - } - close(conn_fd); - exit(0); - } else { /* parent */ - close(conn_fd); - } - } - /* normal exit, never reached */ - exit(0); -} diff --git a/listati/ElemDaytimeTCPServer.c b/listati/ElemDaytimeTCPServer.c deleted file mode 100644 index 5f9b116..0000000 --- a/listati/ElemDaytimeTCPServer.c +++ /dev/null @@ -1,56 +0,0 @@ -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utilities */ -#include /* socket library */ -#include /* include standard I/O library */ -#include -#define MAXLINE 80 -#define BACKLOG 10 -int main(int argc, char *argv[]) -{ -/* - * Variables definition - */ - int list_fd, conn_fd; - int i; - struct sockaddr_in serv_add; - char buffer[MAXLINE]; - time_t timeval; - ... - /* create socket */ - if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - exit(-1); - } - /* initialize address */ - memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(13); /* daytime port is 13 */ - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ - /* bind socket */ - if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("bind error"); - exit(-1); - } - /* listen on socket */ - if (listen(list_fd, BACKLOG) < 0 ) { - perror("listen error"); - exit(-1); - } - /* write daytime to client */ - while (1) { - if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) { - perror("accept error"); - exit(-1); - } - timeval = time(NULL); - snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); - if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { - perror("write error"); - exit(-1); - } - close(conn_fd); - } - /* normal exit */ - exit(0); -} diff --git a/listati/Flock.c b/listati/Flock.c index cf85d3b..59bc48a 100644 --- a/listati/Flock.c +++ b/listati/Flock.c @@ -1,52 +1,52 @@ int main(int argc, char *argv[]) { - int type = F_UNLCK; /* lock type: default to unlock (invalid) */ - off_t start = 0; /* start of the locked region: default to 0 */ - off_t len = 0; /* length of the locked region: default to 0 */ - int fd, res, i; /* internal variables */ - int bsd = 0; /* semantic type: default to POSIX */ - int cmd = F_SETLK; /* lock command: default to non-blocking */ - struct flock lock; /* file lock structure */ + int type = F_UNLCK; /* lock type: default to unlock (invalid) */ + off_t start = 0; /* start of the locked region: default to 0 */ + off_t len = 0; /* length of the locked region: default to 0 */ + int fd, res, i; /* internal variables */ + int bsd = 0; /* semantic type: default to POSIX */ + int cmd = F_SETLK; /* lock command: default to non-blocking */ + struct flock lock; /* file lock structure */ ... - if ((argc - optind) != 1) { /* There must be remaing parameters */ + if ((argc - optind) != 1) { /* There must be remaing parameters */ printf("Wrong number of arguments %d\n", argc - optind); usage(); } - if (type == F_UNLCK) { /* There must be a -w or -r option set */ + if (type == F_UNLCK) { /* There must be a -w or -r option set */ printf("You should set a read or a write lock\n"); usage(); } - fd = open(argv[optind], O_RDWR); /* open the file to be locked */ - if (fd < 0) { /* on error exit */ + fd = open(argv[optind], O_RDWR); /* open the file to be locked */ + if (fd < 0) { /* on error exit */ perror("Wrong filename"); exit(1); } /* do lock */ - if (bsd) { /* if BSD locking */ + if (bsd) { /* if BSD locking */ /* rewrite cmd for suitables flock operation values */ - if (cmd == F_SETLKW) { /* if no-blocking */ - cmd = LOCK_NB; /* set the value for flock operation */ - } else { /* else */ - cmd = 0; /* default is null */ + if (cmd == F_SETLKW) { /* if no-blocking */ + cmd = LOCK_NB; /* set the value for flock operation */ + } else { /* else */ + cmd = 0; /* default is null */ } - if (type == F_RDLCK) cmd |= LOCK_SH; /* set for shared lock */ - if (type == F_WRLCK) cmd |= LOCK_EX; /* set for exclusive lock */ - res = flock(fd, cmd); /* esecute lock */ - } else { /* if POSIX locking */ + if (type == F_RDLCK) cmd |= LOCK_SH; /* set for shared lock */ + if (type == F_WRLCK) cmd |= LOCK_EX; /* set for exclusive lock */ + res = flock(fd, cmd); /* esecute lock */ + } else { /* if POSIX locking */ /* setting flock structure */ - lock.l_type = type; /* set type: read or write */ + lock.l_type = type; /* set type: read or write */ lock.l_whence = SEEK_SET; /* start from the beginning of the file */ - lock.l_start = start; /* set the start of the locked region */ - lock.l_len = len; /* set the length of the locked region */ - res = fcntl(fd, cmd, &lock); /* do lock */ + lock.l_start = start; /* set the start of the locked region */ + lock.l_len = len; /* set the length of the locked region */ + res = fcntl(fd, cmd, &lock); /* do lock */ } /* check lock results */ - if (res) { /* on error exit */ + if (res) { /* on error exit */ perror("Failed lock"); exit(1); - } else { /* else write message */ + } else { /* else write message */ printf("Lock acquired\n"); } - pause(); /* stop the process, use a signal to exit */ + pause(); /* stop the process, use a signal to exit */ return 0; } diff --git a/listati/FortuneClient.c b/listati/FortuneClient.c index f0c1030..6baad61 100644 --- a/listati/FortuneClient.c +++ b/listati/FortuneClient.c @@ -9,28 +9,28 @@ int main(int argc, char *argv[]) int nread; char buffer[PIPE_BUF]; ... - snprintf(fifoname, 80, "/tmp/fortune.%d", getpid()); /* compose name */ - if (mkfifo(fifoname, 0622)) { /* open client fifo */ + snprintf(fifoname, 80, "/tmp/fortune.%d", getpid()); /* compose name */ + if (mkfifo(fifoname, 0622)) { /* open client fifo */ if (errno!=EEXIST) { perror("Cannot create well known fifo"); exit(-1); } } - fifo_server = open(fortunefilename, O_WRONLY); /* open server fifo */ + fifo_server = open(fortunefilename, O_WRONLY); /* open server fifo */ if (fifo_server < 0) { perror("Cannot open well known fifo"); exit(-1); } - nread = write(fifo_server, fifoname, strlen(fifoname)+1); /* write name */ - close(fifo_server); /* close server fifo */ - fifo_client = open(fifoname, O_RDONLY); /* open client fifo */ + nread = write(fifo_server, fifoname, strlen(fifoname)+1); /* write name */ + close(fifo_server); /* close server fifo */ + fifo_client = open(fifoname, O_RDONLY); /* open client fifo */ if (fifo_client < 0) { perror("Cannot open well known fifo"); exit(-1); } - nread = read(fifo_client, buffer, sizeof(buffer)); /* read answer */ - printf("%s", buffer); /* print fortune */ - close(fifo_client); /* close client */ - close(fifo_server); /* close server */ - unlink(fifoname); /* remove client fifo */ + nread = read(fifo_client, buffer, sizeof(buffer)); /* read answer */ + printf("%s", buffer); /* print fortune */ + close(fifo_client); /* close client */ + close(fifo_server); /* close server */ + unlink(fifoname); /* remove client fifo */ } diff --git a/listati/FortuneServer.c b/listati/FortuneServer.c index 7c45d23..40ee3d9 100644 --- a/listati/FortuneServer.c +++ b/listati/FortuneServer.c @@ -9,12 +9,12 @@ int main(int argc, char *argv[]) int fifo_server, fifo_client; int nread; ... - if (n==0) usage(); /* if no pool depth exit printing usage info */ - Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ + if (n==0) usage(); /* if no pool depth exit printing usage info */ + Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ Signal(SIGINT, HandSIGTERM); Signal(SIGQUIT, HandSIGTERM); - i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */ - if (mkfifo(fifoname, 0622)) { /* create well known fifo if does't exist */ + i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */ + if (mkfifo(fifoname, 0622)) { /* create well known fifo if does't exist */ if (errno!=EEXIST) { perror("Cannot create well known fifo"); exit(1); @@ -33,20 +33,20 @@ int main(int argc, char *argv[]) } /* Main body: loop over requests */ while (1) { - nread = read(fifo_server, line, 79); /* read request */ + nread = read(fifo_server, line, 79); /* read request */ if (nread < 0) { perror("Read Error"); exit(1); } - line[nread] = 0; /* terminate fifo name string */ - n = random() % i; /* select random value */ - fifo_client = open(line, O_WRONLY); /* open client fifo */ + line[nread] = 0; /* terminate fifo name string */ + n = random() % i; /* select random value */ + fifo_client = open(line, O_WRONLY); /* open client fifo */ if (fifo_client < 0) { perror("Cannot open"); exit(1); } - nread = write(fifo_client, /* write phrase */ + nread = write(fifo_client, /* write phrase */ fortune[n], strlen(fortune[n])+1); - close(fifo_client); /* close client fifo */ + close(fifo_client); /* close client fifo */ } } diff --git a/listati/LockFile.c b/listati/LockFile.c index 7cd07d3..24bbccf 100644 --- a/listati/LockFile.c +++ b/listati/LockFile.c @@ -1,6 +1,6 @@ #include #include -#include /* unix standard functions */ +#include /* Unix standard functions */ /* * Function LockFile: */ diff --git a/listati/MQFortuneClient.c b/listati/MQFortuneClient.c index 84f86c6..8b8216c 100644 --- a/listati/MQFortuneClient.c +++ b/listati/MQFortuneClient.c @@ -8,10 +8,10 @@ int main(int argc, char *argv[]) exit(1); } /* Main body: do request and write result */ - msg_read.mtype = 1; /* type for request is always 1 */ - msg_read.pid = getpid(); /* use pid for communications */ + msg_read.mtype = 1; /* type for request is always 1 */ + msg_read.pid = getpid(); /* use pid for communications */ size = sizeof(msg_read.pid); - msgsnd(msgid, &msg_read, size, 0); /* send request message */ + msgsnd(msgid, &msg_read, size, 0); /* send request message */ msgrcv(msgid, &msg_write, MSGMAX, msg_read.pid, MSG_NOERROR); printf("%s", msg_write.mtext); } diff --git a/listati/MQFortuneServer.c b/listati/MQFortuneServer.c index cd0dd1e..aec0e1e 100644 --- a/listati/MQFortuneServer.c +++ b/listati/MQFortuneServer.c @@ -1,26 +1,26 @@ -int msgid; /* Message queue identifier */ +int msgid; /* Message queue identifier */ int main(int argc, char *argv[]) { /* Variables definition */ int i, n = 0; - char **fortune; /* array of fortune message string */ - char *fortunefilename = "/usr/share/games/fortunes/linux"; /* file name */ - struct msgbuf_read { /* message struct to read request from clients */ - long mtype; /* message type, must be 1 */ - long pid; /* message data, must be the pid of the client */ + char **fortune; /* array of fortune message string */ + char *fortunefilename = "/usr/share/games/fortunes/linux"; /* file name */ + struct msgbuf_read { /* message struct to read request from clients */ + long mtype; /* message type, must be 1 */ + long pid; /* message data, must be the pid of the client */ } msg_read; - struct msgbuf_write { /* message struct to write result to clients */ - long mtype; /* message type, will be the pid of the client*/ - char mtext[MSGMAX]; /* message data, will be the fortune */ + struct msgbuf_write { /* message struct to write result to clients */ + long mtype; /* message type, will be the pid of the client*/ + char mtext[MSGMAX]; /* message data, will be the fortune */ } msg_write; - key_t key; /* Message queue key */ - int size; /* message size */ + key_t key; /* Message queue key */ + int size; /* message size */ ... - Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ + Signal(SIGTERM, HandSIGTERM); /* set handlers for termination */ Signal(SIGINT, HandSIGTERM); Signal(SIGQUIT, HandSIGTERM); - if (n==0) usage(); /* if no pool depth exit printing usage info */ - i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */ + if (n==0) usage(); /* if no pool depth exit printing usage info */ + i = FortuneParse(fortunefilename, fortune, n); /* parse phrases */ /* Create the queue */ key = ftok("./MQFortuneServer.c", 1); msgid = msgget(key, IPC_CREAT|0666); @@ -32,10 +32,10 @@ int main(int argc, char *argv[]) daemon(0, 0); while (1) { msgrcv(msgid, &msg_read, sizeof(int), 1, MSG_NOERROR); - n = random() % i; /* select random value */ + n = random() % i; /* select random value */ strncpy(msg_write.mtext, fortune[n], MSGMAX); size = min(strlen(fortune[n])+1, MSGMAX); - msg_write.mtype=msg_read.pid; /* use request pid as type */ + msg_write.mtype=msg_read.pid; /* use request pid as type */ msgsnd(msgid, &msg_write, size, 0); } } @@ -43,6 +43,6 @@ int main(int argc, char *argv[]) * Signal Handler to manage termination */ void HandSIGTERM(int signo) { - msgctl(msgid, IPC_RMID, NULL); /* remove message queue */ + msgctl(msgid, IPC_RMID, NULL); /* remove message queue */ exit(0); } diff --git a/listati/MemShared.c b/listati/MemShared.c index dfeea8d..fa72c32 100644 --- a/listati/MemShared.c +++ b/listati/MemShared.c @@ -6,7 +6,7 @@ void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill) int flag; /* first open the object, creating it if not existent */ flag = O_CREAT|O_EXCL|O_RDWR; - fd = shm_open(shm_name, flag, perm); /* get object file descriptor */ + fd = shm_open(shm_name, flag, perm); /* get object file descriptor */ if (fd < 0) { return NULL; } @@ -19,14 +19,14 @@ void * CreateShm(char * shm_name, off_t shm_size, mode_t perm, int fill) if (shm_ptr == MAP_FAILED) { return NULL; } - memset((void *) shm_ptr, fill, shm_size); /* fill segment */ + memset((void *) shm_ptr, fill, shm_size); /* fill segment */ return shm_ptr; } /* Function FindShm: Find a POSIX shared memory segment */ void * FindShm(char * shm_name, off_t shm_size) { void * shm_ptr; - int fd; /* ID of the IPC shared memory segment */ + int fd; /* ID of the IPC shared memory segment */ /* find shared memory ID */ if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) { return NULL; diff --git a/listati/Mutex.c b/listati/Mutex.c index 3d0c4c0..2855c75 100644 --- a/listati/Mutex.c +++ b/listati/Mutex.c @@ -1,13 +1,13 @@ /* Function MutexCreate: create a mutex/semaphore */ int MutexCreate(key_t ipc_key) { - const union semun semunion={1}; /* semaphore union structure */ + const union semun semunion={1}; /* semaphore union structure */ int sem_id, ret; - sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */ - if (sem_id == -1) { /* if error return code */ + sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */ + if (sem_id == -1) { /* if error return code */ return sem_id; } - ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */ + ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */ if (ret == -1) { return ret; } @@ -24,14 +24,14 @@ int MutexRead(int sem_id) return semctl(sem_id, 0, GETVAL); } /* Define sembuf structures to lock and unlock the semaphore */ -struct sembuf sem_lock={ /* to lock semaphore */ - 0, /* semaphore number (only one so 0) */ - -1, /* operation (-1 to use resource) */ - SEM_UNDO}; /* flag (set for undo at exit) */ -struct sembuf sem_ulock={ /* to unlock semaphore */ - 0, /* semaphore number (only one so 0) */ - 1, /* operation (1 to release resource) */ - SEM_UNDO}; /* flag (in this case 0) */ +struct sembuf sem_lock={ /* to lock semaphore */ + 0, /* semaphore number (only one so 0) */ + -1, /* operation (-1 to use resource) */ + SEM_UNDO}; /* flag (set for undo at exit) */ +struct sembuf sem_ulock={ /* to unlock semaphore */ + 0, /* semaphore number (only one so 0) */ + 1, /* operation (1 to release resource) */ + SEM_UNDO}; /* flag (in this case 0) */ /* Function MutexLock: to lock a mutex/semaphore */ int MutexLock(int sem_id) { diff --git a/listati/MutexLocking.c b/listati/MutexLocking.c index 1b45315..e1c2e0a 100644 --- a/listati/MutexLocking.c +++ b/listati/MutexLocking.c @@ -11,24 +11,24 @@ int FindMutex(const char *path_name) /* Function LockMutex: lock mutex using file locking. */ int LockMutex(int fd) { - struct flock lock; /* file lock structure */ + struct flock lock; /* file lock structure */ /* set flock structure */ - lock.l_type = F_WRLCK; /* set type: read or write */ - lock.l_whence = SEEK_SET; /* start from the beginning of the file */ - lock.l_start = 0; /* set the start of the locked region */ - lock.l_len = 0; /* set the length of the locked region */ + lock.l_type = F_WRLCK; /* set type: read or write */ + lock.l_whence = SEEK_SET; /* start from the beginning of the file */ + lock.l_start = 0; /* set the start of the locked region */ + lock.l_len = 0; /* set the length of the locked region */ /* do locking */ return fcntl(fd, F_SETLKW, &lock); } /* Function UnlockMutex: unlock a file. */ int UnlockMutex(int fd) { - struct flock lock; /* file lock structure */ + struct flock lock; /* file lock structure */ /* set flock structure */ - lock.l_type = F_UNLCK; /* set type: unlock */ - lock.l_whence = SEEK_SET; /* start from the beginning of the file */ - lock.l_start = 0; /* set the start of the locked region */ - lock.l_len = 0; /* set the length of the locked region */ + lock.l_type = F_UNLCK; /* set type: unlock */ + lock.l_whence = SEEK_SET; /* start from the beginning of the file */ + lock.l_start = 0; /* set the start of the locked region */ + lock.l_len = 0; /* set the length of the locked region */ /* do locking */ return fcntl(fd, F_SETLK, &lock); } @@ -41,12 +41,12 @@ int RemoveMutex(const char *path_name) int ReadMutex(int fd) { int res; - struct flock lock; /* file lock structure */ + struct flock lock; /* file lock structure */ /* set flock structure */ - lock.l_type = F_WRLCK; /* set type: unlock */ - lock.l_whence = SEEK_SET; /* start from the beginning of the file */ - lock.l_start = 0; /* set the start of the locked region */ - lock.l_len = 0; /* set the length of the locked region */ + lock.l_type = F_WRLCK; /* set type: unlock */ + lock.l_whence = SEEK_SET; /* start from the beginning of the file */ + lock.l_start = 0; /* set the start of the locked region */ + lock.l_len = 0; /* set the length of the locked region */ /* do locking */ if ( (res = fcntl(fd, F_GETLK, &lock)) ) { return res; diff --git a/listati/ReadMonitor.c b/listati/ReadMonitor.c index 8881795..e057ee2 100644 --- a/listati/ReadMonitor.c +++ b/listati/ReadMonitor.c @@ -3,17 +3,17 @@ int main(int argc, char *argv[]) key_t key; ... /* create needed IPC objects */ - key = ftok("~/gapil/sources/DirMonitor.c", 1); /* define a key */ - if (!(shmptr = ShmFind(key, 4096))) { /* get a shared memory segment */ + key = ftok("~/gapil/sources/DirMonitor.c", 1); /* define a key */ + if (!(shmptr = ShmFind(key, 4096))) { /* get a shared memory segment */ perror("Cannot find shared memory"); exit(1); } - if ((mutex = MutexFind(key)) == -1) { /* get the Mutex */ + if ((mutex = MutexFind(key)) == -1) { /* get the Mutex */ perror("Cannot find mutex"); exit(1); } /* main loop */ - MutexLock(mutex); /* lock shared memory */ + MutexLock(mutex); /* lock shared memory */ printf("Ci sono %d file dati\n", shmptr->tot_regular); printf("Ci sono %d directory\n", shmptr->tot_dir); printf("Ci sono %d link\n", shmptr->tot_link); @@ -23,5 +23,5 @@ int main(int argc, char *argv[]) printf("Ci sono %d device a blocchi\n", shmptr->tot_block); printf("Totale %d file, per %d byte\n", shmptr->tot_files, shmptr->tot_size); - MutexUnlock(mutex); /* unlock shared memory */ + MutexUnlock(mutex); /* unlock shared memory */ } diff --git a/listati/SharedMem.c b/listati/SharedMem.c index 9f5b438..872a5bc 100644 --- a/listati/SharedMem.c +++ b/listati/SharedMem.c @@ -2,28 +2,28 @@ void * ShmCreate(key_t ipc_key, int shm_size, int perm, int fill) { void * shm_ptr; - int shm_id; /* ID of the IPC shared memory segment */ - shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm); /* get shm ID */ + int shm_id; /* ID of the IPC shared memory segment */ + shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm); /* get shm ID */ if (shm_id < 0) { return NULL; } - shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ + shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ if (shm_ptr < 0) { return NULL; } - memset((void *)shm_ptr, fill, shm_size); /* fill segment */ + memset((void *)shm_ptr, fill, shm_size); /* fill segment */ return shm_ptr; } /* Function ShmFind: Find a SysV shared memory segment */ void * ShmFind(key_t ipc_key, int shm_size) { void * shm_ptr; - int shm_id; /* ID of the SysV shared memory segment */ - shm_id = shmget(ipc_key, shm_size, 0); /* find shared memory ID */ + int shm_id; /* ID of the SysV shared memory segment */ + shm_id = shmget(ipc_key, shm_size, 0); /* find shared memory ID */ if (shm_id < 0) { return NULL; } - shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ + shm_ptr = shmat(shm_id, NULL, 0); /* map it into memory */ if (shm_ptr < 0) { return NULL; } @@ -32,18 +32,18 @@ void * ShmFind(key_t ipc_key, int shm_size) /* Function ShmRemove: Schedule removal for a SysV shared memory segment */ int ShmRemove(key_t ipc_key, void * shm_ptr) { - int shm_id; /* ID of the SysV shared memory segment */ + int shm_id; /* ID of the SysV shared memory segment */ /* first detach segment */ if (shmdt(shm_ptr) < 0) { return -1; } /* schedule segment removal */ - shm_id = shmget(ipc_key, 0, 0); /* find shared memory ID */ + shm_id = shmget(ipc_key, 0, 0); /* find shared memory ID */ if (shm_id < 0) { if (errno == EIDRM) return 0; return -1; } - if (shmctl(shm_id, IPC_RMID, NULL) < 0) { /* ask for removal */ + if (shmctl(shm_id, IPC_RMID, NULL) < 0) { /* ask for removal */ if (errno == EIDRM) return 0; return -1; } diff --git a/listati/Signal.c b/listati/Signal.c index e2d617b..855faa0 100644 --- a/listati/Signal.c +++ b/listati/Signal.c @@ -4,10 +4,10 @@ inline SigFunc * Signal(int signo, SigFunc *func) struct sigaction new_handl, old_handl; new_handl.sa_handler = func; /* clear signal mask: no signal blocked during execution of func */ - if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ + if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ return SIG_ERR; } - new_handl.sa_flags=0; /* init to 0 all flags */ + new_handl.sa_flags=0; /* init to 0 all flags */ /* change action for signo signal */ if (sigaction(signo, &new_handl, &old_handl)){ return SIG_ERR; diff --git a/listati/TCP_cunc_daytimed.c b/listati/TCP_cunc_daytimed.c new file mode 100644 index 0000000..9af8cc7 --- /dev/null +++ b/listati/TCP_cunc_daytimed.c @@ -0,0 +1,52 @@ +#include /* predefined types */ +#include /* include unix standard library */ +#include /* IP addresses conversion utililites */ +#include /* socket library */ +#include /* include standard I/O library */ +#include + +int main(int argc, char *argv[]) +{ + int list_fd, conn_fd; + int i; + struct sockaddr_in serv_add, client; + char buffer[MAXLINE]; + socklen_t len; + time_t timeval; + pid_t pid; + int logging=0; + ... + /* write daytime to client */ + while (1) { + if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) + <0 ) { + perror("accept error"); + exit(-1); + } + /* fork to handle connection */ + if ( (pid = fork()) < 0 ){ + perror("fork error"); + exit(-1); + } + if (pid == 0) { /* child */ + close(list_fd); + timeval = time(NULL); + snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); + if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { + perror("write error"); + exit(-1); + } + if (logging) { + inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer)); + printf("Request from host %s, port %d\n", buffer, + ntohs(client.sin_port)); + } + close(conn_fd); + exit(0); + } else { /* parent */ + close(conn_fd); + } + } + /* normal exit, never reached */ + exit(0); +} diff --git a/listati/TCP_echo_client.c b/listati/TCP_echo_client.c new file mode 100644 index 0000000..f9a67b6 --- /dev/null +++ b/listati/TCP_echo_client.c @@ -0,0 +1,32 @@ +int main(int argc, char *argv[]) +{ +/* + * Variables definition + */ + int sock_fd, i; + struct sockaddr_in serv_add; + ... + /* create socket */ + if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + return -1; + } + /* initialize address */ + memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */ + serv_add.sin_family = AF_INET; /* address type is INET */ + serv_add.sin_port = htons(7); /* echo port is 7 */ + /* build address using inet_pton */ + if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) { + perror("Address creation error"); + return -1; + } + /* extablish connection */ + if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { + perror("Connection error"); + return -1; + } + /* read daytime from server */ + ClientEcho(stdin, sock_fd); + /* normal exit */ + return 0; +} diff --git a/netlayer.tex b/netlayer.tex index 2934e63..86f4276 100644 --- a/netlayer.tex +++ b/netlayer.tex @@ -32,10 +32,11 @@ nuova versione denominata IPv6. \label{sec:ip_protocol} L'attuale \textit{Internet Protocol} (IPv4) viene standardizzato nel 1981 -dall'RFC~719; esso nasce per disaccoppiare le applicazioni della struttura -hardware delle reti di trasmissione, e creare una interfaccia di trasmissione -dei dati indipendente dal sottostante substrato di rete, che può essere -realizzato con le tecnologie più disparate (Ethernet, Token Ring, FDDI, etc.). +dall'\href{http://www.ietf.org/rfc/rfc0719.txt}{RFC~719}; esso nasce per +disaccoppiare le applicazioni della struttura hardware delle reti di +trasmissione, e creare una interfaccia di trasmissione dei dati indipendente +dal sottostante substrato di rete, che può essere realizzato con le tecnologie +più disparate (Ethernet, Token Ring, FDDI, etc.). \subsection{Introduzione} @@ -207,11 +208,11 @@ apparecchio elettronico sarebbe stato inserito all'interno della rete. Per questo motivo si iniziò a progettare una nuova versione del protocollo L'attuale Internet Protocol (IPv4) viene standardizzato nel 1981 -dall'RFC~719; esso nasce per disaccoppiare le applicazioni della struttura -hardware delle reti di trasmissione, e creare una interfaccia di trasmissione -dei dati indipendente dal sottostante substrato di rete, che può essere -realizzato con le tecnologie più disparate (Ethernet, Token Ring, FDDI, -etc.). +dall'\href{http://www.ietf.org/rfc/rfc0719.txt}{RFC~719}; esso nasce per +disaccoppiare le applicazioni della struttura hardware delle reti di +trasmissione, e creare una interfaccia di trasmissione dei dati indipendente +dal sottostante substrato di rete, che può essere realizzato con le tecnologie +più disparate (Ethernet, Token Ring, FDDI, etc.). \subsection{I motivi della transizione} @@ -619,7 +620,8 @@ allocazione degli indirizzi unicast. \label{sec:IP_ipv6_unicast} Gli indirizzi \textit{provider-based} sono gli indirizzi usati per le -comunicazioni globali, questi sono definiti nell'RFC 2073 e sono gli +comunicazioni globali, questi sono definiti +nell'\href{http://www.ietf.org/rfc/rfc2073.txt}{RFC~2073} e sono gli equivalenti degli attuali indirizzi delle classi da A a C. L'autorità che presiede all'allocazione di questi indirizzi è la IANA; per @@ -975,16 +977,20 @@ per il funzionamento della rete. \textbf{Uso}& \textbf{Indirizzi riservati} & \textbf{Definizione}\\ \hline \hline - all-nodes & \texttt{FFxx:0:0:0:0:0:0:1} & RFC 1970\\ - all-routers & \texttt{FFxx:0:0:0:0:0:0:2} & RFC 1970\\ - all-rip-routers & \texttt{FFxx:0:0:0:0:0:0:9} & RFC 2080\\ - all-cbt-routers & \texttt{FFxx:0:0:0:0:0:0:10} &\\ - reserved & \texttt{FFxx:0:0:0:0:0:1:0} & IANA \\ - link-name & \texttt{FFxx:0:0:0:0:0:1:1} & \\ - all-dhcp-agents & \texttt{FFxx:0:0:0:0:0:1:2} & \\ - all-dhcp-servers & \texttt{FFxx:0:0:0:0:0:1:3} & \\ - all-dhcp-relays & \texttt{FFxx:0:0:0:0:0:1:4} & \\ - solicited-nodes & \texttt{FFxx:0:0:0:0:1:0:0} & RFC 1970\\ + all-nodes & \texttt{FFxx:0:0:0:0:0:0:1} & + \href{http://www.ietf.org/rfc/rfc1970.txt}{RFC~1970} \\ + all-routers & \texttt{FFxx:0:0:0:0:0:0:2} & + \href{http://www.ietf.org/rfc/rfc1970.txt}{RFC~1970} \\ + all-rip-routers & \texttt{FFxx:0:0:0:0:0:0:9} & + \href{http://www.ietf.org/rfc/rfc2080.txt}{RFC~2080} \\ + all-cbt-routers & \texttt{FFxx:0:0:0:0:0:0:10} & \\ + reserved & \texttt{FFxx:0:0:0:0:0:1:0} & IANA \\ + link-name & \texttt{FFxx:0:0:0:0:0:1:1} & \\ + all-dhcp-agents & \texttt{FFxx:0:0:0:0:0:1:2} & \\ + all-dhcp-servers& \texttt{FFxx:0:0:0:0:0:1:3} & \\ + all-dhcp-relays & \texttt{FFxx:0:0:0:0:0:1:4} & \\ + solicited-nodes & \texttt{FFxx:0:0:0:0:1:0:0} & + \href{http://www.ietf.org/rfc/rfc1970.txt}{RFC~1970} \\ \hline \end{tabular} \caption{Gruppi multicast predefiniti.} @@ -1078,9 +1084,11 @@ Le estensioni definite al momento sono le seguenti: vuole frammentare un pacchetto, ed è riprocessato automaticamente alla destinazione che riassembla i frammenti. \item \textbf{Authentication} gestisce l'autenticazione e il controllo di - integrità dei pacchetti; è documentato dall'RFC 162. + integrità dei pacchetti; è documentato + dall'\href{http://www.ietf.org/rfc/rfc1826.txt}{RFC~1826}. \item \textbf{Encapsulation} serve a gestire la segretezza del contenuto - trasmesso; è documentato dall'RFC 1827. + trasmesso; è documentato + dall'\href{http://www.ietf.org/rfc/rfc1827.txt}{RFC~1827}. \end{itemize} La presenza di opzioni è rilevata dal valore del campo \textit{next header} @@ -1225,7 +1233,8 @@ riservatezza a un livello inferiore al primo (quello di applicazione), con IPv6 è stato progettata la possibilità di intervenire al livello di rete (il terzo) prevedendo due apposite estensioni che possono essere usate per fornire livelli di sicurezza a seconda degli utenti. La codifica generale di questa -architettura è riportata nell'RFC 2401. +architettura è riportata +nell'\href{http://www.ietf.org/rfc/rfc2401.txt}{RFC~2401}. Il meccanismo in sostanza si basa su due estensioni: \begin{itemize} diff --git a/network.tex b/network.tex index 2d9186e..a75b786 100644 --- a/network.tex +++ b/network.tex @@ -518,7 +518,8 @@ trasporto. Quando si parla di IP ci si riferisce in genere alla versione attualmente in uso che è la versione 4 (e viene pertanto chiamato IPv4). Questa versione -venne standardizzata nel 1981 dall'RFC~719. +venne standardizzata nel 1981 +dall'\href{http://www.ietf.org/rfc/rfc0719.txt}{RFC~719}. Internet Protocol nasce per disaccoppiare le applicazioni della struttura hardware delle reti di trasmissione, e creare una interfaccia di trasmissione @@ -575,15 +576,16 @@ protocollo IP sono forniti nell'appendice \secref{sec:ip_protocol}. \label{sec:net_udp} UDP è un protocollo di trasporto molto semplice, la sua descrizione completa è -contenuta dell'RFC~768, ma in sostanza esso è una semplice interfaccia a IP -dal livello di trasporto. Quando un'applicazione usa UDP essa scrive un -pacchetto di dati (il cosiddetto \textit{datagram} che da il nome al -protocollo) su un socket\index{socket}, al pacchetto viene aggiunto un header -molto semplice (per una descrizione più accurata vedi \secref{sec:xxx_udp}), e -poi viene passato al livello superiore (IPv4 o IPv6 che sia) che lo spedisce -verso la destinazione. Dato che né IPv4 né IPv6 garantiscono l'affidabilità -niente assicura che il pacchetto arrivi a destinazione, né che più pacchetti -arrivino nello stesso ordine in cui sono stati spediti. +contenuta dell'\href{http://www.ietf.org/rfc/rfc0768.txt}{RFC~768}, ma in +sostanza esso è una semplice interfaccia a IP dal livello di trasporto. Quando +un'applicazione usa UDP essa scrive un pacchetto di dati (il cosiddetto +\textit{datagram} che da il nome al protocollo) su un socket\index{socket}, al +pacchetto viene aggiunto un header molto semplice (per una descrizione più +accurata vedi \secref{sec:xxx_udp}), e poi viene passato al livello superiore +(IPv4 o IPv6 che sia) che lo spedisce verso la destinazione. Dato che né IPv4 +né IPv6 garantiscono l'affidabilità niente assicura che il pacchetto arrivi a +destinazione, né che più pacchetti arrivino nello stesso ordine in cui sono +stati spediti. Pertanto il problema principale che si affronta quando si usa UDP è la mancanza di affidabilità, se si vuole essere sicuri che i pacchetti arrivino a @@ -621,7 +623,8 @@ quelle che usano il multicasting. \subsection{Transport Control Protocol (TCP)} \label{sec:net_tcp} -Il TCP è un protocollo molto complesso, definito nell'RFC~739 e completamente +Il TCP è un protocollo molto complesso, definito +nell'\href{http://www.ietf.org/rfc/rfc0739.txt}{RFC~739} e completamente diverso da UDP; alla base della sua progettazione infatti non stanno semplicità e velocità, ma la ricerca della massima affidabilità possibile nella trasmissione dei dati. @@ -765,8 +768,10 @@ comporta inefficienza, normalmente viene utilizzato un procedimento, detto \textit{path MTU discovery} che permette di determinare il \textit{path MTU} fra due stazioni; per la realizzazione del procedimento si usa il flag DF di IPv4 e il comportamento normale di IPv6 inviando delle opportune serie di -pacchetti (per i dettagli vedere l'RFC~1191 per IPv4 e l'RFC~1981 per IPv6) -fintanto che non si hanno più errori. +pacchetti (per i dettagli vedere +l'\href{http://www.ietf.org/rfc/rfc1191.txt}{RFC~1191} per IPv4 e +l'\href{http://www.ietf.org/rfc/rfc1981.txt}{RFC~1981} per IPv6) fintanto che +non si hanno più errori. Il TCP usa sempre questo meccanismo, che per le implementazioni di IPv4 è opzionale, mentre diventa obbligatorio per IPv6. Per IPv6 infatti, non diff --git a/sources/ElemDaytimeTCPCuncServ.c b/sources/ElemDaytimeTCPCuncServ.c deleted file mode 100644 index 9da060e..0000000 --- a/sources/ElemDaytimeTCPCuncServ.c +++ /dev/null @@ -1,159 +0,0 @@ -/* ElemDaytimeTCPCuncServ.c - * - * Copyright (C) 2001 Simone Piccardi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/**************************************************************** - * - * Program ElemDaytimeTCPCuncServ.c - * Elementary TCP cuncurrent server for daytime service (port 13) - * - * Author: Simone Piccardi - * May. 2001 - * - * Usage: daytimed -h give all info - * - * $Id: ElemDaytimeTCPCuncServ.c,v 1.2 2001/09/09 17:39:15 piccardi Exp $ - * - ****************************************************************/ -/* - * Include needed headers - */ -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utiliites */ -#include /* socket library */ -#include /* include standard I/O library */ -#include - -#define MAXLINE 80 -#define BACKLOG 10 -/* Program begin */ -void usage(void); -int main(int argc, char *argv[]) -{ -/* - * Variables definition - */ - int list_fd, conn_fd; - int i; - struct sockaddr_in serv_add, client; - char buffer[MAXLINE]; - socklen_t len; - time_t timeval; - pid_t pid; - int logging=0; - /* - * Input section: decode parameters passed in the calling - * Use getopt function - */ - opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "hv")) != -1) { - switch (i) { - /* - * Handling options - */ - case 'h': - printf("Wrong -h option use\n"); - usage(); - return(0); - break; - case '?': /* unrecognized options */ - printf("Unrecognized options -%c\n",optopt); - usage(); - return(0); - break; - case 'v': - logging = 1; - break; - default: /* should not reached */ - usage(); - return(0); - } - } - /* *********************************************************** - * - * Options processing completed - * - * Main code beginning - * - * ***********************************************************/ - /* create socket */ - if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - exit(-1); - } - /* initialize address */ - memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(13); /* daytime port is 13 */ - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ - /* bind socket */ - if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("bind error"); - exit(-1); - } - /* listen on socket */ - if (listen(list_fd, BACKLOG) < 0 ) { - perror("listen error"); - exit(-1); - } - /* write daytime to client */ - while (1) { - if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) - <0 ) { - perror("accept error"); - exit(-1); - } - /* fork to handle connection */ - if ( (pid = fork()) < 0 ){ - perror("fork error"); - exit(-1); - } - if (pid == 0) { /* child */ - close(list_fd); - timeval = time(NULL); - snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); - if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { - perror("write error"); - exit(-1); - } - if (logging) { - inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer)); - printf("Request from host %s, port %d\n", buffer, - ntohs(client.sin_port)); - } - close(conn_fd); - exit(0); - } else { /* parent */ - close(conn_fd); - } - } - /* normal exit, never reached */ - exit(0); -} -/* - * routine to print usage info and exit - */ -void usage(void) { - printf("Simple daytime server\n"); - printf("Usage:\n"); - printf(" daytimed [-hv] \n"); - printf(" -h print this help\n"); - printf(" -v print request source on stdout\n"); - exit(1); -} - diff --git a/sources/ElemDaytimeTCPServer.c b/sources/ElemDaytimeTCPServer.c deleted file mode 100644 index 9ab656a..0000000 --- a/sources/ElemDaytimeTCPServer.c +++ /dev/null @@ -1,132 +0,0 @@ -/* ElemDaytimeTCPServer.c - * - * Copyright (C) 2001 Simone Piccardi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/**************************************************************** - * - * Program daytimed: - * Elementary TCP server for daytime service (port 13) - * - * Author: Simone Piccardi - * Apr. 2001 - * - * Usage: daytimed -h give all info - * - * $Id: ElemDaytimeTCPServer.c,v 1.3 2001/09/09 22:45:34 piccardi Exp $ - * - ****************************************************************/ -/* - * Include needed headers - */ -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utiliites */ -#include /* socket library */ -#include /* include standard I/O library */ -#include - -#define MAXLINE 80 -#define BACKLOG 10 -/* Program begin */ -void usage(void); -int main(int argc, char *argv[]) -{ -/* - * Variables definition - */ - int list_fd, conn_fd; - int i; - struct sockaddr_in serv_add; - char buffer[MAXLINE]; - time_t timeval; - /* - * Input section: decode parameters passed in the calling - * Use getopt function - */ - opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "h")) != -1) { - switch (i) { - /* - * Handling options - */ - case 'h': - printf("Wrong -h option use\n"); - usage(); - return(0); - break; - case '?': /* unrecognized options */ - printf("Unrecognized options -%c\n",optopt); - usage(); - default: /* should not reached */ - usage(); - } - } - /* *********************************************************** - * - * Options processing completed - * - * Main code beginning - * - * ***********************************************************/ - /* create socket */ - if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - exit(-1); - } - /* initialize address */ - memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(13); /* daytime port is 13 */ - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ - /* bind socket */ - if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("bind error"); - exit(-1); - } - /* listen on socket */ - if (listen(list_fd, BACKLOG) < 0 ) { - perror("listen error"); - exit(-1); - } - /* write daytime to client */ - while (1) { - if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) { - perror("accept error"); - exit(-1); - } - timeval = time(NULL); - snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); - if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { - perror("write error"); - exit(-1); - } - close(conn_fd); - } - - /* normal exit */ - exit(0); -} -/* - * routine to print usage info and exit - */ -void usage(void) { - printf("Simple daytime server\n"); - printf("Usage:\n"); - printf(" daytimed [-h] \n"); - printf(" -h print this help\n"); - exit(1); -} diff --git a/sources/ElemEchoTCPClient.c b/sources/ElemEchoTCPClient.c index 3529cd7..19f6265 100644 --- a/sources/ElemEchoTCPClient.c +++ b/sources/ElemEchoTCPClient.c @@ -26,7 +26,7 @@ * * Usage: echo -h give all info's * - * $Id: ElemEchoTCPClient.c,v 1.5 2003/02/02 20:35:33 piccardi Exp $ + * $Id: ElemEchoTCPClient.c,v 1.6 2003/04/29 15:33:39 piccardi Exp $ * ****************************************************************/ /* @@ -99,7 +99,7 @@ int main(int argc, char *argv[]) return -1; } /* read daytime from server */ - EchoClient(stdin, sock_fd); + ClientEcho(stdin, sock_fd); /* normal exit */ return 0; } diff --git a/sources/Makefile b/sources/Makefile index 31fff96..e5c6816 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -72,10 +72,10 @@ echo: SimpleEchoTCPClient.c echod: SimpleEchoTCPServer.c $(CC) $(CFLAGJ) $^ -o $@ -daytimed: ElemDaytimeTCPCuncServ.c +daytimed: TCP_cunc_daytimed.c $(CC) $(CFLAGJ) $^ -o $@ -iterdaytimed: ElemDaytimeTCPServer.c +iterdaytimed: TCP_iter_daytimed.c $(CC) $(CFLAGJ) $^ -o $@ daytime: TCP_daytime.c diff --git a/sources/TCP_cunc_daytimed.c b/sources/TCP_cunc_daytimed.c new file mode 100644 index 0000000..5be9d23 --- /dev/null +++ b/sources/TCP_cunc_daytimed.c @@ -0,0 +1,159 @@ +/* TCP_cunc_daytimed.c + * + * Copyright (C) 2001 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Program TCP_cunc_daytimed.c + * Elementary TCP cuncurrent server for daytime service (port 13) + * + * Author: Simone Piccardi + * May. 2001 + * + * Usage: daytimed -h give all info + * + * $Id: TCP_cunc_daytimed.c,v 1.1 2003/04/29 15:33:39 piccardi Exp $ + * + ****************************************************************/ +/* + * Include needed headers + */ +#include /* predefined types */ +#include /* include unix standard library */ +#include /* IP addresses conversion utiliites */ +#include /* socket library */ +#include /* include standard I/O library */ +#include + +#define MAXLINE 80 +#define BACKLOG 10 +/* Program begin */ +void usage(void); +int main(int argc, char *argv[]) +{ +/* + * Variables definition + */ + int list_fd, conn_fd; + int i; + struct sockaddr_in serv_add, client; + char buffer[MAXLINE]; + socklen_t len; + time_t timeval; + pid_t pid; + int logging=0; + /* + * Input section: decode parameters passed in the calling + * Use getopt function + */ + opterr = 0; /* don't want writing to stderr */ + while ( (i = getopt(argc, argv, "hv")) != -1) { + switch (i) { + /* + * Handling options + */ + case 'h': + printf("Wrong -h option use\n"); + usage(); + return(0); + break; + case '?': /* unrecognized options */ + printf("Unrecognized options -%c\n",optopt); + usage(); + return(0); + break; + case 'v': + logging = 1; + break; + default: /* should not reached */ + usage(); + return(0); + } + } + /* *********************************************************** + * + * Options processing completed + * + * Main code beginning + * + * ***********************************************************/ + /* create socket */ + if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + exit(-1); + } + /* initialize address */ + memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ + serv_add.sin_family = AF_INET; /* address type is INET */ + serv_add.sin_port = htons(13); /* daytime port is 13 */ + serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ + /* bind socket */ + if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { + perror("bind error"); + exit(-1); + } + /* listen on socket */ + if (listen(list_fd, BACKLOG) < 0 ) { + perror("listen error"); + exit(-1); + } + /* write daytime to client */ + while (1) { + if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) + <0 ) { + perror("accept error"); + exit(-1); + } + /* fork to handle connection */ + if ( (pid = fork()) < 0 ){ + perror("fork error"); + exit(-1); + } + if (pid == 0) { /* child */ + close(list_fd); + timeval = time(NULL); + snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); + if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { + perror("write error"); + exit(-1); + } + if (logging) { + inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer)); + printf("Request from host %s, port %d\n", buffer, + ntohs(client.sin_port)); + } + close(conn_fd); + exit(0); + } else { /* parent */ + close(conn_fd); + } + } + /* normal exit, never reached */ + exit(0); +} +/* + * routine to print usage info and exit + */ +void usage(void) { + printf("Simple daytime server\n"); + printf("Usage:\n"); + printf(" daytimed [-hv] \n"); + printf(" -h print this help\n"); + printf(" -v print request source on stdout\n"); + exit(1); +} + diff --git a/sources/TCP_daytime.c b/sources/TCP_daytime.c index 18ce8d4..4ed7e4f 100644 --- a/sources/TCP_daytime.c +++ b/sources/TCP_daytime.c @@ -1,4 +1,4 @@ -/* ElemDaytimeTCPClient.c +/* TCP_daytime.c * * Copyright (C) 2001 Simone Piccardi * @@ -26,7 +26,7 @@ * * Usage: daytime -h give all info's * - * $Id: TCP_daytime.c,v 1.1 2003/04/28 14:13:50 piccardi Exp $ + * $Id: TCP_daytime.c,v 1.2 2003/04/29 15:33:39 piccardi Exp $ * ****************************************************************/ /* diff --git a/sources/TCP_iter_daytimed.c b/sources/TCP_iter_daytimed.c new file mode 100644 index 0000000..e50e763 --- /dev/null +++ b/sources/TCP_iter_daytimed.c @@ -0,0 +1,132 @@ +/* TCP_iter_daytimed.c + * + * Copyright (C) 2001 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/**************************************************************** + * + * Program daytimed: + * Elementary TCP server for daytime service (port 13) + * + * Author: Simone Piccardi + * Apr. 2001 + * + * Usage: daytimed -h give all info + * + * $Id: TCP_iter_daytimed.c,v 1.1 2003/04/29 15:33:39 piccardi Exp $ + * + ****************************************************************/ +/* + * Include needed headers + */ +#include /* predefined types */ +#include /* include unix standard library */ +#include /* IP addresses conversion utiliites */ +#include /* socket library */ +#include /* include standard I/O library */ +#include + +#define MAXLINE 80 +#define BACKLOG 10 +/* Program begin */ +void usage(void); +int main(int argc, char *argv[]) +{ +/* + * Variables definition + */ + int list_fd, conn_fd; + int i; + struct sockaddr_in serv_add; + char buffer[MAXLINE]; + time_t timeval; + /* + * Input section: decode parameters passed in the calling + * Use getopt function + */ + opterr = 0; /* don't want writing to stderr */ + while ( (i = getopt(argc, argv, "h")) != -1) { + switch (i) { + /* + * Handling options + */ + case 'h': + printf("Wrong -h option use\n"); + usage(); + return(0); + break; + case '?': /* unrecognized options */ + printf("Unrecognized options -%c\n",optopt); + usage(); + default: /* should not reached */ + usage(); + } + } + /* *********************************************************** + * + * Options processing completed + * + * Main code beginning + * + * ***********************************************************/ + /* create socket */ + if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + exit(-1); + } + /* initialize address */ + memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ + serv_add.sin_family = AF_INET; /* address type is INET */ + serv_add.sin_port = htons(13); /* daytime port is 13 */ + serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ + /* bind socket */ + if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { + perror("bind error"); + exit(-1); + } + /* listen on socket */ + if (listen(list_fd, BACKLOG) < 0 ) { + perror("listen error"); + exit(-1); + } + /* write daytime to client */ + while (1) { + if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) { + perror("accept error"); + exit(-1); + } + timeval = time(NULL); + snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); + if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { + perror("write error"); + exit(-1); + } + close(conn_fd); + } + + /* normal exit */ + exit(0); +} +/* + * routine to print usage info and exit + */ +void usage(void) { + printf("Simple daytime server\n"); + printf("Usage:\n"); + printf(" daytimed [-h] \n"); + printf(" -h print this help\n"); + exit(1); +} diff --git a/system.tex b/system.tex index 87711c0..a2985c7 100644 --- a/system.tex +++ b/system.tex @@ -1888,15 +1888,15 @@ valore nullo serve per leggere i parametri correnti; i valori diversi da zero devono essere specificati come OR binario delle costanti riportate in \secref{tab:sys_timex_mode}. -La funzione utilizza il meccanismo di David L. Mills, descritto nell'RFC~1305, -che è alla base del protocollo NTP; la funzione è specifica di Linux e non -deve essere usata se la portabilità è un requisito, le \acr{glibc} provvedono -anche un suo omonimo \func{ntp\_adjtime}. La trattazione completa di questa -funzione necessita di una lettura approfondita del meccanismo descritto -nell'RFC~1305, ci limitiamo a descrivere in \tabref{tab:sys_timex_mode} i -principali valori utilizzabili per il campo \var{mode}, un elenco più -dettagliato del significato dei vari campi della struttura \struct{timex} può -essere ritrovato in \cite{glibc}. +La funzione utilizza il meccanismo di David L. Mills, descritto +nell'\href{http://www.ietf.org/rfc/rfc1305.txt}{RFC~1305}, che è alla base del +protocollo NTP. La funzione è specifica di Linux e non deve essere usata se la +portabilità è un requisito, le \acr{glibc} provvedono anche un suo omonimo +\func{ntp\_adjtime}. La trattazione completa di questa funzione necessita di +una lettura approfondita del meccanismo descritto nell'RFC~1305, ci limitiamo +a descrivere in \tabref{tab:sys_timex_mode} i principali valori utilizzabili +per il campo \var{mode}, un elenco più dettagliato del significato dei vari +campi della struttura \struct{timex} può essere ritrovato in \cite{glibc}. \begin{table}[htb] \footnotesize