aboutsummaryrefslogtreecommitdiffstats
path: root/trio/CHANGES
blob: fec2926f8cbc5ef65c3acffdb8854d0e7ac0a0a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * odmr.c -- ODMR protocol methods (see RFC 2645)
 *
 * For license terms, see the file COPYING in this directory.
 */

#include  "config.h"
#ifdef ODMR_ENABLE
#include  <stdio.h>
#include  <stdlib.h>
#include  <assert.h>
#ifdef HAVE_STRING_H /* strcat() */
#include <string.h>
#endif
#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
#include <net/socket.h>
#endif
#include  <sys/types.h>
#include  <sys/time.h>
#ifdef HAVE_NET_SELECT_H /* AIX needs this */
#include <net/select.h>
#endif
#ifdef HAVE_SYS_SELECT_H /* AIX 4.1, at least, needs this */
#include  <sys/select.h>
#endif
#include  <netdb.h>
#include  <errno.h>
#include  <unistd.h>
#include  "i18n.h"
#include  "fetchmail.h"
#include  "smtp.h"
#include  "socket.h"

static int odmr_ok (int sock, char *argbuf)
/* parse command response */
{
    int ok;

    ok = SMTP_ok(sock);
    if (ok == SM_UNRECOVERABLE)
	return(PS_PROTOCOL);
    else
	return(ok);
}

static int odmr_getrange(int sock, struct query *ctl, const char *id, 
			 int *countp, int *newp, int *bytes)
/* send ODMR and then run a reverse SMTP session */
{
    int ok, opts, smtp_sock;
    char buf [MSGBUFSIZE+1];
    struct idlist *qnp;		/* pointer to Q names */

    if ((ok = SMTP_ehlo(sock, fetchmailhost, 
			ctl->server.esmtp_name, ctl->server.esmtp_password,
			&opts)))
    {
	report(stderr, GT_("%s's SMTP listener does not support ESMTP\n"),
	      ctl->server.pollname);
	return(ok);
    }
    else if (!(opts & ESMTP_ATRN))
    {
	report(stderr, GT_("%s's SMTP listener does not support ATRN\n"),
	      ctl->server.pollname);
	return(PS_PROTOCOL);
    }

    /* make sure we don't enter the fetch loop */
    *bytes = *countp = *newp = -1;

    /* authenticate via CRAM-MD5 */
    ok = do_cram_md5(sock, "AUTH", ctl, "334 ");
    if (ok)
	return(ok);

    /*
     * By default, the hostlist has a single entry, the fetchmail host's
     * canonical DNS name.
     */
    buf[0] = '\0';
    for (qnp = ctl->domainlist; qnp; qnp = qnp->next)
	if (strlen(buf) + strlen(qnp->id) + 1 >= sizeof(buf))
	    break;
	else
	{
	    strcat(buf, qnp->id);
	    strcat(buf, ",");
	}
    buf[strlen(buf) - 1] = '\0';	/* nuke final comma */

    /* ship the domain list and get turnaround */
    gen_send(sock, "ATRN %s", buf);
    if ((ok = gen_recv(sock, buf, sizeof(buf))))
	return(ok);

    /* this switch includes all response codes described in RFC2645 */
    switch(atoi(buf))
    {
    case 250:	/* OK, turnaround is about to happe */
	if (outlevel > O_SILENT)
	    report(stdout, GT_("Turnaround now...\n"));
	break;

    case 450:	/* ATRN request refused */
	if (outlevel > O_SILENT)
	    report(stdout, GT_("ATRN request refused.\n"));
	return(PS_PROTOCOL);

    case 451:	/* Unable to process ATRN request now */
	report(stderr, GT_("Unable to process ATRN request now\n"));
	return(PS_EXCLUDE);

    case 453:	/* You have no mail */
	if (outlevel > O_SILENT)
	    report(stderr, GT_("You have no mail.\n"));
	return(PS_NOMAIL);

    case 502:	/* Command not implemented */
	report(stderr, GT_("Command not implemented\n"));
	return(PS_PROTOCOL);

    case 530:	/* Authentication required */
	report(stderr, GT_("Authentication required.\n"));
	return(PS_AUTHFAIL);

    default:
	report(stderr, GT_("Unknown ODMR error %d\n"), atoi(buf));
	return(PS_PROTOCOL);
    }

    /*
     * OK, if we got here it's time to become a pipe between the ODMR
     * remote server (sending) and the SMTP listener we've designated
     * (receiving).  We're not going to try to be a protocol machine;
     * instead, we'll use select(2) to watch the read sides of both
     * sockets and just throw their data at each other.
     */
    if ((smtp_sock = smtp_open(ctl)) == -1)
	return(PS_SOCKET);
    else
    {
	int	maxfd = (sock > smtp_sock) ? sock : smtp_sock;

	for (;;)
	{
	    fd_set	readfds;
	    struct timeval timeout;
	    char	buf[MSGBUFSIZE];

	    FD_ZERO(&readfds);
	    FD_SET(sock, &readfds);
	    FD_SET(smtp_sock, &readfds);

	    timeout.tv_sec  = ctl->server.timeout;
	    timeout.tv_usec = 0;

	    if (select(maxfd+1, &readfds, NULL, NULL, &timeout) == -1)
		return(PS_PROTOCOL);		/* timeout */

	    if (FD_ISSET(sock, &readfds))
	    {
		int n = SockRead(sock, buf, sizeof(buf));
		if (n <= 0)
		    break;

		SockWrite(smtp_sock, buf, n);
		if (outlevel >= O_MONITOR)
		    report(stdout, "ODMR< %s", buf);
	    }
	    if (FD_ISSET(smtp_sock, &readfds))
	    {
		int n = SockRead(smtp_sock, buf, sizeof(buf));
		if (n <= 0)
		    break;

		SockWrite(sock, buf, n);
		if (outlevel >= O_MONITOR)
		    report(stdout, "ODMR> %s", buf);
	    }
	}
	SockClose(smtp_sock);
    }

    return(0);
}

