1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 #ifndef _MAILUTILS_SYS_POP3_H
19 #define _MAILUTILS_SYS_POP3_H
20 
21 #include <sys/types.h>
22 #include <mailutils/pop3.h>
23 #include <mailutils/errno.h>
24 #include <mailutils/cstr.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 enum mu_pop3_state
31   {
32     MU_POP3_NO_STATE,
33     MU_POP3_CONNECT, MU_POP3_GREETINGS,
34     MU_POP3_APOP,
35     MU_POP3_AUTH,
36     MU_POP3_CAPA, MU_POP3_CAPA_RX,
37     MU_POP3_DELE,
38     MU_POP3_LIST, MU_POP3_LIST_RX,
39     MU_POP3_NOOP,
40     MU_POP3_PASS,
41     MU_POP3_QUIT,
42     MU_POP3_RETR, MU_POP3_RETR_RX,
43     MU_POP3_RSET,
44     MU_POP3_STAT,
45     MU_POP3_STLS, MU_POP3_STLS_CONNECT,
46     MU_POP3_TOP,  MU_POP3_TOP_RX,
47     MU_POP3_UIDL, MU_POP3_UIDL_RX,
48     MU_POP3_USER,
49     MU_POP3_DONE,
50     MU_POP3_UNKNOWN,
51     MU_POP3_ERROR
52   };
53 
54 #define MU_POP3_ACK   0x01
55 #define MU_POP3_TRACE 0x02
56 #define MU_POP3_XSCRIPT_MASK(n) (1<<((n)+1))
57 
58 /* Structure to hold things general to POP3 mailbox, like its state, etc ... */
59 struct _mu_pop3
60   {
61     int flags;
62 
63     /* Holds the first line response of the last command, i.e the ACK  */
64     char *ackbuf;
65     size_t acksize;
66 
67     char *rdbuf;
68     size_t rdsize;
69 
70     char *timestamp;    /* For apop, if supported.  */
71     unsigned timeout;   /* Default is 10 minutes.  */
72 
73     enum mu_pop3_state state;  /* Indicate the state of the running
74 				  command.  */
75     mu_list_t capa;            /* Capabilities. */
76     mu_stream_t carrier;       /* TCP Connection. */
77   };
78 
79 #define MU_POP3_FSET(p,f) ((p)->flags |= (f))
80 #define MU_POP3_FISSET(p,f) ((p)->flags & (f))
81 #define MU_POP3_FCLR(p,f) ((p)->flags &= ~(f))
82 
83 extern int  mu_pop3_iterator_create (mu_pop3_t pop3, mu_iterator_t *piterator);
84 extern int  mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream);
85 extern int  mu_pop3_carrier_is_ready (mu_stream_t carrier, int flag,
86 				      int timeout);
87 
88 int _mu_pop3_xscript_level (mu_pop3_t pop3, int xlev);
89 
90 int _mu_pop3_trace_enable (mu_pop3_t pop3);
91 int _mu_pop3_trace_disable (mu_pop3_t pop3);
92 
93 int _mu_pop3_init (mu_pop3_t pop3);
94 
95 /* Check if status indicates an error.
96    If the error is recoverable just return the status.
97    Otherwise, set the error state and return the status
98  */
99 #define MU_POP3_CHECK_EAGAIN(pop3, status)	\
100   do						\
101     {						\
102       switch (status)				\
103 	{					\
104         case 0:                                 \
105 	  break;				\
106         case EAGAIN:                            \
107         case EINPROGRESS:                       \
108         case EINTR:                             \
109 	  return status;                        \
110         case MU_ERR_REPLY:                      \
111         case MU_ERR_BADREPLY:                   \
112 	  pop3->state = MU_POP3_NO_STATE;	\
113 	  return status;                        \
114         default:                                \
115           pop3->state = MU_POP3_ERROR;		\
116 	  return status;			\
117 	}					\
118     }						\
119   while (0)
120 
121 /* If status indicates an error, return.
122   */
123 #define MU_POP3_CHECK_ERROR(pop3, status)	\
124   do						\
125     {						\
126       if (status != 0)				\
127 	{					\
128           pop3->state = MU_POP3_ERROR;		\
129           return status;			\
130 	}					\
131     }						\
132   while (0)
133 
134 /* Check if we got "+OK".
135    In POP3 protocol and ack of "+OK" means the command was successfull.
136  */
137 #define MU_POP3_CHECK_OK(pop3)					\
138   do								\
139     {								\
140       if (mu_c_strncasecmp (pop3->ackbuf, "+OK", 3) != 0)	\
141 	{							\
142           pop3->state = MU_POP3_NO_STATE;			\
143           return EACCES;					\
144 	}							\
145     }								\
146   while (0)
147 
148 #ifdef __cplusplus
149 }
150 #endif
151 
152 #endif /* _MAILUTILS_SYS_POP3_H */
153