/*************************************************************
 * WebMailFolder                                             *
 * COPYRIGHT 1998 by Norbert Kuemin <norbert.kuemin@gmx.net> *
 *************************************************************/
   
#define MAIL_FILE
#include "wmf.h"

char *Email2Html(struct MAILHEAD *mh) {
    char *tmpEmail, *tmpName;

    tmpEmail = NULL;
    tmpName = NULL;
    if (strlen(mh->SendName) > 0) {
	tmpName = Text_2_Html(mh->SendName);
    } else {
	tmpName = dupchar(mh->SendName);
    }
    if (config.MailCommand != NULL) {
	if (strlen(mh->SendName) == 0) {
	    tmpEmail = newchar(strlen(config.MailCommand)+
		strlen(mh->SendAddress)*2+23);
	    sprintf(tmpEmail,"<I><A HREF=\"%s%s\">%s</A></I>",config.MailCommand,
		mh->SendAddress,mh->SendAddress);
	} else {
	    tmpEmail = newchar(strlen(config.MailCommand)+
		strlen(mh->SendAddress)+strlen(tmpName)+23);
	    sprintf(tmpEmail,"<I><A HREF=\"%s%s\">%s</A></I>",config.MailCommand,
		mh->SendAddress,tmpName);
	}
    } else {
	if (strlen(mh->SendName) == 0) {
	    tmpEmail = newchar(strlen(mh->SendAddress)+8);
	    sprintf(tmpEmail,"<I>%s</I>",mh->SendAddress);
	} else {
	    tmpEmail = newchar(strlen(tmpName)+8);
	    sprintf(tmpEmail,"<I>%s</I>",tmpName);
	}
    }
    freechar(tmpName);
    tmpName = NULL;
    return tmpEmail;
}

int IsEmailChar(char chr) {
    if ((chr >= 'A') && (chr <= 'Z')) return TRUE;
    if ((chr >= 'a') && (chr <= 'z')) return TRUE;
    if ((chr >= '0') && (chr <= '9')) return TRUE;
    if (chr == '-') return TRUE;
    if (chr == '_') return TRUE;
    return FALSE;
}


char *GetHeadData(char *line) {
    char *c;
    char *data;
    int i;

    if (config.DebugLevel & 1)
        printf(".GetHeadData(%s)\n",line);
    if (line == NULL) return NULL;

    c = line;
    /* Find start */
    while ((c[0] != ':') && (c[0] != '\0')) c++;
    if (c[0] != '\0') c++;

    /* move whitechars away at the beginning */
    while ((c[0] == ' ') || (c[0] == '\t')) c++;

    /* calculate length */
    i = 0;
    while ((c[i] != '\n') && (c[i] != '\0'))
        i++;
    if (i > 0) i--;

    /* move whitechars away at the end */
    while (((c[i] == ' ') || (c[i] == '\t')) && (i > 0)) i--;
    if (c[i] != '\0') i++;

    /* copy the data */
    data = newchar(i+1);
    strncpy(data,c,i);
    data[i] = '\0';
    if (config.DebugLevel & 2)
        printf("..GetHeadData_Return(%s)\n",data);
    return data;
}


int GetEmailType(char *line) {
    /* 0=unknown   1=a@b.c (d e)   2=d e <a@b.c>   3="d e" <a@b.c> */
    int i, inner, quote, type;

    if (config.DebugLevel & 1)
	printf(".GetEmailType(%s)\n",line);
    if (line == NULL) return 0;
    type = 0;
    i = 0;
    inner = FALSE;
    quote = FALSE;
    while (TRUE) {
	if (line[i] == '\0') break;
	if ((line[i] == ',') && (inner == FALSE)) break;
	if ((line[i] == '<') && (inner == FALSE)) {
	    if (quote == TRUE) {
		type=3;
	    } else {
		type=2;
	    }
	}
	if ((line[i] == '(') && (inner == FALSE)) type=1;
	if (line[i] == '\"') {
	    quote = TRUE;
	    if (inner == TRUE) {
		inner = FALSE;
	    } else {
		inner = TRUE;
	    }
	}
	if (type != 0) break;
	i++;
    }
    if (config.DebugLevel & 2)
	printf("..GetEmailType_Return(%d)\n",type);
    return type;
}


char *GetName(char *line) {
    char *name, *tmpline;
    int i, first;
        

    if (config.DebugLevel & 1)
        printf(".GetName(%s)\n",line);
    if (line == NULL) return NULL;
    
    /* result can't be bigger than the input */
    name = newchar(strlen(line)+1);
    name[0] = '\0';
    tmpline = line;
    first = TRUE;

    while (strlen(tmpline) > 0) {
	switch (GetEmailType(tmpline)) {
	    case 1: /* email (name) */
		while ((tmpline[0] != '(') && (tmpline[0] != '\0')) tmpline++;
		while ((tmpline[0] == '(') || (tmpline[0] == '\"') || (tmpline[0] == '\'')) tmpline++;
		/* Calculate length */
		i = 0;
		while ((tmpline[i] != ')') && (tmpline[i] != '\0')) i++;
		if (i > 0) {
		    while ((i>0) && ((tmpline[i-1] == '\"') || (tmpline[i-1] == '\''))) i--;
		    if (first == TRUE) {
			first = FALSE;
		    } else {
			strcat(name,",");
		    }
		    strcat(name,"\'");
		    strncat(name,tmpline,i);
		    strcat(name,"\'");
		} else {
		    /* empty string */
		}
		tmpline = tmpline + i;
		while ((tmpline[0] == ')') || (tmpline[0] == ',') ||
		  (tmpline[0] == ' ') || (tmpline[0] == '\t'))
		    tmpline++;
		break;

	    case 3: /* "name" <email> */
	    case 2: /* name <email> */
		/* Remove spaces/tabs at the begin */
		while ((tmpline[0] == ' ') || (tmpline[0] == '\t') ||
		  (tmpline[0] == '\"') || (tmpline[0] == '\''))
		    tmpline++;
		/* Calculate length */
		i = 0;
		while ((tmpline[i] != '<') && (tmpline[i] != '\0'))
		    i++;
		i--;
		if (i > 0) {
		    /* Remove spaces at the end */
		    while (((tmpline[i] == ' ') || (tmpline[i] == '\t') ||
		      (tmpline[i] == '\"') || (tmpline[i] == '\'')) && (i >= 0))
			i--;
		    i++;
		    if (first == TRUE) {
			first = FALSE;
		    } else {
			strcat(name,",");
		    }
		    strcat(name,"\'");
		    strncat(name,tmpline,i);
		    strcat(name,"\'");
		} else {
		    /* empty string */
		}
		tmpline = tmpline + i;
		while ((tmpline[0] != '>') && (tmpline[0] != '\0')) tmpline++;
		if (tmpline[0] == '>') tmpline++;
		while ((tmpline[0] == ',') || (tmpline[0] == ' ') ||
		  (tmpline[0] == '\t'))
		    tmpline++;
		break;
	    default:
		if (first == TRUE) {
		    first = FALSE;
		} else {
		    strcat(name,",");
		}
		tmpline = "";
		break;
	}
    }
    if (config.DebugLevel & 2)
        printf("..GetName_Return(%s)\n",name);
    return name;
}


