31 #define SZ_WORK (SZ_P + SZ_FREE + 1) 51 scan_block(
id, chunk, sz_chunk,
new, sz_new, state, content, list)
61 #if _FFR_NEW_SCAN_BLOCK 62 return new_scan_block(
id, chunk, sz_chunk,
new, sz_new, state, content, list);
64 return old_scan_block(
id, chunk, sz_chunk,
new, sz_new, state, content, list);
74 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 76 #define MAX2(a,b) MAX((a),(b)) 77 #define MAX3(a,b,c) MAX(a, MAX((b),(c))) 78 #define MAX4(a,b,c,d) MAX(MAX((a),(b)), MAX((c),(d))) 81 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 83 #define MIN2(a,b) MIN((a),(b)) 84 #define MIN3(a,b,c) MIN(a, MIN((b),(c))) 85 #define MIN4(a,b,c,d) MIN(MIN((a),(b)), MIN((c),(d))) 164 #define MAX_LINE 4096 166 #define REGCOMP_FLAGS (REG_ICASE | REG_NEWLINE | REG_EXTENDED) 168 #define REGEXEC_FLAGS (REG_NOTBOL | REG_NOTEOL) 170 #define REGEXEC_FLAGS (0) 174 #define RE_CT "Content-type[ \t]*:" 175 #define RE_CD "Content-disposition[ \t]*:" 177 #define RE_CT "^Content-type[ \t]*:" 178 #define RE_CD "^Content-disposition[ \t]*:" 182 #define RE_UU "^begin(-base64){0,1}[ \t]{1,}[0]{0,1}[0-7]{3,3}[ \t]{1,}[^\t\r\n]{1,}" 184 #define RE_UU "^begin(-base64)?[ \t]{1,}[0]?[0-7]{3,3}[ \t]{1,}[^\t\r\n]{1,}" 196 static REGEX_T RE = {
FALSE, PTHREAD_MUTEX_INITIALIZER };
198 #define SCAN_REGEX_LOCK() MUTEX_LOCK(&RE.mutex) 199 #define SCAN_REGEX_UNLOCK() MUTEX_UNLOCK(&RE.mutex) 215 memset(sout, 0,
sizeof (sout));
217 regerror(r, &RE.
re_ct, sout, sizeof (sout));
223 regerror(r, &RE.
re_cd, sout, sizeof (sout));
229 regerror(r, &RE.
re_uu, sout, sizeof (sout));
248 regex_lookup(re, buf, pi, pf)
278 #define MALLOC_WORK 1 316 for (i = sz_new; i > 0; i--, p++) {
321 memset(old, 0,
sizeof (old));
322 strncpy(old, chunk,
sizeof (old) - 1);
325 if ((work = malloc(
SZ_WORK + 1)) == NULL) {
332 while (nok < sz_new) {
343 p = work + strlen(work);
344 memset(old, 0,
sizeof (old));
350 szc = (sz_new - nok) >=
SZ_P ?
SZ_P : sz_new - nok;
352 if (strlen(work) + szc >
SZ_WORK) {
360 id, (
long) (strlen(work) + szc), (
long) szc);
365 memcpy(p,
new + nok, szc);
369 if (strcspn(p,
"\r\n") >
SZ_FREE) {
371 "linelenght : %ld; strlen : %ld",
id, (
long) strcspn(p,
396 if (last_rc == NULL && strlen(work) >
SZ_P) {
397 ZE_LogMsgError(0,
"ERROR : scanmail strlen(work) = %ld result = 6",
398 (
long) strlen(work));
407 while (result == 0) {
408 long d1, d2, d3, d4, d;
411 if (p == NULL || *p ==
'\0')
418 regmatch_t pm_cd, pm_ct, pm_uu;
419 bool ok_cd, ok_ct, ok_uu;
442 if (
min3(duu, dcd, dct) == duu) {
450 pm_uu.rm_eo - pm_uu.rm_so);
451 t += strcspn(t,
" \t");
452 t += strspn(t,
" \t");
453 t += strcspn(t,
" \t");
454 t += strspn(t,
" \t");
455 memset(fname, 0,
sizeof (fname));
459 zeSafeStrnCpy(fname,
sizeof (fname), t, strcspn(t,
" \t\r\n"));
466 strlcpy(fname, tmp,
sizeof (fname));
474 strlcpy(fname, tmp,
sizeof (fname));
479 content->
value = strdup(fname);
480 if (content->
value == NULL) {
488 if (ok_cd || ok_ct) {
500 if (ok_ct && ok_cd) {
501 if (pm_cd.rm_eo < pm_ct.rm_eo) {
522 p += strspn(p,
" \t\r\n");
526 d = strcspn(p,
" \t\r\n;");
527 if (d >=
sizeof (sout))
547 if ((d = strspn(p,
"\r\n")) > 0) {
555 if ((d = strcspn(p,
";")) == 0) {
560 if ((d = strspn(p,
" \t;")) > 0) {
561 d1 = strspn(p,
" \t");
562 d2 = strspn(p,
" \t;");
563 d3 = strspn(p,
" \t\r\n");
569 d =
min4(d1, d2, d3, d4);
588 if (d + d1 <
sizeof (sout)) {
589 strncat(sout, p, d1);
593 "%-12s scan_block : d + d1 >= sizeof(sout) = %ld",
596 content->
value = strdup(sout);
604 if (content->
value != NULL)
605 free(content->
value);
606 content->
value = strdup(sout);
615 d = strspn(p,
" \t\r\n");
638 p += strspn(p,
" \t\r\n");
642 d2 = strcspn(p,
"=");
647 d4 = strcspn(p,
"\t");
648 d =
min4(d1, d2, d3, d4);
652 if (d == strlen(p)) {
660 int rfc2231_code = 0;
662 if (d >=
sizeof (name))
670 if (name[d - 1] ==
'*') {
687 d = strcspn(p,
"\"\r\n");
689 int dx = strcspn(p,
"; \t\r\n");
700 da = strcspn(p,
"\r\n");
701 db = strcspn(p,
";\r\n");
702 if (da == db && da > 0 && db > 0) {
707 while (da > 0 && tmpstr[da - 1] ==
' ')
714 if (d >=
sizeof (value))
727 strlcpy(value, sout,
sizeof (value));
733 strlcpy(value, sout,
sizeof (value));
747 if (d >=
sizeof (sout))
769 if (last_rc != NULL) {
772 sz = strlen((
char *) (last_rc + 1));
773 if (strlen((
char *) (last_rc + 1)) >=
sizeof (old)) {
774 strlcpy(old,
"",
sizeof (old));
775 ZE_LogMsgNotice(0,
"scan_block : strlen(last_rc + 1) = %ld > SZ_CHUNK",
780 strlcpy(old, (
char *) (last_rc + 1),
sizeof (old));
785 memset(chunk, 0, sz_chunk);
786 if (strlen(old) < sz_chunk)
809 #define NRE_CT "Content-type[ \t]*:" 810 #define NRE_CD "Content-disposition[ \t]*:" 811 #define NRE_UU "begin(-base64){0,1}[ \t]{1,}[0]{0,1}[0-7]{3,3}[ \t]{1,}[^\t\r\n]{1,}" 862 for (i = sz_new; i > 0; i--, p++) {
868 if ((work = malloc(
SZ_WORK + 1)) == NULL) {
875 while (sz_ok < sz_new) {
878 work_len = strlen(old);
887 memset(old, 0, sz_old);
895 memcpy(work + work_len,
new + sz_ok, dx);
900 while ((lastcr =
strrchr(wptr,
'\n')) != NULL) {
909 if (regex_lookup(&RE.
re_uu, wptr, &pi, &pf))
911 if (regex_lookup(&RE.
re_ct, wptr, &pi, &pf))
913 if (regex_lookup(&RE.
re_cd, wptr, &pi, &pf))
930 memset(line, 0,
sizeof (line));
932 i = strcspn(wptr,
"\r\n");
940 strncpy(line, wptr, i);
942 memset(fname, 0,
sizeof (fname));
946 for (s = strtok_r(line,
" \t", &ptr), i = 0;
947 s != NULL; s = strtok_r(NULL,
" \t", &ptr), i++) {
954 strlcpy(fname, s,
sizeof (fname));
959 if (strlen(fname) > 0) {
964 strlcpy(fname, tmp,
sizeof (fname));
970 strlcpy(fname, tmp,
sizeof (fname));
974 content->
value = strdup(fname);
976 content->
value = strdup(
"attachment/uuencoded");
978 if (content->
value == NULL)
987 memset(content, 0,
sizeof (*content));
991 wptr += strcspn(wptr,
"\r\n");
998 char *p =
strchr(wptr,
':');
1006 p += strspn(p,
": \t");
1008 memset(str, 0,
sizeof (str));
1009 len = strcspn(p,
"; \t\r\n");
1010 if (len >=
sizeof (str)) {
1015 strncpy(str, p, len);
1017 content->
value = strdup(str);
1018 if (content->
value == NULL) {
1033 char *p =
strchr(wptr,
':');
1041 p += strspn(p,
": \t");
1043 memset(str, 0,
sizeof (str));
1044 len = strcspn(p,
"; \t\r\n");
1045 if (len >=
sizeof (str)) {
1050 strncpy(str, p, len);
1052 content->
value = strdup(str);
1053 if (content->
value == NULL) {
1067 if (*lastcr !=
'\0')
1077 if (decode_mime_content_tag(&wptr, content)) {
1079 memset(content, 0,
sizeof (*content));
1084 if (decode_mime_content_tag(&wptr, content)) {
1086 memset(content, 0,
sizeof (*content));
1097 if (lastcr != NULL) {
1098 if (strlen(lastcr) + 1 <= sz_old)
1116 static void log_mime_attr_value(
char *,
char *,
bool,
bool);
1118 #define CHECK_DOUBLE_NAME(val) do \ 1122 already_there = FALSE; \ 1123 for (i = 0; i < 16; i++) \ 1125 if (pname[i] != NULL && strcasecmp(pname[i], val) == 0) \ 1127 already_there = TRUE; \ 1134 decode_mime_content_tag(
buf, content)
1138 char *p = (
char *) *
buf, *ps;
1142 if ((
buf == NULL) || (strlen(*
buf) == 0))
1156 char key[256], val[256];
1158 bool rfc2047, rfc2231;
1160 if ((*p ==
'\r') || (*p ==
'\n'))
1163 if (strcspn(p,
"\r\n") >=
LINESZ) {
1171 if ((strlen(line) == 0) || ((*line !=
';') && (*line !=
'\t'))) {
1178 ptr += strspn(ptr,
" \t");
1182 while ((*ptr ==
';') || (strlen(ptr) > 0)) {
1183 bool doublequotes =
FALSE;
1187 rfc2047 = rfc2231 =
FALSE;
1188 ptr += strspn(ptr,
"; \t\r\n");
1189 if (strlen(ptr) == 0)
1200 if ((psep =
strchr(ptr,
'=')) == NULL) {
1205 n = strspn(ptr,
"abcdefghijklmnopqrstuvwxyz");
1206 if (n >=
sizeof (key)) {
1212 memset(key, 0,
sizeof (key));
1213 strncpy(key, ptr, n);
1217 rfc2231 = strcspn(ptr,
"*") < strcspn(ptr,
"=");
1219 ptr += strspn(ptr,
" *=");
1225 doublequotes =
TRUE;
1234 valLength = strcspn(ptr,
"\"");
1245 if (!rfc2047 && !rfc2231) {
1246 if (valLength >=
sizeof (val)) {
1252 strncpy(val, ptr, valLength);
1253 val[valLength] =
'\0';
1268 log_mime_attr_value(key, val, rfc2047, rfc2231);
1285 if (!doublequotes && !rfc2231 && !rfc2047) {
1286 if (strcasecmp(key,
"name") == 0 || strcasecmp(key,
"filename") == 0) {
1288 bool already_there =
FALSE;
1290 memset(pname, 0,
sizeof (pname));
1295 if ((
strchr(ptr,
' ') != NULL) && (
strchr(ptr,
';') == NULL)) {
1307 if ((strcspn(ptr,
";") < strlen(ptr)) && (
strchr(ptr,
' ') == NULL)) {
1310 if (!already_there) {
1323 if (strcspn(ptr,
";") < strlen(ptr)) {
1324 char *pwssep = strstr(ptr,
" ;");
1325 char *psepws = strstr(ptr,
"; ");
1327 if ((pwssep == NULL) && (psepws == NULL)) {
1330 if (!already_there) {
1344 if (!doublequotes && strcspn(ptr,
TSPECIALS) < strlen(ptr)) {
1347 if (!already_there) {
1379 decode_uuencoded(
buf, content)
1393 log_mime_attr_value(key, value, rfc2047, rfc2231)
void clean_tag_value(char *fname)
int scan_block(char *id, char *chunk, long sz_chunk, char *new, long sz_new, int *state, content_field_T *content, content_field_T **list)
char * zeStrClearTrailingBlanks(char *)
#define ZE_LogMsgInfo(level,...)
#define ZE_LogMsgError(level,...)
bool zeStrRegex(char *, char *, long *, long *, bool)
#define ZE_LogMsgNotice(level,...)
#define SCAN_REGEX_LOCK()
long min4(long a, long b, long c, long d)
#define ZE_MessageDebug(level,...)
#define ZE_MessageInfo(level,...)
int zeSafeStrnCpy(char *, size_t, char *, size_t)
#define ZE_LogSysError(...)
char * buf_get_next_line(char *, char *, size_t)
int new_scan_block(char *, char *, long, char *, long, int *, content_field_T *, content_field_T **)
long min3(long a, long b, long c)
char * zeStr2Lower(char *)
#define SCAN_REGEX_UNLOCK()
#define CHECK_DOUBLE_NAME(val)
int old_scan_block(char *, char *, long, char *, long, int *, content_field_T *, content_field_T **)