Esempio n. 1
0
File: ppproc.c Progetto: BR903/cppp
/* Partially preprocesses the current line of input. If the input
 * contains a preprocessor statement, the state of ppproc is updated
 * to reflect the current section, and if necessary the line of input
 * will be altered for output.
 */
static void seq(struct ppproc *ppp)
{
    char const *input;
    char const *cmd;
    enum status status;
    int incomment;
    enum ppcmd id;
    int size, n;

    incomment = ccommentp(ppp->cl);
    ppp->absorb = FALSE;
    input = examinechar(ppp->cl, ppp->line);
    while (!preproclinep(ppp->cl)) {
	if (endoflinep(ppp->cl))
	    return;
	input = nextchar(ppp->cl, input);
    }

    cmd = skipwhite(ppp->cl, nextchar(ppp->cl, input));
    input = getpreprocessorcmd(ppp->cl, cmd, &id);

    switch (id) {
      case cmdIfdef:
      case cmdIfndef:
	if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	++ppp->level;
	ppp->stack[ppp->level] = F_If | F_Ifdef;
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	ppp->stack[ppp->level] |= F_Copy;
	size = getidentifierlength(input);
	if (!size) {
	    error(errEmptyIf);
	    break;
	}
	if (findsymbolinset(ppp->defs, input, NULL))
	    n = statDefined;
	else if (findsymbolinset(ppp->undefs, input, NULL))
	    n = statUndefined;
	else
	    n = statUnaffected;
	input = skipwhite(ppp->cl, nextchars(ppp->cl, input, size));
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    break;
	}
	if (n != statUnaffected) {
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	    ppp->copy = n == (id == cmdIfdef ? statDefined : statUndefined);
	}
	break;

      case cmdIf:
	if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	++ppp->level;
	ppp->stack[ppp->level] = F_If | (ppp->copy ? F_Copy : 0);
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	input = seqif(ppp, (char*)input, &status);
	if (status == statError)
	    break;
	input = skipwhite(ppp->cl, input);
	if (!endoflinep(ppp->cl)) {
	    error(errIfSyntax);
	    break;
	}
	if (status == statDefined || status == statUndefined) {
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	    ppp->copy = status == statDefined;
	}
	break;

      case cmdElse:
	if (ppp->level < 0 || (ppp->stack[ppp->level] & F_Else)) {
	    error(errDanglingElse);
	    break;
	}
	ppp->stack[ppp->level] |= F_Else;
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    break;
	}
	if (ppp->stack[ppp->level] & F_Ours) {
	    ppp->copy = !ppp->copy;
	    ppp->absorb = TRUE;
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		if (ppp->stack[n] & F_ElseModify) {
		    ppp->absorb = TRUE;
		    break;
		}
		--n;
		if (!(ppp->stack[n] & F_Ours))
		    ppp->absorb = FALSE;
	    }
	}
	break;

      case cmdElif:
	if (ppp->level < 0 || !(ppp->stack[ppp->level] & F_If)
			   || (ppp->stack[ppp->level] & F_Else)) {
	    error(errDanglingElse);
	    break;
	} else if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	if (ppp->stack[ppp->level] & F_Ifdef)
	    error(errElifWithIfdef);
	ppp->stack[ppp->level] |= F_Else;
	if (ppp->stack[ppp->level] & F_Ours)
	    ppp->copy = !ppp->copy;
	++ppp->level;
	ppp->stack[ppp->level] = F_If | F_Elif | (ppp->copy ? F_Copy : 0);
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	input = seqif(ppp, (char*)input, &status);
	if (status == statError)
	    break;
	input = skipwhite(ppp->cl, input);
	if (!endoflinep(ppp->cl)) {
	    error(errIfSyntax);
	    break;
	}
	if (status == statUndefined) {
	    ppp->copy = FALSE;
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	} else if (status == statDefined) {
	    ppp->absorb = TRUE;
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		--n;
		if (!(ppp->stack[n] & F_Ours)) {
		    strcpy((char*)cmd, "else");
		    ppp->stack[ppp->level] |= F_ElseModify;
		    ppp->absorb = FALSE;
		    break;
		}
	    }
	    ppp->stack[ppp->level] |= F_Ours;
	} else {
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		--n;
		if (!(ppp->stack[n] & F_Ours)) {
		    n = -1;
		    break;
		}
	    }
	    if (n >= 0) {
		memmove((char*)cmd, cmd + 2, strlen(cmd + 2) + 1);
		ppp->stack[ppp->level] |= F_IfModify;
	    }
	}
	break;

      case cmdEndif:
	if (ppp->level < 0) {
	    error(errDanglingEnd);
	    break;
	}
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    input = restofline(ppp->cl, input);
	}
	ppp->absorb = TRUE;
	for ( ; ppp->stack[ppp->level] & F_Elif ; --ppp->level) {
	    if (ppp->stack[ppp->level] & (F_IfModify | F_ElseModify))
		ppp->absorb = FALSE;
	}
	if (ppp->absorb)
	    ppp->absorb = ppp->stack[ppp->level] & F_Ours;
	ppp->copy = ppp->stack[ppp->level] & F_Copy;
	--ppp->level;
	break;

      default:
	input = restofline(ppp->cl, input);
	break;
    }

    if (ppp->absorb && incomment != ccommentp(ppp->cl))
	error(errBrokenComment);
}
Esempio n. 2
0
int
readcontrolfile(struct letter *let, char *qid)
{
    int   fd;
    char  ctrlfile[sizeof(CTRLPFX)+6+1];
    char *ctrl = 0;
    size_t size;
    char *sep;
    char *p, *q, *end;
    struct address to;

    sprintf(ctrlfile, CTRLPFX "%.6s", qid);

    if ( (fd = open(ctrlfile, O_RDONLY)) != -1) {
	ctrl = mapfd(fd, &size);
	close(fd);
    }

    if (ctrl == 0) return 0;

    reset(let);

    strlcpy(let->qid, qid, sizeof let->qid);

    p = ctrl;
    end = p + size;

    for (p = ctrl ; (p < end) && (q = memchr(p, '\n', end-p)); p = q+1) {
	switch (*p) {
	case C_FROM:		/* From: address */
		if (let->from)
		    freeaddress(let->from);
		if ( (let->from = calloc(1, sizeof let->from[0])) == 0 ) {
		    syslog(LOG_ERR, "out of memory");
		    abort();
		}
		if ( (let->from->full = restofline(1+p, q)) == 0) {
		    syslog(LOG_ERR, "out of memory");
		    abort();
		}
		let->from->domain = strdup(let->env->localhost);
		break;

	case C_TO:		/* To: address */
		memset(&to, 0, sizeof to);
		if ( (to.full = restofline(1+p, q)) == 0) {
		    syslog(LOG_ERR, "out of memory");
		    abort();
		}
		if ( ((sep = strchr(to.full, '|')) == 0) || (sep == to.full) ) {
		    syslog(LOG_ERR, "Qid %s: corrupted to address <%s>",
				    let->qid, to.full);
		    abort();
		}
		*sep++ = 0;
		to.domain = sep;

		if ( *to.domain == 0 ) {
		    syslog(LOG_ERR, "Qid %s: corrupted to address <%s>",
				    let->qid, to.full);
		    abort();
		}
		else if (newrecipient(&let->remote, &to,
				       emUSER, NOBODY_UID, NOBODY_GID) == -1)
		    abort();
		free(to.full);
		break;

	case C_FLAGS:		/* extra flags */
		switch (p[1]) {
		case 'H':   let->has_headers = 1;
			    break;
		case 'F':   let->mesgfrom = 1;
			    break;
		}
		break;

	case C_HEADER:		/* real headers live past here */
		if (1+q < end) {
		    let->headtext = restofline(1+q, end);
		    let->headsize = strlen(let->headtext);
		}
		else {
		    let->headtext = calloc(1,1);
		    let->headsize = 0;

		}
		munmap(ctrl,size);
		return 1;
	}
    }
    munmap(ctrl, size);
    return 0;
}