/*
 * This is where we actually parse the memory map lines.
 */
static int mem_map_add_string(target_context_t *tc,
			      const char *desc)
{
	mem_region_t *mr = NULL;
	char *ptr = NULL, *s = NULL, *tok;
	int i = 0;

	mr = region_new();

	/* strtok_r modifies its first argument, so we duplicate
	   'desc' before using it */
	for (s = xstrdup(desc);
#ifndef WIN32
	     (tok = strtok_r(ptr ? NULL : s, " \t\n", &ptr));
#else
	     (tok = strtok(ptr ? NULL : s, " \t\n"));
#endif
	     /* nada */) {
#ifdef WIN32
		ptr = (ptr ? ptr : s) + strlen (tok) + 1;
#endif

		/* order of tokens is fixed */
		switch (i++) {
		case 0:
			if (parse_addrs(mr, tok) < 0)
				goto failure;
			break;
		case 1:
			mr->type = region_type(tok);
			if (mr->type == MEMTYPE_INVALID)
				goto failure;
			break;
		case 2:
			/* name is always valid */
			mr->name = xstrdup(tok);
			break;
		default:
			/* there can be any number of options */
			if (parse_opt(mr, tok) < 0)
				goto failure;
		}
	}
	if (i < 3)
		goto failure;
	mem_map_add(tc, mr);
	free(s);
	return 0;

failure:
	if (tok)
		bad_desc(desc, desc + (tok - s));
	else
		bad_desc(desc, desc + strlen(desc));
	free(mr);
	free(s);
	return -1;
}
Exemplo n.º 2
0
const rfc822_addr* rfc822::parse_addr(const char* in)
{
	const std::list<rfc822_addr*> addr_list = parse_addrs(in);
	if (addr_list.empty())
		return (NULL);
	std::list<rfc822_addr*>::const_iterator cit = addr_list.begin();
	acl_assert(cit != addr_list.end());
	return (*cit);
}
Exemplo n.º 3
0
int
readmail(struct queue *queue, int nodot, int recp_from_header)
{
	struct parse_state parse_state;
	char line[1000];	/* by RFC2822 */
	size_t linelen;
	size_t error;
	int had_headers = 0;
	int had_from = 0;
	int had_messagid = 0;
	int had_date = 0;
	int had_last_line = 0;
	int nocopy = 0;

	parse_state.state = NONE;

	error = fprintf(queue->mailf,
		"Received: from %s (uid %d)\n"
		"\t(envelope-from %s)\n"
		"\tid %s\n"
		"\tby %s (%s);\n"
		"\t%s\n",
		username, useruid,
		queue->sender,
		queue->id,
		hostname(), VERSION,
		rfc822date());
	if ((ssize_t)error < 0)
		return (-1);

	while (!feof(stdin)) {
		if (fgets(line, sizeof(line) - 1, stdin) == NULL)
			break;
		if (had_last_line)
			errlogx(1, "bad mail input format:"
				" from %s (uid %d) (envelope-from %s)",
				username, useruid, queue->sender);
		linelen = strlen(line);
		if (linelen == 0 || line[linelen - 1] != '\n') {
			/*
			 * This line did not end with a newline character.
			 * If we fix it, it better be the last line of
			 * the file.
			 */
			line[linelen] = '\n';
			line[linelen + 1] = 0;
			had_last_line = 1;
		}
		if (!had_headers) {
			/*
			 * Unless this is a continuation, switch of
			 * the Bcc: nocopy flag.
			 */
			if (!(line[0] == ' ' || line[0] == '\t'))
				nocopy = 0;

			if (strprefixcmp(line, "Date:") == 0)
				had_date = 1;
			else if (strprefixcmp(line, "Message-Id:") == 0)
				had_messagid = 1;
			else if (strprefixcmp(line, "From:") == 0)
				had_from = 1;
			else if (strprefixcmp(line, "Bcc:") == 0)
				nocopy = 1;

			if (parse_state.state != NONE) {
				if (parse_addrs(&parse_state, line, queue) < 0) {
					errlogx(1, "invalid address in header\n");
					/* NOTREACHED */
				}
			}

			if (recp_from_header && (
					strprefixcmp(line, "To:") == 0 ||
					strprefixcmp(line, "Cc:") == 0 ||
					strprefixcmp(line, "Bcc:") == 0)) {
				parse_state.state = START;
				if (parse_addrs(&parse_state, line, queue) < 0) {
					errlogx(1, "invalid address in header\n");
					/* NOTREACHED */
				}
			}
		}

		if (strcmp(line, "\n") == 0 && !had_headers) {
			had_headers = 1;
			while (!had_date || !had_messagid || !had_from) {
				if (!had_date) {
					had_date = 1;
					snprintf(line, sizeof(line), "Date: %s\n", rfc822date());
				} else if (!had_messagid) {
					/* XXX msgid, assign earlier and log? */
					had_messagid = 1;
					snprintf(line, sizeof(line), "Message-Id: <%"PRIxMAX".%s.%"PRIxMAX"@%s>\n",
						 (uintmax_t)time(NULL),
						 queue->id,
						 (uintmax_t)random(),
						 hostname());
				} else if (!had_from) {
					had_from = 1;
					snprintf(line, sizeof(line), "From: <%s>\n", queue->sender);
				}
				if (fwrite(line, strlen(line), 1, queue->mailf) != 1)
					return (-1);
			}
			strcpy(line, "\n");
		}
		if (!nodot && linelen == 2 && line[0] == '.')
			break;
		if (!nocopy) {
			if (fwrite(line, strlen(line), 1, queue->mailf) != 1)
				return (-1);
		}
	}

	return (0);
}
Exemplo n.º 4
0
int
readmail(struct queue *queue, int nodot, int recp_from_header)
{
	struct parse_state parse_state;
	char *line = NULL;
	ssize_t linelen;
	size_t linecap = 0;
	char newline[MAX_LINE_RFC822];
	size_t error;
	int had_headers = 0;
	int had_from = 0;
	int had_messagid = 0;
	int had_date = 0;
	int nocopy = 0;
	int ret = -1;

	parse_state.state = NONE;

	error = fprintf(queue->mailf,
		"Received: from %s (uid %d)\n"
		"\t(envelope-from %s)\n"
		"\tid %s\n"
		"\tby %s (%s);\n"
		"\t%s\n",
		username, useruid,
		queue->sender,
		queue->id,
		hostname(), VERSION,
		rfc822date());
	if ((ssize_t)error < 0)
		return (-1);

	while (!feof(stdin)) {
		newline[0] = '\0';
		if ((linelen = getline(&line, &linecap, stdin)) <= 0)
			break;

		if (!had_headers) {
			if (linelen > MAX_LINE_RFC822) {
				/* XXX also split headers */
				errlogx(EX_DATAERR, "bad mail input format:"
				    " from %s (uid %d) (envelope-from %s)",
				    username, useruid, queue->sender);
			}
			/*
			 * Unless this is a continuation, switch of
			 * the Bcc: nocopy flag.
			 */
			if (!(line[0] == ' ' || line[0] == '\t'))
				nocopy = 0;

			if (strprefixcmp(line, "Date:") == 0)
				had_date = 1;
			else if (strprefixcmp(line, "Message-Id:") == 0)
				had_messagid = 1;
			else if (strprefixcmp(line, "From:") == 0)
				had_from = 1;
			else if (strprefixcmp(line, "Bcc:") == 0)
				nocopy = 1;

			if (parse_state.state != NONE) {
				if (parse_addrs(&parse_state, line, queue) < 0) {
					errlogx(EX_DATAERR, "invalid address in header\n");
					/* NOTREACHED */
				}
			}

			if (recp_from_header && (
					strprefixcmp(line, "To:") == 0 ||
					strprefixcmp(line, "Cc:") == 0 ||
					strprefixcmp(line, "Bcc:") == 0)) {
				parse_state.state = START;
				if (parse_addrs(&parse_state, line, queue) < 0) {
					errlogx(EX_DATAERR, "invalid address in header\n");
					/* NOTREACHED */
				}
			}
		}

		if (strcmp(line, "\n") == 0 && !had_headers) {
			had_headers = 1;
			while (!had_date || !had_messagid || !had_from) {
				if (!had_date) {
					had_date = 1;
					snprintf(newline, sizeof(newline), "Date: %s\n", rfc822date());
				} else if (!had_messagid) {
					/* XXX msgid, assign earlier and log? */
					had_messagid = 1;
					snprintf(newline, sizeof(newline), "Message-Id: <%"PRIxMAX".%s.%"PRIxMAX"@%s>\n",
						 (uintmax_t)time(NULL),
						 queue->id,
						 (uintmax_t)random(),
						 hostname());
				} else if (!had_from) {
					had_from = 1;
					snprintf(newline, sizeof(newline), "From: <%s>\n", queue->sender);
				}
				if (fwrite(newline, strlen(newline), 1, queue->mailf) != 1)
					goto fail;
			}
			strlcpy(newline, "\n", sizeof(newline));
		}
		if (!nodot && linelen == 2 && line[0] == '.')
			break;
		if (!nocopy) {
			if (newline[0]) {
				if (fwrite(newline, strlen(newline), 1, queue->mailf) != 1)
					goto fail;
			} else {
				if (writeline(queue, line, linelen) != 0)
					goto fail;
			}
		}
	}

	ret = 0;
fail:
	free(line);
	return (ret);
}