Beispiel #1
0
/* Get the top item on the stack. */
struct paste_buffer *
paste_get_top(struct paste_stack *ps)
{
	if (ARRAY_LENGTH(ps) == 0)
		return (NULL);
	return (ARRAY_FIRST(ps));
}
Beispiel #2
0
/*
 * Add an item onto the tail of the stack, freeing the bottom if at limit. Note
 * that the caller is responsible for allocating data.
 */
void
paste_add_tail(struct paste_stack *ps, char *data, size_t size, u_int limit)
{
	struct paste_buffer	*pb;

	if (size == 0)
		return;

	while (ARRAY_LENGTH(ps) >= limit) {
		pb = ARRAY_LAST(ps);
		xfree(pb->data);
		xfree(pb);
		ARRAY_TRUNC(ps, 1);
	}

	pb = xmalloc(sizeof *pb);

	if (ARRAY_LENGTH(ps) > 0) {
		ARRAY_ADD(ps, ARRAY_FIRST(ps));
		ARRAY_SET(ps, 0, pb);
	} else {
		ARRAY_ADD(ps, pb);
	}
    //	ARRAY_INSERT(ps, 0, pb);

	pb->data = data;
	pb->size = size;
}
Beispiel #3
0
/* Body state. */
int
imap_state_body(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	struct mail		*m = fctx->mail;
	struct fetch_imap_mail	*aux;
	char			*line, *ptr;
	u_int			 n;

	if (imap_getln(a, fctx, IMAP_UNTAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);

	if (sscanf(line, "* %u FETCH (", &n) != 1)
		return (imap_invalid(a, line));
	if ((ptr = strstr(line, "BODY[] {")) == NULL)
		return (imap_invalid(a, line));

	if (sscanf(ptr, "BODY[] {%zu}", &data->size) != 1)
		return (imap_invalid(a, line));
	data->lines = 0;

	/* Fill in local data. */
	aux = xcalloc(1, sizeof *aux);
	aux->uid = ARRAY_FIRST(&data->wanted);
	m->auxdata = aux;
	m->auxfree = imap_free;
	ARRAY_REMOVE(&data->wanted, 0);

	/* Open the mail. */
	if (mail_open(m, data->size) != 0) {
		log_warnx("%s: failed to create mail", a->name);
		return (FETCH_ERROR);
	}
	m->size = 0;

	/* Tag mail. */
	default_tags(&m->tags, data->src);
	if (data->server.host != NULL) {
		add_tag(&m->tags, "server", "%s", data->server.host);
		add_tag(&m->tags, "port", "%s", data->server.port);
	}
	add_tag(&m->tags, "server_uid", "%u", aux->uid);
	add_tag(&m->tags,
	    "folder", "%s", ARRAY_ITEM(data->folders, data->folder));

	/* If we already know the mail is oversize, start off flushing it. */
	data->flushing = data->size > conf.max_size;

	fctx->state = imap_state_line;
	return (FETCH_AGAIN);
}
Beispiel #4
0
/* Free the top item on the stack. */
int
paste_free_top(struct paste_stack *ps)
{
	struct paste_buffer	*pb;

	if (ARRAY_LENGTH(ps) == 0)
		return (-1);

	pb = ARRAY_FIRST(ps);
	ARRAY_REMOVE(ps, 0);

	xfree(pb->data);
	xfree(pb);

	return (0);
}
Beispiel #5
0
// wp_next
struct
window_pane *wp_next(
	struct	window_pane *cur_wp, int dir,
	bool	(*filt)(struct window_pane *, struct window_pane *),
	int	(*sort)(const void *a, const void *b))
{
	struct	window_pane *wp;
	struct	window_pane *tar_wp;

	ARRAY_INIT(&panes);
	TAILQ_FOREACH(wp, &cur_wp->window->panes, entry)
		if (filt(cur_wp, wp))
			ARRAY_ADD(&panes, wp);

	// bypass filter
	if (ARRAY_LENGTH(&panes) == 0)
		TAILQ_FOREACH(wp, &cur_wp->window->panes, entry)
			switch(dir) {
				case WP_L:
					if (wp->xoff < cur_wp->xoff)
						ARRAY_ADD(&panes, wp);
					break;
				case WP_R:
					if (wp->xoff > cur_wp->xoff)
						ARRAY_ADD(&panes, wp);
					break;
				case WP_U:
					if (wp->yoff < cur_wp->yoff)
						ARRAY_ADD(&panes, wp);
					break;
				case WP_D:
					if (wp->yoff > cur_wp->yoff)
						ARRAY_ADD(&panes, wp);
					break;
			}

	if (ARRAY_LENGTH(&panes) > 0)
		qsort(ARRAY_DATA(&panes), ARRAY_LENGTH(&panes),
				sizeof(struct window_pane *), sort);

	if (ARRAY_LENGTH(&panes) > 0)
		tar_wp = ARRAY_FIRST(&panes);

	ARRAY_FREE(&panes);
	return tar_wp;
}
Beispiel #6
0
/*
 * Next state. Get next mail. This is also the idle state when completed, so
 * check for finished mail, exiting, and so on.
 */
int
imap_state_next(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;

	/* Handle dropped and kept mail. */
	if (!ARRAY_EMPTY(&data->dropped)) {
		if (imap_putln(a, "%u UID STORE %u +FLAGS.SILENT (\\Deleted)",
		    ++data->tag, ARRAY_FIRST(&data->dropped)) != 0)
			return (FETCH_ERROR);
		ARRAY_REMOVE(&data->dropped, 0);
		fctx->state = imap_state_commit;
		return (FETCH_BLOCK);
	}
	if (!ARRAY_EMPTY(&data->kept)) {
		/*
		 * GMail is broken and does not set the \Seen flag after mail
		 * is fetched, so set it explicitly for kept mail.
		 */
		if (imap_putln(a, "%u UID STORE %u +FLAGS.SILENT (\\Seen)",
		    ++data->tag, ARRAY_FIRST(&data->kept)) != 0)
			return (FETCH_ERROR);
		ARRAY_REMOVE(&data->kept, 0);
		fctx->state = imap_state_commit;
		return (FETCH_BLOCK);
	}

	/* Need to purge, switch to purge state. */
	if (fctx->flags & FETCH_PURGE) {
		/*
		 * If can't purge now, loop through this state until there is
		 * no mail on the dropped queue and FETCH_EMPTY is set. Can't
		 * have a seperate state to loop through without returning
		 * here: mail could potentially be added to the dropped list
		 * while in that state.
		 */
		if (fctx->flags & FETCH_EMPTY) {
			fctx->flags &= ~FETCH_PURGE;

			if (imap_putln(a, "%u EXPUNGE", ++data->tag) != 0)
				return (FETCH_ERROR);
			fctx->state = imap_state_expunge;
			return (FETCH_BLOCK);
		}

		/*
		 * Must be waiting for delivery, so permit blocking even though
		 * we (fetch) aren't waiting for any data.
		 */
		return (FETCH_BLOCK);
	}

	/* If last mail, wait for everything to be committed then close down. */
	if (ARRAY_EMPTY(&data->wanted)) {
		if (data->committed != data->total)
			return (FETCH_BLOCK);
		if (imap_putln(a, "%u CLOSE", ++data->tag) != 0)
			return (FETCH_ERROR);
		fctx->state = imap_state_close;
		return (FETCH_BLOCK);
	}

	/* Fetch the next mail. */
	if (imap_putln(a, "%u "
	    "UID FETCH %u BODY[]",++data->tag, ARRAY_FIRST(&data->wanted)) != 0)
		return (FETCH_ERROR);
	fctx->state = imap_state_body;
	return (FETCH_BLOCK);
}