MIME-Explode

 view release on metacpan or  search on metacpan

Explode.xs  view on Meta::CPAN

		}
	*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 )