session.c
author Sunil Nimmagadda <sunil@nimmagadda.net>
Thu, 29 May 2014 16:02:35 +0500
changeset 26 b20d78c55e91
parent 25 ce31cbe9193a
child 29 9ced98f59ea6
permissions -rw-r--r--
knf and whitespace fixes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     1
/*
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     2
 * Copyright (c) 2014 Sunil Nimmagadda <sunil@nimmagadda.net>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     3
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     4
 * Permission to use, copy, modify, and distribute this software for any
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     5
 * purpose with or without fee is hereby granted, provided that the above
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     6
 * copyright notice and this permission notice appear in all copies.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     7
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    15
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    16
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    17
#include <sys/types.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    18
#include <sys/socket.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    19
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    20
#include <ctype.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    21
#include <err.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    22
#include <limits.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    23
#include <stdio.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    24
#include <stdlib.h>
25
ce31cbe9193a Fix a crash during concurrent sessions TIMEOUT reported by James
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 23
diff changeset
    25
#include <string.h>
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    26
#include <syslog.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    27
#include <unistd.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    28
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    29
#include "imsgev.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    30
#include "pop3d.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    31
#include "ssl.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    32
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    33
#define MAXLINESIZE	2048
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    34
#define TIMEOUT		600000
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    35
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    36
enum pop_command {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
	CMD_STLS = 0,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    38
	CMD_CAPA,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    39
	CMD_USER,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    40
	CMD_PASS,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    41
	CMD_QUIT,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    42
	CMD_STAT,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    43
	CMD_RETR,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    44
	CMD_LIST,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
	CMD_DELE,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
	CMD_RSET,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    47
	CMD_TOP,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
	CMD_UIDL,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
	CMD_NOOP
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    50
};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
enum arg_constraint {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
	OPTIONAL = 1,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    54
	PROHIBITED,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    55
	REQUIRED
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    56
};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    57
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    58
static struct {int code; enum arg_constraint c; const char *cmd;} commands[] = {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    59
	{CMD_STLS, PROHIBITED, "STLS"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    60
	{CMD_CAPA, PROHIBITED, "CAPA"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    61
	{CMD_USER, REQUIRED, "USER"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    62
	{CMD_PASS, REQUIRED, "PASS"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    63
	{CMD_QUIT, PROHIBITED, "QUIT"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    64
	{CMD_STAT, PROHIBITED, "STAT"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    65
	{CMD_RETR, REQUIRED, "RETR"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    66
	{CMD_LIST, OPTIONAL, "LIST"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    67
	{CMD_DELE, REQUIRED, "DELE"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    68
	{CMD_RSET, PROHIBITED, "RSET"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    69
	{CMD_TOP,  REQUIRED, "TOP"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    70
	{CMD_UIDL, OPTIONAL, "UIDL"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    71
	{CMD_NOOP, PROHIBITED, "NOOP"},
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    72
	{-1, OPTIONAL, NULL}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    73
};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    74
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    75
static void auth_request(struct session *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    76
static void capa(struct session *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    77
static void command(struct session *, int, char *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    78
static void session_io(struct io *, int);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    79
static void parse(struct session *, char *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    80
static void auth_command(struct session *, int, char *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    81
static void trans_command(struct session *, int, char *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    82
static void get_list_all(struct session *, int);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    83
static void get_list(struct session *, unsigned int, int);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    84
static void maildrop_imsgev(struct imsgev *, int, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    85
static void handle_init(struct session *, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    86
static void handle_retr(struct session *, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    87
static void handle_dele(struct session *, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    88
static void handle_list(struct session *, struct imsg *);
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
    89
static void handle_list_all(struct session *, struct imsg *);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    90
static void handle_update(struct session *, struct imsg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    91
static void needfd(struct imsgev *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    92
static void pop3_debug(char *, ...);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    93
static void session_write(struct session *, const char *, size_t);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    94
static const char *strstate(enum state);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    95
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    96
struct session_tree	sessions;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    97
static int		_pop3_debug = 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    98
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    99
void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   100
session_init(struct listener *l, int fd)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   101
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   102
	struct session	*s;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   103
	void		*ssl;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   104
	extern void	*ssl_ctx;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   105
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   106
	s = xcalloc(1, sizeof(*s), "session_init");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   107
	s->l = l;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   108
	if (iobuf_init(&s->iobuf, 0, 0) == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   109
		fatal("iobuf_init");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   110
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   111
	io_init(&s->io, fd, s, session_io, &s->iobuf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   112
	io_set_timeout(&s->io, TIMEOUT);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   113
	s->id = arc4random();
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   114
	s->state = AUTH;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   115
	if (s->l->flags & POP3S) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   116
		s->flags |= POP3S;
17
596dec2978b2 Remove redundant sock member in session. io already holds the sock for each session.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   117
		ssl = pop3s_init(ssl_ctx, fd);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   118
		io_set_read(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   119
		io_start_tls(&s->io, ssl);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   120
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   121
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   122
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   123
	log_connect(s->id, &l->ss, l->ss.ss_len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   124
	SPLAY_INSERT(session_tree, &sessions, s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   125
	session_reply(s, "%s", "+OK pop3d ready");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   126
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   127
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   128
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   129
void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   130
session_close(struct session *s, int flush)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   132
	struct session *entry;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   133
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   134
	entry = SPLAY_REMOVE(session_tree, &sessions,  s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   135
	if (entry == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   136
		 /* STARTTLS session was in progress and got interrupted */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   137
		logit(LOG_DEBUG, "%u: not in tree", s->id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   138
		entry = s;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   139
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   140
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   141
	if (flush) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   142
		if (entry->flags & POP3S)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   143
			iobuf_flush_ssl(&entry->iobuf, entry->io.ssl);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   144
		else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   145
			iobuf_flush(&entry->iobuf, entry->io.sock);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   146
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   147
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   148
	iobuf_clear(&entry->iobuf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   149
	io_clear(&entry->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   150
	imsgev_clear(&entry->iev_maildrop);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   151
	logit(LOG_INFO, "%u: session closed", entry->id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   152
	free(entry);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   153
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   154
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   155
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   156
session_io(struct io *io, int evt)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   157
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   158
	struct session	*s = io->arg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   159
	char		*line;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   160
	size_t		len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   161
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   162
	pop3_debug("%u: %s", s->id, io_strevent(evt));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   163
	switch (evt) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   164
	case IO_DATAIN:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   165
		line = iobuf_getline(&s->iobuf, &len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   166
		if (line == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   167
			iobuf_normalize(&s->iobuf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   168
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   169
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   170
		if (strncasecmp(line, "PASS", 4) == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   171
			pop3_debug(">>> PASS");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   172
		else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   173
			pop3_debug(">>> %s", line);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   174
		parse(s, line);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   175
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   176
	case IO_LOWAT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   177
		if (iobuf_queued(&s->iobuf) == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   178
			io_set_read(io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   179
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
	case IO_TLSREADY:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
		/* greet only for pop3s, STLS already greeted */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
		if (s->flags & POP3S) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
			log_connect(s->id, &s->l->ss, s->l->ss.ss_len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
			session_reply(s, "%s", "+OK pop3 ready");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
			io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
		SPLAY_INSERT(session_tree, &sessions, s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   188
		/* mark STLS session as secure */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   189
		s->flags |= POP3S;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   190
		logit(LOG_INFO, "%u: TLS ready", s->id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
	case IO_DISCONNECTED:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
	case IO_TIMEOUT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
	case IO_ERROR:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
		session_close(s, 0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
	default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
		logit(LOG_DEBUG, "unknown event %s", io_strevent(evt));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
parse(struct session *s, char *line)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206
	enum arg_constraint	c = OPTIONAL;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   207
	int			i, cmd = -1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   208
	char			*args;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   209
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   210
	/* trim newline */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   211
	line[strcspn(line, "\n")] = '\0';
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   212
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   213
	args = strchr(line, ' ');
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   214
	if (args) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   215
		*args++ = '\0';
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   216
		while (isspace((unsigned char)*args))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   217
			args++;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   218
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   219
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   220
	for (i = 0; commands[i].code != -1; i++) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   221
		if (strcasecmp(line, commands[i].cmd) == 0) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   222
			cmd = commands[i].code;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   223
			c = commands[i].c;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   224
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   225
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   226
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   227
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   228
	if (cmd == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   229
		logit(LOG_INFO, "%u: invalid command %s", s->id, line);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   230
		session_reply(s, "%s", "-ERR invalid command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   231
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   232
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   233
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   234
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   235
	if (c == PROHIBITED && args) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   236
		session_reply(s, "%s", "-ERR no arguments allowed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   237
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   238
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   239
	} else if ((c == REQUIRED) &&
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   240
	    (args == NULL || strlen(args) >= ARGLEN)) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   241
		session_reply(s, "%s", "-ERR args required or too long");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   242
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   243
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   244
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   245
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   246
	command(s, cmd, args);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   247
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   248
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   249
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   250
command(struct session *s, int cmd, char *args)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   251
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   252
	switch (s->state) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   253
	case AUTH:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   254
		auth_command(s, cmd, args);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   255
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   256
	case TRANSACTION:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   257
		trans_command(s, cmd, args);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   258
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   259
	case UPDATE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   260
		session_reply(s, "%s", "-ERR commands not allowed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   261
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   262
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   263
	default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   264
		fatalx("Invalid state");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   265
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   266
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   267
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   268
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   269
auth_command(struct session *s, int cmd, char *args)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   270
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   271
	extern void	*ssl_ctx;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   272
	void		*ssl;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   273
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   274
	switch (cmd) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   275
	case CMD_STLS:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   276
		if (s->flags & POP3S) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   277
			session_reply(s, "%s", "-ERR already secured");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   278
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   279
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   280
		session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   281
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   282
		iobuf_flush(&s->iobuf, s->io.sock);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   283
		/* add back when IO_TLSREADY. */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   284
		SPLAY_REMOVE(session_tree, &sessions, s);
17
596dec2978b2 Remove redundant sock member in session. io already holds the sock for each session.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 8
diff changeset
   285
		ssl = pop3s_init(ssl_ctx, s->io.sock);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   286
		io_set_read(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   287
		io_start_tls(&s->io, ssl);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   288
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   289
	case CMD_CAPA:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   290
		capa(s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   291
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   292
	case CMD_USER:
21
a591c0872243 args are checked for size in parse function. Cast to void as no truncation check required here.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 17
diff changeset
   293
		(void)strlcpy(s->user, args, sizeof(s->user));
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   294
		session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   295
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   296
	case CMD_PASS:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   297
		if (s->user[0] == '\0') {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   298
			session_reply(s, "%s", "-ERR no USER specified");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   299
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   300
		}
21
a591c0872243 args are checked for size in parse function. Cast to void as no truncation check required here.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 17
diff changeset
   301
		(void)strlcpy(s->pass, args, sizeof(s->pass));
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   302
		auth_request(s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   303
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   304
	case CMD_QUIT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   305
		session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   306
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   307
		session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   308
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   309
	default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   310
		session_reply(s, "%s", "-ERR invalid command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   311
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   312
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   313
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   314
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   315
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   316
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   317
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   318
auth_request(struct session *s)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   319
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   320
	extern struct imsgev	iev_pop3d;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   321
	struct auth_req		req;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   322
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   323
	memset(&req, 0, sizeof(req));
22
5529e269a78c Equal sized buffer copy, no truncation happens.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 21
diff changeset
   324
	(void)strlcpy(req.user, s->user, sizeof(req.user));
5529e269a78c Equal sized buffer copy, no truncation happens.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 21
diff changeset
   325
	(void)strlcpy(req.pass, s->pass, sizeof(req.pass));
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   326
	imsgev_xcompose(&iev_pop3d, IMSG_AUTH, s->id, 0, -1,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   327
	    &req, sizeof(req), "auth_request");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   328
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   329
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   330
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   331
capa(struct session *s)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   332
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   333
	session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   334
	session_reply(s, "%s", "STLS");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   335
	session_reply(s, "%s", "USER");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   336
	session_reply(s, "%s", "TOP");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   337
	session_reply(s, "%s", "UIDL");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   338
	session_reply(s, "%s", "IMPLEMENTATION pop3d");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   339
	session_reply(s, "%s", ".");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   340
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   341
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   342
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   343
trans_command(struct session *s, int cmd, char *args)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   344
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   345
	struct retr_req	retr_req;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   346
	unsigned int	idx, n;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   347
	char		*c;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   348
	const char	*errstr;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   349
	int		uidl = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   350
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   351
	memset(&retr_req, 0, sizeof(retr_req));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   352
	switch (cmd) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   353
	case CMD_CAPA:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   354
		capa(s);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   355
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   356
	case CMD_STAT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   357
		session_reply(s, "%s %zu %zu", "+OK", s->nmsgs, s->m_sz);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   358
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   359
	case CMD_TOP:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   360
		if ((c = strchr(args, ' ')) == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   361
			session_reply(s, "%s", "-ERR invalid arguments");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   362
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   363
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   364
		*c++ = '\0';
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   365
		n = strtonum(c, 0, UINT_MAX, &errstr);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   366
		if (errstr) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   367
			session_reply(s, "%s", "-ERR invalid n");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   368
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   369
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   370
		retr_req.top = 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   371
		retr_req.ntop = n;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   372
		/* FALLTRHROUGH */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   373
	case CMD_RETR:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   374
		if (!get_index(s, args, &retr_req.idx))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   375
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   376
		imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_RETR,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   377
		    s->id, 0, -1, &retr_req, sizeof(retr_req), "trans_command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   378
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   379
	case CMD_NOOP:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   380
		session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   381
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   382
	case CMD_DELE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   383
		if (!get_index(s, args, &idx))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   384
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   385
		imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_DELE,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   386
		    s->id, 0, -1, &idx, sizeof(idx), "trans_command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   387
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   388
	case CMD_RSET:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   389
		imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_RSET,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   390
		    s->id, 0, -1, NULL, 0, "trans_command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   391
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   392
	case CMD_UIDL:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   393
		uidl = 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   394
		/* FALLTHROUGH */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   395
	case CMD_LIST:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   396
		if (args) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   397
			if (!get_index(s, args, &idx))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   398
				break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   399
			get_list(s, idx, uidl);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   400
		} else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   401
			get_list_all(s, uidl);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   402
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   403
	case CMD_QUIT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   404
		imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_UPDATE,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   405
		    s->id, 0, -1, NULL, 0, "trans_command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   406
		session_set_state(s, UPDATE);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   407
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   408
	default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   409
		session_reply(s, "%s", "-ERR invalid command");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   410
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   411
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   412
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   413
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   414
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   415
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   416
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   417
get_list_all(struct session *s, int uidl)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   418
{
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   419
	io_pause(&s->io, IO_PAUSE_IN);
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   420
	session_reply(s, "+OK");
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   421
	imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_LISTALL,
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   422
	    s->id, 0, -1, &uidl, sizeof(uidl), "list_all");
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   423
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   424
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   425
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   426
get_list(struct session *s, unsigned int i, int uidl)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   427
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   428
	struct list_req	req;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   429
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   430
	req.idx = i;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   431
	req.uidl = uidl;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   432
	imsgev_xcompose(&s->iev_maildrop, IMSG_MAILDROP_LIST,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   433
	    s->id, 0, -1, &req, sizeof(req), "list");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   434
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   435
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   436
void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   437
session_imsgev_init(struct session *s, int fd)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   438
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   439
	imsgev_init(&s->iev_maildrop, fd, s, maildrop_imsgev, needfd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   440
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   441
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   442
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   443
maildrop_imsgev(struct imsgev *iev, int code, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   444
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   445
	struct session	key, *r;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   446
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   447
	switch (code) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   448
	case IMSGEV_IMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   449
		key.id = imsg->hdr.peerid;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   450
		r = SPLAY_FIND(session_tree, &sessions, &key);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   451
		if (r == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   452
			logit(LOG_INFO, "%u: session not found", key.id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   453
			fatalx("session: session lost");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   454
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   455
		switch (imsg->hdr.type) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   456
		case IMSG_MAILDROP_INIT:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   457
			handle_init(r, imsg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   458
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   459
		case IMSG_MAILDROP_RETR:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   460
			handle_retr(r, imsg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   461
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   462
		case IMSG_MAILDROP_DELE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   463
			handle_dele(r, imsg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   464
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   465
		case IMSG_MAILDROP_RSET:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   466
			session_reply(r, "%s", "+OK reset");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   467
			io_set_write(&r->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   468
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   469
		case IMSG_MAILDROP_LIST:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   470
			handle_list(r, imsg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   471
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   472
		case IMSG_MAILDROP_LISTALL:
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   473
			handle_list_all(r, imsg);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   474
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   475
		case IMSG_MAILDROP_UPDATE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   476
			handle_update(r, imsg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   477
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   478
		default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   479
			logit(LOG_DEBUG, "%s: unexpected imsg %u",
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   480
			    __func__, imsg->hdr.type);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   481
			break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   482
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   483
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   484
	case IMSGEV_EREAD:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   485
	case IMSGEV_EWRITE:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   486
	case IMSGEV_EIMSG:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   487
		fatal("session: imsgev read/write error");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   488
		break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   489
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   490
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   491
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   492
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   493
handle_init(struct session *s, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   494
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   495
	size_t		datalen;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   496
	struct stats	*stats;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   497
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   498
	datalen = imsg->hdr.len - sizeof(imsg->hdr);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   499
	if (datalen) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   500
		stats = imsg->data;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   501
		s->m_sz = stats->sz;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   502
		s->nmsgs = stats->nmsgs;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   503
		session_reply(s, "%s", "+OK maildrop ready");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   504
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   505
		session_set_state(s, TRANSACTION);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   506
	} else {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   507
		session_reply(s, "%s", "-ERR maildrop init failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   508
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   509
		session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   510
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   511
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   512
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   513
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   514
handle_retr(struct session *s, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   515
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   516
	struct retr_res	*r = imsg->data;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   517
	FILE		*fp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   518
	char		*line;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   519
	size_t		len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   520
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   521
	if (imsg->fd == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   522
		session_reply(s, "%s", "-ERR marked for delete");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   523
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   524
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   525
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   526
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   527
	if ((fp = fdopen(imsg->fd, "r")) == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   528
		logit(LOG_INFO, "%zu: retr failed", s->id);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   529
		session_reply(s, "%s", "-ERR RETR failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   530
		io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   531
		session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   532
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   533
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   534
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   535
	if (fseek(fp, r->offset, SEEK_SET) == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   536
		fatal("fseek");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   537
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   538
	session_reply(s, "%s", "+OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   539
	/* Ignore "From " line when type is mbox; maildir doesn't have it */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   540
	if ((line = fgetln(fp, &len)) && strncmp(line, "From ", 5))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   541
		session_write(s, line, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   542
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   543
	if (r->top) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   544
		/* print headers regardless of ntop */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   545
		while ((line = fgetln(fp, &len))) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   546
			session_write(s, line, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   547
			r->nlines -= 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   548
			if (strncmp(line , "\n", 1) == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   549
				break;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   550
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   551
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   552
		/* print ntop lines of body */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   553
		while ((r->ntop-- > 0) && r->nlines-- &&
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   554
		    (line = fgetln(fp, &len)))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   555
			session_write(s, line, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   556
	} else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   557
		while (r->nlines-- && (line = fgetln(fp, &len)))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   558
			session_write(s, line, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   559
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   560
	session_reply(s, "%s", ".");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   561
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   562
	fclose(fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   563
	close(imsg->fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   564
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   565
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   566
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   567
handle_dele(struct session *s, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   568
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   569
	int	*res = imsg->data;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   570
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   571
	if (*res == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   572
		session_reply(s, "%s", "+OK marked for delete");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   573
	else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   574
		session_reply(s, "%s", "+ERR msg already marked delete");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   575
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   576
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   577
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   578
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   579
/* DELEted msg's hash and sz will be zero, ignore them */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   580
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   581
handle_list(struct session *s, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   582
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   583
	struct list_res	*res = imsg->data;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   584
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   585
	res->idx += 1;	/* POP3 index is 1 based */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   586
	if (res->uidl) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   587
		if (strlen(res->u.hash))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   588
			session_reply(s, "+OK %zu %s", res->idx, res->u.hash);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   589
		else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   590
			session_reply(s, "-ERR marked for delete");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   591
	} else {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   592
		if (res->u.sz)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   593
			session_reply(s, "+OK %zu %zu", res->idx, res->u.sz);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   594
		else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   595
			session_reply(s, "-ERR marked for delete");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   596
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   597
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   598
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   599
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   600
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   601
/* List terminal is indicated by hash being empty string or sz = 0 */
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   602
static void
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   603
handle_list_all(struct session *s, struct imsg *imsg)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   604
{
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   605
	struct list_res	*res = imsg->data;
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   606
8
dd898f214ed7 Use correct format of listing.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 2
diff changeset
   607
	res->idx += 1;	/* POP3 index is 1 based */
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   608
	if (res->uidl)
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   609
		if (strlen(res->u.hash))
8
dd898f214ed7 Use correct format of listing.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 2
diff changeset
   610
			session_reply(s, "%zu %s", res->idx, res->u.hash);
26
b20d78c55e91 knf and whitespace fixes.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 25
diff changeset
   611
		else
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   612
			goto end;
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   613
	else
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   614
		if (res->u.sz)
8
dd898f214ed7 Use correct format of listing.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 2
diff changeset
   615
			session_reply(s, "%zu %zu", res->idx, res->u.sz);
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   616
		else
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   617
			goto end;
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   618
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   619
	return;
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   620
end:
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   621
	session_reply(s, ".");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   622
	io_set_write(&s->io);
2
6e7b98264ea2 Simplify list_all handling. Send an imsg for each msg instead of
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   623
	io_resume(&s->io, IO_PAUSE_IN);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   624
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   625
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   626
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   627
handle_update(struct session *s, struct imsg *imsg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   628
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   629
	int	*res = imsg->data;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   630
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   631
	if (*res == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   632
		session_reply(s, "%s", "+OK maildrop updated");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   633
	else
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   634
		session_reply(s, "%s", "-ERR maildrop update failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   635
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   636
	io_set_write(&s->io);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   637
	session_close(s, 1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   638
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   639
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   640
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   641
needfd(struct imsgev *iev)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   642
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   643
	/* XXX */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   644
	fatalx("session needs an fd");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   645
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   646
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   647
int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   648
session_cmp(struct session *a, struct session *b)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   649
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   650
	if (a->id < b->id)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   651
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   652
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   653
	if (a->id > b->id)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   654
		return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   655
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   656
	return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   657
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   658
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   659
void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   660
session_set_state(struct session *s, enum state newstate)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   661
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   662
	pop3_debug("%u: %s -> %s", s->id, strstate(s->state),
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   663
	    strstate(newstate));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   664
	s->state = newstate;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   665
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   666
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   667
#define CASE(x) case x : return #x
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   668
static const char *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   669
strstate(enum state state)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   670
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   671
	static char buf[32];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   672
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   673
	switch (state) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   674
	CASE(AUTH);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   675
	CASE(TRANSACTION);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   676
	CASE(UPDATE);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   677
	default:
23
a65ab8b73e52 This cannot truncate unless new states are added.
Sunil Nimmagadda <sunil@sunilnimmagadda.com>
parents: 22
diff changeset
   678
		(void)snprintf(buf, sizeof(buf), "%d ???", state);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   679
		return (buf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   680
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   681
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   682
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   683
void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   684
session_reply(struct session *s, char *fmt, ...)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   685
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   686
	va_list	ap;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   687
	int	n;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   688
	char	buf[MAXLINESIZE];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   689
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   690
	va_start(ap, fmt);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   691
	n = vsnprintf(buf, sizeof(buf), fmt, ap);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   692
	va_end(ap);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   693
	if (n == -1 || n > MAXLINESIZE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   694
		fatalx("session_reply: response too long");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   695
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   696
	if (buf[0] == '+')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   697
		pop3_debug("<<< +OK");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   698
	else if (buf[0] == '-')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   699
		pop3_debug("<<< -ERR");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   700
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   701
	iobuf_xfqueue(&s->iobuf, "session_reply", "%s\r\n", buf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   702
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   703
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   704
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   705
session_write(struct session *s, const char *data, size_t len)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   706
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   707
	/* remove terminating \n or \r\n if any */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   708
	if (data[len - 1] == '\n')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   709
		len -= 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   710
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   711
	if (data[len - 1] == '\r')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   712
		len -= 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   713
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   714
	/* byte stuff "." if at beginning of line */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   715
	if (data[0] == '.')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   716
		iobuf_xfqueue(&s->iobuf, "session_write", ".");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   717
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   718
	iobuf_xqueue(&s->iobuf, "session_write", data, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   719
	/* explicitly terminate with CRLF */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   720
	iobuf_xfqueue(&s->iobuf, "session_write", "\r\n");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   721
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   722
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   723
static void
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   724
pop3_debug(char *fmt, ...)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   725
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   726
	va_list		ap;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   727
	char		buf[MAXLINESIZE];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   728
	int		n;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   729
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   730
	if (!_pop3_debug)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   731
		return;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   732
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   733
	va_start(ap, fmt);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   734
	n = vsnprintf(buf, sizeof(buf), fmt, ap);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   735
	va_end(ap);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   736
	if (n == -1 || n > MAXLINESIZE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   737
		fatalx("pop3_debug: response too long");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   738
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   739
	logit(LOG_DEBUG, "%s", buf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   740
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   741
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   742
SPLAY_GENERATE(session_tree, session, entry, session_cmp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   743