Example #1
0
char *
replace(char *src, struct strb *tags, struct mail *m, struct rmlist *rml)
{
	const char	*tptr, *alias;
	char		*ptr, *tend, *dst, ch;
	size_t		 i, off, len, tlen;
	int		 strip;

	if (src == NULL)
		return (NULL);
	if (*src == '\0')
		return (xstrdup(""));

	off = 0;
	len = REPLBUFSIZE;
	dst = xmalloc(len);

	strip = 1;
	for (ptr = src; *ptr != '\0'; ptr++) {
		switch (*ptr) {
		case '%':
			break;
		default:
			ENSURE_FOR(dst, len, off, 1);
			dst[off++] = *ptr;
			continue;
		}

		switch (ch = *++ptr) {
		case '\0':
			goto out;
		case '%':
			ENSURE_FOR(dst, len, off, 1);
			dst[off++] = '%';
			continue;
		case '[':
			if ((tend = strchr(ptr, ']')) == NULL) {
				ENSURE_FOR(dst, len, off, 2);
				dst[off++] = '%';
				dst[off++] = '[';
				continue;
			}
			ptr++;

			if (*ptr == ':') {
				strip = 0;
				ptr++;
			}
			if (ptr == tend)
				continue;

			*tend = '\0';
			if ((tptr = find_tag(tags, ptr)) == NULL) {
				*tend = ']';
				ptr = tend;
				continue;
			}
			tlen = strlen(tptr);
			*tend = ']';

			ptr = tend;
			break;
		case ':':
			ch = *++ptr;
			if (ch >= '0' && ch <= '9') {
				tptr = submatch(ch, m, rml, &tlen);
				if (tptr == NULL)
					continue;
				strip = 0;
				break;
			}

			ENSURE_FOR(dst, len, off, 1);
			dst[off++] = ch;
			continue;
		default:
			if (ch >= '0' && ch <= '9') {
				tptr = submatch(ch, m, rml, &tlen);
				if (tptr == NULL)
					continue;
				break;
			}

			alias = NULL;
			if (ALIAS_IDX((u_char) ch) != -1)
				alias = aliases[ALIAS_IDX((u_char) ch)];
			if (alias == NULL)
				continue;

			if ((tptr = find_tag(tags, alias)) == NULL)
				continue;
			tlen = strlen(tptr);
			break;
		}

		if (tlen == 0)
			continue;
		ENSURE_FOR(dst, len, off, tlen);
		if (!strip) {
			memcpy(dst + off, tptr, tlen);
			off += tlen;
			continue;
		}
		for (i = 0; i < tlen; i++) {
			if (strchr(conf.strip_chars, tptr[i]) == NULL)
				dst[off++] = tptr[i];
		}
	}

out:
	ENSURE_FOR(dst, len, off, 1);
	dst[off] = '\0';

	return (dst);
}
Example #2
0
File: io.c Project: mbeck-/fdm
/*
 * Return a line from the read buffer. EOL is stripped and the string returned
 * is zero-terminated.
 */
char *
io_readline2(struct io *io, char **buf, size_t *len)
{
    char	*ptr, *base;
    size_t	 size, maxlen, eollen;

    if (io->error != NULL)
        return (NULL);

    maxlen = BUFFER_USED(io->rd);
    if (maxlen > IO_MAXLINELEN)
        maxlen = IO_MAXLINELEN;
    eollen = strlen(io->eol);
    if (BUFFER_USED(io->rd) < eollen)
        return (NULL);

    IO_DEBUG(io, "in: rd: used=%zu, free=%zu",
             BUFFER_USED(io->rd), BUFFER_FREE(io->rd));

    base = ptr = BUFFER_OUT(io->rd);
    for (;;) {
        /* Find the first character in the EOL string. */
        ptr = memchr(ptr, *io->eol, maxlen - (ptr - base));

        if (ptr != NULL) {
            /* Found. Is there enough space for the rest? */
            if (ptr - base + eollen > maxlen) {
                /*
                 * No, this isn't it. Set ptr to NULL to handle
                 * as not found.
                 */
                ptr = NULL;
            } else if (strncmp(ptr, io->eol, eollen) == 0) {
                /* This is an EOL. */
                size = ptr - base;
                break;
            }
        }
        if (ptr == NULL) {
            IO_DEBUG(io,
                     "not found (%zu, %d)", maxlen, IO_CLOSED(io));

            /*
             * Not found within the length searched. If that was
             * the maximum length, this is an error.
             */
            if (maxlen == IO_MAXLINELEN) {
                if (io->error != NULL)
                    xfree(io->error);
                io->error =
                    xstrdup("io: maximum line length exceeded");
                return (NULL);
            }

            /*
             * If the socket has closed, just return all the data
             * (the buffer is known to be at least eollen long).
             */
            if (!IO_CLOSED(io))
                return (NULL);
            size = BUFFER_USED(io->rd);

            ENSURE_FOR(*buf, *len, size, 1);
            buffer_read(io->rd, *buf, size);
            (*buf)[size] = '\0';
            return (*buf);
        }

        /* Start again from the next character. */
        ptr++;
    }

    /* Copy the line and remove it from the buffer. */
    ENSURE_FOR(*buf, *len, size, 1);
    if (size != 0)
        buffer_read(io->rd, *buf, size);
    (*buf)[size] = '\0';

    /* Discard the EOL from the buffer. */
    buffer_remove(io->rd, eollen);

    IO_DEBUG(io, "out: %zu bytes, rd: used=%zu, free=%zu",
             size, BUFFER_USED(io->rd), BUFFER_FREE(io->rd));

    return (*buf);
}
Example #3
0
char *
read_string(char endch, int esc)
{
	int		 ch, oldch;
	size_t		 pos, len, slen;
	char	        *name, *s, *buf;
	struct macro	*macro;

	len = 24;
        buf = xmalloc(len + 1);

	pos = 0;
        while ((ch = lex_getc()) != endch) {
                switch (ch) {
		case EOF:
			yyerror("missing %c", endch);
                case '\\':
			if (!esc)
				break;
                        switch (ch = lex_getc()) {
			case EOF:
				yyerror("missing %c", endch);
                        case 'r':
                                ch = '\r';
                                break;
                        case 'n':
                                ch = '\n';
                                break;
                        case 't':
                                ch = '\t';
                                break;
                        }
                        break;
		case '$':
		case '%':
			if (!esc)
				break;
			oldch = ch;

			ch = lex_getc();
			if (ch == EOF)
				yyerror("missing %c", endch);
			if (ch != '{') {
				lex_ungetc(ch);
				ch = oldch;
				break;
			}

			name = read_macro(oldch, '{');
			if ((macro = find_macro(name)) == NULL) {
				xfree(name);
				continue;
			}
			xfree(name);

			if (macro->type == MACRO_NUMBER)
 				xasprintf(&s, "%lld", macro->value.num);
			else
				s = macro->value.str;
			slen = strlen(s);

			ENSURE_FOR(buf, len, pos, slen + 1);
			memcpy(buf + pos, s, slen);
			pos += slen;

			if (macro->type == MACRO_NUMBER)
				xfree(s);
			continue;
                }

                buf[pos++] = ch;
                ENSURE_SIZE(buf, len, pos);
        }

        buf[pos] = '\0';

	return (buf);
}