Example #1
0
File: mail.c Project: 99years/plan9
/* parse a mailbox style header */
int
parse_header(char *line, String *sender, String *date)
{
	if (!IS_HEADER(line))
		return -1;
	line += sizeof("From ") - 1;
	s_restart(sender);
	while(*line==' '||*line=='\t')
		line++;
	if(*line == '"'){
		s_putc(sender, *line++);
		while(*line && *line != '"')
			s_putc(sender, *line++);
		s_putc(sender, *line++);
	} else {
		while(*line && *line != ' ' && *line != '\t')
			s_putc(sender, *line++);
	}
	s_terminate(sender);
	s_restart(date);
	while(*line==' '||*line=='\t')
		line++;
	while(*line)
		s_putc(date, *line++);
	s_terminate(date);
	return 0;
}
Example #2
0
/*
 *  Get the next token from `line'.  The symbol `\l' is replaced by
 *  the name of the local system.
 */
extern String *
rule_parse(String *line, char *system, int *backl)
{
	String *token;
	String *expanded;
	char *cp;

	token = s_parse(line, 0);
	if(token == 0)
		return(token);
	if(strchr(s_to_c(token), '\\')==0)
		return(token);
	expanded = s_new();
	for(cp = s_to_c(token); *cp; cp++) {
		if(*cp == '\\') switch(*++cp) {
		case 'l':
			s_append(expanded, system);
			*backl = 1;
			break;
		case '\\':
			s_putc(expanded, '\\');
			break;
		default:
			s_putc(expanded, '\\');
			s_putc(expanded, *cp);
			break;
		} else
			s_putc(expanded, *cp);
	}
	s_free(token);
	s_terminate(expanded);
	return(expanded);
}
Example #3
0
/* Get the next field from a String.  The field is delimited by white space,
 * single or double quotes.
 */
String *
s_parse(String *from, String *to)
{
	if (*from->ptr == '\0')
		return 0;
	if (to == 0)
		to = s_new();
	if (*from->ptr == '\'') {
		from->ptr++;
		for (;*from->ptr != '\'' && *from->ptr != '\0'; from->ptr++)
			s_putc(to, *from->ptr);
		if (*from->ptr == '\'')	
			from->ptr++;
	} else if (*from->ptr == '"') {
		from->ptr++;
		for (;*from->ptr != '"' && *from->ptr != '\0'; from->ptr++)
			s_putc(to, *from->ptr);
		if (*from->ptr == '"')	
			from->ptr++;
	} else {
		for (;!isspace(*from->ptr) && *from->ptr != '\0'; from->ptr++)
			s_putc(to, *from->ptr);
	}
	s_terminate(to);

	/* crunch trailing white */
	while(isspace(*from->ptr))
		from->ptr++;

	return to;
}
Example #4
0
/*
 *  simplify an address, reduce to a domain
 */