static int odmr_logout(int sock, struct query *ctl)
/* send logout command */
{
    /* if we have a smtp_socket, then we've turned around and the
       local smtp server is in control of the connection (so we don't
       send QUIT) */
    if (ctl->smtp_socket == -1)
       return(gen_transact(sock, "QUIT"));
    else
       return(PS_SUCCESS);
}

const static struct method odmr =
{
    "ODMR",		/* ODMR protocol */
#if INET6_ENABLE
    "odmr",		/* standard SMTP port */
    "odmrs",		/* ssl SMTP port */
#else /* INET6_ENABLE */
    366,		/* standard SMTP port */
    2366,		/* ssl SMTP port (BOGUS! RANDOM VALUE) */
#endif /* INET6_ENABLE */
    FALSE,		/* this is not a tagged protocol */
    FALSE,		/* this does not use a message delimiter */
    odmr_ok,		/* parse command response */
    NULL,		/* no need to get authentication */
    odmr_getrange,	/* initialize message sending */
    NULL,		/* we cannot get a list of sizes */
    NULL,		/* how do we tell a message is old? */
    NULL,		/* no way to fetch headers */
    NULL,		/* no way to fetch body */
    NULL,		/* no message trailer */
    NULL,		/* how to delete a message */
    odmr_logout,	/* log out, we're done */
    FALSE,		/* no, we can't re-poll */
};

int doODMR (struct query *ctl)
/* retrieve messages using ODMR */
{
    int status;

    if (ctl->keep) {
	fprintf(stderr, GT_("Option --keep is not supported with ODMR\n"));
	return(PS_SYNTAX);
    }
    if (ctl->flush) {
	fprintf(stderr, GT_("Option --flush is not supported with ODMR\n"));
	return(PS_SYNTAX);
    }
    if (ctl->mailboxes->id) {
	fprintf(stderr, GT_("Option --remote is not supported with ODMR\n"));
	return(PS_SYNTAX);
    }
    if (check_only) {
	fprintf(stderr, GT_("Option --check is not supported with ODMR\n"));
	return(PS_SYNTAX);
    }
    peek_capable = FALSE;

    status = do_protocol(ctl, &odmr);
    if (status == PS_NOMAIL)
	status = PS_SUCCESS;
    return(status);
}
#endif /* ODMR_ENABLE */

/* odmr.c ends here */
work on TrioScan. * Return values for errors changed. Two macros to unpack the error code has been added to the header. * Shortshort (hh) flag added. * %#s also quotes the quote-char now. * Removed the 'errorInFormat' boolean, which isn't used anymore after the functions bail out with an error instead. Version - 1999/03/04 -------------------- * More than MAX_PARAMETERS parametes will now cause the TrioPreprocess() function to return error. * Unknown flags and/or specifiers cause errors too. * Added trio_snprintfcat and trio_vsnprintfcat and the defined name StrFormatAppendMax. They append a formatted string to the end of a string. * Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when that exists. * Added platform fixes for Amiga as suggested by Tero J�nk� <tesaja@utu.fi> Version - 1999/01/31 -------------------- * vaprintf did add a zero byte even when it had failed. * Cleaned up the code for locale handling and thousand separator * Added trio_aprintf() and trio_vaprintf(). They return an allocated string. * Added thousands separator for numbers * Added floating point support for *printf Version - 1998/10/20 -------------------- * StrMatchCase() called StrMatch() instead of itself recursively * Rewrote the implementation of *printf and *scanf and put all the code in this file. Extended qualifiers and qualifiers from other standards were added. * Added StrSpanFunction, StrToLong, and StrToUnsignedLong Version - 1998/05/23 -------------------- * Made the StrEqual* functions resistant to NULL pointers * Turns out strdup() is no standard at all, and some platforms (I seem to recall HP-UX) has problems with it. Made our own StrDuplicate() instead. * Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf() respectively.