use XDELE

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@6797 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1999-08-12 11:44:54 +00:00
parent da53560e90
commit 79af5ad01f

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H<>gskolan * Copyright (c) 1997-1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -144,7 +144,7 @@ do_connect (const char *hostname, int port, int nodelay)
} }
typedef enum { INIT = 0, GREET, USER, PASS, STAT, RETR, TOP, typedef enum { INIT = 0, GREET, USER, PASS, STAT, RETR, TOP,
DELE, QUIT } pop_state; DELE, XDELE, QUIT} pop_state;
#define PUSH_BUFSIZ 65536 #define PUSH_BUFSIZ 65536
@@ -228,6 +228,7 @@ doit(int s,
pop_state state = INIT; pop_state state = INIT;
unsigned count, bytes; unsigned count, bytes;
unsigned asked_for = 0, retrieved = 0, asked_deleted = 0, deleted = 0; unsigned asked_for = 0, retrieved = 0, asked_deleted = 0, deleted = 0;
unsigned sent_xdele = 0;
int out_fd; int out_fd;
char from_line[128]; char from_line[128];
size_t from_line_length; size_t from_line_length;
@@ -269,6 +270,7 @@ doit(int s,
FD_SET(s,&readset); FD_SET(s,&readset);
if (((state == STAT || state == RETR || state == TOP) if (((state == STAT || state == RETR || state == TOP)
&& asked_for < count) && asked_for < count)
|| (state == XDELE && !sent_xdele)
|| (state == DELE && asked_deleted < count)) || (state == DELE && asked_deleted < count))
FD_SET(s,&writeset); FD_SET(s,&writeset);
ret = select (s + 1, &readset, &writeset, NULL, NULL); ret = select (s + 1, &readset, &writeset, NULL, NULL);
@@ -278,22 +280,22 @@ doit(int s,
else else
err (1, "select"); err (1, "select");
} }
if (FD_ISSET(s, &readset)) { if (FD_ISSET(s, &readset)) {
char *beg, *p; char *beg, *p;
size_t rem; size_t rem;
int blank_line = 0; int blank_line = 0;
ret = read (s, in_ptr, sizeof(in_buf) - in_len - 1); ret = read (s, in_ptr, sizeof(in_buf) - in_len - 1);
if (ret < 0) if (ret < 0)
err (1, "read"); err (1, "read");
else if (ret == 0) else if (ret == 0)
errx (1, "EOF during read"); errx (1, "EOF during read");
in_len += ret; in_len += ret;
in_ptr += ret; in_ptr += ret;
*in_ptr = '\0'; *in_ptr = '\0';
beg = in_buf; beg = in_buf;
rem = in_len; rem = in_len;
while(rem > 1 while(rem > 1
@@ -302,8 +304,8 @@ doit(int s,
char *copy = beg; char *copy = beg;
if (strncasecmp(copy, if (strncasecmp(copy,
header_str, header_str,
min(p - copy + 1, strlen(header_str))) == 0) { min(p - copy + 1, strlen(header_str))) == 0) {
fprintf (stdout, "%.*s\n", (int)(p - copy), copy); fprintf (stdout, "%.*s\n", (int)(p - copy), copy);
} }
if (beg[0] == '.' && beg[1] == '\r' && beg[2] == '\n') { if (beg[0] == '.' && beg[1] == '\r' && beg[2] == '\n') {
@@ -335,7 +337,7 @@ doit(int s,
state = QUIT; state = QUIT;
net_write (s, "QUIT\r\n", 6); net_write (s, "QUIT\r\n", 6);
if (verbose > 1) if (verbose > 1)
net_write (STDERR_FILENO, "QUIT\r\n", 6); net_write (STDERR_FILENO, "QUIT\r\n", 6);
} else { } else {
if (forkp) { if (forkp) {
pid_t pid; pid_t pid;
@@ -351,7 +353,7 @@ doit(int s,
} }
} }
state = DELE; state = XDELE;
if (verbose) if (verbose)
fprintf (stderr, "deleting... "); fprintf (stderr, "deleting... ");
} }
@@ -378,6 +380,12 @@ doit(int s,
state = TOP; state = TOP;
else else
state = RETR; state = RETR;
} else if (state == XDELE) {
state = QUIT;
net_write (s, "QUIT\r\n", 6);
if (verbose > 1)
net_write (STDERR_FILENO, "QUIT\r\n", 6);
break;
} else if (state == DELE) { } else if (state == DELE) {
if (++deleted == count) { if (++deleted == count) {
state = QUIT; state = QUIT;
@@ -404,8 +412,12 @@ doit(int s,
rem -= p - beg + 2; rem -= p - beg + 2;
beg = p + 2; beg = p + 2;
} else } else {
errx (1, "Bad response: %.*s", (int)(p - beg), beg); if(state == XDELE)
state = DELE;
else
errx (1, "Bad response: %.*s", (int)(p - beg), beg);
}
} }
if (!do_from) if (!do_from)
write_state_flush (&write_state); write_state_flush (&write_state);
@@ -421,6 +433,11 @@ doit(int s,
else if ((state == STAT && do_from) || state == TOP) else if ((state == STAT && do_from) || state == TOP)
out_len = snprintf (out_buf, sizeof(out_buf), out_len = snprintf (out_buf, sizeof(out_buf),
"TOP %u 0\r\n", ++asked_for); "TOP %u 0\r\n", ++asked_for);
else if(state == XDELE) {
out_len = snprintf(out_buf, sizeof(out_buf),
"XDELE %u %u\r\n", 1, count);
sent_xdele++;
}
else if(state == DELE) else if(state == DELE)
out_len = snprintf (out_buf, sizeof(out_buf), out_len = snprintf (out_buf, sizeof(out_buf),
"DELE %u\r\n", ++asked_deleted); "DELE %u\r\n", ++asked_deleted);
@@ -634,10 +651,13 @@ parse_pobox (char *a0, const char **host, const char **user)
return; return;
} }
/* if the specification starts with po:, remember this information */
if(strncmp(a0, "po:", 3) == 0) { if(strncmp(a0, "po:", 3) == 0) {
a0 += 3; a0 += 3;
po++; po++;
} }
/* if there is an `@', the hostname is after it, otherwise at the
beginning of the string */
p = strchr(a0, '@'); p = strchr(a0, '@');
if(p != NULL) { if(p != NULL) {
*p++ = '\0'; *p++ = '\0';
@@ -645,6 +665,8 @@ parse_pobox (char *a0, const char **host, const char **user)
} else { } else {
h = a0; h = a0;
} }
/* if there is a `:', the username comes before it, otherwise at
the beginning of the string */
p = strchr(a0, ':'); p = strchr(a0, ':');
if(p != NULL) { if(p != NULL) {
*p++ = '\0'; *p++ = '\0';
@@ -748,7 +770,7 @@ main(int argc, char **argv)
#ifdef KRB5 #ifdef KRB5
port = krb5_getportbyname (context, "kpop", "tcp", 1109); port = krb5_getportbyname (context, "kpop", "tcp", 1109);
#elif defined(KRB4) #elif defined(KRB4)
port = k_getportbyname ("kpop", "tcp", 1109); port = k_getportbyname ("kpop", "tcp", 1109);
#else #else
#error must define KRB4 or KRB5 #error must define KRB4 or KRB5
#endif #endif