Ho risolto quasi tutto. Ora ho problemi nell'inviare il corpo dell'email (dopo l'invio di DATA il server legge finchè il client non invia "."). Inoltre ho il problema che dovrei inviare MAIL TO soltanto dopo aver inviato MAIL FROM e così via. Lo devo fare con degli if annidati?

Il server modificato è:
codice:
void server_echo(int sockfd) {
        ssize_t         n;
        char         line[MAXLINE], mittente[MAXLINE], destinatario[MAXLINE];
    // Messaggi standard del server
    char opening[] = "Server mini-smtp, v1.0. Inviare comando\n";
    char mittOK[] = "OK, mittente ricevuto\n";
    char destOK[] = "OK, destinatario ricevuto\n";
    char dataReady[] = "Pronto a ricevere i dati\n";
    char dataOK[] = "OK, mail ricevuta\n";
    char error[] = "Comando ricevuto non valido\n";
    
    reti_writen(sockfd, opening, strlen(opening)); // Invio il benvenuto al client

        for ( ; ; ) {
        reti_readline(sockfd, line, MAXLINE); // Leggo dal client
        
        if(sscanf(line, "MAIL FROM: %s", mittente)!=0){ // Ricevo MAIL FROM
            printf("%s", mittOK);
            reti_writen(sockfd, mittOK, strlen(mittOK));
        }else if(sscanf(line, "MAIL TO: %s", destinatario)!=0){ // Ricevo MAIL TO
            printf("%s", destOK);
            reti_writen(sockfd, destOK, strlen(destOK));
        }else if(strcmp(line, "DATA\n")==0){ // Ricevo DATA
            printf("%s", dataReady);
            reti_writen(sockfd, dataReady, strlen(dataReady));
            // ? devo aprire il file
            reti_readline(sockfd, line, MAXLINE);
            while(strcmp(line, ".")!=0){
                reti_writen(sockfd, "OK\n", strlen("OK"));
                reti_readline(sockfd, line, MAXLINE);
                // ? Leggo e scrivo su file
            }
            printf("%s", dataOK);
            reti_writen(sockfd, dataOK, strlen(dataOK));
        }else if(strcmp(line, "BYE\n")==0){ // Ricevo BYE
            return;
        }else{
            printf("%s", error);
            reti_writen(sockfd, error, strlen(error)); // Comando ricevuto non valido
        }

        }
}
Il client è questo:
codice:
void client_echo(FILE *fp, int sockfd) {
        char    sendline[MAXLINE], recvline[MAXLINE];
    // Leggo la stringa di benvenuto
    if (reti_readline(sockfd, recvline, MAXLINE) == 0)
                { printf("%s: server terminated prematurely",__FILE__); exit(1); }
        fputs(recvline, stdout);
        while (fgets(sendline, MAXLINE, fp) != NULL) {
                reti_writen(sockfd, sendline, strlen(sendline));
        if(strcmp(sendline, "DATA")==0){ // Pronto a scrivere il testo dell'email
            while(strcmp(sendline, ".")!=0){ // Invio dati finchè non inserisco "."
                printf("PROVA\n");
                fgets(sendline, MAXLINE, fp);
                reti_writen(sockfd, sendline, strlen(sendline));
            }
        }
                if (reti_readline(sockfd, recvline, MAXLINE) == 0){ 
            printf("%s: server terminated prematurely",__FILE__); 
            exit(1); 
        }
                fputs(recvline, stdout);
        }
}