E-Mail Express
Programma per invio di posta elettronica con interfaccia utente HTML
di Andrea Prosperi (prosperi@cosimo.ing.unifi.it) Elaborato per il corso di TELEMATICA Prof. F. Pirri Ing. M. Lunghi Anno Accademico 1995-96
INDICE
Introduzione Perché costruire interfacce basate sull'HTML? Cosa c'è bisogno di fare? Perchè non limitarsi a scrivere una GUI? Cosa occorre per un corretto funzionamento? L'uso del WWW per applicazioni interattive Introduzione Cenni sulle HTML Forms Descrizione delle HTML Form Osservazioni conclusive L'interazione tra WWW Browser, HTTP Server e programma CGI La Common Gateway Interface Invio del contenuto della form compilata dall'utente al Server WWW Come sono codificati i dati di una form. Come si ottengono i dati da una form. Metodo GET Metodo POST Comunicazione tra Server Web e Programma CGI Input dei CGI Script Variabili ambientali della CGI Output dei programmi CGI Convenzioni sul nome dei programmi CGI. Header prodotti dai programmi CGI. Esempi. Invio al client del risultato dell'esecuzione SOMMARIO DELLE OPERAZIONI DELLA CGI E-Mail Express: un servizio di posta in Internet. Scopo dell'elaborato Funzionamento del programma in linea di comando Vincoli cui sono sottoposti i programmi CGI Soluzione proposta Funzionamento del programma Problemi di implementazione incontrati Comandi disponibili 1. PUT: Invia un messaggio ad un utente. 2. SHOW: Mostra un messaggio ad un utente. 3. DEL: Cancella un messaggio dalla coda. 4. LIST: Mostra la lista dei messaggi in coda. 5. BYE: Chiude la connessione con il Mail-server. Comandi soppressi Conclusione Approfondimenti 1. Le URL URL relative a file (File URLs) URL relative a risorse Gopher (Gopher URLs) URL relative a risorse Usenet (News URLs) URL relative a risorse World Wide Web (HTTP URLs) URL parziali Altre URL 2. I sistemi con stato Definizione di STATO 3. La gestione dei file con il Perl Appendice A - Listati Implementazione in C di un programma CGI Input del programma CGI Variabili ambientali del programma CGI Output del programma CGI Modulo: HTML_UTILITY.c Modulo: MAIL_CLIENT.c Modulo: MAIL_CLIENTUTIL.c Modulo: JOLLY.c Modulo: JOLLY_PROC.c Modulo: PARAMETRI.c Documento: OPEN.html Appendice B - Come aprire un applicativo esterno Configurazione del server Come usare il browser Appendice C - Riferimenti Riferimenti ad ipertesti Altri riferimenti Appendice D - Librerie C per la programmazione CGI NCSA httpd LibCGI By EIT (Enterprise Integration Technologies Co.): libreria per ANSI C e C++ cgic: an ANSI C library for CGI Programming Cosa è cgic? Come ottenere cgic Conclusione
");
printf("
");
printf("%c",LF);
printf("SERVIZIO DI POSTA IN RETE INTERNET
");
printf("%c",LF);
printf("%c",LF);
printf("
");
printf("%c",LF);
printf("CONNESSIONE AL MAIL-SERVER DAEMON
");
printf("%c",LF);
printf("
");
printf("%c",LF);
BuildUpChannel(entries[0].val,1);
ClientLogin(entries[1].val,entries[2].val);
printf("%c",LF);
ByeBye(0);
printf("
");
printf("%c",LF);
printf("COMANDI DISPONIBILI:
");
printf("%c",LF);
printf("");
printf("
");
/* out=fopen("/disk3/usr/netman/mail.exp/prozio/html/prova.c","wt");
fprintf(out,"%s\n",entries[0].val);
fprintf(out,"%s\n",entries[1].val);
fprintf(out,"%s\n",entries[2].val);
fclose(out); */
ByeBye(0);
printf("");
exit(1);
}
Modulo: MAIL_CLIENTUTIL.c
/***************************************************************/
/* BuildUpChannel: costruisce il canale di comunicazione con */
/* il server per lo scambio di dati, comandi, file di testo */
/***************************************************************/
int BuildUpChannel(arg1,write)
char *arg1;
int write;
{
char hostname[40];
char command[BUFSIZ],data[BUFSIZ];
int length,nbytes,port,n_err;
struct in_addr *host;
if ((pp = getprotobyname("tcp")) == 0) {
perror("\n-->Client: getprotobyname sconosciuto\n");
exit(1);
}
/* crea il socket */
if ((client_id = socket(AF_INET,SOCK_STREAM,pp->p_proto)) == -1) {
perror("\n-->Client: socket\n");
exit(1);
}
strcpy(hostname,arg1);
/* scopre indirizzo internet della macchina remota */
/* tramite il nome ricevuto come parametro */
if ((server=gethostbyname(hostname)) == 0) {
perror("\n-->Client: gethostbyname - host sconosciuto\n");
close (client_id);
exit(1);
}
host=(struct in_addr *)server->h_addr;
if (write) {
printf("%c",LF);
printf ("----------- C L I E N T -------------");
printf("%c",LF);
printf ("+ Nome Host: %30s +",server->h_name);
printf("%c",LF);
printf ("+ Indirizzo Host: %25s +",inet_ntoa(*host));
printf("%c",LF);
printf ("+ Porta Mailserver: %23d +",SERVER_PORT);
printf("%c",LF);
printf ("-------------------------------------");
printf("%c",LF);
}
bcopy (server->h_addr, (char *)&server_addr,server->h_length);
/* assegnazioni per collegamento al server */
server_sock.sin_family = AF_INET;
server_sock.sin_addr = server_addr;
server_sock.sin_port = htons(SERVER_PORT);
/* richiesta di connessione */
if (connect(client_id, &server_sock,sizeof(server_sock)) == -1) {
perror("\n-->Client: connect\n");
exit(1);
}
}
/*************************************************************/
/* Checkdata: controlla la correttezza dei dati scambiati */
/*************************************************************/
int Checkdata(char *f)
{
char command[20],data[BUFSIZ];
int nbytes,n_err;
strcpy(command,f);
if (send(client_id,command,strlen(command)+1,0)<0) { perror("\n-->
Client: send\n");
exit(1);
}
/* gestione errore dato inesistente */
if ((nbytes=recv(client_id,data,1,0))==-1) {
perror("\n-->Client : recv dal server figlio \n");
return 0;
}
/* controlla OK dal server */
if (data[0]==NOK) { /* file inesistente */
sscanf(&data[1],"%d",n_err);
printf("\n-->Client: %s\n",sys_errlist[n_err]);
return 0;
}
return 1;
}
/*************************************************************/
/* CLIENTLOGIN: controlla login e password dell'utente */
/*************************************************************/
int ClientLogin(login,pwd)
char login[20],pwd[20];
{
if (Checkdata(login)==1) {
if (Checkdata(pwd)==1) return 1;
}
return 0;
}
/****************************************************************/
/* RECEIVEACK: riceve dal server una stringa di acknowledgement */
/****************************************************************/
int ReceiveAck(int client_id)
{
int nbytes;
char data[5];
do {
if ((nbytes=recv(client_id,data,4,0))==-1) {
perror("\n-->Client : receiving ack from server \n");
exit(1);
}
data[4]='\0';
}
while (strcmp(data,"ACK")!=0);
}
/*****************************************************/
/* LISTMESSAGE: mostra la lista di tutti i messaggi */
/*****************************************************/
int ListMessage(int new)
{
char **lines=(char **)calloc(512,sizeof(char *));
char data[BUFSIZ];
int nbytes,nlines=1;
int i=-1;
if (new) {
sprintf(data,"listnew");
printf("Listing unread messages");
lines[0]=strdup("\n");
}
/* invia richiesta lista messaggi */
else {
sprintf(data,"list");
printf("Listing all messages");
lines[0]=strdup("\n");
}
if (send(client_id,data,strlen(data)+1,0)<0) { perror("\n-->
Client: send\n");
exit(1);
}
ReceiveAck(client_id);
while (((nbytes=recv(client_id,data,BUFSIZ,0))!= 0)) {
if (nbytes < 0) { perror("\n-->
Client: recv\n");
exit(1);
}
/*write (1,data,nbytes);*/
data[nbytes]='\0';
lines[nlines]=strdup(data);
nlines++;
/*printf("\n-++->Arrivati %d bytes su %d \n",nbytes,BUFSIZ-1);*/
lines[nlines-1][nbytes-4]='\0';
if (strcmp((data+nbytes-4),"ACK")==0) break;
}
lines[nlines]=NULL;
printf("%c",LF);
while (lines[++i]!=NULL) {
printf("%s",lines[i]);
printf("%c",LF);
free(lines[i]);
}
free(lines);
lines=NULL;
return 1;
}
/**************************************************/
/* BYEBYE: chiude la connessione col server */
/**************************************************/
int ByeBye(int stampa)
{
char **lines=(char **)calloc(4,sizeof(char *));
char data[80];
int i=-1;
sprintf(data,"bye");
if (send(client_id,data,strlen(data)+1,0)<0) { perror("\n-->
Client: send\n");
exit(1);
}
ReceiveAck(client_id);
if (stampa) {
lines[0]="\n End of Mail Session";
lines[1]="\nFor bugs,problem,hints contact";
lines[2]="\n");
printf("
");
printf("%c",LF);
printf("SERVIZIO DI POSTA IN RETE INTERNET
");
printf("%c",LF);
printf("%c",LF);
printf("
");
printf("%c",LF);
printf("COMANDO %s - ESECUZIONE :
",entries[4].val);
printf("%c",LF);
BuildUpChannel(entries[0].val,0);
ClientLogin(entries[1].val,entries[2].val);
printf("
");
printf("%c",LF);
switch (atoi(entries[3].val)) {
case 1 :PutMsg(entries[5].val,entries[6].val,atoi(entries[7].val), entries[8].val,entries[9].val); break;
case 2 :ShowMsg(atoi(entries[5].val),entries[6].val); break;
case 3 :DelMessage(atoi(entries[5].val)); break;
case 4 :if (strcmp(entries[5].val,"TUTTI I MESSAGGI NELLA CODA")==0) { ListMessage(0); break; }
else { ListMessage(1); break; }
case 5 :ByeBye(1);printf("");exit(1);break;
default: printf("Unknown command"); break;
}
printf("%c",LF);
printf("
");
printf("%c",LF);
printf("COMANDI DISPONIBILI:
");
printf("%c",LF);
printf("");
printf("
");
ByeBye(0);
printf("