static String*
simplify(char *addr)
{
	int dots, dotlim;
	char *p, *at;
	String *s;

	mklower(addr);
	at = strchr(addr, '@');
	if(at == nil){
		/* local address, make it an exact match */
		s = s_copy("=");
		s_append(s, addr);
		return s;
	}

	/* copy up to, and including, the '@' sign */
	at++;
	s = s_copy("~");
	for(p = addr; p < at; p++){
		if(strchr(".*+?(|)\\[]^$", *p))
			s_putc(s, '\\');
		s_putc(s, *p);
	}

	/*
	 * just any address matching the two most significant domain elements,
	 * except for .uk, which needs three.
	 */
	s_append(s, "(.*\\.)?");
	p = addr+strlen(addr);			/* point at NUL */
	if (p[-1] == '.')
		*--p = '\0';
	if (p - addr > 3 && strcmp(".uk", p - 3) == 0)
		dotlim = 3;
	else
		dotlim = 2;
	dots = 0;
	while(--p > at)
		if(*p == '.' && ++dots >= dotlim){
			p++;
			break;
		}
	for(; *p; p++){
		if(strchr(".*+?(|)\\[]^$", *p) != nil)
			s_putc(s, '\\');
		s_putc(s, *p);
	}
	s_terminate(s);

	return s;
}
Example #5
0
static void xtoa(unsigned long x, const unsigned long *dp)
{
    char c;
    unsigned long d;
    if(x) {
        while(x < *dp) ++dp;
        do {
            d = *dp++;
            c = '0';
            while(x >= d) ++c, x -= d;
            s_putc(c);
        } while(!(d & 1));
    } else
        s_putc('0');
}
Example #6
0
uint16_t s_printf(char *instr, const char *format, ...)
{
    char c;
    int i;
    long n;

    sptr = instr;
    slen = 0;
    sptr[slen] = '\0';
    va_list a;
    va_start(a, format);
    while( (c = *format++) ) {
        if(c == '%') {
            switch(c = *format++) {
                case 's':                       // String
                    s_puts(va_arg(a, char*));
                    break;
                case 'c':                       // Char
                    s_putc(va_arg(a, int));   // Char gets promoted to Int in args, so it's an int we're looking for (GCC warning)
                    break;
                case 'i':                       // 16 bit Integer
                case 'd':                       // 16 bit Integer
                case 'u':                       // 16 bit Unsigned
                    i = va_arg(a, int);
                    if( (c == 'i' || c == 'd') && i < 0 ) i = -i, s_putc('-');
                    xtoa((unsigned)i, dv + 5);
                    break;
                case 'l':                       // 32 bit Long
                case 'n':                       // 32 bit uNsigned loNg
                    n = va_arg(a, long);
                    if(c == 'l' &&  n < 0) n = -n, s_putc('-');
                    xtoa((unsigned long)n, dv);
                    break;
                case 'x':                       // 16 bit heXadecimal
                    i = va_arg(a, int);
                    puth(i >> 12);
                    puth(i >> 8);
                    puth(i >> 4);
                    puth(i);
                    break;
                case 0: return slen;
                default: goto bad_fmt;
            }
        } else
bad_fmt:    s_putc(c);
    }
Example #7
0
/*
 *  simplify an address, reduce to a domain
 */
static String*
simplify(char *addr)
{
	int dots;
	char *p, *at;
	String *s;

	mklower(addr);
	at = strchr(addr, '@');
	if(at == nil){
		/* local address, make it an exact match */
		s = s_copy("=");
		s_append(s, addr);
		return s;
	}

	/* copy up to the '@' sign */
	at++;
	s = s_copy("~");
	for(p = addr; p < at; p++){
		if(strchr(".*+?(|)\\[]^$", *p))
			s_putc(s, '\\');
		s_putc(s, *p);
	}

	/* just any address matching the two most significant domain elements */
	s_append(s, "(.*\\.)?");
	p = addr+strlen(addr);
	dots = 0;
	for(; p > at; p--){
		if(*p != '.')
			continue;
		if(dots++ > 0){
			p++;
			break;
		}
	}
	for(; *p; p++){
		if(strchr(".*+?(|)\\[]^$", *p) != 0)
			s_putc(s, '\\');
		s_putc(s, *p);
	}
	s_terminate(s);

	return s;
}
Example #8
0
/*  Append an input line to a String.
 *
 *  Empty lines and leading whitespace are removed.
 */
static char *
rdline(Biobuf *fp, String *to)
{
	int c;
	int len = 0;

	c = Bgetc(fp);

	/* eat leading white */
	while(c==' ' || c=='\t' || c=='\n' || c=='\r')
		c = Bgetc(fp);

	if(c < 0)
		return 0;

	for(;;){
		switch(c) {
		case -1:
			goto out;
		case '\\':
			c = Bgetc(fp);
			if (c != '\n') {
				s_putc(to, '\\');
				s_putc(to, c);
				len += 2;
			}
			break;
		case '\r':
			break;
		case '\n':
			if(len != 0)
				goto out;
			break;
		default:
			s_putc(to, c);
			len++;
			break;
		}
		c = Bgetc(fp);
	}
out:
	s_terminate(to);
	return to->ptr - len;
}
Example #9
0
File: post.c Project: lufia/monafs
void
escape(String *s, char c)
{
	/*
	 * a-zA-Z0-9: pass
	 * space(' '): '+'
	 * other: %XX
	 */
	char buf[4];

	if (c == ' ')
		s_putc(s, '+');
	else if (isalnum(c))
		s_putc(s, c);
	else {
		sprint(buf, "%%%02x", (uchar) c);
		s_append(s, buf);
	}
}
Example #10
0
/*
 *  get a line that ends in crnl or cr, turn terminating crnl into a nl
 *
 *  return 0 on EOF
 */
static int
getcrnl(String *s, Biobuf *fp)
{
	int c;

	for(;;){
		c = Bgetc(fp);
		if(debug) {
			seek(2, 0, 2);
			fprint(2, "%c", c);
		}
		switch(c){
		case 0:
			break;
		case -1:
			goto out;
		case '\r':
			c = Bgetc(fp);
			if(c == '\n'){
				if(debug) {
					seek(2, 0, 2);
					fprint(2, "%c", c);
					stamp();
				}
				s_putc(s, '\n');
				goto out;
			}
			Bungetc(fp);
			s_putc(s, '\r');
			break;
		case '\n':
			s_putc(s, c);
			goto out;
		default:
			s_putc(s, c);
			break;
		}
	}
out:
	s_terminate(s);
	return s_len(s);
}
Example #11
0
/* append a char array to a String */
String *
s_append(String *to, char *from)
{
	if (to == 0)
		to = s_new();
	if (from == 0)
		return to;
	for(; *from; from++)
		s_putc(to, *from);
	s_terminate(to);
	return to;
}
Example #12
0
/*
 *  Get a line including a crnl into a string.  Convert crnl into nl.
 */
char *
getcrnl(String *s)
{
	int c;
	int count;

	count = 0;
	for(;;){
		c = Bgetc(&bin);
		if(debug)
			Bputc(&berr, c);
		switch(c){
		case -1:
			s_append(s, "connection closed unexpectedly by remote system");
			s_terminate(s);
			return 0;
		case '\r':
			c = Bgetc(&bin);
			if(c == '\n'){
		case '\n':
				s_putc(s, c);
				if(debug)
					Bputc(&berr, c);
				count++;
				s_terminate(s);
				return s->ptr - count;
			}
			Bungetc(&bin);
			s_putc(s, '\r');
			if(debug)
				Bputc(&berr, '\r');
			count++;
			break;
		default:
			s_putc(s, c);
			count++;
			break;
		}
	}
}
Example #13
0
PT(ssd1306_printf,uint8_t row, uint8_t col, __code const char * format, ...) {
    va_list args;
    PT_B
    PT_LOCK(busy);
    va_start(args,format);
    i=0;
    printf_tiny(format,args);
    va_end(args);
    sbuf[16]=0; //force trancation
    PT_CALL(ssd1306_move,row,col);
    i=0;
    while(sbuf[i] != 0) {
        s_putc(sbuf[i++]);
        PT_CALL(ssd1306_tile,buf,9);
    }
    PT_UNLOCK(busy);
    PT_E
}
Example #14
0
File: lex.c Project: lufia/wf
static int
rreadstr(char *delim, char *s)	/* if s != 0, skip this chars before reading */
{
	int c;

	s_reset(sbuf);
	if(s)
		skip(s);
	while((c=GETC()) >= 0){
		if(strchr(delim, c)){
			UNGETC(c);
			s_terminate(sbuf);
			return Tstring;
		}
		s_putc(sbuf, c);
	}
	if(c == Beof)
		yyerror("eof in string");
	return Terror;
}
Example #15
0
/* get the text of a header line minus the field name */
static String*
getstring(Node *p)
{
	String *s;

	s = s_new();
	if(p == nil)
		return s;

	for(p = p->next; p; p = p->next){
		if(p->s){
			s_append(s, s_to_c(p->s));
		}else{
			s_putc(s, p->c);
			s_terminate(s);
		}
		if(p->white)
			s_append(s, s_to_c(p->white));
	}
	return s;
}
Example #16
0
File: lex.c Project: lufia/wf
static int
readname(char *s)
{
	int c;

	s_reset(sbuf);
	if(s)
		skip(s);
	while((c=GETC()) >= 0 && (isalnum(c) || c == '-'))
		s_putc(sbuf, c);
	if(c == Beof){
		yyerror("eof in id/class");
		return Terror;
	}
	UNGETC(c);
	if(s_len(sbuf) == 0){
		yyerror("empty name");
		return Terror;
	}
	s_terminate(sbuf);
	return Tstring;
}
Example #17
0
File: post.c Project: lufia/monafs
char *
convert(Rune *s)
{
	static String *sbuf;
	int i, n, state;
	char buf[JISmax];

	if (sbuf == nil) {
		sbuf = s_new();
		if (sbuf == nil)
			sysfatal("s_new: %r");
	}

	state = 0;
	s_reset(sbuf);
	for ( ; *s; s++) {
		switch (chset) {
		case EUC_JP:
			n = runetoujis(buf, s);
			break;
		case ISO_2022_JP:
			n = runetojis(buf, s, &state);
			break;
		case Shift_JIS:
			n = runetosjis(buf, s);
			break;
		default:
			n = runetochar(buf, s);
			break;
		}

		for (i = 0; i < n; i++)
			escape(sbuf, buf[i]);
	}
	s_putc(sbuf, '\0');
	return estrdup(s_to_c(sbuf));
}
Example #18
0
File: lex.c Project: lufia/wf
int
yylex(void)
{
	int c, r;
	char c1;
	Sym *s;

genblock:
	if(block != nblock){
		if(block > nblock){
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tend), block, nblock);
			block--;
			return Tend;
		}else{
			if(debug)
				fprint(2, "%s %d -> %d\n", ty(Tbegin), block, nblock);
			block++;
			return Tbegin;
		}
	}

	c = GETC();
	if(c == Beof){
		nblock = 0;
		if(block != nblock)
			goto genblock;
		return 0;
	}
	UNGETC(c);

	switch(state){
	case Head0:			/* [%type] string */
		c = GETC();
		if(c != '%'){
			UNGETC(c);
			setstate(Body0);
			goto genblock;
		}
		r = readname(" \t");
		if(r == Terror)
			return fail(Head2);

		s = lookup(s_to_c(sbuf));
		yylval.sym = s;
		if(debug)
			fprint(2, "Sym[%s] %s\n", ty(s->type), s->name);
		setstate(Head1);
		return s->type;

	case Head1:			/* %type [string] */
		r = readstr("\n", " \t", 0);
		if(r == Terror)
			return fail(Head2);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		setstate(Head2);
		return Tstring;

	case Head2:
		skip(" \t");
		c = GETC();
		assert(c == '\n' || c == Beof);
		setstate(Head0);
		return ';';

	case Body0:			/* [indent] cmd inline */
		c = GETC();
		if(c == '%'){
			UNGETC(c);
			setstate(Head0);
			goto genblock;
		}
		UNGETC(c);

		r = skip(" \t");
		c = GETC();
		if(c == '\n'){
			if(debug)
				fprint(2, "%s\n", ty(Tbreak));
			return Tbreak;
		}
		UNGETC(c);

		nblock = r;
		setstate(Body1);
		goto genblock;

	case Body1:			/* indent [cmd] inline */
		switch(c = GETC()){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '=':
		case '\\':
		case '+':
		case '*':
		case ':':
		case '-':
		case '>':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body2);
			return c;
		case '!':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Code);
			return c;
		case '{':
		case '}':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Body3);
			return c;
		case '#':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(ID);
			return c;
		case '.':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Class);
			return c;
		case '|':
			if(debug)
				fprint(2, "%c\n", c);
			setstate(Table);
			return c;
		default:
			UNGETC(c);
			if(debug)
				fprint(2, "\\\n");
			setstate(Body2);
			return '\\';
		}

	case Body2:			/* indent cmd [inline] */
	case Table:
		r = skip(" \t");
		if(state == Table && r > 0)
			return ',';

		switch(c = getcc(&c1, "*[]|<>")){
		case Beof:
			yyerror("eof in body");
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		case '\n':
			UNGETC(c);
			setstate(Body3);
			break;
		case '*':
		case '[':
		case ']':
		case '|':
		case '<':
		case '>':
			if(c == '[' || c == '|' || c == '<')
				skip(" \t\n");
			if(debug)
				fprint(2, "%c\n", c);
			return c;
		default:
			s_reset(sbuf);
			s_putc(sbuf, c1);
			while((c=getcc(&c1, "*[]|<>")) == 0){
				if(state == Table && c1 == '\t'){
					UNGETC(c);
					break;
				}
				s_putc(sbuf, c1);
			}
			s_terminate(sbuf);
			if(c > 0)
				UNGETC(c);
			yylval.s = estrdup(s_to_c(sbuf));
			if(debug)
				fprint(2, "%s %q\n", ty(Tstring), yylval.s);
			return Tstring;
		}

	case Body3:
		skip(" \t");
		c = GETC();
		if(c != '\n')
			return fail(Body3);
		setstate(Body0);
		return ';';

	case Code:
		r = readstr("\n", "", 1);
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	case ID:
	case Class:
		r = readname(" \t");
		if(r == Terror){
			if(debug)
				fprint(2, "%s\n", ty(Terror));
			return fail(Body3);
		}
		setstate(Body3);
		yylval.s = estrdup(s_to_c(sbuf));
		if(debug)
			fprint(2, "%s %q\n", ty(Tstring), yylval.s);
		return Tstring;

	default:
		assert(0);
		return Terror;
	}
}
Example #19
0
static void puth(unsigned n)
{
    static const char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
    s_putc(hex[n & 15]);
}
Example #20
0
/* fix 822 addresses */
static void
rfc822cruft(message *mp)
{
	Field *f;
	Node *p;
	String *body, *s;
	char *cp;

	/*
	 *  parse headers in in-core part
	 */
	yyinit(s_to_c(mp->body), s_len(mp->body));
	mp->rfc822headers = 0;
	yyparse();
	mp->rfc822headers = 1;
	mp->received = received;

	/*
	 *  remove equivalent systems in all addresses
	 */
	body = s_new();
	cp = s_to_c(mp->body);
	for(f = firstfield; f; f = f->next){
		if(f->node->c == MIMEVERSION)
			mp->havemime = 1;
		if(f->node->c == FROM)
			mp->havefrom = getaddr(f->node);
		if(f->node->c == SENDER)
			mp->havesender = getaddr(f->node);
		if(f->node->c == REPLY_TO)
			mp->havereplyto = getaddr(f->node);
		if(f->node->c == TO)
			mp->haveto = 1;
		if(f->node->c == DATE)
			mp->havedate = 1;
		if(f->node->c == SUBJECT)
			mp->havesubject = getstring(f->node);
		if(f->node->c == PRECEDENCE && f->node->next && f->node->next->next){
			s = f->node->next->next->s;
			if(s && (strcmp(s_to_c(s), "bulk") == 0
				|| strcmp(s_to_c(s), "Bulk") == 0))
					mp->bulk = 1;
		}
		for(p = f->node; p; p = p->next){
			if(p->s){
				if(p->addr){
					cp = skipequiv(s_to_c(p->s));
					s_append(body, cp);
				} else 
					s_append(body, s_to_c(p->s));
			}else{
				s_putc(body, p->c);
				s_terminate(body);
			}
			if(p->white)
				s_append(body, s_to_c(p->white));
			cp = p->end+1;
		}
		s_append(body, "\n");
	}

	if(*s_to_c(body) == 0){
		s_free(body);
		return;
	}

	if(*cp != '\n')
		s_append(body, "\n");
	s_memappend(body, cp, s_len(mp->body) - (cp - s_to_c(mp->body)));
	s_terminate(body);

	firstfield = 0;
	mp->size += s_len(body) - s_len(mp->body);
	s_free(mp->body);
	mp->body = body;
}
Example #21
0
static String *
substitute(String *source, Resub *subexp, message *mp)
{
	int i;
	char *s;
	char *sp;
	String *stp;
	
	if(source == 0)
		return 0;
	sp = s_to_c(source);

	/* someplace to put it */
	stp = s_new();

	/* do the substitution */
	while (*sp != '\0') {
		if(*sp == '\\') {
			switch (*++sp) {
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
				i = *sp-'0';
				if(subexp[i].s.sp != 0)
					for (s = subexp[i].s.sp;
					     s < subexp[i].e.ep;
					     s++)
						s_putc(stp, *s);
				break;
			case '\\':
				s_putc(stp, '\\');
				break;
			case '\0':
				sp--;
				break;
			case 's':
				for(s = s_to_c(mp->replyaddr); *s; s++)
					s_putc(stp, *s);
				break;
			case 'p':
				if(mp->bulk)
					s = "bulk";
				else
					s = "normal";
				for(;*s; s++)
					s_putc(stp, *s);
				break;
			default:
				s_putc(stp, *sp);
				break;
			}
		} else if(*sp == '&') {			
			if(subexp[0].s.sp != 0)
				for (s = subexp[0].s.sp;
				     s < subexp[0].e.ep; s++)
					s_putc(stp, *s);
		} else if(*sp == '$') {
			sp = getrcvar(sp+1, &s);
			s_append(stp, s);
			free(s);
			sp--;	/* counter sp++ below */
		} else
			s_putc(stp, *sp);
		sp++;
	}
	s_terminate(stp);

	return s_restart(stp);
}