/*
**
** Copyright (C) 1993 Swedish University Network (SUNET)
**
**
** This program is developed by UDAC, Uppsala University by commission
** of the Swedish University Network (SUNET).
**
** 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 FITTNESS 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.
**
**
** Martin.Wendel@its.uu.se
** Torbjorn.Wictorin@its.uu.se
**
** ITS
** P.O. Box 887
** S-751 08 Uppsala
** Sweden
**
*/
#include "emil.h"
/*
*
*/
/*
* void
* encode_header()
*
*/
void
encode_header(struct message *m)
{
switch(target->iformat)
{
case MIME:
encode_mime(m);
break;
case MAILTOOL:
encode_mailtool(m);
break;
default:
encode_rfc822(m);
break;
}
}
/*
* void
* decode_header()
*
* Parses the header of current message.
*/
void
decode_header(struct message *m)
{
struct data *d;
d = m->sd;
if (m->h == NULL)
{
logger(LOG_DEBUG, "decode_header: empty header");
return;
}
/**
** m->level 0 specifics
**/
if (m->level == 0)
{
if (matchheader(m, "Content-Conversion", "Prohibited", 0))
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "Content conversion prohibited.\n");
#endif
det_sket_sig = TRUE;
return;
}
}
if (decode_mime(m) != OK)
{
if (decode_mailtool(m) != OK)
{
decode_rfc822(m);
}
}
}
/*
* char *
* fixstring(STRING, BEFORE, AFTER, PROCESS)
*
* Process STRING according to PROCESS (UNQUOTE, UNSPACE) and return
* the merged BEFORE, STRING and AFTER.
*/
char *
fixstring(char *string, char *before, char *after, short process)
{
char *tmp1, *tmp2;
int slen, blen, alen;
if (string == NULL)
return(NULL);
if (*string != '\0' && (process & UNSPACE))
{
tmp1 = string;
while(*tmp1 == ' ' || *tmp1 == '\t')
tmp1++;
if (*tmp1 != '\0')
{
tmp2 = tmp1 + strlen(tmp1) - 1;
while (*tmp2 == ' ' || *tmp2 == '\t')
tmp2--;
tmp2++;
*tmp2 = '\0';
}
string = tmp1;
}
if (*string != '\0' && (process & UNQUOTE) )
{
tmp1 = string;
if (*tmp1 == '"')
{
tmp1++;
tmp2 = string + strlen(string) - 1;
if (*tmp2 == '"')
{
*tmp2 = '\0';
string = tmp1;
}
}
}
if (*string != '\0')
slen = strlen(string);
else
slen = 0;
if (before != NULL && *before != '\0')
blen = strlen(before);
else
blen = 0;
if (after != NULL && *after != '\0')
alen = strlen(after);
else
alen = 0;
tmp1 = (char *)Yalloc(blen + slen + alen + 1);
if (blen)
strcpy(tmp1, before);
if (slen)
strcat(tmp1, string);
if (alen)
strcat(tmp1, after);
return(tmp1);
}
/*
* bool
* matchheader(HFIELD, HVAL)
*
* If header HFIELD is available, matches HVAL against the value
* of the header. Returns TRUE on success and FALSE on failure.
*/
int
matchheader(struct message *m, char *hfield, char *hval, int format)
{
struct header *hdr;
if (hfield == NULL || hval == NULL)
return(FALSE);
for (hdr = m->h; hdr != NULL; hdr = hdr->next)
{
if (hdr->type != UNIXFROM && hdr->field->end != 0 &&
(cmatch(hdr->field->contents, hfield) == TRUE))
{
if (matchhvalue(hdr, hval))
/* if (hdr->value->end != 0 &&
(cmatch(hdr->value->contents, hval) == TRUE))
*/
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* matchhvalue success\n");
#endif
hdr->format = format;
return(TRUE);
}
else
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* matchhvalue failed\n");
#endif
return(FALSE);
}
}
}
return(FALSE);
}
int
matchhvalue(struct header *hdr, char *line)
{
static struct header *th = NULL;
if (th == NULL)
{
th = (struct header *)Yalloc(sizeof(struct header));
th->field = (struct data *)Yalloc(sizeof(struct data));
th->value = (struct data *)Yalloc(sizeof(struct data));
}
else
{
th->field->end = 0;
th->value->end = 0;
th->value->offset = 0;
th->hvalue = NULL;
}
append_data(th->field, hdr->field->contents, strlen(hdr->field->contents),
256);
append_data(th->value, line, strlen(line),
256);
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* matchhvalue: %s: matching %s with %s\n",
hdr->field->contents,
hdr->value->contents,
line);
#endif
if (parse_rfc1522(th) != OK)
return(0);
if (parse_rfc1522(hdr) != OK)
return(0);
return(compare_header(hdr->hvalue, th->hvalue));
}
int
compare_header(struct hprs *dirty, struct hprs *clean)
{
if (clean == NULL && dirty == NULL)
return(0);
if (clean == NULL || clean->type != DELIMITER)
{
while(dirty != NULL && dirty->type == DELIMITER)
dirty = dirty->sibling;
if (dirty == NULL)
{
if (clean == NULL)
return(0);
else
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: dirty unexpected end\n");
#endif
return(0);
}
}
}
while(dirty->type == COMMENT)
dirty = dirty->sibling;
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: trying match between %d and %d\n",
dirty->type, clean->type);
#endif
switch (clean->type)
{
case UNKNOWN:
if (dirty->type != UNKNOWN)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: clean type is UNKNOWN\n");
#endif
return(0);
}
break;
case COMMENT:
break;
case HQSTRING:
if (dirty->type != HQSTRING)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting COMMENT got %d\n",
dirty->type);
#endif
return(0);
}
break;
case DLITERAL:
if (dirty->type != DLITERAL)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting DLITERAL got %d\n",
dirty->type);
#endif
return(0);
}
break;
case RADDR:
if (dirty->type != RADDR)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting RADDR got %d\n",
dirty->type);
#endif
return(0);
}
break;
case RFC1522:
if (dirty->type != RFC1522)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting RFC1522 got %d\n",
dirty->type);
#endif
return(0);
}
break;
case ATOM:
if (dirty->type != ATOM)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting ATOM got %d\n",
dirty->type);
#endif
return(0);
}
/* MW 960517
if (dmatch(clean->sd, dirty->sd) == 0)
return(0);
*/
if (dmatch(clean->sd, dirty->sd) != 0)
return(1);
break;
case DELIMITER:
if (dirty->type != DELIMITER)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting DELIMITER got %d\n",
dirty->type);
#endif
return(0);
}
break;
case TEXT:
if (dirty->type != TEXT)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* compare_header: expecting TEXT got %d\n",
dirty->type);
#endif
return(0);
}
clean = clean->child;
dirty = dirty->child;
return(compare_header(dirty, clean));
break;
default:
break;
}
/* clean = clean->sibling; */
dirty = dirty->sibling;
return(compare_header(dirty, clean));
}
int
dmatch(struct data *a, struct data *b)
{
int alen, blen;
alen = a->bodyend - a->bodystart;
blen = b->bodyend - b->bodystart;
if (alen == 0 || alen != blen)
{
#ifdef DEBUG
if (edebug)
{
fprintf(stderr, "* dmatch: lengths differ: %d %d\n",
alen, blen);
fprintf(stderr, "* dmatch: tried to compare %s and %s\n",
a->contents, b->contents);
}
#endif
return(0);
}
if (strncasecmp(a->contents + a->bodystart, b->contents + b->bodystart, alen) != 0)
{
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* dmatch: %s and %s does not match\n",
a->contents + a->bodystart, b->contents + b->bodystart);
#endif
return(0);
}
#ifdef DEBUG
if (edebug)
fprintf(stderr, "* dmatch: %s and %s does match\n",
a->contents + a->bodystart, b->contents + b->bodystart);
#endif
return(1);
}
/*
* char *
* gethval(HFIELD)
*
* If header HFIELD is available, returns the corresponding value
* as a string. Returns NULL on failure.
*/
char *
gethval(struct message *m, char *hfield, int format)
{
struct header *hdr;
if (hfield == NULL)
return(NULL);
for (hdr = m->h; hdr != NULL; hdr = hdr->next)
{
if (hdr->type != UNIXFROM && hdr->field->end != 0 &&
cmatch(hdr->field->contents, hfield) == TRUE)
{
if (format)
hdr->format = format;
return(hdr->value->contents);
}
}
return(NULL);
}
/*
* int
* string2dec(STRING)
*
* If STRING is not NULL and not of m->length zero and consists of 0-9,
* returns the translation to an integer. Returns 0 on failure.
*/
int
string2dec(char *string)
{
if (string == NULL)
return(0);
return((int)atol(string));
}
/*
* char *
* stringpart(STRING, DEL, PARTNO)
*
* Delimits STRING by DEL and returns part number PARTNO, where
* parts start with zero for the first part and so on. Returns
* NULL on failure.
*/
char *
stringpart(char *string, char *del, int partno)
{
char *str, *start;
int slen;
int i = 0;
if (string == NULL || del == NULL)
return(string);
slen = strlen(string);
str = (char *)NEWSTR(string);
start = str;
/* Loop on string */
while (1)
{
/* Delimit string */
while (*str != '\0' && index(del, *str) == NULL)
{
str++;
slen--;
}
*str = '\0';
if (i == partno)
return(start);
else
{
if (!slen)
break;
str++;
slen--;
start = str;
}
i++;
}
return(NULL);
}
/*
* bool
* matchpart(STRING1, STRING2, DEL, PARTNO)
*
* Delimits STRING2 by DEL and and matches part number PARTNO with
* STRING1. Returns TRUE on success and FALSE on failure.
*/
int
matchpart(char *string1, char *string2, char *del, int partno)
{
char *str, *start;
int i = 0;
if (string1 == NULL || string2 == NULL || del == NULL)
return(FALSE);
str = NEWSTR(string1);
start = str;
for (; str != '\0' && i <= partno; str++)
{
if (index(del, *str) != NULL)
{
*str = '\0';
if (i == partno && cmatch(start, string2) == TRUE)
{
return(TRUE);
}
else
{
str++;
start = str;
}
i++;
}
}
return(FALSE);
}
/*
* char *
* getpartrest(STRING, MATCH, DEL)
*
* Delimits STRING by DEL and tries MATCH on every part returns the
* unmatched part of the part matched.
*/
char *
getpartrest(char *string, char *matchstr, char *del)
{
char *str, *start;
int mlen, slen;
#ifdef DEBUG
if (edebug)
fprintf(stderr, "\ngetpartrest: string: %s matchstr: %s, del: %s\n",
string, matchstr, del);
#endif
if (string == NULL || matchstr == NULL || del == NULL)
return(NULL);
if ((mlen = strlen(matchstr)) == 0 || (slen = strlen(string)) == 0)
return(NULL);
str = (char *)NEWSTR(string);
start = str;
while (1)
{
/* Delimit string */
if (!slen)
return(NULL);
while (*str != '\0' && *del != *str)
{
str++;
slen--;
if (!slen)
break;
}
*str = '\0';
while (isspace(*start))
start++;
if (strncasecmp(matchstr, start, mlen) == 0)
return(start + mlen);
else
{
if (!slen)
break;
str++;
slen--;
start = str;
}
}
return(NULL);
}
/*
* int
* match(string1, string2)
*
* Case sensitive match
*/
int
match(char *string1, char *string2)
{
if (string1 == NULL || string2 == NULL)
return(FALSE);
if (strcmp(string1, string2) == 0)
return(TRUE);
else
return(FALSE);
}
/*
* int
* cmatch(string1, string2)
*
* Case insensitive match
*/
int
cmatch(char *string1, char *string2)
{
if (string1 == NULL || string2 == NULL)
return(FALSE);
if (strcasecmp(string1, string2) == 0)
return(TRUE);
else
return(FALSE);
}
syntax highlighted by Code2HTML, v. 0.9.1