char *GetEmail(char *line) {
    char *email, *tmpline;
    int i, first;

    if (config.DebugLevel & 1)
        printf(".GetEmail(%s)\n",line);        
    if (line == NULL) return NULL;
    
    /* result can't be bigger than the input */
    email = newchar(strlen(line)+1);
    email[0] = '\0';
    tmpline = line;
    first = TRUE;

    while (strlen(tmpline) > 0) {
	switch (GetEmailType(tmpline)) {
	    case 1: /* email (name) */
		/* Remove spaces/tabs at the begin */
		while ((tmpline[0] == ' ') || (tmpline[0] == '\t'))
		    tmpline++;
		/* Calculate length */
		i = 0;
		while ((tmpline[i] != '(') && (tmpline[i] != '\0'))
		    i++;
		i--;
		/* Remove spaces at the end */
		if (i > 0) {
		    while (((tmpline[i] == ' ') || (tmpline[i] == '\t')) && (i >= 0))
			i--;
		    i++;
		    if (first == TRUE) {
			first = FALSE;
		    } else {
			strcat(email,",");
		    }
		    strncat(email,tmpline,i);
		} else {
		    /* empty string */
		}
		tmpline = tmpline + i;
		while ((tmpline[0] != ')') && (tmpline[0] != '\0')) tmpline++;
		if (tmpline[0] == ')') tmpline++;
		while ((tmpline[0] == ',') || (tmpline[0] == ' ') ||
		  (tmpline[0] == '\t'))
		    tmpline++;
		break;
	    case 3: /* "name" <email> */
		i = 0;
		while ((tmpline[0] != '\0') && (i < 2)) {
		    if (tmpline[0] == '\"') i++;
		    tmpline++;
		}
	    case 2: /* name <email> */
		while ((tmpline[0] != '<') && (tmpline[0] != '\0')) tmpline++;
		if (tmpline[0] == '<') tmpline++;
		/* Calculate length */
		i = 0;
		while ((tmpline[i] != '>') && (tmpline[i] != '\0')) i++;
		if (i > 0) {
		    if (first == TRUE) {
			first = FALSE;
		    } else {
			strcat(email,",");
		    }
		    strncat(email,tmpline,i);
		} else {
		    /* empty string */
		}
		tmpline = tmpline + i;
		while ((tmpline[0] == '>') || (tmpline[0] == ',') ||
		  (tmpline[0] == ' ') || (tmpline[0] == '\t'))
		    tmpline++;
		break;
	    default:
		if (first == TRUE) {
		    first = FALSE;
		} else {
		    strcat(email,",");
		}
		strcat(email,tmpline);
		tmpline = "";
		break;
	}
    }
    if (config.DebugLevel & 2)
        printf("..GetEmail_Return(%s)\n",email);
    return email;
}


char *GetMsgId(char *line) {
    char *id;
    char *c;
    int i;
        

    if (config.DebugLevel & 1)
        printf(".GetMsgId(%s)\n",line);
    if (line == NULL) return NULL;
    c = line;
    /* Start at < */
    while (c[0] != '<') {
        if (c[0] == 0) break;
        c++;
    }
    if (c[0] != 0) c++;
    /* Calculate length */
    i = 0;
    while ((c[i] != '>') && (c[i] != '\0'))
        i++;
    /* Copy data */
    id = newchar(i+1);
    strncpy(id,c,i);
    id[i] = '\0';
    return id;
}


char *AddData(char *line, char *data) {
    char *newdata;
    char *c;
    int i;
        
    if (config.DebugLevel & 1)
        printf(".AddData(%s)\n",line);
    c = line;
    /* remove spaces and tabs at start */
    while ((c[0] == ' ') || (c[0] == '\t')) c++;
    /* Calculate length */
    i = 0;
    while ((c[i] != '\n') && (c[i] != '\0'))
        i++;
    if ((line[0] == '\t') || (strncmp(line,"        ",8) == 0)) {
	newdata = newchar(i+strlen(data)+2);
    } else {
	newdata = newchar(i+strlen(data)+1);
    }
    strcpy(newdata,data);
    if ((line[0] == '\t') || (strncmp(line,"        ",8) == 0)) {
        strcat(newdata," ");
    }
    strncat(newdata,c,i);
    strcat(newdata,"\0");
    return newdata;
}


struct MAILBODY *addbody(char *line, struct MAILBODY *body) {

    if (config.DebugLevel & 1)
        printf(".addbody(%s)\n",line);
    if (body->Line == NULL) {
	body->Line = dupchar(line);
	body->Next = NULL;
	return body;
    } else {
	body->Next = (struct MAILBODY *) malloc(sizeof(struct MAILBODY));
	body->Next->Line = dupchar(line);
	body->Next->Next = NULL;
	return body->Next;
    }
}


void InitMail(struct MAILHEAD *mh, struct MAILBODY *mb) {

    mh->SendName = NULL;
    mh->SendAddress = NULL;
    mh->ReceiveName = NULL;
    mh->ReceiveAddress = NULL;
    mh->SentDate = NULL;
    mh->MsgId = NULL;
    mh->Subject = NULL;
    mh->Reference = NULL;
    mh->Xface = NULL;
    mh->FileName = NULL;
    mh->HomePage = NULL;
    mh->AttachFile = NULL;
    mh->MimeBoundary = NULL;
    mh->MimeDescription = NULL;
    mh->MimeType = MIME_TYPE_NONE;
    mh->MimeCharset = MIME_CHARSET_NONE;
    mh->MimeEncode = MIME_ENCODE_NONE;
    mh->InReply = FALSE;
    mb->Line = NULL;
    mb->Next = NULL;
}

void GetMail(FILE *fd, struct MAILHEAD *mh, struct MAILBODY *mb) {
    char line[BUFSIZ];
    char *tmpFrom, *tmpTo, *tmpId, *tmpRef, *tmpstr, *tmpType, *tmpEncode;
    struct MAILBODY *body;
    int status; /* -1=Error 0=End 1=Header 2=Body */
    int lastlength;
    int lastheadcmd; /*-1=Unknown 0=None 1=From 2=To 3=Subject 4=Date
    			5=Message-Id 6=Reference 7=Xface 8=HomePage
    			9=MimeType 10=MimeEncode 11=MimeDescription*/
    
    if (config.DebugLevel & 1)
        printf(".GetMail\n");
    body = mb;
    lastheadcmd = 0;
    status = 1;
    lastlength = 0;
    tmpFrom = NULL;
    tmpTo = NULL;
    tmpId = NULL;
    tmpRef = NULL;
    tmpType = NULL;
    tmpEncode = NULL;
    while (status > 0) {
        if(feof(fd) == 0) {
            fgets(line,BUFSIZ,fd);
	    if ((status == 2) && (strncmp(line,"\001\001\001\001",4) == 0))
		status = 0;
            while ((status == 1) && (strncmp(line,"\001\001\001\001",4) == 0) &&
		(feof(fd) == 0))
		fgets(line,BUFSIZ,fd);
	} else {
            status = 0;
	}
	switch (status) {
	    case 1:
	        /* Header */
		if ((strlen(line) == 0) || (line[0] == '\n')) {
		    /* An empty line indicates the end of the header */
		    status = 2;
		    if (tmpFrom != NULL) {
			mh->SendAddress = GetEmail(tmpFrom);
			mh->SendName = GetName(tmpFrom);
			freechar(tmpFrom);
			tmpFrom = NULL;
		    }
		    if (tmpTo != NULL) {
			mh->ReceiveAddress = GetEmail(tmpTo);
			mh->ReceiveName = GetName(tmpTo);
			freechar(tmpTo);
			tmpTo = NULL;
		    }
		    if (mh->ReceiveAddress == NULL) {
			mh->ReceiveAddress = dupchar("unknown");
		    }
		    if (tmpId != NULL) {
			mh->MsgId = GetMsgId(tmpId);
			freechar(tmpId);
			tmpId = NULL;
		    }
		    if (tmpRef != NULL) {
			mh->Reference = GetMsgId(tmpRef);
			freechar(tmpRef);
			tmpRef = NULL;
		    }
		    if (tmpType != NULL) {
			mh->MimeType = GetContentType(tmpType);
			if (mh->MimeType == MIME_TYPE_TEXT_PLAIN)
			    mh->MimeCharset = GetCharset(tmpType);
			if ((mh->MimeType == MIME_TYPE_MULTIPART_MIXED) ||
			    (mh->MimeType == MIME_TYPE_MULTIPART_SIGNED))
			    mh->MimeBoundary = GetBoundary(tmpType);
			freechar(tmpType);
			tmpType = NULL;
		    }
		    if (tmpEncode != NULL) {
			mh->MimeEncode = GetContentEncode(tmpEncode);
			freechar(tmpEncode);
			tmpEncode = NULL;
		    }
		    if (HeaderIsMimeEncoded(mh->Subject) == TRUE) {
			tmpstr = DecodeMimeHeader(mh->Subject);
			freechar(mh->Subject);
			mh->Subject = tmpstr;
			tmpstr = NULL;
		    }
		    if (HeaderIsMimeEncoded(mh->SendName) == TRUE) {
			tmpstr = DecodeMimeHeader(mh->SendName);
			freechar(mh->SendName);
			mh->SendName = tmpstr;
			tmpstr = NULL;
		    }
		    if (HeaderIsMimeEncoded(mh->ReceiveName) == TRUE) {
			tmpstr = DecodeMimeHeader(mh->ReceiveName);
			freechar(mh->ReceiveName);
			mh->ReceiveName = tmpstr;
			tmpstr = NULL;
		    }
		}
		if ((line[0] == ' ') || (line[0] == '\t')) {
		    /* A space or tab means add info to previous line */
		    switch (lastheadcmd) {
			case 1:
			    tmpstr = AddData(line,tmpFrom);
			    freechar(tmpFrom);
			    tmpFrom = tmpstr;
			    tmpstr = NULL;
			    break;
			case 2:
			    tmpstr = AddData(line,tmpTo);
			    freechar(tmpTo);
			    tmpTo = tmpstr;
			    tmpstr = NULL;
			    break;
			case 3:
			    tmpstr = AddData(line,mh->Subject);
			    freechar(mh->Subject);
			    mh->Subject = tmpstr;
			    tmpstr = NULL;
			    break;
			case 4: break; /* Unknown to handle */
			case 5:
			    tmpstr = AddData(line,tmpId);
			    freechar(tmpId);
			    tmpId = tmpstr;
			    tmpstr = NULL;
			    break;
			case 6:
			    tmpstr = AddData(line,tmpRef);
			    freechar(tmpRef);
			    tmpRef = tmpstr;
			    tmpstr = NULL;
			    break;
			case 7:
			    tmpstr = AddData(line,mh->Xface);
			    freechar(mh->Xface);
			    mh->Xface = tmpstr;
			    tmpstr = NULL;
			    break;
			case 8:
			    tmpstr = AddData(line,mh->HomePage);
			    freechar(mh->HomePage);
			    mh->HomePage = tmpstr;
			    tmpstr = NULL;
			    break;
			case 9:
			    tmpstr = AddData(line,tmpType);
			    freechar(tmpType);
			    tmpType = tmpstr;
			    tmpstr = NULL;
			    break;
			case 10:
			    tmpstr = AddData(line,tmpEncode);
			    freechar(tmpEncode);
			    tmpEncode = tmpstr;
			    tmpstr = NULL;
			    break;
			case 11:
			    tmpstr = AddData(line,mh->MimeDescription);
			    freechar(mh->MimeDescription);
			    mh->MimeDescription = tmpstr;
			    tmpstr = NULL;
			    break;
		    }
		} else {
		    lastheadcmd = -1;
		}
		if (strncmp(line,"From:",5) == 0) {
		    if (tmpFrom != NULL) {
			freechar(tmpFrom);
			tmpFrom = NULL;
		    }
		    tmpFrom = GetHeadData(line);
		    lastheadcmd = 1;
		}
		if ((strncmp(line,"To:",3) == 0) ||
		    (strncmp(line,"TO:",3) == 0)) {
		    if (tmpTo != NULL) {
			freechar(tmpTo);
			tmpTo = NULL;
		    }
		    tmpTo = GetHeadData(line);
		    lastheadcmd = 2;
		}
		if (strncmp(line,"Subject:",8) == 0) {
		    if (mh->Subject != NULL) {
			freechar(mh->Subject);
			mh->Subject = NULL;
		    }
		    mh->Subject = GetHeadData(line);
		    lastheadcmd = 3;
		}
		if (strncmp(line,"Date:",5) == 0) {
		    if (mh->SentDate != NULL) {
			freechar(mh->SentDate);
			mh->SentDate = NULL;
		    }
		    mh->SentDate = GetHeadData(line);
		    lastheadcmd = 4;
		}
		if ((strncmp(line,"Message-Id:",11) == 0) ||
		    (strncmp(line,"Message-ID:",11) == 0)) {
		    if (tmpId != NULL) {
			freechar(tmpId);
			tmpId = NULL;
		    }
		    tmpId = GetHeadData(line);
		    lastheadcmd = 5;
		}
		if ((strncmp(line,"In-Reply-To:",12) == 0) ||
		    (strncmp(line,"References:",11) == 0)) {
		    if (tmpRef != NULL) {
			freechar(tmpRef);
			tmpRef = NULL;
		    }
		    tmpRef = GetHeadData(line);
		    lastheadcmd = 6;
		}
		if ((strncmp(line,"X-face:",7) == 0) ||
		    (strncmp(line,"X-Face:",7) == 0)) {
		    if (mh->Xface != NULL) {
			freechar(mh->Xface);
			mh->Xface = NULL;
		    }
		    mh->Xface = GetHeadData(line);
		    lastheadcmd = 7;
		}
		if (strncmp(line,"X-URL:",6) == 0) {
		    if (mh->HomePage != NULL) {
			freechar(mh->HomePage);
			mh->HomePage = NULL;
		    }
		    mh->HomePage = GetHeadData(line);
		    lastheadcmd = 8;
		}
		if (strncmp(line,"Content-Type:",13) == 0) {
		    if (tmpType != NULL) {
			freechar(tmpType);
			tmpType = NULL;
		    }
		    tmpType = GetHeadData(line);
		    lastheadcmd = 9;
		}
		if (strncmp(line,"Content-Transfer-Encoding:",26) == 0) {
		    if (tmpEncode != NULL) {
			freechar(tmpEncode);
			tmpEncode = NULL;
		    }
		    tmpEncode = GetHeadData(line);
		    lastheadcmd = 10;
		}
		if (strncmp(line,"Content-Description:",20) == 0) {
		    if (mh->MimeDescription != NULL) {
			freechar(mh->MimeDescription);
			mh->MimeDescription = NULL;
		    }
		    mh->MimeDescription = GetHeadData(line);
		    lastheadcmd = 11;
		}
		break;
	    case 2:
	        /* Body */
		if (lastlength == 0) {
		    if (strncmp(line,"From ",5) == 0) {
			/* Next mail detected */
			status = 0;
		    } else {
			/* It was only an empty line */
			body = addbody("\n",body);
		    }
		}
		lastlength = strlen(line);
		if (line[0] == '\n') lastlength = 0;
		if ((lastlength != 0) && (status > 0) && (feof(fd) == 0)) {
		    body = addbody(line,body);
		}
		break;
	}
	if(feof(fd) != 0) status=0;
    }
}


int GetCountOfEmail(char *line) {
    int count;
    char *tmpstr;

    if (config.DebugLevel & 1)
        printf(".GetCountOfEmail(%s)\n",line);

    if (line == NULL) return 0;
    if (strlen(line) == 0) return 0;

    count = 1;
    tmpstr = line;
    while (strstr(tmpstr,",") != NULL) {
	count++;
	if (strstr(tmpstr,",") == NULL) {
	    tmpstr = NULL;
	} else {
	    tmpstr = strstr(tmpstr,",") + 1;
	}
    }
    if (config.DebugLevel & 2)
        printf("..GetCountOfEmail_Return(%d)\n",count);
    return count;
}


char *GetEmailFromList(char *list, int number) {
    int count;
    char *tmpstr, *email;

    if (config.DebugLevel & 1)
        printf(".GetCountOfEmail\n");

    if (list == NULL) return dupchar("");
    if (strlen(list) == 0) return dupchar("");

    count = 1;
    tmpstr = list;
    while ((count < number) && (tmpstr != NULL)) {
	count++;
	if (strstr(tmpstr,",") == NULL) {
	    tmpstr = NULL;
	} else {
	    tmpstr = strstr(tmpstr,",") + 1;
	}
    }

    if (tmpstr == NULL) return dupchar("");
    while((tmpstr[0] == '\'') || (tmpstr[0] == ',')) tmpstr++;
    count = 0;
    while((tmpstr[count] != ',') && (tmpstr[count] != '\0')) count++;
    email = newchar(count + 1);
    email[0] = '\0';
    if (count > 0) strncat(email,tmpstr,count);

    if (config.DebugLevel & 2)
        printf("..GetEmailFromList_Return(%s)\n",email);
    return email;
}


int GetCountOfName(char *line) {
    int count;
    char *tmpstr;

    if (config.DebugLevel & 1)
        printf(".GetCountOfName(%s)\n",line);

    if (line == NULL) return 0;
    if (strlen(line) == 0) return 0;

    count = 1;
    tmpstr = line;
    while (strstr(tmpstr,"','") != NULL) {
	count++;
	if (strstr(tmpstr,"','") == NULL) {
	    tmpstr = NULL;
	} else {
	    tmpstr = strstr(tmpstr,"','") + 3;
	}
    }
    if (config.DebugLevel & 2)
        printf("..GetCountOfName_Return(%d)\n",count);
    return count;
}


char *GetNameFromList(char *list, int number) {
    int count;
    char *tmpstr, *name;

    if (config.DebugLevel & 1)
        printf(".GetNameFromList(%s,%d)\n",list,number);

    if (list == NULL) return dupchar("");
    if (strlen(list) == 0) return dupchar("");

    count = 1;
    tmpstr = list;
    while ((count < number) && (tmpstr != NULL)) {
	count++;
	if (strstr(tmpstr,"','") == NULL) {
	    tmpstr = NULL;
	} else {
	    tmpstr = strstr(tmpstr,"','") + 3;
	}
    }

    if (tmpstr == NULL) return dupchar("");
    while((tmpstr[0] == '\'') || (tmpstr[0] == ',')) tmpstr++;
    count = 0;
    while((tmpstr[count] != '\'') && (tmpstr[count] != '\0')) count++;
    name = newchar(count + 1);
    name[0] = '\0';
    if (count > 0) strncat(name,tmpstr,count);

    if (config.DebugLevel & 2)
        printf("..GetNameFromList_Return(%s)\n",name);
    return name;
}


void LineWrapper(char *Line, long Length) {
    long tmpLength, n;

    if (config.DebugLevel & 1)
        printf(".LineWrapper\n");

    if (Line == NULL) return;

    tmpLength = 0;

    while (tmpLength + Length < strlen(Line)) {
	/* Search a space to break the line */
	n = tmpLength + Length;
	while (n > tmpLength) {
	    if (Line[n] == ' ') break;
	    n--;
	}

	if (Line[n] != ' ') {
	    /* No Space found, search to the end */
	    n = tmpLength + Length;
	    while (n < strlen(Line)) {
		if (Line[n] == ' ') break;
		n++;
	    }
	}

	if (Line[n] == ' ') {
	    /* Space found, replace it with a newline */
	    Line[n] = '\n';
	} else {
	    /* Sorry, but no linebreaks without spaces */
	}
	tmpLength = n;
    }
}


void WriteMailBodyLine(char *FileName, char *Data, struct MAILHEAD *mh) {
    char *datastr, *tmpstr, *tmpmail, tmpchar;
    int tmpint, n, m;

    if (config.DebugLevel & 1)
        printf(".WriteMailBodyLine\n");

    if ((mh->MimeType != MIME_TYPE_TEXT_HTML) && (config.BodyHtmlConvert == TRUE)) {
	if ((config.LineSize != WMF_NOVALUE) && (config.LineSize < strlen(Data))) {
	    LineWrapper(Data,config.LineSize);
	}
	datastr = Text_2_Html(Data);
    } else {
	datastr = dupchar(Data);
    }
    
    /* url hyperlinks */
    /* url never will be greater than 10 times the original length */
    if (config.BodyLinkUrl == TRUE) {
	if (config.DebugLevel & 2)
            printf("..UrlHyperlinks\n");
	tmpstr = newchar(strlen(datastr)*10+1);
	tmpstr[0] = '\0';
	for(n=0;n<(strlen(datastr));n++) {
	    tmpchar = 0;
	    for(m=0 ; protocols[m] != NULL ; m++) {
		if (strncmp((datastr+n),protocols[m],strlen(protocols[m])) == 0) {
		    tmpchar = 0;
	            if (n > 0) tmpchar = datastr[n-1];
		    if (tmpchar != '"') tmpchar = ' ';
		    tmpint = 0;
		    strcat(tmpstr,"<A HREF=\"");
		    for (;;) {
			if (tmpchar == '"') {
			    if (datastr[n+tmpint] == '"') break;
			} else {
			    if (IsUrlChar(datastr[n+tmpint]) == FALSE) break;
			}
			tmpint++;
		    }
		    strncat(tmpstr,datastr+n,tmpint);
		    strcat(tmpstr,"\"");
		    if (config.FrameSupport == TRUE) {
			strcat(tmpstr," TARGET=_top");
		    }
		    strcat(tmpstr,">");
		    strncat(tmpstr,datastr+n,tmpint);
		    strcat(tmpstr,"</A>");
		    n = n + tmpint;
		}
	    }
	    if (n < strlen(datastr)) {
		tmpstr[strlen(tmpstr)+1] = '\0';
		tmpstr[strlen(tmpstr)] = datastr[n];
	    }
	}
	freechar(datastr);
	datastr = tmpstr;
	tmpstr = NULL;
    }

    /* mail hyperlinks */
    /* mail never will be greater than 10 times the original length */
    if (config.DebugLevel & 2)
        printf("..MailHyperlinks\n");
    if ((strstr(datastr,"@") != NULL) && (config.MailCommand != NULL) &&
	(config.BodyLinkEmail == TRUE)) {
    	tmpstr = newchar(strlen(datastr)*10+1);
	tmpstr[0] = '\0';
	tmpmail = datastr;
	while (tmpmail != NULL) {
	    n=0;
	    while ((tmpmail[n] != '@') && (tmpmail[n] != '\0')) n++;
	    if (tmpmail[n] == '\0') {
		/* Append the rest of the line */
		strcat(tmpstr,tmpmail);
		tmpmail = NULL;
	    } else {
		/* Found a @, now check if it is an email */
		if ((n>0) && (tmpmail[n+1] != '\n')) {
		    if (IsEmailChar(tmpmail[n-1]) && IsEmailChar(tmpmail[n+1])) {
			/* Real email found */
			/* Move to the beginning */
			n--;
			while ((n>=0) && (IsEmailChar(tmpmail[n]) ||
			    (tmpmail[n]=='.'))) n--;
			n++;
			if (n > 0) {
			    strncat(tmpstr,tmpmail,n);
			    tmpmail = tmpmail + n;
			}
			/* Move to the ending */
			n = 0;
			while ((tmpmail[n] != '\0') && ((IsEmailChar(tmpmail[n]) ||
			    (tmpmail[n] == '.') || (tmpmail[n] == '@')))) n++;
			strcat(tmpstr,"<A HREF=\"");
			strcat(tmpstr,config.MailCommand);
			strncat(tmpstr,tmpmail,n);
			strcat(tmpstr,"\">");
			strncat(tmpstr,tmpmail,n);
			strcat(tmpstr,"</A>");
			tmpmail = tmpmail + n;
		    } else {
			/* Seams to be anything else */
			n++;
			strncat(tmpstr,tmpmail,n);
			tmpmail = tmpmail + n;
		    }
		} else {
		    /* Found a @ at the begin or the end of the line */
		    n++;
		    strncat(tmpstr,tmpmail,n);
		    tmpmail = tmpmail + n;
		}
	    }
	}
	freechar(datastr);
	datastr = tmpstr;
	tmpstr = NULL;
    }

    /* Write line */
    if ((config.ReplyChars != NULL) && (strchr(config.ReplyChars,Data[0]) != NULL)) {
	if (HtmlCmd.ReplyStart != NULL) AppendFile(FileName,HtmlCmd.ReplyStart);
        mh->InReply = TRUE;
    }
    AppendFile(FileName,datastr);
    freechar(datastr);
    if (((strchr(Data,'\n') != NULL) ||(strchr(Data,'\r') != NULL)) &&
      (mh->InReply == TRUE)) {
	if (HtmlCmd.ReplyEnd != NULL) AppendFile(FileName,HtmlCmd.ReplyEnd);
        mh->InReply = FALSE;
    }
}

void WriteIndexNavigation (char *Filename) {
    char *tmpstr;

    if (config.DebugLevel & 1)
        printf(".WriteNavIndex\n");

    tmpstr = NULL;
    AppendFile(Filename,"Index:\n");
    if (config.IndexThread == TRUE) {
	tmpstr = newchar(31+strlen(config.Extension));
	sprintf(tmpstr,"[<A HREF=\"thread%s\">thread</A>]\n",config.Extension);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    if (config.IndexDate == TRUE) {
	tmpstr = newchar(27+strlen(config.Extension));
	sprintf(tmpstr,"[<A HREF=\"date%s\">date</A>]\n",config.Extension);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    if (config.IndexSubject == TRUE) {
	tmpstr = newchar(33+strlen(config.Extension));
	sprintf(tmpstr,"[<A HREF=\"subject%s\">subject</A>]\n",config.Extension);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    if (config.IndexAuthor == TRUE) {
	tmpstr = newchar(31+strlen(config.Extension));
	sprintf(tmpstr,"[<A HREF=\"author%s\">author</A>]\n",config.Extension);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    if (config.Statistics == TRUE) {
	tmpstr = newchar(31+strlen(config.Extension));
	sprintf(tmpstr,"[<A HREF=\"stats%s\">stats</A>]\n",config.Extension);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    if (config.AboutLink != NULL) {
	tmpstr = newchar(strlen(config.AboutLink)+24);
	sprintf(tmpstr,"[<A HREF=\"%s\">about</A>]\n",config.AboutLink);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }

}


void WriteMailHeadData(char *Filename, struct MAILHEAD *mh) {

    if (config.DebugLevel & 1)
        printf(".WriteMailHeadData\n");

    /* Write headdata as remark */
    WriteHtmlValue(Filename,"EmailData","Start");
    WriteHtmlValue(Filename,"Version",HTML_VERSION);
    if (mh->Subject != NULL) {
	WriteHtmlValue(Filename,"Subject",mh->Subject);
    } else {
	WriteHtmlValue(Filename,"Subject","");
    }
    if (mh->SendName != NULL) {
	WriteHtmlValue(Filename,"FromName",mh->SendName);
    } else {
	WriteHtmlValue(Filename,"FromName","");
    }
    if (mh->SendAddress != NULL) {
	WriteHtmlValue(Filename,"FromEmail",mh->SendAddress);
    } else {
	WriteHtmlValue(Filename,"FromEmail","");
    }
    if (mh->ReceiveName != NULL) {
	WriteHtmlValue(Filename,"ToName",mh->ReceiveName);
    } else {
	WriteHtmlValue(Filename,"ToName","");
    }
    if (mh->ReceiveAddress != NULL) {
	WriteHtmlValue(Filename,"ToEmail",mh->ReceiveAddress);
    } else {
	WriteHtmlValue(Filename,"ToEmail","");
    }
    if (mh->SentDate != NULL) {
	WriteHtmlValue(Filename,"Date",mh->SentDate);
    } else {
	WriteHtmlValue(Filename,"Date","");
    }
    if (mh->MsgId != NULL) {
	WriteHtmlValue(Filename,"Id",mh->MsgId);
    } else {
	WriteHtmlValue(Filename,"Id","");
    }
    if (mh->Reference != NULL) {
	WriteHtmlValue(Filename,"Reference",mh->Reference);
    } else {
	WriteHtmlValue(Filename,"Reference","");
    }
    if (mh->Xface != NULL) {
	WriteHtmlValue(Filename,"X-Face",mh->Xface);
    } else {
	WriteHtmlValue(Filename,"X-Face","");
    }
    if (mh->HomePage != NULL) {
	WriteHtmlValue(Filename,"X-URL",mh->HomePage);
    } else {
	WriteHtmlValue(Filename,"X-URL","");
    }
    WriteHtmlValue(Filename,"EmailData","End");
}

void WriteMailHead (char *Filename, struct MAILHEAD *mh) {

    char *tmpstr, *tmpmail, *tmpname, *tmpfname, *ls_subject;
    int i, email_count;

    if (config.DebugLevel & 1)
        printf(".WriteMailHead\n");

    WriteMailHeadData(Filename,mh);

    if (mh->Subject != NULL) {
        ls_subject = Text_2_Html(mh->Subject);
    } else {
	ls_subject = dupchar("");
    }

    if (config.DocStartFile != NULL) {
	IncludeFile(Filename,config.DocStartFile);
    } else {
	/* Write html head data */
	if (HtmlCmd.HeadStart == NULL) {
	    AppendFile(Filename,HTMLCMD_HEAD_START);
	} else {
	    AppendFile(Filename,HtmlCmd.HeadStart);
	}
	AppendFile(Filename,"\n");
	if (config.Name == NULL) {
	    tmpstr = newchar(strlen(ls_subject)+17);
	    sprintf(tmpstr,"<TITLE>%s</TITLE>\n",ls_subject);
	} else {
	    tmpstr = newchar(strlen(config.Name)+strlen(ls_subject)+19);
	    sprintf(tmpstr,"<TITLE>%s: %s</TITLE>\n",config.Name,ls_subject);
	}
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
	if (HtmlCmd.HeadEnd == NULL) {
	    AppendFile(Filename,HTMLCMD_HEAD_END);
	} else {
	    AppendFile(Filename,HtmlCmd.HeadEnd);
	}
	AppendFile(Filename,"\n");
	/* Write html body data */
	if (HtmlCmd.BodyStart == NULL) {
	    AppendFile(Filename,HTMLCMD_BODY_START);
	} else {
	    AppendFile(Filename,HtmlCmd.BodyStart);
	}
	AppendFile(Filename,"\n");
    }

    if (config.DebugLevel & 2)
        printf("..IndexControl1\n");
    if (config.FrameSupport == FALSE) {
	WriteHtmlValue(Filename,"IndexControl1","Start");
	WriteIndexNavigation(Filename);
	if (HtmlCmd.HrStart == NULL) {
	    AppendFile(Filename,HTMLCMD_HR_START);
	} else {
	    AppendFile(Filename,HtmlCmd.HrStart);
	}
	AppendFile(Filename,"\n");
	WriteHtmlValue(Filename,"IndexControl1","End");
    }

    WriteHtmlValue(Filename,"Header","Start");
    AppendFile(Filename,"<PRE>\n");

#ifdef FACES
    /* Include face picture */
    if (config.DebugLevel & 2)
        printf("..Faces\n");
    if (config.FaceSupport == TRUE) {
	if (mh->Xface != NULL) {
	    if (config.FaceDirectory == NULL) {
		tmpstr = newchar(strlen(mh->SendAddress)+5);
		sprintf(tmpstr,"%s.xbm",mh->SendAddress);
	    } else {
		tmpstr = newchar(strlen(mh->SendAddress)+
		    strlen(config.FaceDirectory)+6);
		sprintf(tmpstr,"%s/%s.xbm",config.FaceDirectory,
		    mh->SendAddress);
	    }
	    AppendFile(Filename,"<IMG ALIGN=RIGHT SRC=\"");
	    AppendFile(Filename,tmpstr);
	    AppendFile(Filename,"\">");
	    freechar(tmpstr);
	    tmpstr = NULL;
	} else {
	    if (config.NoFaceFile != NULL) {
		AppendFile(Filename,"<IMG ALIGN=RIGHT SRC=\"");
		AppendFile(Filename,config.NoFaceFile);
		AppendFile(Filename,"\">");
	    }
	}
    }
#endif

    /* From */
    if (config.DebugLevel & 2)
        printf("..From\n");
    tmpstr = NULL;
    tmpmail = NULL;
    tmpname = NULL;
    tmpfname = NULL;
    AppendFile(Filename,"  From: ");
    email_count = GetCountOfEmail(mh->SendAddress);
    for(i=1;i<=email_count;i++) {
	tmpstr = GetNameFromList(mh->SendName,i);
	if (i>1) AppendFile(Filename,"<BR>        ");
	if (strlen(tmpstr) > 0) {
	    tmpfname = Text_2_Html(tmpstr);
	    AppendFile(Filename,tmpfname);
	    freechar(tmpfname);
	    tmpfname = NULL;
	    AppendFile(Filename," ");
	}
	freechar(tmpstr);
	tmpstr = NULL;
	tmpstr = GetEmailFromList(mh->SendAddress,i);
	AppendFile(Filename,"&lt;<I>");
	if (config.MailCommand != NULL) {
	    AppendFile(Filename,"<A HREF=\"");
	    AppendFile(Filename,config.MailCommand);
	    AppendFile(Filename,tmpstr);
	    AppendFile(Filename,"\">");
	}
	AppendFile(Filename,tmpstr);
	if (config.MailCommand != NULL) {
	    AppendFile(Filename,"</A>");
	}
	AppendFile(Filename,"</I>&gt;");
	freechar(tmpstr);
	tmpstr = NULL;
    }
    AppendFile(Filename,"\n");

    /* To */
    if (config.DebugLevel & 2)
        printf("..To\n");
    AppendFile(Filename,"  To  : ");
    email_count = GetCountOfEmail(mh->ReceiveAddress);
    for(i=1;i<=email_count;i++) {
	tmpstr = GetNameFromList(mh->ReceiveName,i);
	if (i>1) AppendFile(Filename,"<BR>        ");
	if (strlen(tmpstr) > 0) {
	    tmpfname = Text_2_Html(tmpstr);
	    AppendFile(Filename,tmpfname);
	    freechar(tmpfname);
	    tmpfname = NULL;
	    AppendFile(Filename," ");
	}
	freechar(tmpstr);
	tmpstr = NULL;
	tmpstr = GetEmailFromList(mh->ReceiveAddress,i);
	AppendFile(Filename,"&lt;<I>");
	if (config.MailCommand != NULL) {
	    AppendFile(Filename,"<A HREF=\"");
	    AppendFile(Filename,config.MailCommand);
	    AppendFile(Filename,tmpstr);
	    AppendFile(Filename,"\">");
	}
	AppendFile(Filename,tmpstr);
	if (config.MailCommand != NULL) {
	    AppendFile(Filename,"</A>");
	}
	AppendFile(Filename,"</I>&gt;");
	freechar(tmpstr);
	tmpstr = NULL;
    }
    AppendFile(Filename,"\n");

    /* Date */
    if (config.DebugLevel & 2)
        printf("..Date\n");
    if (mh->SentDate != NULL) {
	tmpstr = newchar(strlen(mh->SentDate)+10);
	sprintf(tmpstr,"  Date: %s\n",mh->SentDate);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }
    AppendFile(Filename,"</PRE>\n");

    /* Subject as title */
    if (config.DebugLevel & 2)
        printf("..Subject\n");
    if ((mh->Subject != NULL) && (ls_subject != NULL)) {
	tmpstr = newchar(strlen(ls_subject)+11);
	sprintf(tmpstr,"<H1>%s</H1>\n",ls_subject);
	AppendFile(Filename,tmpstr);
	freechar(tmpstr);
	tmpstr = NULL;
    }

    freechar(ls_subject);
    ls_subject = NULL;
    WriteHtmlValue(Filename,"Header","End");
}


void WriteMailBody (char *Filename,  struct MAILHEAD *mh, struct MAILBODY *mb,
                    int FileNumber) {

    char *tmpstr, *tmpfile, *tmpContent, *tmpDisposition, *tmpEncode, *tmpDescription;
    struct MAILBODY *tmpmb, *lastmb;
    int Multipart, tmplen, fd, BoundaryFound, LastMimeValue;

    if (config.DebugLevel & 1)
        printf(".WriteMailBody\n");

    if ((mh->MimeType == MIME_TYPE_MULTIPART_MIXED) ||
	(mh->MimeType == MIME_TYPE_MULTIPART_SIGNED)) {
	Multipart = TRUE;
    } else {
	Multipart = FALSE;
    }
    WriteHtmlValue(Filename,"Body","Start");
    AppendFile(Filename,"<PRE>\n");
    lastmb = NULL;
    tmpmb = mb;
    if (Multipart == TRUE) {
	if (config.DebugLevel & 2)
            printf("..Multipart\n");
	/* Search first boundary */
	while (tmpmb != NULL) {
	    if (tmpmb->Line != NULL) {
		BoundaryFound = FALSE;
		if (mh->MimeBoundary != NULL) {
		    if (strstr(tmpmb->Line,mh->MimeBoundary) != NULL) {
			BoundaryFound = TRUE;
		    }
		} else {
		    /* brocken boundary */
		    if (strncmp(tmpmb->Line,"--",2) == 0) {
			if (lastmb == NULL) {
			    BoundaryFound = TRUE;
			} else {
			    if (strcmp(lastmb->Line,"\n") == 0) {
				BoundaryFound = TRUE;
			    }
			}
		    }
		}
		if (BoundaryFound == TRUE) break;
		lastmb = tmpmb;
		tmpmb = tmpmb->Next;
	    }
	}
	while (tmpmb != NULL) {
	    /* If boundery */
	    BoundaryFound = FALSE;
	    if (mh->MimeBoundary != NULL) {
		if (strstr(tmpmb->Line,mh->MimeBoundary) != NULL) {
		    BoundaryFound = TRUE;
		}
	    } else {
		/* brocken boundary */
		if (strncmp(tmpmb->Line,"--",2) == 0) {
		    if (lastmb == NULL) {
			BoundaryFound = TRUE;
		    } else {
			if (strcmp(lastmb->Line,"\n") == 0) {
			    BoundaryFound = TRUE;
			}
		    }
		}
	    }
	    if (BoundaryFound == TRUE) {
		if (config.DebugLevel & 2)
		    printf("..boundary found(%s)\n",mh->MimeBoundary);
		if (mh->AttachFile != NULL) {
		    freechar(mh->AttachFile);
		    mh->AttachFile = NULL;
		}
		if (mh->MimeDescription != NULL) {
		    freechar(mh->MimeDescription);
		    mh->MimeDescription = NULL;
		}
		mh->MimeEncode = MIME_ENCODE_NONE;
		LastMimeValue = 0; /* unknown */
		tmpContent = NULL;
		tmpDisposition = NULL;
		tmpEncode = NULL;
		tmpDescription = NULL;
		lastmb = tmpmb;
		tmpmb = tmpmb->Next;
		while (tmpmb != NULL) {
		    if ((tmpmb->Line == NULL) || (tmpmb->Line[0] == '\n')) {
			/* An empty line ends the boundery */
			if (config.DebugLevel & 2)
		            printf("..boundary end\n");
		        /* finalize mime */
		        if (tmpContent != NULL) {
			    mh->MimeType = GetContentType(tmpContent);
			    if ((strstr(tmpContent,"name") != NULL ) &&
			      (mh->MimeType != MIME_TYPE_TEXT_PLAIN)) {
				tmpstr = GetAttachmentName(tmpContent + 14);
				if (tmpstr != NULL) {
				    if (mh->AttachFile != NULL) freechar(mh->AttachFile);
				    mh->AttachFile = tmpstr;
				    tmpstr = NULL;
				}
			    }
			    freechar(tmpContent);
			    tmpContent = NULL;
			}
		        if (tmpDisposition != NULL) {
			    if (strstr(tmpDisposition,"attachment") != NULL ) {
				tmpstr = GetAttachmentName(tmpDisposition);
				if (tmpstr != NULL) {
				    if (mh->AttachFile != NULL) freechar(mh->AttachFile);
				    mh->AttachFile = tmpstr;
				    tmpstr = NULL;
				}
			    }
			    freechar(tmpDisposition);
			    tmpDisposition = NULL;
		        }
		        if (tmpEncode != NULL) {
			    mh->MimeEncode = GetContentEncode(tmpEncode);
			    freechar(tmpEncode);
			    tmpEncode = NULL;
		        }
		        if (tmpDescription != NULL) {
		            mh->MimeDescription = tmpDescription;
		            tmpDescription = NULL;
		        }
		        if (mh->AttachFile != NULL) {
			    if (HeaderIsMimeEncoded(mh->AttachFile) == TRUE) {
				tmpstr = DecodeMimeHeader(mh->AttachFile);
				freechar(mh->AttachFile);
				mh->AttachFile = tmpstr;
				tmpstr = NULL;
			    }
		        }
		        lastmb = tmpmb;
			tmpmb = tmpmb->Next;
			break;
		    }
		    if (config.DebugLevel & 2)
		       printf("..boundary value (%s)\n",tmpmb->Line);
		    if (tmpmb->Line[0] == '\t') {
			switch (LastMimeValue) {
			    case 1:
				tmpstr = AddData(tmpmb->Line,tmpContent);
				freechar(tmpContent);
				tmpContent = tmpstr;
				tmpstr = NULL;
				break;
			    case 2:
				tmpstr = AddData(tmpmb->Line,tmpDisposition);
				freechar(tmpDisposition);
				tmpDisposition = tmpstr;
				tmpstr = NULL;
				break;
			    case 3:
				tmpstr = AddData(tmpmb->Line,tmpEncode);
				freechar(tmpEncode);
				tmpEncode = tmpstr;
				tmpstr = NULL;
				break;
			    case 4:
				tmpstr = AddData(tmpmb->Line,tmpDescription);
				freechar(tmpDescription);
				tmpDescription = tmpstr;
				tmpstr = NULL;
				break;
			}
		    }
		    if (strncmp(tmpmb->Line,"Content-Type:",13) == 0) {
			LastMimeValue = 1; /* Content */
			tmpContent = GetHeadData(tmpmb->Line);
		    }
		    if (strncmp(tmpmb->Line,"Content-Disposition:",20) == 0) {
			LastMimeValue = 2; /* Disposition */
			tmpDisposition = GetHeadData(tmpmb->Line);
		    }
		    if (strncmp(tmpmb->Line,"Content-Transfer-Encoding:",26) == 0) {
			LastMimeValue = 3; /* Transfer-Encoding */
			tmpEncode = GetHeadData(tmpmb->Line);
		    }
		    if (strncmp(tmpmb->Line,"Content-Description:",20) == 0) {
			LastMimeValue = 4; /* Description */
			tmpDescription = GetHeadData(tmpmb->Line);
		    }
		    lastmb = tmpmb;
		    tmpmb = tmpmb->Next;
		}
		if ((mh->MimeType == MIME_TYPE_APPLICATION_OCTETSTREAM) &&
		    (mh->AttachFile == NULL)) {
		    if (mh->MimeDescription != NULL)
			mh->AttachFile = dupchar(mh->MimeDescription);
		}
		if ((mh->MimeType == MIME_TYPE_IMAGE_XBITMAP) &&
		    (mh->AttachFile == NULL)) {
		    if (mh->MimeDescription != NULL)
			mh->AttachFile = dupchar(mh->MimeDescription);
		}

		/* create hyperlink*/
		if (mh->AttachFile != NULL) {
		    tmpfile = NULL;
		    switch (mh->MimeType) {
			case MIME_TYPE_IMAGE_GIF:
			case MIME_TYPE_IMAGE_XBITMAP:
			    tmpfile = newchar(24 + strlen(mh->AttachFile));
			    sprintf(tmpfile,"<IMG SRC=\"%d_%s\">\n",FileNumber,
				mh->AttachFile);
			    break;
			default:
			    tmpfile = newchar(28 + strlen(mh->AttachFile)*2);
			    sprintf(tmpfile,"<A HREF=\"%d_%s\">%s</A>\n",
				FileNumber,mh->AttachFile,mh->AttachFile);
			    break;
		    }
		    AppendFile(Filename,tmpfile);
		    freechar(tmpfile);
		    tmpfile = NULL;
		}
	    } /* End of boundery detection */
	    if (tmpmb != NULL) {
	        if (mh->AttachFile != NULL) {
		    /* There is a filename */
		    tmpfile = newchar(13 + strlen(config.Directory) +
			strlen(mh->AttachFile));
		    sprintf(tmpfile,"%s/%d_%s",config.Directory,FileNumber,
			mh->AttachFile);
		    switch (mh->MimeEncode) {
			case MIME_ENCODE_QUOTED:
			    tmpstr = Quoted_2_Text(tmpmb->Line);
			    AppendFile(tmpfile,tmpstr);
			    freechar(tmpstr);
			    tmpstr = NULL;
			    break;
			case MIME_ENCODE_UUENCODE:
			case MIME_ENCODE_BASE64:
			    NewFile(tmpfile,"");
			    fd = open(tmpfile,O_WRONLY);
			    if (fd == -1) {
				fprintf(stderr,"Warning: Couldn't open file %s for writing.\n",tmpfile);
				break;
			    }
			    for(;;) {
				tmplen = 0;
				if(strlen(tmpmb->Line) > 0) {
				    /* Cut newlines at the end */
				    if (tmpmb->Line[strlen(tmpmb->Line)-1] == '\n')
					tmpmb->Line[strlen(tmpmb->Line)-1] = '\0';
				}
				if ((mh->MimeEncode != MIME_ENCODE_UUENCODE) ||
				   (strncmp(tmpmb->Line,"begin ",6) != 0)) {
				   tmpstr = ByteConvert4to3(tmpmb->Line,&tmplen,mh->MimeEncode);
				   if (tmplen > 0) write(fd,tmpstr,tmplen);
				   freechar(tmpstr);
				   tmpstr = NULL;
				}
				if (tmpmb->Next == NULL) {
				    break;
				} else {
				    if (strstr(tmpmb->Next->Line,mh->MimeBoundary) != NULL) {
					break;
				    } else {
					lastmb = tmpmb;
					tmpmb = tmpmb->Next;
				    }
				}
			    }
			    close(fd);
			    break;
			default:
			    AppendFile(tmpfile,tmpmb->Line);
			    break;
		    }
		    freechar(tmpfile);
		    tmpfile = NULL;
	        } else {
		    /* Normal output */
		    switch (mh->MimeEncode) {
			case MIME_ENCODE_QUOTED:
			    tmpstr = Quoted_2_Text(tmpmb->Line);
			    break;
			case MIME_ENCODE_UUENCODE:
			case MIME_ENCODE_BASE64:
			    tmpstr = ByteConvert4to3(tmpmb->Line,&tmplen,mh->MimeEncode);
			    break;
			default:
			    tmpstr = dupchar(tmpmb->Line);
			    break;
		    }
		    switch (mh->MimeType) {
			default:
			    WriteMailBodyLine(Filename,tmpstr,mh);
			    break;
		    }
		    freechar(tmpstr);
		    tmpstr = NULL;
		}
		lastmb = tmpmb;
		tmpmb = tmpmb->Next;
	    }
	}
    } else {
	if (config.DebugLevel & 2)
            printf("..normal Text\n");
	/* Remove leading empty lines */
	while ((tmpmb != NULL) && (tmpmb->Line != NULL) && (tmpmb->Line[0] == '\n')) {
	    lastmb = tmpmb;
	    tmpmb = tmpmb->Next;
	}
	while ((tmpmb != NULL) && (tmpmb->Line != NULL)) {
	    if (IfUuencode(tmpmb->Line) == TRUE) {
		/* There is a filename */
		tmpstr = GetUuencodeFile(tmpmb->Line);
		tmpfile = newchar(13 + strlen(config.Directory) +
		    strlen(tmpstr));
		sprintf(tmpfile,"%s/%d_%s",config.Directory,FileNumber,
		    tmpstr);
		lastmb = tmpmb;
		tmpmb = tmpmb->Next;
		NewFile(tmpfile,"");
		fd = open(tmpfile,O_WRONLY);
		if (fd == -1) {
		   fprintf(stderr,"Warning: Couldn't open file %s for writing.\n",tmpfile);
		   break;
		}
		freechar(tmpfile);
		tmpfile = NULL;
		tmpfile = newchar(13 + strlen(tmpstr));
		sprintf(tmpfile,"%d_%s",FileNumber,tmpstr);
		AppendFile(Filename,"<A HREF=\"");
		AppendFile(Filename,tmpfile);
		AppendFile(Filename,"\">");
		AppendFile(Filename,tmpstr);
		AppendFile(Filename,"</A>\n");
		freechar(tmpfile);
		tmpfile = NULL;
		freechar(tmpstr);
		tmpstr = NULL;
		for(;;) {
		    tmplen = 0;
		    if (tmpmb->Next == NULL) break;
		    if (strncmp(tmpmb->Line,"end",3) == 0) break;
		    tmpstr = ByteConvert4to3(tmpmb->Line,&tmplen,MIME_ENCODE_UUENCODE);
		    if (tmplen > 0) write(fd,tmpstr,tmplen);
		    freechar(tmpstr);
		    tmpstr = NULL;
		    lastmb = tmpmb;
		    tmpmb = tmpmb->Next;
		}
		close(fd);
	    } else {
		switch (mh->MimeEncode) {
		    case MIME_ENCODE_QUOTED:
			tmpstr = Quoted_2_Text(tmpmb->Line);
			break;
		    case MIME_ENCODE_UUENCODE:
		    case MIME_ENCODE_BASE64:
			tmpstr = ByteConvert4to3(tmpmb->Line,&tmplen,mh->MimeEncode);
			break;
		    default:
			tmpstr = dupchar(tmpmb->Line);
			break;
		}
		WriteMailBodyLine(Filename,tmpstr,mh);
		freechar(tmpstr);
		tmpstr = NULL;
	    }
	    lastmb = tmpmb;
	    tmpmb = tmpmb->Next;
	}
    }
    AppendFile(Filename,"</PRE>\n");
    WriteHtmlValue(Filename,"Body","End");

    if (config.FrameSupport == FALSE) {
	WriteHtmlValue(Filename,"IndexControl2","Start");
	if (HtmlCmd.HrStart == NULL) {
	    AppendFile(Filename,HTMLCMD_HR_START);
	} else {
	    AppendFile(Filename,HtmlCmd.HrStart);
	}
	AppendFile(Filename,"\n");
	WriteIndexNavigation(Filename);
	WriteHtmlValue(Filename,"IndexControl2","End");
    }

    if (config.DocEndFile != NULL) {
	IncludeFile(Filename, config.DocEndFile);
    } else {
	if (HtmlCmd.BodyEnd == NULL) {
	    AppendFile(Filename,HTMLCMD_BODY_END);
	} else {
	    AppendFile(Filename,HtmlCmd.BodyEnd);
	}
	AppendFile(Filename,"\n");
    }
}

void WriteMail (char *Filename, struct MAILHEAD *mh, struct MAILBODY *mb,
                int FileNumber) {

    if (config.DebugLevel & 1)
        printf(".WriteMail\n");

    /* No page without identification */
    if (mh->SendAddress == NULL) return;
     
    InitHtml(Filename);
    WriteMailHead(Filename,mh);
    WriteMailBody(Filename,mh,mb,FileNumber);
    EndHtml(Filename);
}


void CleanMailMem(struct MAILHEAD *mh, struct MAILBODY *mb) {
    struct MAILBODY *tmpmb, *tmpmbnext;

    if (config.DebugLevel & 1)
        printf(".CleanMailMem\n");
    if (mh != NULL) {
	if (mh->SendName != NULL) {
	    freechar(mh->SendName);
	    mh->SendName = NULL;
	}
	if (mh->SendAddress != NULL) {
	    freechar(mh->SendAddress);
	    mh->SendAddress = NULL;
	}
	if (mh->ReceiveName != NULL) {
	    freechar(mh->ReceiveName);
	    mh->ReceiveName = NULL;
	}
	if (mh->ReceiveAddress != NULL) {
	    freechar(mh->ReceiveAddress);
	    mh->ReceiveAddress = NULL;
	}
	if (mh->SentDate != NULL) {
	    freechar(mh->SentDate);
	    mh->SentDate = NULL;
	}
	if (mh->MsgId != NULL) {
	    freechar(mh->MsgId);
	    mh->MsgId = NULL;
	}
	if (mh->Reference != NULL) {
	    freechar(mh->Reference);
	    mh->Reference = NULL;
	}
	if (mh->Subject != NULL) {
	    freechar(mh->Subject);
	    mh->Subject = NULL;
	}
	if (mh->Xface != NULL) {
	    freechar(mh->Xface);
	    mh->Xface = NULL;
	}
	if (mh->HomePage != NULL) {
	    freechar(mh->HomePage);
	    mh->HomePage = NULL;
	}
	if (mh->FileName != NULL) {
	    freechar(mh->FileName);
	    mh->FileName = NULL;
	}
	if (mh->MimeBoundary != NULL) {
	    freechar(mh->MimeBoundary);
	    mh->MimeBoundary = NULL;
	}
	if (mh->MimeDescription != NULL) {
	    freechar(mh->MimeDescription);
	    mh->MimeDescription = NULL;
	}
	if (mh->AttachFile != NULL) {
	    freechar(mh->AttachFile);
	    mh->AttachFile = NULL;
	}
    }

    if (mb != NULL) {
	if (mb->Line != NULL) freechar(mb->Line);
	tmpmb = mb->Next;
	while (tmpmb != NULL) {
	    if (tmpmb->Line != NULL) freechar(tmpmb->Line);
	    tmpmbnext = tmpmb->Next;
	    free (tmpmb);
	    tmpmb = tmpmbnext;
	}
    }
}

#ifdef FACES
void WriteXFace(struct MAILHEAD *mh) {
    char buffer[4096], line[1024];
    char *FileName;
    int byte1, byte2, BitmapCount, BufferCount;

    if (config.DebugLevel & 1)
        printf(".WriteXFace (%s)\n",mh->SendAddress);

    /* Calculate full filename */
    if (config.FaceDirectory == NULL) {
	FileName = newchar(strlen(config.Directory)+strlen(mh->SendAddress)+6);
	sprintf(FileName,"%s/%s.xbm",config.Directory,mh->SendAddress);
    } else {
	FileName = newchar(strlen(config.Directory)+strlen(config.FaceDirectory)+
	    strlen(mh->SendAddress)+7);
	sprintf(FileName,"%s/%s/%s.xbm",config.Directory,config.FaceDirectory,
	    mh->SendAddress);
    }

    /* Getting bitmap */
    strcpy(buffer, mh->Xface);
    switch (uncompface(buffer)) {
	case -2 :
	    fprintf(stderr,"internal compface error (%s)\n",mh->FileName);
	    return;
	    break;
	case -1 :
	    fprintf(stderr,"bad face data (%s)\n",mh->FileName);
	    return;
	    break;
	case 1 :
	    fprintf(stderr,"ignoring trailing garbage (%s)\n",mh->FileName);
	    return;
	    break;
    }

    /* Writing XBM-Header */
    sprintf(line,"#define %s_width %d\n",mh->SendAddress,WIDTH);
    NewFile(FileName,line);
    sprintf(line,"#define %s_height %d\n",mh->SendAddress,HEIGHT);
    AppendFile(FileName,line);
    sprintf(line,"static char %s_bits[] = {\n",mh->SendAddress);
    AppendFile(FileName,line);

    /* Writing data */
    BitmapCount = BufferCount = 0;
    while (buffer[BufferCount]) {
	if (sscanf (buffer + BufferCount, " 0x%2x%2x , ", &byte1, &byte2) != 2)
	    break;
	if (BitmapCount > 11) {
	    AppendFile(FileName,",\n");
	    BitmapCount = 0;
	}
        if (BitmapCount == 0) AppendFile(FileName,"   ");
        if (BitmapCount > 0) AppendFile(FileName,", ");
	while (buffer[BufferCount++] != ',');
	if (byte1 > 255 || byte2 > 255) return;
	sprintf(line,"0x%.2x, 0x%.2x",FaceConvertTable[byte1],FaceConvertTable[byte2]);
	AppendFile(FileName,line);
	BitmapCount = BitmapCount + 2;
    }

    /* Writing XBM-Foot */
    AppendFile(FileName,"};\n");
    freechar(FileName);
}
#endif


void Mail2Html(char *mbox) {
    FILE *fd;
    int FileNumber;
    struct MAILHEAD mh;
    struct MAILBODY mb;
    char *FileName;
        
    if (config.DebugLevel & 1)
        printf(".Mail2Html(%s)\n",mbox);
    if (config.WriteMode == HTML_INDEX) {
        if (config.DebugLevel & 2)
            printf("..IndexOnly -> abort\n");
        return;
    }
    if (strcmp(mbox,"-") != 0) {
        if (!FileExist(mbox)) {
            fprintf(stderr,"* file %s doesn't exist. *\n",mbox);
            return;
        }
        fd = fopen(mbox,"r");
	if (fd == NULL) {
            fprintf(stderr,"* unable to open file %s. *\n",mbox);
            return;
	}
    } else {
        fd = stdin;
    }
    if ((config.WriteMode == HTML_APPEND) ||
	(config.WriteMode == HTML_APPENDNOINDEX)) {
        FileNumber=0;
    } else {
	/* delete all files in the html-directory */
	CleanDirectory(config.Directory);
        FileNumber=-1;
    }
#ifdef DEBUG
    if (config.DebugLevel & 2)
	printf("..xAllStr=%d RelStr=%d Stats=%d\n",Debug.StrAlloc,Debug.StrDeAlloc,
	    Debug.StrAlloc-Debug.StrDeAlloc);
#endif
    while (feof(fd) == 0) {
	InitMail(&mh,&mb);
	GetMail(fd,&mh,&mb);
	if ((config.WriteMode == HTML_APPEND) ||
	    (config.WriteMode == HTML_APPENDNOINDEX)) {
	    FileNumber = GetNextFileNumber(FileNumber);
	} else {
	    FileNumber++;
	}
        FileName = GetFileName(FileNumber);
	WriteMail(FileName,&mh,&mb,FileNumber);
#ifdef FACES
	if ((mh.Xface != NULL) && (config.FaceSupport == TRUE))
	    WriteXFace(&mh);
#endif
	freechar(FileName);
	FileName = NULL;
	CleanMailMem(&mh,&mb);
#ifdef DEBUG
	if (config.DebugLevel & 2)
	    printf("..AllStr=%d RelStr=%d Stats=%d\n",Debug.StrAlloc,
		Debug.StrDeAlloc,Debug.StrAlloc-Debug.StrDeAlloc);
#endif
    }
    if (strcmp(mbox,"-") != 0)
	fclose(fd);
}
