⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vf.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(np && np->boundary){		cp = Brdline(&in, '\n');		Bwrite(&out, cp, Blinelen(&in));	}fprint(2, "a %p\n", np);	return np;}static intisattribute(char **pp, char *attr){	char *p;	int n;	n = strlen(attr);	p = *pp;	if(cistrncmp(p, attr, n) != 0)		return 0;	p += n;	while(*p == ' ')		p++;	if(*p++ != '=')		return 0;	while(*p == ' ')		p++;	*pp = p;	return 1;}/* *  parse content type header  */static voidctype(Part *p, Hdef *h, char *cp){	String *s;	cp += h->len;	cp = skipwhite(cp);	p->type = s_new();	cp = getstring(cp, p->type, 1);	if(badtype(s_to_c(p->type)))		p->badtype = 1;		while(*cp){		if(isattribute(&cp, "boundary")){			s = s_new();			cp = getstring(cp, s, 0);			p->boundary = s_reset(p->boundary);			s_append(p->boundary, "--");			s_append(p->boundary, s_to_c(s));			p->blen = s_len(p->boundary);			s_free(s);		} else if(cistrncmp(cp, "multipart", 9) == 0){			/*			 *  the first unbounded part of a multipart message,			 *  the preamble, is not displayed or saved			 */		} else if(isattribute(&cp, "name")){			setfilename(p, cp);		} else if(isattribute(&cp, "charset")){			if(p->charset == nil)				p->charset = s_new();			cp = getstring(cp, s_reset(p->charset), 0);		}				cp = skiptosemi(cp);	}}/* *  parse content encoding header  */static voidcencoding(Part *m, Hdef *h, char *p){	p += h->len;	p = skipwhite(p);	if(cistrncmp(p, "base64", 6) == 0)		m->encoding = Ebase64;	else if(cistrncmp(p, "quoted-printable", 16) == 0)		m->encoding = Equoted;}/* *  parse content disposition header  */static voidcdisposition(Part *p, Hdef *h, char *cp){	cp += h->len;	cp = skipwhite(cp);	while(*cp){		if(cistrncmp(cp, "inline", 6) == 0){			p->disposition = Dinline;		} else if(cistrncmp(cp, "attachment", 10) == 0){			p->disposition = Dfile;		} else if(cistrncmp(cp, "filename=", 9) == 0){			cp += 9;			setfilename(p, cp);		}		cp = skiptosemi(cp);	}}static voidsetfilename(Part *p, char *name){	if(p->filename == nil)		p->filename = s_new();	getstring(name, s_reset(p->filename), 0);	p->filename = tokenconvert(p->filename);	p->badfile = badfile(s_to_c(p->filename));}static char*skipwhite(char *p){	while(isspace(*p))		p++;	return p;}static char*skiptosemi(char *p){	while(*p && *p != ';')		p++;	while(*p == ';' || isspace(*p))		p++;	return p;}/* *  parse a possibly "'d string from a header.  A *  ';' terminates the string. */static char*getstring(char *p, String *s, int dolower){	s = s_reset(s);	p = skipwhite(p);	if(*p == '"'){		p++;		for(;*p && *p != '"'; p++)			if(dolower)				s_putc(s, tolower(*p));			else				s_putc(s, *p);		if(*p == '"')			p++;		s_terminate(s);		return p;	}	for(; *p && !isspace(*p) && *p != ';'; p++)		if(dolower)			s_putc(s, tolower(*p));		else			s_putc(s, *p);	s_terminate(s);	return p;}static voidinit_hdefs(void){	Hdef *hd;	static int already;	if(already)		return;	already = 1;	for(hd = hdefs; hd->type != nil; hd++)		hd->len = strlen(hd->type);}/* *  create a new boundary */static String*mkboundary(void){	char buf[32];	int i;	static int already;	if(already == 0){		srand((time(0)<<16)|getpid());		already = 1;	}	strcpy(buf, "upas-");	for(i = 5; i < sizeof(buf)-1; i++)		buf[i] = 'a' + nrand(26);	buf[i] = 0;	return s_copy(buf);}/* *  skip blank lines till header */static voidpassnotheader(void){	char *cp;	int i, n;	while((cp = Brdline(&in, '\n')) != nil){		n = Blinelen(&in);		for(i = 0; i < n-1; i++)			if(cp[i] != ' ' && cp[i] != '\t' && cp[i] != '\r'){				Bseek(&in, -n, 1);				return;			}		Bwrite(&out, cp, n);	}}/* *  pass unix header lines */static voidpassunixheader(void){	char *p;	int n;	while((p = Brdline(&in, '\n')) != nil){		n = Blinelen(&in);		if(strncmp(p, "From ", 5) != 0){			Bseek(&in, -n, 1);			break;		}		Bwrite(&out, p, n);	}}/* *  Read mime types */static voidreadmtypes(void){	Biobuf *b;	char *p;	char *f[6];	Mtype *m;	Mtype **l;	b = Bopen("/sys/lib/mimetype", OREAD);	if(b == nil)		return;	l = &mtypes;	while((p = Brdline(b, '\n')) != nil){		if(*p == '#')			continue;		p[Blinelen(b)-1] = 0;		if(tokenize(p, f, nelem(f)) < 5)			continue;		m = mallocz(sizeof *m, 1);		if(m == nil)			goto err;		m->ext = strdup(f[0]);		if(m->ext == 0)			goto err;		m->gtype = strdup(f[1]);		if(m->gtype == 0)			goto err;		m->stype = strdup(f[2]);		if(m->stype == 0)			goto err;		m->class = *f[4];		*l = m;		l = &(m->next);	}	Bterm(b);	return;err:	if(m == nil)		return;	free(m->ext);	free(m->gtype);	free(m->stype);	free(m);	Bterm(b);}/* *  if the class is 'm' or 'y', accept it *  if the class is 'p' check a previous extension *  otherwise, filename is bad */static intbadfile(char *name){	char *p;	Mtype *m;	int rv;	p = strrchr(name, '.');	if(p == nil)		return 0;	for(m = mtypes; m != nil; m = m->next)		if(cistrcmp(p, m->ext) == 0){			switch(m->class){			case 'm':			case 'y':				return 0;			case 'p':				*p = 0;				rv = badfile(name);				*p = '.';				return rv;			case 'r':				return 2;			}		}	return 1;}/* *  if the class is 'm' or 'y' or 'p', accept it *  otherwise, filename is bad */static intbadtype(char *type){	Mtype *m;	char *s, *fix;	int rv = 1;	fix = s = strchr(type, '/');	if(s != nil)		*s++ = 0;	else		s = "-";	for(m = mtypes; m != nil; m = m->next){		if(cistrcmp(type, m->gtype) != 0)			continue;		if(cistrcmp(s, m->stype) != 0)			continue;		switch(m->class){		case 'y':		case 'p':		case 'm':			rv = 0;			break;		}		break;	}	if(fix != nil)		*fix = '/';	return rv;}/* rfc2047 non-ascii */typedef struct Charset Charset;struct Charset {	char *name;	int len;	int convert;} charsets[] ={	{ "us-ascii",		8,	1, },	{ "utf-8",		5,	0, },	{ "iso-8859-1",		10,	1, },};/* *  convert to UTF if need be */static String*tokenconvert(String *t){	String *s;	char decoded[1024];	char utfbuf[2*1024];	int i, len;	char *e;	char *token;	token = s_to_c(t);	len = s_len(t);	if(token[0] != '=' || token[1] != '?' ||	   token[len-2] != '?' || token[len-1] != '=')		goto err;	e = token+len-2;	token += 2;	// bail if we don't understand the character set	for(i = 0; i < nelem(charsets); i++)		if(cistrncmp(charsets[i].name, token, charsets[i].len) == 0)		if(token[charsets[i].len] == '?'){			token += charsets[i].len + 1;			break;		}	if(i >= nelem(charsets))		goto err;	// bail if it doesn't fit 	if(strlen(token) > sizeof(decoded)-1)		goto err;	// bail if we don't understand the encoding	if(cistrncmp(token, "b?", 2) == 0){		token += 2;		len = dec64((uchar*)decoded, sizeof(decoded), token, e-token);		decoded[len] = 0;	} else if(cistrncmp(token, "q?", 2) == 0){		token += 2;		len = decquoted(decoded, token, e);		if(len > 0 && decoded[len-1] == '\n')			len--;		decoded[len] = 0;	} else		goto err;	s = nil;	switch(charsets[i].convert){	case 0:		s = s_copy(decoded);		break;	case 1:		s = s_new();		latin1toutf(utfbuf, decoded, decoded+len);		s_append(s, utfbuf);		break;	}	return s;err:	return s_clone(t);}/* *  decode quoted  */enum{	Self=	1,	Hex=	2,};uchar	tableqp[256];static voidinitquoted(void){	int c;	memset(tableqp, 0, 256);	for(c = ' '; c <= '<'; c++)		tableqp[c] = Self;	for(c = '>'; c <= '~'; c++)		tableqp[c] = Self;	tableqp['\t'] = Self;	tableqp['='] = Hex;}static inthex2int(int x){	if(x >= '0' && x <= '9')		return x - '0';	if(x >= 'A' && x <= 'F')		return (x - 'A') + 10;	if(x >= 'a' && x <= 'f')		return (x - 'a') + 10;	return 0;}static char*decquotedline(char *out, char *in, char *e){	int c, soft;	/* dump trailing white space */	while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))		e--;	/* trailing '=' means no newline */	if(*e == '='){		soft = 1;		e--;	} else		soft = 0;	while(in <= e){		c = (*in++) & 0xff;		switch(tableqp[c]){		case Self:			*out++ = c;			break;		case Hex:			c = hex2int(*in++)<<4;			c |= hex2int(*in++);			*out++ = c;			break;		}	}	if(!soft)		*out++ = '\n';	*out = 0;	return out;}static intdecquoted(char *out, char *in, char *e){	char *p, *nl;	if(tableqp[' '] == 0)		initquoted();	p = out;	while((nl = strchr(in, '\n')) != nil && nl < e){		p = decquotedline(p, in, nl);		in = nl + 1;	}	if(in < e)		p = decquotedline(p, in, e-1);	// make sure we end with a new line	if(*(p-1) != '\n'){		*p++ = '\n';		*p = 0;	}	return p - out;}/* translate latin1 directly since it fits neatly in utf */static intlatin1toutf(char *out, char *in, char *e){	Rune r;	char *p;	p = out;	for(; in < e; in++){		r = (*in) & 0xff;		p += runetochar(p, &r);	}	*p = 0;	return p - out;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -