[prog-it] Il codice.

  • From: brain <xbrain@xxxxxxxxxx>
  • To: prog-it@xxxxxxxxxxxxx
  • Date: Wed, 9 Jan 2002 17:26:30 -0500

Ecco finalmente il codice... Se volete compilarlo ed eseguirlo avete 
bisogno delle librerie Gtk (http://www.gtk.org)...
Il problema: oltre il terzo contronto, nella mbox_get_msg_index(), non 
posso piu' liberare la memoria di s: se lo faccio mi da' Segmentation 
fault. Perche'?

----- begin list.c -----
/* Programma sotto GPL, bla bla bla ;-P */
/* Crea in memoria un indice dei messaggi contenuti in un file mbox. 
L'indice puo' poi essere visualizzato in una CList (lista a colonne), o 
stampato a video (come avviene qui). */
#include <stdio.h>
#include <gtk/gtk.h>

struct msg_s {
    long int head;
    long int body;
    gchar *from;
    gchar *to;
    gchar *replyto;
    gchar *date;
    gchar *subject;
    gint status;
};

/* legge una linea dal file f. Mantiene il \n finale. */
/* conto il numero di caratteri della riga corrente; poi torno
 * indietro (fseek) e metto la riga in memoria. */
char *readline(FILE *f)
{
    char c;
    char *s = NULL;
    long pos;
    int count = 0;

    pos = ftell(f);
    while ((c = fgetc(f)) != EOF) {
        count ++;
        if (c == '\n') {
            fseek(f, pos, SEEK_SET);
            s = (char *) malloc(count + 1);
            if (!s) {
                fprintf(stderr, "Not enough memory.\n");
                return(NULL);
            }
            fgets(s, count + 1, f);
            return(s);
        }
    }
    return (NULL);
}

void msg_data_free(gpointer user_data)
{
    struct msg_s *msg = (struct msg_s *) user_data;

    if (!msg->from) free(msg->from);
    if (!msg->to) free(msg->to);
    if (!msg->replyto) free(msg->replyto);
    if (!msg->date) free(msg->date);
    if (!msg->subject) free(msg->subject);
}

void msg_data_print(gpointer user_data)
{
    struct msg_s *msg = (struct msg_s *) user_data;
    
    printf("head: %d\n", msg->head);
    printf("body: %d\n", msg->body);
    printf("from: %s\n", msg->from);
    printf("to: %s\n", msg->to);
    printf("reply to: %s\n", msg->replyto);
    printf("date: %s\n", msg->date);
    printf("subject: %s\n", msg->subject);
    printf("status: %s\n", msg->status ? "yes" : "no");
    puts("-----------------------------------------------");
    getchar();
}

struct msg_s *msg_new(void)
{
    struct msg_s *msg;
    
    if (!(msg = (struct msg_s *) malloc(sizeof(struct msg_s))))
        g_error("Malloc error.\n");        

    msg->from = NULL;
    msg->to = NULL;
    msg->replyto = NULL;
    msg->date = NULL;
    msg->subject = NULL;
    msg->status = 0;

    return(msg);
}

/* parser per i messaggi all'interno di una mbox */
GList *mbox_get_msg_index(FILE *mbox)
{
    GList *list = NULL;
    gpointer data;    
    struct msg_s *msg;
    char *s;
    guint status = 0;

    /* riempi msg */
    while (s = readline(mbox)) {
        // puts(s);
        if (!status && !strncmp(s, "From ", 5)) {
            msg = msg_new();
            msg-> head = ftell(mbox);
            status = 1;
            free(s);
        }
        else if (status && !strncmp(s, "From: ", 6)) {
            s += 6;
            s[strlen(s) - 1] = '\0';
            msg->from = g_strdup(s);
            free(s);
        }
        else if (status && !strncmp(s, "Date: ", 6)) {
            s += 6;
            s[strlen(s) - 1] = '\0';
            msg->date = g_strdup(s);
            /* se provo a liberare s qui da' Segmentation fault. :-\ */
            /* free(s); */
        }
        else if (status && !strncmp(s, "Subject: ", 9)) {
            s += 9;
            s[strlen(s) - 1] = '\0';
            msg->subject = g_strdup(s);
            /* free(s); */
        }
        else if (status && !strncmp(s, "To: ", 4)) {
            s += 4;
            s[strlen(s) - 1] = '\0';
            msg->to = g_strdup(s);
            /* free(s); */
        }
        else if (status && !strncmp(s, "Reply-To: ", 9)) {
            s += 9;
            s[strlen(s) - 1] = '\0';
            msg->replyto = g_strdup(s);
            /* free(s); */
        }
        else if (status && !strncmp(s, "Status: ", 8)) {
            s += 8;
            s[strlen(s) - 1] = '\0';
            /* ... */
            /* free(s); */
        }
        else if (status && !strcmp(s, "\n")) {
            msg->body = ftell(mbox);
            list = g_list_append(list, (gpointer) msg);
            status = 0;
            /* free(s); */
        }
        else free(s);
        // getchar();
    }    
    return(list);
}

int main(void)
{
    FILE *f;
    GList *list;

    if (!(f = fopen("mbox", "r"))) 
        g_error("mbox not found.\n");
    /* creo l'indice dei messaggi */
    list = mbox_get_msg_index(f);
    fclose(f);

    /* stampa i dati di ogni nodo */
    g_list_foreach(list, (GFunc) msg_data_print, NULL);
    /* libera i vari campi di ogni nodo */
    g_list_foreach(list, (GFunc) msg_data_free, NULL);
    /* libera la lista */
    g_list_free(list);

    puts("Funziona!");
    return(0);
}
----- end list.c -----

-- 
Ciaooooo
brain - xbrain@xxxxxxxxxx

Other related posts: