Commit e9b90de7 e9b90de7b7807f0828243e04785b03d9de0055e3 by Sergey Poznyakoff

Provide a function for quick retrieval of message lines.

* include/mailutils/message.h (mu_message_quick_lines): New proto.
(mu_message_set_lines): Change signature of the 2nd argument.
* include/mailutils/sys/message.h (_mu_message) <lines>: Change
signature.
* libmailutils/diag/errors (MU_ERR_INFO_UNAVAILABLE): New error code.
* libmailutils/mailbox/message.c (mu_message_set_lines): Change
signature of the 2nd argument.
(mu_message_lines): Update call to the _lines method.
(mu_message_quick_lines): New function.
* libproto/pop/mbox.c (_POP3_MSG_LINES): New flag.
(_pop3_message)<message_lines>: New member.
(pop_create_pop3_message): New function.
(pop_scan): Use LIST to obtain scan listing.
(pop_message_lines): New function.
(pop_create_message): Set _lines method.
(pop_get_message): Use pop_create_pop3_message.

* mail/from.c (hdr_quick_lines): New function.
(compile_headline): New escape %L

* pop3d/capa.c (pop3d_capa): Show XLINES capability if
configured.
* pop3d/list.c (pop3d_list): Optionally output the number of
lines in the message.
* pop3d/pop3d.c (pop3d_xlines): New global.
(pop3d_cfg_param): New statement "scan-lines".
* pop3d/pop3d.h (pop3d_xlines): New extern.
1 parent b6a16292
...@@ -97,8 +97,9 @@ extern int mu_message_set_size (mu_message_t, ...@@ -97,8 +97,9 @@ extern int mu_message_set_size (mu_message_t,
97 void *owner); 97 void *owner);
98 98
99 extern int mu_message_lines (mu_message_t, size_t *); 99 extern int mu_message_lines (mu_message_t, size_t *);
100 extern int mu_message_quick_lines (mu_message_t, size_t *);
100 extern int mu_message_set_lines (mu_message_t, 101 extern int mu_message_set_lines (mu_message_t,
101 int (*_lines) (mu_message_t, size_t *), 102 int (*_lines) (mu_message_t, size_t *, int),
102 void *owner); 103 void *owner);
103 104
104 extern int mu_message_get_num_parts (mu_message_t, size_t *nparts); 105 extern int mu_message_get_num_parts (mu_message_t, size_t *nparts);
......
...@@ -58,7 +58,7 @@ struct _mu_message ...@@ -58,7 +58,7 @@ struct _mu_message
58 int (*_get_num_parts) (mu_message_t, size_t *); 58 int (*_get_num_parts) (mu_message_t, size_t *);
59 int (*_get_part) (mu_message_t, size_t, mu_message_t *); 59 int (*_get_part) (mu_message_t, size_t, mu_message_t *);
60 int (*_is_multipart) (mu_message_t, int *); 60 int (*_is_multipart) (mu_message_t, int *);
61 int (*_lines) (mu_message_t, size_t *); 61 int (*_lines) (mu_message_t, size_t *, int);
62 int (*_size) (mu_message_t, size_t *); 62 int (*_size) (mu_message_t, size_t *);
63 }; 63 };
64 64
......
...@@ -95,3 +95,5 @@ MU_ERR_AUTH_NO_CRED _("No credentials supplied") ...@@ -95,3 +95,5 @@ MU_ERR_AUTH_NO_CRED _("No credentials supplied")
95 95
96 MU_ERR_URL_MISS_PARTS _("URL missing required parts") 96 MU_ERR_URL_MISS_PARTS _("URL missing required parts")
97 MU_ERR_URL_EXTRA_PARTS _("URL has parts not allowed by its scheme") 97 MU_ERR_URL_EXTRA_PARTS _("URL has parts not allowed by its scheme")
98
99 MU_ERR_INFO_UNAVAILABLE _("Information is not yet available")
......
...@@ -882,7 +882,7 @@ mu_message_set_get_stream (mu_message_t msg, ...@@ -882,7 +882,7 @@ mu_message_set_get_stream (mu_message_t msg,
882 882
883 int 883 int
884 mu_message_set_lines (mu_message_t msg, int (*_lines) 884 mu_message_set_lines (mu_message_t msg, int (*_lines)
885 (mu_message_t, size_t *), void *owner) 885 (mu_message_t, size_t *, int), void *owner)
886 { 886 {
887 if (msg == NULL) 887 if (msg == NULL)
888 return EINVAL; 888 return EINVAL;
...@@ -902,7 +902,7 @@ mu_message_lines (mu_message_t msg, size_t *plines) ...@@ -902,7 +902,7 @@ mu_message_lines (mu_message_t msg, size_t *plines)
902 return EINVAL; 902 return EINVAL;
903 /* Overload. */ 903 /* Overload. */
904 if (msg->_lines) 904 if (msg->_lines)
905 return msg->_lines (msg, plines); 905 return msg->_lines (msg, plines, 0);
906 if (plines) 906 if (plines)
907 { 907 {
908 hlines = blines = 0; 908 hlines = blines = 0;
...@@ -913,6 +913,36 @@ mu_message_lines (mu_message_t msg, size_t *plines) ...@@ -913,6 +913,36 @@ mu_message_lines (mu_message_t msg, size_t *plines)
913 return ret; 913 return ret;
914 } 914 }
915 915
916 /* Return the number of lines in the message, without going into
917 excess trouble for calculating it. If obtaining the result
918 means downloading the entire message (as is the case for POP3,
919 for example), return MU_ERR_INFO_UNAVAILABLE. */
920 int
921 mu_message_quick_lines (mu_message_t msg, size_t *plines)
922 {
923 size_t hlines, blines;
924 int rc;
925
926 if (msg == NULL)
927 return EINVAL;
928 /* Overload. */
929 if (msg->_lines)
930 {
931 int rc = msg->_lines (msg, plines, 1);
932 if (rc != ENOSYS)
933 return rc;
934 }
935 if (plines)
936 {
937 hlines = blines = 0;
938 if ((rc = mu_header_lines (msg->header, &hlines)) == 0)
939 rc = mu_body_lines (msg->body, &blines);
940 if (rc == 0)
941 *plines = hlines + blines;
942 }
943 return rc;
944 }
945
916 int 946 int
917 mu_message_set_size (mu_message_t msg, int (*_size) 947 mu_message_set_size (mu_message_t msg, int (*_size)
918 (mu_message_t, size_t *), void *owner) 948 (mu_message_t, size_t *), void *owner)
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
60 #define _POP3_MSG_SIZE 0x02 /* Message size obtained */ 60 #define _POP3_MSG_SIZE 0x02 /* Message size obtained */
61 #define _POP3_MSG_SCANNED 0x04 /* Message has been scanned */ 61 #define _POP3_MSG_SCANNED 0x04 /* Message has been scanned */
62 #define _POP3_MSG_ATTRSET 0x08 /* Attributes has been set */ 62 #define _POP3_MSG_ATTRSET 0x08 /* Attributes has been set */
63 #define _POP3_MSG_LINES 0x10 /* Number of lines was obtained */
63 64
64 struct _pop3_message 65 struct _pop3_message
65 { 66 {
...@@ -71,6 +72,7 @@ struct _pop3_message ...@@ -71,6 +72,7 @@ struct _pop3_message
71 size_t body_lines; /* Number of lines in the body */ 72 size_t body_lines; /* Number of lines in the body */
72 int attr_flags; /* Message attributes */ 73 int attr_flags; /* Message attributes */
73 size_t message_size; /* Message size */ 74 size_t message_size; /* Message size */
75 size_t message_lines; /* Number of lines in the message */
74 size_t num; /* Message number */ 76 size_t num; /* Message number */
75 char *uidl; /* Cached uidl string. */ 77 char *uidl; /* Cached uidl string. */
76 mu_message_t message; /* Pointer to the message structure */ 78 mu_message_t message; /* Pointer to the message structure */
...@@ -95,6 +97,9 @@ struct _pop3_mailbox ...@@ -95,6 +97,9 @@ struct _pop3_mailbox
95 mu_secret_t secret; 97 mu_secret_t secret;
96 }; 98 };
97 99
100 static int pop_create_pop3_message (struct _pop3_mailbox *mpd, size_t msgno,
101 struct _pop3_message **mptr);
102
98 103
99 /* ------------------------------------------------------------------------- */ 104 /* ------------------------------------------------------------------------- */
100 /* Basic operations */ 105 /* Basic operations */
...@@ -277,27 +282,82 @@ pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount) ...@@ -277,27 +282,82 @@ pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
277 int status; 282 int status;
278 size_t i; 283 size_t i;
279 size_t count = 0; 284 size_t count = 0;
285 struct _pop3_mailbox *mpd = mbox->data;
286 int flags;
287 mu_iterator_t itr;
280 288
281 status = pop_messages_count (mbox, &count); 289 status = pop_messages_count (mbox, &count);
282 if (status != 0) 290 if (status != 0)
283 return status; 291 return status;
284 if (pcount) 292 if (pcount)
285 *pcount = count; 293 *pcount = count;
286 if (mbox->observable == NULL) 294
287 return 0; 295 flags = _POP3_MSG_SIZE;
288 for (i = msgno; i <= count; i++) 296 if (!mu_pop3_capa_test (mpd->pop3, "XLINES", NULL))
297 flags |= _POP3_MSG_LINES;
298
299 status = mu_pop3_list_all (mpd->pop3, &itr);
300 if (status)
301 return status;
302
303 for (i = 0, mu_iterator_first (itr);
304 i <= count && !mu_iterator_is_done (itr);
305 i++, mu_iterator_next (itr))
306 {
307 const char *str;
308 char *p;
309 size_t num;
310
311 mu_iterator_current (itr, (void**) &str);
312 num = strtoul (str, &p, 10);
313
314 if (*p != ' ')
315 {
316 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
317 ("invalid reply to LIST command: %s", str));
318 status = MU_ERR_BADREPLY;
319 break;
320 }
321 if (num >= msgno)
322 {
323 size_t size, lines;
324 struct _pop3_message *mpm;
325
326 size = strtoul (p + 1, &p, 10);
327 if (flags & _POP3_MSG_LINES)
328 {
329 if (*p != ' ')
330 {
331 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
332 ("invalid reply to LIST command: %s", str));
333 status = MU_ERR_BADREPLY;
334 break;
335 }
336 lines = strtoul (p + 1, &p, 10);
337 }
338
339 status = pop_create_pop3_message (mpd, num, &mpm);
340 if (status)
341 break;
342 mpm->message_size = size;
343 if (flags & _POP3_MSG_LINES)
344 mpm->message_lines = lines;
345 mpm->flags |= flags;
346
347 if (mbox->observable)
289 { 348 {
290 size_t tmp = i;
291 if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD, 349 if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD,
292 &tmp) != 0) 350 &num) != 0)
293 break; 351 break;
294 if (((i + 1) % 10) == 0) 352 if (((i + 1) % 10) == 0)
295 { 353 mu_observable_notify (mbox->observable,
296 mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS, 354 MU_EVT_MAILBOX_PROGRESS,
297 NULL); 355 NULL);
298 } 356 }
299 } 357 }
300 return 0; 358 }
359 mu_iterator_destroy (&itr);
360 return status;
301 } 361 }
302 362
303 /* There's no way to retrieve this info via POP3 */ 363 /* There's no way to retrieve this info via POP3 */
...@@ -475,6 +535,29 @@ pop_message_size (mu_message_t msg, size_t *psize) ...@@ -475,6 +535,29 @@ pop_message_size (mu_message_t msg, size_t *psize)
475 } 535 }
476 536
477 static int 537 static int
538 pop_message_lines (mu_message_t msg, size_t *plines, int quick)
539 {
540 int rc;
541 struct _pop3_message *mpm = mu_message_get_owner (msg);
542
543 if (!(mpm->flags & _POP3_MSG_LINES))
544 {
545 if (quick && !(mpm->flags & _POP3_MSG_CACHED))
546 return MU_ERR_INFO_UNAVAILABLE;
547 if (!pop_is_updated (mpm->mpd->mbox))
548 pop_scan (mpm->mpd->mbox, 1, NULL);
549 rc = pop_scan_message (mpm);
550 if (rc)
551 return rc;
552 mpm->message_lines = mpm->header_lines + mpm->body_lines + 1;
553 mpm->flags |= _POP3_MSG_LINES;
554 }
555
556 *plines = mpm->message_lines;
557 return 0;
558 }
559
560 static int
478 pop_create_message (struct _pop3_message *mpm, struct _pop3_mailbox *mpd) 561 pop_create_message (struct _pop3_message *mpm, struct _pop3_mailbox *mpd)
479 { 562 {
480 int status; 563 int status;
...@@ -486,10 +569,47 @@ pop_create_message (struct _pop3_message *mpm, struct _pop3_mailbox *mpd) ...@@ -486,10 +569,47 @@ pop_create_message (struct _pop3_message *mpm, struct _pop3_mailbox *mpd)
486 569
487 mu_message_set_get_stream (msg, pop_message_get_stream, mpm); 570 mu_message_set_get_stream (msg, pop_message_get_stream, mpm);
488 mu_message_set_size (msg, pop_message_size, mpm); 571 mu_message_set_size (msg, pop_message_size, mpm);
572 mu_message_set_lines (msg, pop_message_lines, mpm);
489 mpm->message = msg; 573 mpm->message = msg;
490 return 0; 574 return 0;
491 } 575 }
492 576
577 static int
578 pop_create_pop3_message (struct _pop3_mailbox *mpd, size_t msgno,
579 struct _pop3_message **mptr)
580 {
581 int status;
582 struct _pop3_message *mpm;
583
584 if (msgno > mpd->msg_count)
585 return EINVAL;
586
587 if (!mpd->msg)
588 {
589 mpd->msg = calloc (mpd->msg_count, sizeof (mpd->msg[0]));
590 if (!mpd->msg)
591 return ENOMEM;
592 }
593 if (mpd->msg[msgno - 1])
594 {
595 *mptr = mpd->msg[msgno - 1];
596 return 0;
597 }
598
599 mpm = calloc (1, sizeof (*mpm));
600 if (mpm == NULL)
601 return ENOMEM;
602
603 /* Back pointer. */
604 mpm->mpd = mpd;
605 mpm->num = msgno;
606
607 mpd->msg[msgno - 1] = mpm;
608 *mptr = mpm;
609 return status;
610 }
611
612
493 613
494 /* ------------------------------------------------------------------------- */ 614 /* ------------------------------------------------------------------------- */
495 /* Header */ 615 /* Header */
...@@ -798,35 +918,18 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) ...@@ -798,35 +918,18 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg)
798 if (!pop_is_updated (mbox)) 918 if (!pop_is_updated (mbox))
799 pop_scan (mbox, 1, NULL); 919 pop_scan (mbox, 1, NULL);
800 920
801 if (msgno > mpd->msg_count) 921 status = pop_create_pop3_message (mpd, msgno, &mpm);
802 return EINVAL; 922 if (status)
803 923 return status;
804 if (!mpd->msg) 924 if (mpm->message)
805 {
806 mpd->msg = calloc (mpd->msg_count, sizeof (mpd->msg[0]));
807 if (!mpd->msg)
808 return ENOMEM;
809 }
810 if (mpd->msg[msgno - 1])
811 { 925 {
812 *pmsg = mpd->msg[msgno - 1]->message; 926 *pmsg = mpm->message;
813 return 0; 927 return 0;
814 } 928 }
815 929
816 mpm = calloc (1, sizeof (*mpm));
817 if (mpm == NULL)
818 return ENOMEM;
819
820 /* Back pointer. */
821 mpm->mpd = mpd;
822 mpm->num = msgno;
823
824 status = pop_create_message (mpm, mpd); 930 status = pop_create_message (mpm, mpd);
825 if (status) 931 if (status)
826 {
827 free (mpm);
828 return status; 932 return status;
829 }
830 933
831 do 934 do
832 { 935 {
...@@ -852,7 +955,6 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg) ...@@ -852,7 +955,6 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, mu_message_t *pmsg)
852 955
853 mu_message_set_uid (mpm->message, pop_uid, mpm); 956 mu_message_set_uid (mpm->message, pop_uid, mpm);
854 957
855 mpd->msg[msgno - 1] = mpm;
856 mu_message_set_mailbox (mpm->message, mbox, mpm); 958 mu_message_set_mailbox (mpm->message, mbox, mpm);
857 *pmsg = mpm->message; 959 *pmsg = mpm->message;
858 return 0; 960 return 0;
......
...@@ -294,11 +294,29 @@ hdr_lines (struct header_call_args *args, void *data) ...@@ -294,11 +294,29 @@ hdr_lines (struct header_call_args *args, void *data)
294 { 294 {
295 size_t m_lines; 295 size_t m_lines;
296 char buf[UINTMAX_STRSIZE_BOUND]; 296 char buf[UINTMAX_STRSIZE_BOUND];
297
297 mu_message_lines (args->msg, &m_lines); 298 mu_message_lines (args->msg, &m_lines);
298 299
299 return header_buf_string (args, umaxtostr (m_lines, buf)); 300 return header_buf_string (args, umaxtostr (m_lines, buf));
300 } 301 }
301 302
303 /* %L */
304 static char *
305 hdr_quick_lines (struct header_call_args *args, void *data)
306 {
307 size_t m_lines;
308 char buf[UINTMAX_STRSIZE_BOUND];
309 int rc;
310 const char *p;
311
312 rc = mu_message_quick_lines (args->msg, &m_lines);
313 if (rc == 0)
314 p = umaxtostr (m_lines, buf);
315 else
316 p = "NA";
317 return header_buf_string (args, p);
318 }
319
302 /* %m */ 320 /* %m */
303 static char * 321 static char *
304 hdr_number (struct header_call_args *args, void *data) 322 hdr_number (struct header_call_args *args, void *data)
...@@ -467,6 +485,11 @@ compile_headline (const char *str) ...@@ -467,6 +485,11 @@ compile_headline (const char *str)
467 seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_lines); 485 seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_lines);
468 break; 486 break;
469 487
488 case 'L': /* Same, but in quick mode */
489 seg = new_header_segment (ALIGN_NUMBER, width, NULL,
490 hdr_quick_lines);
491 break;
492
470 case 'm': /* Message number */ 493 case 'm': /* Message number */
471 seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_number); 494 seg = new_header_segment (ALIGN_NUMBER, width, NULL, hdr_number);
472 break; 495 break;
......
...@@ -38,6 +38,8 @@ pop3d_capa (char *arg) ...@@ -38,6 +38,8 @@ pop3d_capa (char *arg)
38 pop3d_outf ("UIDL\n"); 38 pop3d_outf ("UIDL\n");
39 pop3d_outf ("RESP-CODES\n"); 39 pop3d_outf ("RESP-CODES\n");
40 pop3d_outf ("PIPELINING\n"); 40 pop3d_outf ("PIPELINING\n");
41 if (pop3d_xlines)
42 pop3d_outf ("XLINES\n");
41 43
42 #ifdef WITH_TLS 44 #ifdef WITH_TLS
43 if (tls_available && tls_done == 0) 45 if (tls_available && tls_done == 0)
......
...@@ -17,8 +17,27 @@ ...@@ -17,8 +17,27 @@
17 17
18 #include "pop3d.h" 18 #include "pop3d.h"
19 19
20 /* Displays the size of message number arg or all messages (if no arg) */ 20 /* From RFC 1939:
21 21
22 In order to simplify parsing, all POP3 servers are
23 required to use a certain format for scan listings. A
24 scan listing consists of the message-number of the
25 message, followed by a single space and the exact size of
26 the message in octets. Methods for calculating the exact
27 size of the message are described in the "Message Format"
28 section below. This memo makes no requirement on what
29 follows the message size in the scan listing. Minimal
30 implementations should just end that line of the response
31 with a CRLF pair. More advanced implementations may
32 include other information, as parsed from the message.
33 <end of quote>
34
35 GNU pop3d uses this allowance and includes in the scan
36 listing the number of lines in message. This optional
37 feature is enabled by setting "scan-lines yes" in the
38 configuration file. When on, it is indicated by the
39 XLINES capability.
40 */
22 int 41 int
23 pop3d_list (char *arg) 42 pop3d_list (char *arg)
24 { 43 {
...@@ -47,9 +66,12 @@ pop3d_list (char *arg) ...@@ -47,9 +66,12 @@ pop3d_list (char *arg)
47 { 66 {
48 mu_message_size (msg, &size); 67 mu_message_size (msg, &size);
49 mu_message_lines (msg, &lines); 68 mu_message_lines (msg, &lines);
50 pop3d_outf ("%s %s\n", 69 pop3d_outf ("%s %s",
51 mu_umaxtostr (0, mesgno), 70 mu_umaxtostr (0, mesgno),
52 mu_umaxtostr (1, size + lines)); 71 mu_umaxtostr (1, size + lines));
72 if (pop3d_xlines)
73 pop3d_outf (" %s", mu_umaxtostr (2, lines));
74 pop3d_outf ("\n");
53 } 75 }
54 } 76 }
55 pop3d_outf (".\n"); 77 pop3d_outf (".\n");
...@@ -64,10 +86,14 @@ pop3d_list (char *arg) ...@@ -64,10 +86,14 @@ pop3d_list (char *arg)
64 return ERR_MESG_DELE; 86 return ERR_MESG_DELE;
65 mu_message_size (msg, &size); 87 mu_message_size (msg, &size);
66 mu_message_lines (msg, &lines); 88 mu_message_lines (msg, &lines);
67 pop3d_outf ("+OK %s %s\n", 89 pop3d_outf ("+OK %s %s",
68 mu_umaxtostr (0, mesgno), 90 mu_umaxtostr (0, mesgno),
69 mu_umaxtostr (1, size + lines)); 91 mu_umaxtostr (1, size + lines));
92 if (pop3d_xlines)
93 pop3d_outf (" %s", mu_umaxtostr (2, lines));
94 pop3d_outf ("\n");
70 } 95 }
71 96
72 return OK; 97 return OK;
73 } 98 }
99
......
...@@ -30,6 +30,7 @@ unsigned int idle_timeout; ...@@ -30,6 +30,7 @@ unsigned int idle_timeout;
30 int pop3d_transcript; 30 int pop3d_transcript;
31 int debug_mode; 31 int debug_mode;
32 int tls_required; 32 int tls_required;
33 int pop3d_xlines;
33 34
34 #ifdef WITH_TLS 35 #ifdef WITH_TLS
35 int tls_available; 36 int tls_available;
...@@ -95,6 +96,8 @@ static struct mu_cfg_param pop3d_cfg_param[] = { ...@@ -95,6 +96,8 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
95 N_("days") }, 96 N_("days") },
96 { "delete-expired", mu_cfg_bool, &expire_on_exit, 0, NULL, 97 { "delete-expired", mu_cfg_bool, &expire_on_exit, 0, NULL,
97 N_("Delete expired messages upon closing the mailbox.") }, 98 N_("Delete expired messages upon closing the mailbox.") },
99 { "scan-lines", mu_cfg_bool, &pop3d_xlines, 0, NULL,
100 N_("Output the number of lines in the message in its scan listing.") },
98 #ifdef WITH_TLS 101 #ifdef WITH_TLS
99 { "tls-required", mu_cfg_bool, &tls_required, 0, NULL, 102 { "tls-required", mu_cfg_bool, &tls_required, 0, NULL,
100 N_("Always require STLS before entering authentication phase.") }, 103 N_("Always require STLS before entering authentication phase.") },
......
...@@ -196,6 +196,7 @@ extern struct mu_auth_data *auth_data; ...@@ -196,6 +196,7 @@ extern struct mu_auth_data *auth_data;
196 extern unsigned int idle_timeout; 196 extern unsigned int idle_timeout;
197 extern int pop3d_transcript; 197 extern int pop3d_transcript;
198 extern size_t pop3d_output_bufsize; 198 extern size_t pop3d_output_bufsize;
199 extern int pop3d_xlines;
199 200
200 extern pop3d_command_handler_t pop3d_find_command (const char *name); 201 extern pop3d_command_handler_t pop3d_find_command (const char *name);
201 202
......
...@@ -59,3 +59,4 @@ pop3d_stat (char *arg) ...@@ -59,3 +59,4 @@ pop3d_stat (char *arg)
59 59
60 return OK; 60 return OK;
61 } 61 }
62
......