MIME-Explode
view release on metacpan or search on metacpan
}
*len = d - (char *) ret;
return ret;
}
void *uu_decode(char *buff, unsigned long srcl, unsigned long *len) {
char *p;
int n;
void *ret = NULL;
char *d = NULL;
p = buff;
n = DEC(*p);
ret = New(2, ret, (size_t) (*len = n + ((3*srcl-6)/4) + 1), void);
d = (char *)ret;
memset(ret,0,(size_t)*len);
*len = 0;
if(n <= 0) return("");
for(++p; n > 0; p += 4, n -= 3) {
if(n >= 3) {
*d++ = DEC(p[0]) << 2 | DEC (p[1]) >> 4;
*d++ = DEC(p[1]) << 4 | DEC (p[2]) >> 2;
*d++ = DEC(p[2]) << 6 | DEC (p[3]);
} else {
if(n >= 1)
*d++ = DEC(p[0]) << 2 | DEC (p[1]) >> 4;
if(n >= 2)
*d++ = DEC(p[1]) << 4 | DEC (p[2]) >> 2;
}
}
*d = '\0';
*len = d - (char *)ret;
return(ret);
}
void data_cat(char* tmp, char* data,
unsigned long *tmplen, unsigned long len) {
unsigned int i = 0;
for(i = 0; i < len; i++) {
if(*tmplen > TMPBUFFLEN-1) break;
tmp[*tmplen] = data[i];
(*tmplen)++;
}
tmp[*tmplen] = '\0';
}
MODULE = MIME::Explode PACKAGE = MIME::Explode PREFIX = exp_
PROTOTYPES: DISABLE
void
exp_rfc822_qprint(source)
SV *source
PREINIT:
STRLEN srcl;
unsigned long len;
unsigned char *s;
PPCODE:
s = (unsigned char*)SvPV(source, srcl);
if(s = _rfc822_qprint(s, (unsigned long)srcl, &len)) {
XPUSHs(sv_2mortal(newSVpv((char*)s, (STRLEN)len)));
Safefree(s);
}
void
exp_rfc822_base64(source)
SV *source
PREINIT:
STRLEN srcl;
unsigned long len;
unsigned char *s;
PPCODE:
s = (unsigned char*)SvPV(source, srcl);
if(s = _rfc822_base64(s, (unsigned long)srcl, &len)) {
XPUSHs(sv_2mortal(newSVpv((char*)s, (STRLEN)len)));
Safefree(s);
}
void
exp_set_content_type(source, ...)
SV *source
PREINIT:
STRLEN srcl;
unsigned char *s;
char *base = NULL;
char *mt;
PPCODE:
if(items == 2) base = SvPV(ST(1), PL_na);
s = (unsigned char*)SvPV(source, srcl);
mt = set_mime_type(s, (unsigned long)srcl, base);
XPUSHs(sv_2mortal(newSVpv(mt, (STRLEN)strlen(mt))));
void
exp_uu_file(fhs, filename, mode, ...)
SV *fhs;
char *filename;
char *mode;
PREINIT:
PerlIO *fpin = NULL;
PerlIO *fptmp = NULL;
PerlIO *fpout = NULL;
I32 avlen = 0;
AV *av_fhs = (AV*)SvRV(fhs);
HV *hvtypes;
SV *buff_sv = newSV(BUFFLEN);
unsigned long len = 0;
unsigned char *decoded = NULL;
bool verify = TRUE;
bool exclude = FALSE;
bool action = TRUE;
char mimetype[BUFFLEN] = "";
AV *av_ret = newAV();
char tmp[TMPBUFFLEN];
unsigned long tmplen = 0;
PPCODE:
if((avlen = av_len(av_fhs)) != -1) {
fpin = IoIFP(sv_2io(*av_fetch(av_fhs, 0, 0)));
if(avlen == 1)
fptmp = IoIFP(sv_2io(*av_fetch(av_fhs, 1, 0)));
} else
croak("Null Array Reference");
if(items == 4) {
HV *hv = (HV*)SvRV(ST(3));
if(hv_exists(hv, "action", 6)) {
SV **value = hv_fetch(hv, "action", 6, 0);
action = SvIVx(*value) ? TRUE : FALSE;
}
if(hv_exists(hv, "mimetypes", 9)) {
SV **value = hv_fetch(hv, "mimetypes", 9, 0);
hvtypes = (HV*)SvRV(*value);
}
}
if((fpout = PerlIO_open(filename, "wb")) == NULL)
croak("Failed to open file \"%s\"", filename);
while(sv_gets(buff_sv, fpin, 0)) {
STRLEN l = SvCUR(buff_sv);
char *line = SvGROW(buff_sv, l);
if(line[l-1] != 0x0a) break;
if(fptmp != NULL) PerlIO_write(fptmp, line, l);
if(instr(line, "end\n") || line[0] == 0x0a) break;
if(!exclude) {
decoded = uu_decode(line, l, &len);
if(len) PerlIO_write(fpout, decoded, len);
}
if(verify) {
if(line[0] == 0x20 || line[0] == 0x0a || line[0] == 0x0d) {
// nothing to do...
} else {
data_cat(tmp, decoded, &tmplen, len);
if(tmplen >= TMPBUFFLEN) {
strcpy(mimetype, set_mime_type(tmp, tmplen, mimetype));
exclude = hv_exists(hvtypes, mimetype, strlen(mimetype)) ? (action ? FALSE : TRUE) :
hv_iterinit(hvtypes) ? (action ? TRUE : FALSE) : (action ? FALSE : TRUE);
verify = FALSE;
}
}
}
if (decoded) {
Safefree(decoded);
decoded = NULL;
len = 0;
}
}
PerlIO_close(fpout);
if(verify) {
strcpy(mimetype, set_mime_type(tmp, tmplen, mimetype));
exclude = hv_exists(hvtypes, mimetype, strlen(mimetype)) ? (action ? FALSE : TRUE) :
hv_iterinit(hvtypes) ? (action ? TRUE : FALSE) : (action ? FALSE : TRUE);
}
if(exclude)
if(unlink(filename))
croak("Failed to delete file \"%s\"", filename);
av_push(av_ret, mimetype ? newSVpv(mimetype, 0) : newSVsv(&PL_sv_undef));
av_push(av_ret, newSViv(exclude ? 1 : 0));
XPUSHs(sv_2mortal(newRV_noinc((SV*)av_ret)));
SvREFCNT_dec(buff_sv);
void
exp_decode_content(fhs, encoding="base64", filename, boundary="", ...)
SV *fhs;
char *encoding;
char *filename;
char *boundary;
PREINIT:
PerlIO *fpin = NULL;
PerlIO *fptmp = NULL;
PerlIO *fpout = NULL;
unsigned char *decoded = NULL;
unsigned char *rest = NULL;
SV *buff_sv = newSV(BUFFLEN);
SV *part = newSVsv(&PL_sv_undef);
char mt[BUFFLEN] = "";
bool exclude = FALSE;
bool verify = TRUE;
bool checktype = FALSE;
bool action = TRUE;
bool last = FALSE;
I32 avlen = 0;
HV *hvtypes;
AV *av_ret = newAV();
AV *av_fhs = (AV*)SvRV(fhs);
unsigned long len = 0;
char tmp[TMPBUFFLEN];
unsigned long tmplen = 0;
answers findmbox = NO;
answers endbase64 = NO;
char *mimetype;
PPCODE:
if((avlen = av_len(av_fhs)) != -1) {
fpin = IoIFP(sv_2io(*av_fetch(av_fhs, 0, 0)));
if(avlen == 1)
fptmp = IoIFP(sv_2io(*av_fetch(av_fhs, 1, 0)));
} else
croak("Null Array Reference");
if(items == 5) {
HV *hv = (HV*)SvRV(ST(4));
if(hv_exists(hv, "mimetype", 8)) {
SV **value = hv_fetch(hv, "mimetype", 8, 0);
mimetype = SvPVx(*value, PL_na);
}
if(hv_exists(hv, "checktype", 9)) {
SV **value = hv_fetch(hv, "checktype", 9, 0);
if(SvIVx(*value)) checktype = TRUE;
}
if(hv_exists(hv, "action", 6)) {
SV **value = hv_fetch(hv, "action", 6, 0);
action = SvIVx(*value) ? TRUE : FALSE;
}
if(hv_exists(hv, "mimetypes", 9)) {
SV **value = hv_fetch(hv, "mimetypes", 9, 0);
hvtypes = (HV*)SvRV(*value);
}
if(hv_exists(hv, "mailbox", 7)) {
SV **value = hv_fetch(hv, "mailbox", 7, 0);
if(SvIVx(*value)) findmbox = MAYBE;
}
}
if((fpout = PerlIO_open(filename, "wb")) == NULL)
croak("Failed to open file \"%s\"", filename);
while(!last && sv_gets(buff_sv, fpin, 0)) {
STRLEN l = SvCUR(buff_sv);
char *line = SvGROW(buff_sv, l);
if(fptmp != NULL) PerlIO_write(fptmp, line, l);
if(findmbox == YES) {
if(ismailbox(line)) {
sv_setsv(part, buff_sv);
break;
}
findmbox = MAYBE;
}
if(line[0] == 0x0a && findmbox == MAYBE) {
findmbox = YES;
if(encoding[0] == 'b') continue;
}
if(encoding[0] == 'b') {
if(boundary[0] != '\0' && line[l-1] != 0x0a) break;
if(line[l-2] == '=' && line[l-1] == 0x0a) endbase64 = MAYBE;
}
if(boundary[0] != '\0' && (rest = instr(line, boundary))) {
sv_setpvn(part, rest, strlen(rest));
l -= SvCUR(part);
if(l == 0) break;
line[l] = '\0';
last = TRUE;
} else if(endbase64 == YES && line[0] != 0x0a) {
sv_setpvn(part, line, l);
break;
}
( run in 0.755 second using v1.01-cache-2.11-cpan-5511b514fd6 )