1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ POP3 (RFCs 1939, 2595) client.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 - 2014 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
9 * Gunnar Ritter. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Gunnar Ritter
22 * and his contributors.
23 * 4. Neither the name of Gunnar Ritter nor the names of his contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #ifndef HAVE_AMALGAMATION
47 #define POP3_ANSWER(RV,ACTIONSTOP) \
48 do if (((RV) = pop3_answer(mp)) == STOP) {\
52 #define POP3_OUT(RV,X,Y,ACTIONSTOP) \
54 if (((RV) = pop3_finish(mp)) == STOP) {\
57 if (options & OPT_VERBOSE)\
58 fprintf(stderr, ">>> %s", X);\
60 if (((RV) = swrite(&mp->mb_sock, X)) == STOP) {\
65 static char *_pop3_buf
;
66 static size_t _pop3_bufsize
;
67 static sigjmp_buf _pop3_jmp
;
68 static sighandler_type _pop3_savealrm
;
69 static int _pop3_keepalive
;
70 static int volatile _pop3_lock
;
72 /* Perform entire login handshake */
73 static enum okay
_pop3_login(struct mailbox
*mp
, char *xuser
, char *pass
,
74 char const *uhp
, char const *xserver
);
76 /* APOP: get greeting credential or NULL */
78 static char * _pop3_lookup_apop_timestamp(char const *bp
);
81 static bool_t
_pop3_use_starttls(char const *uhp
);
83 /* APOP: shall we use it (for uhp)? */
84 static bool_t
_pop3_no_apop(char const *uhp
);
86 /* Several authentication methods */
88 static enum okay
_pop3_auth_apop(struct mailbox
*mp
, char *xuser
, char *pass
,
91 static enum okay
_pop3_auth_plain(struct mailbox
*mp
, char *xuser
, char *pass
);
93 static void pop3_timer_off(void);
94 static enum okay
pop3_answer(struct mailbox
*mp
);
95 static enum okay
pop3_finish(struct mailbox
*mp
);
96 static void pop3catch(int s
);
97 static void _pop3_maincatch(int s
);
98 static enum okay
pop3_noop1(struct mailbox
*mp
);
99 static void pop3alarm(int s
);
100 static enum okay
pop3_stat(struct mailbox
*mp
, off_t
*size
, int *cnt
);
101 static enum okay
pop3_list(struct mailbox
*mp
, int n
, size_t *size
);
102 static void pop3_init(struct mailbox
*mp
, int n
);
103 static void pop3_dates(struct mailbox
*mp
);
104 static void pop3_setptr(struct mailbox
*mp
);
105 static enum okay
pop3_get(struct mailbox
*mp
, struct message
*m
,
107 static enum okay
pop3_exit(struct mailbox
*mp
);
108 static enum okay
pop3_delete(struct mailbox
*mp
, int n
);
109 static enum okay
pop3_update(struct mailbox
*mp
);
112 _pop3_login(struct mailbox
*mp
, char *xuser
, char *pass
, char const *uhp
,
122 /* Get the greeting, check wether APOP is advertised */
123 POP3_ANSWER(rv
, goto jleave
);
125 ts
= _pop3_lookup_apop_timestamp(_pop3_buf
);
128 if ((cp
= strchr(xserver
, ':')) != NULL
) { /* TODO GENERIC URI PARSE! */
129 size_t l
= PTR2SIZE(cp
- xserver
);
130 char *x
= salloc(l
+1);
131 memcpy(x
, xserver
, l
);
136 /* If not yet secured, can we upgrade to TLS? */
138 if (mp
->mb_sock
.s_use_ssl
== 0 && _pop3_use_starttls(uhp
)) {
139 POP3_OUT(rv
, "STLS\r\n", MB_COMD
, goto jleave
);
140 POP3_ANSWER(rv
, goto jleave
);
141 if ((rv
= ssl_open(xserver
, &mp
->mb_sock
, uhp
)) != OKAY
)
145 if (_pop3_use_starttls(uhp
)) {
146 fprintf(stderr
, "No SSL support compiled in.\n");
152 /* Use the APOP single roundtrip? */
153 if (!_pop3_no_apop(uhp
)) {
156 if ((rv
= _pop3_auth_apop(mp
, xuser
, pass
, ts
)) != OKAY
)
157 fprintf(stderr
, tr(276,
158 "POP3 `APOP' authentication failed, "
159 "maybe try setting *pop3-no-apop*\n"));
163 if (options
& OPT_VERBOSE
)
164 fprintf(stderr
, tr(204, "No POP3 `APOP' support "
165 "available, sending password in clear text\n"));
167 rv
= _pop3_auth_plain(mp
, xuser
, pass
);
175 _pop3_lookup_apop_timestamp(char const *bp
)
178 * A POP3 server which implements the APOP command will include
179 * a timestamp in its banner greeting. The syntax of the timestamp
180 * corresponds to the `msg-id' in [RFC822]
182 * msg-id = "<" addr-spec ">"
183 * addr-spec = local-part "@" domain */
190 if ((cp
= strchr(bp
, '<')) == NULL
)
193 /* xxx What about malformed APOP timestamp (<@>) here? */
194 for (ep
= cp
; *ep
!= '\0'; ++ep
) {
199 else if (*ep
== '>') {
208 tl
= PTR2SIZE(++ep
- cp
);
219 _pop3_use_starttls(char const *uhp
)
224 if (!(rv
= ok_blook(pop3_use_starttls
)))
225 rv
= vok_blook(savecat("pop3-use-starttls-", uhp
));
231 _pop3_no_apop(char const *uhp
)
236 if (!(rv
= ok_blook(pop3_no_apop
)))
237 rv
= vok_blook(savecat("pop3-no-apop-", uhp
));
244 _pop3_auth_apop(struct mailbox
*mp
, char *xuser
, char *pass
, char const *ts
)
246 unsigned char digest
[16];
247 char hex
[MD5TOHEX_SIZE
];
254 for (tl
= strlen(ts
);;) {
256 if (!getcredentials(&user
, &pass
))
260 md5_update(&ctx
, (unsigned char*)UNCONST(ts
), tl
);
261 md5_update(&ctx
, (unsigned char*)pass
, strlen(pass
));
262 md5_final(digest
, &ctx
);
263 md5tohex(hex
, digest
);
266 cp
= ac_alloc(5 + i
+ 1 + MD5TOHEX_SIZE
+ 2 +1);
268 memcpy(cp
, "APOP ", 5);
269 memcpy(cp
+ 5, user
, i
);
272 memcpy(cp
+ i
, hex
, MD5TOHEX_SIZE
);
274 memcpy(cp
+ i
, "\r\n\0", 3);
275 POP3_OUT(rv
, cp
, MB_COMD
, goto jcont
);
276 POP3_ANSWER(rv
, goto jcont
);
287 #endif /* HAVE_MD5 */
290 _pop3_auth_plain(struct mailbox
*mp
, char *xuser
, char *pass
)
297 /* The USER/PASS plain text version */
300 if (!getcredentials(&user
, &pass
))
305 cp
= ac_alloc(MAX(ul
, pl
) + 5 + 2 +1);
307 memcpy(cp
, "USER ", 5);
308 memcpy(cp
+ 5, user
, ul
);
309 memcpy(cp
+ 5 + ul
, "\r\n\0", 3);
310 POP3_OUT(rv
, cp
, MB_COMD
, goto jcont
);
311 POP3_ANSWER(rv
, goto jcont
);
313 memcpy(cp
, "PASS ", 5);
314 memcpy(cp
+ 5, pass
, pl
);
315 memcpy(cp
+ 5 + pl
, "\r\n\0", 3);
316 POP3_OUT(rv
, cp
, MB_COMD
, goto jcont
);
317 POP3_ANSWER(rv
, goto jcont
);
333 if (_pop3_keepalive
> 0) {
335 safe_signal(SIGALRM
, _pop3_savealrm
);
341 pop3_answer(struct mailbox
*mp
)
348 if ((sz
= sgetline(&_pop3_buf
, &_pop3_bufsize
, NULL
, &mp
->mb_sock
)) > 0) {
349 if ((mp
->mb_active
& (MB_COMD
| MB_MULT
)) == MB_MULT
)
351 if (options
& OPT_VERBOSE
)
352 fputs(_pop3_buf
, stderr
);
353 switch (*_pop3_buf
) {
356 mp
->mb_active
&= ~MB_COMD
;
360 mp
->mb_active
= MB_NONE
;
361 fprintf(stderr
, tr(218, "POP3 error: %s"), _pop3_buf
);
364 /* If the answer starts neither with '+' nor with '-', it must be part
365 * of a multiline response. Get lines until a single dot appears */
367 while (_pop3_buf
[0] != '.' || _pop3_buf
[1] != '\r' ||
368 _pop3_buf
[2] != '\n' || _pop3_buf
[3] != '\0') {
369 sz
= sgetline(&_pop3_buf
, &_pop3_bufsize
, NULL
, &mp
->mb_sock
);
373 mp
->mb_active
&= ~MB_MULT
;
374 if (mp
->mb_active
!= MB_NONE
)
380 mp
->mb_active
= MB_NONE
;
387 pop3_finish(struct mailbox
*mp
)
390 while (mp
->mb_sock
.s_fd
> 0 && mp
->mb_active
!= MB_NONE
)
399 NYD_X
; /* Signal handler */
402 fprintf(stderr
, tr(102, "Interrupt\n"));
403 siglongjmp(_pop3_jmp
, 1);
406 fprintf(stderr
, "Received SIGPIPE during POP3 operation\n");
412 _pop3_maincatch(int s
)
414 NYD_X
; /* Signal handler */
417 if (interrupts
++ == 0)
418 fprintf(stderr
, tr(102, "Interrupt\n"));
424 pop3_noop1(struct mailbox
*mp
)
429 POP3_OUT(rv
, "NOOP\r\n", MB_COMD
, goto jleave
);
430 POP3_ANSWER(rv
, goto jleave
);
439 sighandler_type
volatile saveint
, savepipe
;
440 NYD_X
; /* Signal handler */
443 if (_pop3_lock
++ == 0) {
444 if ((saveint
= safe_signal(SIGINT
, SIG_IGN
)) != SIG_IGN
)
445 safe_signal(SIGINT
, &_pop3_maincatch
);
446 savepipe
= safe_signal(SIGPIPE
, SIG_IGN
);
447 if (sigsetjmp(_pop3_jmp
, 1)) {
448 safe_signal(SIGINT
, saveint
);
449 safe_signal(SIGPIPE
, savepipe
);
452 if (savepipe
!= SIG_IGN
)
453 safe_signal(SIGPIPE
, pop3catch
);
454 if (pop3_noop1(&mb
) != OKAY
) {
455 safe_signal(SIGINT
, saveint
);
456 safe_signal(SIGPIPE
, savepipe
);
459 safe_signal(SIGINT
, saveint
);
460 safe_signal(SIGPIPE
, savepipe
);
463 alarm(_pop3_keepalive
);
469 pop3_stat(struct mailbox
*mp
, off_t
*size
, int *cnt
)
475 POP3_OUT(rv
, "STAT\r\n", MB_COMD
, goto jleave
);
476 POP3_ANSWER(rv
, goto jleave
);
478 for (cp
= _pop3_buf
; *cp
!= '\0' && !spacechar(*cp
); ++cp
)
480 while (*cp
!= '\0' && spacechar(*cp
))
484 *cnt
= (int)strtol(cp
, NULL
, 10);
485 while (*cp
!= '\0' && !spacechar(*cp
))
487 while (*cp
!= '\0' && spacechar(*cp
))
490 *size
= (int)strtol(cp
, NULL
, 10);
497 fprintf(stderr
, tr(260, "invalid POP3 STAT response: %s\n"), _pop3_buf
);
504 pop3_list(struct mailbox
*mp
, int n
, size_t *size
)
506 char o
[LINESIZE
], *cp
;
510 snprintf(o
, sizeof o
, "LIST %u\r\n", n
);
511 POP3_OUT(rv
, o
, MB_COMD
, goto jleave
);
512 POP3_ANSWER(rv
, goto jleave
);
514 for (cp
= _pop3_buf
; *cp
!= '\0' && !spacechar(*cp
); ++cp
)
516 while (*cp
!= '\0' && spacechar(*cp
))
518 while (*cp
!= '\0' && !spacechar(*cp
))
520 while (*cp
!= '\0' && spacechar(*cp
))
523 *size
= (size_t)strtol(cp
, NULL
, 10);
532 pop3_init(struct mailbox
*mp
, int n
)
539 m
->m_flag
= MUSED
| MNEW
| MNOFROM
| MNEWEST
;
542 pop3_list(mp
, PTR2SIZE(m
- message
+ 1), &m
->m_xsize
);
544 if ((cp
= hfield1("status", m
)) != NULL
) {
545 while (*cp
!= '\0') {
557 pop3_dates(struct mailbox
*mp
)
563 for (i
= 0; UICMP(z
, i
, <, msgCount
); ++i
)
564 substdate(message
+ i
);
569 pop3_setptr(struct mailbox
*mp
)
574 message
= scalloc(msgCount
+ 1, sizeof *message
);
575 for (i
= 0; UICMP(z
, i
, <, msgCount
); ++i
)
579 message
[msgCount
].m_size
= 0;
580 message
[msgCount
].m_lines
= 0;
586 pop3_get(struct mailbox
*mp
, struct message
*m
, enum needspec
volatile need
)
588 char o
[LINESIZE
], *line
, *lp
;
589 sighandler_type
volatile saveint
, savepipe
;
590 size_t linesize
, linelen
, size
;
591 int number
, emptyline
, lines
;
596 line
= NULL
; /* TODO line pool */
597 saveint
= savepipe
= SIG_IGN
;
599 number
= (int)PTR2SIZE(m
- message
+ 1);
603 if (mp
->mb_sock
.s_fd
< 0) {
604 fprintf(stderr
, tr(219, "POP3 connection already closed.\n"));
609 if (_pop3_lock
++ == 0) {
610 if ((saveint
= safe_signal(SIGINT
, SIG_IGN
)) != SIG_IGN
)
611 safe_signal(SIGINT
, &_pop3_maincatch
);
612 savepipe
= safe_signal(SIGPIPE
, SIG_IGN
);
613 if (sigsetjmp(_pop3_jmp
, 1)) {
614 safe_signal(SIGINT
, saveint
);
615 safe_signal(SIGPIPE
, savepipe
);
619 if (savepipe
!= SIG_IGN
)
620 safe_signal(SIGPIPE
, pop3catch
);
623 fseek(mp
->mb_otf
, 0L, SEEK_END
);
624 offset
= ftell(mp
->mb_otf
);
628 snprintf(o
, sizeof o
, "TOP %u 0\r\n", number
);
631 snprintf(o
, sizeof o
, "RETR %u\r\n", number
);
636 POP3_OUT(rv
, o
, MB_COMD
| MB_MULT
, goto jleave
);
638 if (pop3_answer(mp
) == STOP
) {
639 if (need
== NEED_HEADER
) {
640 /* The TOP POP3 command is optional, so retry with entire message */
649 while (sgetline(&line
, &linesize
, &linelen
, &mp
->mb_sock
) > 0) {
650 if (line
[0] == '.' && line
[1] == '\r' && line
[2] == '\n' &&
652 mp
->mb_active
&= ~MB_MULT
;
655 if (line
[0] == '.') {
661 * Need to mask 'From ' lines. This cannot be done properly
662 * since some servers pass them as 'From ' and others as
663 * '>From '. Although one could identify the first kind of
664 * server in principle, it is not possible to identify the
665 * second as '>From ' may also come from a server of the
666 * first type as actual data. So do what is absolutely
667 * necessary only - mask 'From '.
669 * If the line is the first line of the message header, it
670 * is likely a real 'From ' line. In this case, it is just
671 * ignored since it violates all standards.
672 * TODO i have *never* seen the latter?!?!?
675 /* Since we simply copy over data without doing any transfer
676 * encoding reclassification/adjustment we *have* to perform
677 * RFC 4155 compliant From_ quoting here */
678 if (is_head(lp
, linelen
)) {
681 fputc('>', mp
->mb_otf
);
685 if (lp
[linelen
-1] == '\n' && (linelen
== 1 ||
686 lp
[linelen
-2] == '\r')) {
687 emptyline
= linelen
<= 2;
689 fwrite(lp
, 1, linelen
- 2, mp
->mb_otf
);
690 fputc('\n', mp
->mb_otf
);
694 fwrite(lp
, 1, linelen
, mp
->mb_otf
);
699 /* This is very ugly; but some POP3 daemons don't end a
700 * message with \r\n\r\n, and we need \n\n for mbox format */
701 fputc('\n', mp
->mb_otf
);
707 m
->m_block
= mailx_blockof(offset
);
708 m
->m_offset
= mailx_offsetof(offset
);
713 m
->m_have
|= HAVE_HEADER
;
716 m
->m_have
|= HAVE_HEADER
| HAVE_BODY
;
717 m
->m_xlines
= m
->m_lines
;
718 m
->m_xsize
= m
->m_size
;
728 if (saveint
!= SIG_IGN
)
729 safe_signal(SIGINT
, saveint
);
730 if (savepipe
!= SIG_IGN
)
731 safe_signal(SIGPIPE
, savepipe
);
740 pop3_exit(struct mailbox
*mp
)
745 POP3_OUT(rv
, "QUIT\r\n", MB_COMD
, goto jleave
);
746 POP3_ANSWER(rv
, goto jleave
);
753 pop3_delete(struct mailbox
*mp
, int n
)
759 snprintf(o
, sizeof o
, "DELE %u\r\n", n
);
760 POP3_OUT(rv
, o
, MB_COMD
, goto jleave
);
761 POP3_ANSWER(rv
, goto jleave
);
768 pop3_update(struct mailbox
*mp
)
771 int dodel
, c
, gotcha
, held
;
777 for (m
= message
; PTRCMP(m
, <, message
+ msgCount
); ++m
)
778 if (m
->m_flag
& MBOX
)
785 for (m
= message
; PTRCMP(m
, <, message
+ msgCount
); ++m
) {
787 dodel
= m
->m_flag
& MDELETED
;
789 dodel
= !((m
->m_flag
& MPRESERVE
) || !(m
->m_flag
& MTOUCH
));
791 pop3_delete(mp
, PTR2SIZE(m
- message
+ 1));
796 if (gotcha
&& edit
) {
797 printf(tr(168, "\"%s\" "), displayname
);
798 printf((ok_blook(bsdcompat
) || ok_blook(bsdmsgs
))
799 ? tr(170, "complete\n") : tr(212, "updated.\n"));
800 } else if (held
&& !edit
) {
802 printf(tr(155, "Held 1 message in %s\n"), displayname
);
804 printf(tr(156, "Held %d messages in %s\n"), held
, displayname
);
814 sighandler_type
volatile saveint
, savepipe
;
819 if ((saveint
= safe_signal(SIGINT
, SIG_IGN
)) != SIG_IGN
)
820 safe_signal(SIGINT
, &_pop3_maincatch
);
821 savepipe
= safe_signal(SIGPIPE
, SIG_IGN
);
822 if (sigsetjmp(_pop3_jmp
, 1) == 0) {
823 if (savepipe
!= SIG_IGN
)
824 safe_signal(SIGPIPE
, pop3catch
);
825 rv
= pop3_noop1(&mb
);
827 safe_signal(SIGINT
, saveint
);
828 safe_signal(SIGPIPE
, savepipe
);
835 pop3_setfile(char const *server
, int nmail
, int isedit
)
838 sighandler_type saveint
, savepipe
;
839 char * volatile user
, * volatile pass
;
840 char const *cp
, *uhp
, * volatile sp
= server
;
841 int use_ssl
= 0, rv
= 1;
847 if (!strncmp(sp
, "pop3://", 7)) {
851 } else if (!strncmp(sp
, "pop3s://", 8)) {
857 pass
= lookup_password_for_token(uhp
);
859 if ((cp
= last_at_before_slash(sp
)) != NULL
) {
860 user
= salloc(cp
- sp
+1);
861 memcpy(user
, sp
, cp
- sp
);
862 user
[cp
- sp
] = '\0';
864 user
= urlxdec(user
);
868 if (sopen(sp
, &so
, use_ssl
, uhp
, (use_ssl
? "pop3s" : "pop3")) != OKAY
) {
873 edit
= (isedit
!= 0);
874 if (mb
.mb_sock
.s_fd
>= 0)
885 mb
.mb_type
= MB_VOID
;
889 saveint
= safe_signal(SIGINT
, SIG_IGN
);
890 savepipe
= safe_signal(SIGPIPE
, SIG_IGN
);
891 if (sigsetjmp(_pop3_jmp
, 1)) {
893 safe_signal(SIGINT
, saveint
);
894 safe_signal(SIGPIPE
, savepipe
);
898 if (saveint
!= SIG_IGN
)
899 safe_signal(SIGINT
, pop3catch
);
900 if (savepipe
!= SIG_IGN
)
901 safe_signal(SIGPIPE
, pop3catch
);
903 if ((cp
= ok_vlook(pop3_keepalive
)) != NULL
) {
904 if ((_pop3_keepalive
= (int)strtol(cp
, NULL
, 10)) > 0) {
905 _pop3_savealrm
= safe_signal(SIGALRM
, pop3alarm
);
906 alarm(_pop3_keepalive
);
910 mb
.mb_sock
.s_desc
= "POP3";
911 mb
.mb_sock
.s_onclose
= pop3_timer_off
;
912 if (_pop3_login(&mb
, user
, pass
, uhp
, sp
) != OKAY
||
913 pop3_stat(&mb
, &mailsize
, &msgCount
) != OKAY
) {
916 safe_signal(SIGINT
, saveint
);
917 safe_signal(SIGPIPE
, savepipe
);
921 mb
.mb_type
= MB_POP3
;
922 mb
.mb_perm
= (options
& OPT_R_FLAG
) ? 0 : MB_DELE
;
927 safe_signal(SIGINT
, saveint
);
928 safe_signal(SIGPIPE
, savepipe
);
930 if (!edit
&& msgCount
== 0) {
931 if (mb
.mb_type
== MB_POP3
&& !ok_blook(emptystart
))
932 fprintf(stderr
, tr(258, "No mail at %s\n"), server
);
942 pop3_header(struct message
*m
)
947 rv
= pop3_get(&mb
, m
, (ok_blook(pop3_bulk_load
) ? NEED_BODY
: NEED_HEADER
));
953 pop3_body(struct message
*m
)
958 rv
= pop3_get(&mb
, m
, NEED_BODY
);
966 sighandler_type
volatile saveint
, savepipe
;
969 if (mb
.mb_sock
.s_fd
< 0) {
970 fprintf(stderr
, tr(219, "POP3 connection already closed.\n"));
975 saveint
= safe_signal(SIGINT
, SIG_IGN
);
976 savepipe
= safe_signal(SIGPIPE
, SIG_IGN
);
977 if (sigsetjmp(_pop3_jmp
, 1)) {
978 safe_signal(SIGINT
, saveint
);
979 safe_signal(SIGPIPE
, saveint
);
983 if (saveint
!= SIG_IGN
)
984 safe_signal(SIGINT
, pop3catch
);
985 if (savepipe
!= SIG_IGN
)
986 safe_signal(SIGPIPE
, pop3catch
);
990 safe_signal(SIGINT
, saveint
);
991 safe_signal(SIGPIPE
, savepipe
);
996 #endif /* HAVE_POP3 */
998 /* vim:set fenc=utf-8:s-it-mode */