Exemplo n.º 1
0
Arquivo: mailinfo.c Projeto: 9b/git
static int handle_boundary(struct mailinfo *mi, struct strbuf *line)
{
	struct strbuf newline = STRBUF_INIT;

	strbuf_addch(&newline, '\n');
again:
	if (line->len >= (*(mi->content_top))->len + 2 &&
	    !memcmp(line->buf + (*(mi->content_top))->len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		strbuf_release(*(mi->content_top));
		free(*(mi->content_top));
		*(mi->content_top) = NULL;

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (--mi->content_top < mi->content) {
			error("Detected mismatched boundaries, can't recover");
			mi->input_error = -1;
			mi->content_top = mi->content;
			return 0;
		}
		handle_filter(mi, &newline);
		strbuf_release(&newline);
		if (mi->input_error)
			return 0;

		/* skip to the next boundary */
		if (!find_boundary(mi, line))
			return 0;
		goto again;
	}

	/* set some defaults */
	mi->transfer_encoding = TE_DONTCARE;
	strbuf_reset(&mi->charset);

	/* slurp in this section's info */
	while (read_one_header_line(line, mi->input))
		check_header(mi, line, mi->p_hdr_data, 0);

	strbuf_release(&newline);
	/* replenish line */
	if (strbuf_getline_lf(line, mi->input))
		return 0;
	strbuf_addch(line, '\n');
	return 1;
}
Exemplo n.º 2
0
static int handle_boundary(void)
{
	struct strbuf newline = STRBUF_INIT;

	strbuf_addch(&newline, '\n');
again:
	if (line.len >= (*content_top)->len + 2 &&
	    !memcmp(line.buf + (*content_top)->len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		strbuf_release(*content_top);
		free(*content_top);
		*content_top = NULL;

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (--content_top < content) {
			fprintf(stderr, "Detected mismatched boundaries, "
					"can't recover\n");
			exit(1);
		}
		handle_filter(&newline);
		strbuf_release(&newline);

		/* skip to the next boundary */
		if (!find_boundary())
			return 0;
		goto again;
	}

	/* set some defaults */
	transfer_encoding = TE_DONTCARE;
	strbuf_reset(&charset);
	message_type = TYPE_TEXT;

	/* slurp in this section's info */
	while (read_one_header_line(&line, fin))
		check_header(&line, p_hdr_data, 0);

	strbuf_release(&newline);
	/* replenish line */
	if (strbuf_getline(&line, fin, '\n'))
		return 0;
	strbuf_addch(&line, '\n');
	return 1;
}
Exemplo n.º 3
0
static int handle_boundary(void)
{
	char newline[]="\n";
again:
	if (!memcmp(line+content_top->boundary_len, "--", 2)) {
		/* we hit an end boundary */
		/* pop the current boundary off the stack */
		free(content_top->boundary);

		/* technically won't happen as is_multipart_boundary()
		   will fail first.  But just in case..
		 */
		if (content_top-- < content) {
			fprintf(stderr, "Detected mismatched boundaries, "
					"can't recover\n");
			exit(1);
		}
		handle_filter(newline, sizeof(newline));

		/* skip to the next boundary */
		if (!find_boundary())
			return 0;
		goto again;
	}

	/* set some defaults */
	transfer_encoding = TE_DONTCARE;
	charset[0] = 0;
	message_type = TYPE_TEXT;

	/* slurp in this section's info */
	while (read_one_header_line(line, sizeof(line), fin))
		check_header(line, sizeof(line), p_hdr_data, 0);

	/* eat the blank line after section info */
	return (fgets(line, sizeof(line), fin) != NULL);
}
Exemplo n.º 4
0
static void handle_body(void)
{
	struct strbuf prev = STRBUF_INIT;

	/* Skip up to the first boundary */
	if (*content_top) {
		if (!find_boundary())
			goto handle_body_out;
	}

	do {
		/* process any boundary lines */
		if (*content_top && is_multipart_boundary(&line)) {
			/* flush any leftover */
			if (prev.len) {
				handle_filter(&prev);
				strbuf_reset(&prev);
			}
			if (!handle_boundary())
				goto handle_body_out;
		}

		/* Unwrap transfer encoding */
		decode_transfer_encoding(&line);

		switch (transfer_encoding) {
		case TE_BASE64:
		case TE_QP:
		{
			struct strbuf **lines, **it, *sb;

			/* Prepend any previous partial lines */
			strbuf_insert(&line, 0, prev.buf, prev.len);
			strbuf_reset(&prev);

			/* binary data most likely doesn't have newlines */
			if (message_type != TYPE_TEXT) {
				handle_filter(&line);
				break;
			}
			/*
			 * This is a decoded line that may contain
			 * multiple new lines.  Pass only one chunk
			 * at a time to handle_filter()
			 */
			lines = strbuf_split(&line, '\n');
			for (it = lines; (sb = *it); it++) {
				if (*(it + 1) == NULL) /* The last line */
					if (sb->buf[sb->len - 1] != '\n') {
						/* Partial line, save it for later. */
						strbuf_addbuf(&prev, sb);
						break;
					}
				handle_filter(sb);
			}
			/*
			 * The partial chunk is saved in "prev" and will be
			 * appended by the next iteration of read_line_with_nul().
			 */
			strbuf_list_free(lines);
			break;
		}
		default:
			handle_filter(&line);
		}

	} while (!strbuf_getwholeline(&line, fin, '\n'));

handle_body_out:
	strbuf_release(&prev);
}
Exemplo n.º 5
0
static void handle_body(void)
{
	int rc = 0;
	static char newline[2000];
	static char *np = newline;

	/* Skip up to the first boundary */
	if (content_top->boundary) {
		if (!find_boundary())
			return;
	}

	do {
		/* process any boundary lines */
		if (content_top->boundary && is_multipart_boundary(line)) {
			/* flush any leftover */
			if ((transfer_encoding == TE_BASE64)  &&
			    (np != newline)) {
				handle_filter(newline, sizeof(newline));
			}
			if (!handle_boundary())
				return;
		}

		/* Unwrap transfer encoding */
		decode_transfer_encoding(line, sizeof(line));

		switch (transfer_encoding) {
		case TE_BASE64:
		case TE_QP:
		{
			char *op = line;

			/* binary data most likely doesn't have newlines */
			if (message_type != TYPE_TEXT) {
				rc = handle_filter(line, sizeof(newline));
				break;
			}

			/* this is a decoded line that may contain
			 * multiple new lines.  Pass only one chunk
			 * at a time to handle_filter()
			 */

			do {
				while (*op != '\n' && *op != 0)
					*np++ = *op++;
				*np = *op;
				if (*np != 0) {
					/* should be sitting on a new line */
					*(++np) = 0;
					op++;
					rc = handle_filter(newline, sizeof(newline));
					np = newline;
				}
			} while (*op != 0);
			/* the partial chunk is saved in newline and
			 * will be appended by the next iteration of fgets
			 */
			break;
		}
		default:
			rc = handle_filter(line, sizeof(newline));
		}
		if (rc)
			/* nothing left to filter */
			break;
	} while (fgets(line, sizeof(line), fin));

	return;
}
Exemplo n.º 6
0
int main(int argc, char **argv)
{
        struct timespec  timeout = {SELECT_TIMEOUT_SECONDS, 0};
        struct sigaction sigact;
        sigset_t         select_sigset;
        int              exitval = EXIT_FAILURE;
        int              syslog_options = LOG_ODELAY | LOG_PERROR;
        int              settings_retval;

        parse_args(argc, argv);

        openlog(program_invocation_short_name, syslog_options, LOG_DAEMON);

        syslog(LOG_INFO, "starting");

        memset(&sigact, 0, sizeof(struct sigaction));
        sigact.sa_handler = &sigterm_handler;

        if (sigfillset(&sigact.sa_mask) == -1) {
                syslog(LOG_ERR, "sigfillset: %s", strerror(errno));
                goto out;
        }

        if (sigaction(SIGTERM, &sigact, NULL) == -1) {
                syslog(LOG_ERR, "sigaction SIGTERM: %s", strerror(errno));
                goto out;
        }

        if (!is_daemon && sigaction(SIGINT, &sigact, NULL) == -1) {
                syslog(LOG_ERR, "sigaction SIGINT: %s", strerror(errno));
                goto out;
        }

        if (sigemptyset(&select_sigset) == -1) {
                syslog(LOG_ERR, "sigemptyset: %s", strerror(errno));
                goto out;
        }

        if (sigaddset(&select_sigset, SIGTERM) == -1) {
                syslog(LOG_ERR, "sigaddset SIGTERM: %s", strerror(errno));
                goto out;
        }

        if (!is_daemon && sigaddset(&select_sigset, SIGINT) == -1) {
                syslog(LOG_ERR, "sigaddset SIGINT: %s", strerror(errno));
                goto out;
        }

        settings_retval = settings_read(&settings);
        switch (settings_retval) {
        case 0:
                break;
        case -1:
                syslog(LOG_ERR, "settings_read: %s", strerror(errno));
                goto out;
        default:
                syslog(LOG_ERR, "settings_read: %s",
                       settings_strerror(settings_retval));
                goto out;
        }

        if ((monitor_fd = open_evdev_by_name(settings.monitor_name)) == -1) {
                syslog(LOG_ERR, "open monitor %s: %s", settings.monitor_name,
                       strerror(errno));
                goto out;
        }

        if ((filter_fd = open_evdev_by_name(settings.filter_name)) == -1) {
                syslog(LOG_ERR, "open filter %s: %s", settings.filter_name,
                       strerror(errno));
                goto out;
        }

        if (ioctl(filter_fd, EVIOCGRAB, 1) == -1) {
                syslog(LOG_ERR, "grab filter: %s", strerror(errno));
                goto out;
        }

        if ((clone_fd = clone_evdev(filter_fd, &settings.clone_id,
                                    settings.clone_name)) == -1) {
                syslog(LOG_ERR, "clone_evdev: %s", strerror(errno));
                goto out;
        }

        if (is_daemon && daemonize() == -1) {
                syslog(LOG_ERR, "daemonize: %s", strerror(errno));
                goto out;
        }

        syslog(LOG_INFO, "started");

        while (is_running) {
                fd_set rfds;

                FD_ZERO(&rfds);
                FD_SET(monitor_fd, &rfds);
                FD_SET(filter_fd, &rfds);

                switch (pselect(filter_fd + 1, &rfds, NULL, NULL, &timeout,
                                &select_sigset)) {
                case 0:
                        break;
                case -1:
                        syslog(LOG_ERR, "select: %s", strerror(errno));
                        goto out;
                default:
                        if (FD_ISSET(filter_fd, &rfds)) {
                                if (handle_filter() == -1) {
                                        goto out;
                                }
                        } else if (FD_ISSET(monitor_fd, &rfds)) {
                                if (handle_monitor() == -1) {
                                        goto out;
                                }
                        }
                        break;
                }
        }
        syslog(LOG_INFO, "stopped");
        syslog(LOG_INFO, "terminating");

        exitval = EXIT_SUCCESS;
out:
        settings_free(&settings);

        if (clone_fd != -1) {
                if (ioctl(clone_fd, UI_DEV_DESTROY) == -1) {
                        syslog(LOG_ERR, "destroy clone: %s", strerror(errno));
                        exitval = EXIT_FAILURE;
                }

                if (close(clone_fd) == -1) {
                        syslog(LOG_ERR, "close clone: %s", strerror(errno));
                        exitval = EXIT_FAILURE;
                }
        }

        if (filter_fd != -1) {
                if (ioctl(filter_fd, EVIOCGRAB, 0) == -1) {
                        syslog(LOG_ERR, "release filter: %s", strerror(errno));
                        exitval = EXIT_FAILURE;
                }

                if (close(filter_fd) == -1) {
                        syslog(LOG_ERR, "close filter: %s", strerror(errno));
                        exitval = EXIT_FAILURE;
                }
        }

        if (monitor_fd != -1) {
                if (close(monitor_fd) == -1) {
                        syslog(LOG_ERR, "close monitor: %s", strerror(errno));
                        exitval = EXIT_FAILURE;
                }
        }

        syslog(LOG_INFO, "terminated");
        return exitval;
}