Commit 87f5761f 87f5761f9c0289afc5d485cdd270c1749f55f69f by Alain Magloire

Adding more framework for NNTP support.

1 parent ecccf28a
...@@ -35,10 +35,20 @@ libmu_nntp_la_SOURCES = \ ...@@ -35,10 +35,20 @@ libmu_nntp_la_SOURCES = \
35 nntp_disconnect.c \ 35 nntp_disconnect.c \
36 nntp_group.c \ 36 nntp_group.c \
37 nntp_head.c \ 37 nntp_head.c \
38 nntp_help.c \
39 nntp_ihave.c \
38 nntp_last.c \ 40 nntp_last.c \
41 nntp_list_active.c \
42 nntp_list_distribpats.c \
43 nntp_list_distributions.c \
39 nntp_list_extensions.c \ 44 nntp_list_extensions.c \
45 nntp_list_newsgroups.c \
46 nntp_list_times.c \
40 nntp_mode_reader.c \ 47 nntp_mode_reader.c \
48 nntp_newgroups.c \
49 nntp_newnews.c \
41 nntp_next.c \ 50 nntp_next.c \
51 nntp_post.c \
42 nntp_quit.c \ 52 nntp_quit.c \
43 nntp_readline.c \ 53 nntp_readline.c \
44 nntp_response.c \ 54 nntp_response.c \
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #include <string.h>
23 #include <stdlib.h>
23 #include <errno.h> 24 #include <errno.h>
24 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
25 26
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #include <string.h>
23 #include <stdlib.h>
23 #include <errno.h> 24 #include <errno.h>
24 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
25 26
......
...@@ -40,7 +40,7 @@ mu_nntp_connect (mu_nntp_t nntp) ...@@ -40,7 +40,7 @@ mu_nntp_connect (mu_nntp_t nntp)
40 if (nntp->carrier == NULL) 40 if (nntp->carrier == NULL)
41 return EINVAL; 41 return EINVAL;
42 42
43 /* Enter the pop state machine, and boogy: AUTHORISATION State. */ 43 /* Enter the nntp state machine, and boogy */
44 switch (nntp->state) 44 switch (nntp->state)
45 { 45 {
46 default: 46 default:
...@@ -69,9 +69,9 @@ mu_nntp_connect (mu_nntp_t nntp) ...@@ -69,9 +69,9 @@ mu_nntp_connect (mu_nntp_t nntp)
69 MU_NNTP_CHECK_EAGAIN (nntp, status); 69 MU_NNTP_CHECK_EAGAIN (nntp, status);
70 mu_nntp_debug_ack (nntp); 70 mu_nntp_debug_ack (nntp);
71 /* 200 Service available, posting allowed */ 71 /* 200 Service available, posting allowed */
72 /* 2001 Servie available, posting prohibited */ 72 /* 201 Servie available, posting prohibited */
73 code = mu_nntp_response_code(nntp); 73 code = mu_nntp_response_code(nntp);
74 if (code == MU_NNTP_RESP_CODE_POSTING_ALLOWED || code == MU_NNTP_RESP_CODE_POSTING_PROHIBITED) 74 if (code != MU_NNTP_RESP_CODE_POSTING_ALLOWED && code != MU_NNTP_RESP_CODE_POSTING_PROHIBITED)
75 { 75 {
76 stream_close (nntp->carrier); 76 stream_close (nntp->carrier);
77 nntp->state = MU_NNTP_NO_STATE; 77 nntp->state = MU_NNTP_NO_STATE;
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
23 #include <errno.h> 23 #include <errno.h>
24 #include <mailutils/sys/nntp.h> 24 #include <mailutils/sys/nntp.h>
25 25
26 static int
27 mu_nntp_parse_date (mu_nntp_t nntp, int code, unsigned int *year, unsigned int *month, unsigned int *day,
28 unsigned int *hour, unsigned int *min, unsigned int *sec);
29
26 int 30 int
27 mu_nntp_date (mu_nntp_t nntp, unsigned int *year, unsigned int *month, unsigned int *day, 31 mu_nntp_date (mu_nntp_t nntp, unsigned int *year, unsigned int *month, unsigned int *day,
28 unsigned int *hour, unsigned int *min, unsigned int *sec) 32 unsigned int *hour, unsigned int *min, unsigned int *sec)
...@@ -56,7 +60,7 @@ mu_nntp_date (mu_nntp_t nntp, unsigned int *year, unsigned int *month, unsigned ...@@ -56,7 +60,7 @@ mu_nntp_date (mu_nntp_t nntp, unsigned int *year, unsigned int *month, unsigned
56 nntp->state = MU_NNTP_NO_STATE; 60 nntp->state = MU_NNTP_NO_STATE;
57 61
58 /* parse the answer now. */ 62 /* parse the answer now. */
59 status = mu_parse_date(nntp, MU_NNTP_RESP_CODE_SERVER_DATE, year, month, day, hour, min, sec); 63 status = mu_nntp_parse_date(nntp, MU_NNTP_RESP_CODE_SERVER_DATE, year, month, day, hour, min, sec);
60 MU_NNTP_CHECK_ERROR (nntp, status); 64 MU_NNTP_CHECK_ERROR (nntp, status);
61 break; 65 break;
62 66
......
...@@ -42,6 +42,9 @@ mu_nntp_destroy (mu_nntp_t *pnntp) ...@@ -42,6 +42,9 @@ mu_nntp_destroy (mu_nntp_t *pnntp)
42 if (nntp->carrier) 42 if (nntp->carrier)
43 stream_destroy (&nntp->carrier, nntp); 43 stream_destroy (&nntp->carrier, nntp);
44 44
45 /* Any posting residue. */
46 if (nntp->post.buf)
47 free (nntp->post.buf);
45 free (nntp); 48 free (nntp);
46 49
47 *pnntp = NULL; 50 *pnntp = NULL;
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
26 26
27 static int mu_nntp_parse_group(mu_nntp_t nntp, int code, unsigned long *ptotal, unsigned long *plow, unsigned long *phigh, char **name);
28
27 int 29 int
28 mu_nntp_group (mu_nntp_t nntp, const char *group, unsigned long *total, unsigned long *low, unsigned long *high, char **name) 30 mu_nntp_group (mu_nntp_t nntp, const char *group, unsigned long *total, unsigned long *low, unsigned long *high, char **name)
29 { 31 {
...@@ -72,8 +74,7 @@ mu_nntp_group (mu_nntp_t nntp, const char *group, unsigned long *total, unsigned ...@@ -72,8 +74,7 @@ mu_nntp_group (mu_nntp_t nntp, const char *group, unsigned long *total, unsigned
72 return status; 74 return status;
73 } 75 }
74 76
75 77 static int
76 int
77 mu_nntp_parse_group(mu_nntp_t nntp, int code, unsigned long *ptotal, unsigned long *plow, unsigned long *phigh, char **name) 78 mu_nntp_parse_group(mu_nntp_t nntp, int code, unsigned long *ptotal, unsigned long *plow, unsigned long *phigh, char **name)
78 { 79 {
79 unsigned long dummy = 0; 80 unsigned long dummy = 0;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #include <string.h>
23 #include <stdlib.h>
23 #include <errno.h> 24 #include <errno.h>
24 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
25 26
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23 #include <errno.h>
24 #include <mailutils/sys/nntp.h>
25
26 int
27 mu_nntp_help (mu_nntp_t nntp, stream_t *pstream)
28 {
29 int status;
30
31 if (nntp == NULL)
32 return EINVAL;
33
34 if (pstream == NULL)
35 return MU_ERR_OUT_PTR_NULL;
36
37 switch (nntp->state)
38 {
39 case MU_NNTP_NO_STATE:
40 status = mu_nntp_writeline (nntp, "HELP\r\n");
41 MU_NNTP_CHECK_ERROR (nntp, status);
42 mu_nntp_debug_cmd (nntp);
43 nntp->state = MU_NNTP_HELP;
44
45 case MU_NNTP_HELP:
46 status = mu_nntp_send (nntp);
47 MU_NNTP_CHECK_EAGAIN (nntp, status);
48 nntp->acknowledge = 0;
49 nntp->state = MU_NNTP_HELP_ACK;
50
51 case MU_NNTP_HELP_ACK:
52 status = mu_nntp_response (nntp, NULL, 0, NULL);
53 MU_NNTP_CHECK_EAGAIN (nntp, status);
54
55 mu_nntp_debug_ack (nntp);
56 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_HELP_FOLLOW);
57 nntp->state = MU_NNTP_HELP_RX;
58
59 case MU_NNTP_HELP_RX:
60 status = mu_nntp_stream_create (nntp, pstream);
61 MU_NNTP_CHECK_ERROR (nntp, status);
62 break;
63
64 /* They must deal with the error first by reopening. */
65 case MU_NNTP_ERROR:
66 status = ECANCELED;
67 break;
68
69 default:
70 status = EINPROGRESS;
71 }
72
73 return status;
74 }
1
2 /* GNU Mailutils -- a suite of utilities for electronic mail
3 Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <mailutils/sys/nntp.h>
27
28 int
29 mu_nntp_ihave (mu_nntp_t nntp, const char *mid, stream_t stream)
30 {
31 int status;
32 unsigned long dummy = 0;
33 char *buf;
34
35 if (nntp == NULL)
36 return EINVAL;
37
38 switch (nntp->state)
39 {
40 case MU_NNTP_NO_STATE:
41 status = mu_nntp_writeline (nntp, "IHAVE %s\r\n", mid);
42 MU_NNTP_CHECK_ERROR (nntp, status);
43 mu_nntp_debug_cmd (nntp);
44 nntp->state = MU_NNTP_IHAVE;
45
46 case MU_NNTP_IHAVE:
47 status = mu_nntp_send (nntp);
48 MU_NNTP_CHECK_EAGAIN (nntp, status);
49 nntp->acknowledge = 0;
50 nntp->state = MU_NNTP_IHAVE_ACK;
51
52 case MU_NNTP_IHAVE_ACK:
53 status = mu_nntp_response (nntp, NULL, 0, NULL);
54 MU_NNTP_CHECK_EAGAIN (nntp, status);
55 mu_nntp_debug_ack (nntp);
56 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_TRANSFER_ARTICLE);
57 if (nntp->post.buf != NULL)
58 {
59 free (nntp->post.buf);
60 }
61 nntp->post.buf = calloc (1, 256);
62 if (nntp->post.buf == NULL)
63 {
64 MU_NNTP_CHECK_ERROR (nntp, ENOMEM);
65 }
66 nntp->post.len = 256;
67 nntp->post.offset = 0;
68 nntp->post.nread = 0;
69 nntp->post.sent_crlf = 0;
70 nntp->state = MU_NNTP_IHAVE_0;
71
72 ihave_loop:
73 case MU_NNTP_IHAVE_0:
74 status = stream_readline (stream, nntp->post.buf, nntp->post.len, nntp->post.offset, &(nntp->post.nread));
75 MU_NNTP_CHECK_EAGAIN (nntp, status);
76 nntp->post.offset += nntp->post.nread;
77 if (nntp->post.nread > 0)
78 {
79 if (nntp->post.buf[nntp->post.nread - 1] == '\n')
80 {
81 nntp->post.buf[nntp->post.nread - 1] = '\0';
82 if (nntp->post.sent_crlf && nntp->post.buf[0] == '.')
83 {
84 status = mu_nntp_writeline (nntp, ".%s\r\n", nntp->post.buf);
85 }
86 else
87 {
88 status = mu_nntp_writeline (nntp, "%s\r\n", nntp->post.buf);
89 }
90 nntp->post.sent_crlf = 1;
91 }
92 else
93 {
94 if (nntp->post.sent_crlf && nntp->post.buf[0] == '.')
95 {
96 status = mu_nntp_writeline (nntp, ".%s", nntp->post.buf);
97 }
98 else
99 {
100 status = mu_nntp_writeline (nntp, "%s", nntp->post.buf);
101 }
102 nntp->post.sent_crlf = 0;
103 }
104 MU_NNTP_CHECK_ERROR (nntp, status);
105 }
106 nntp->state = MU_NNTP_IHAVE_1;
107
108 case MU_NNTP_IHAVE_1:
109 status = mu_nntp_send (nntp);
110 MU_NNTP_CHECK_EAGAIN (nntp, status);
111 if (nntp->post.nread > 0)
112 {
113 goto ihave_loop;
114 }
115 if (nntp->post.sent_crlf)
116 status = mu_nntp_writeline (nntp, ".\r\n");
117 else
118 status = mu_nntp_writeline (nntp, "\r\n.\r\n");
119 if (nntp->post.buf != NULL)
120 {
121 free (nntp->post.buf);
122 nntp->post.buf = NULL;
123 nntp->post.len = 0;
124 nntp->post.offset = 0;
125 nntp->post.nread = 0;
126 nntp->post.sent_crlf = 0;
127 }
128 MU_NNTP_CHECK_ERROR (nntp, status);
129 nntp->state = MU_NNTP_IHAVE_2;
130
131 case MU_NNTP_POST_2:
132 status = mu_nntp_send (nntp);
133 MU_NNTP_CHECK_EAGAIN (nntp, status);
134 nntp->state = MU_NNTP_IHAVE_3;
135
136 case MU_NNTP_POST_3:
137 status = mu_nntp_response (nntp, NULL, 0, NULL);
138 MU_NNTP_CHECK_EAGAIN (nntp, status);
139 mu_nntp_debug_ack (nntp);
140 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_TRANSFER_OK);
141 nntp->state = MU_NNTP_NO_STATE;
142 break;
143
144 /* They must deal with the error first by reopening. */
145 case MU_NNTP_ERROR:
146 status = ECANCELED;
147 break;
148
149 default:
150 status = EINPROGRESS;
151 }
152
153 return status;
154 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <mailutils/error.h>
28 #include <mailutils/sys/nntp.h>
29
30 /*
31 LIST xxxx command, return a list that contains the result.
32 It is the responsability of the caller to destroy the list(list_destroy).
33 */
34 int
35 mu_nntp_list_distrib_pats (mu_nntp_t nntp, list_t *plist)
36 {
37 int status;
38
39 if (nntp == NULL)
40 return EINVAL;
41 if (plist == NULL)
42 return MU_ERR_OUT_PTR_NULL;
43
44 switch (nntp->state)
45 {
46 case MU_NNTP_NO_STATE:
47 status = mu_nntp_writeline (nntp, "LIST DISTRIB.PATS\r\n");
48 MU_NNTP_CHECK_ERROR (nntp, status);
49 mu_nntp_debug_cmd (nntp);
50 nntp->state = MU_NNTP_LIST_DISTRIB_PATS;
51
52 case MU_NNTP_LIST_DISTRIB_PATS:
53 status = mu_nntp_send (nntp);
54 MU_NNTP_CHECK_EAGAIN (nntp, status);
55 nntp->acknowledge = 0;
56 nntp->state = MU_NNTP_LIST_DISTRIB_PATS_ACK;
57
58 case MU_NNTP_LIST_DISTRIB_PATS_ACK:
59 status = mu_nntp_response (nntp, NULL, 0, NULL);
60 MU_NNTP_CHECK_EAGAIN (nntp, status);
61 mu_nntp_debug_ack (nntp);
62 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_LIST_FOLLOW);
63 status = list_create (plist);
64 MU_NNTP_CHECK_ERROR(nntp, status);
65 list_set_destroy_item(*plist, free);
66 nntp->state = MU_NNTP_LIST_DISTRIB_PATS_RX;
67
68 case MU_NNTP_LIST_DISTRIB_PATS_RX:
69 {
70 /* line are 512 octets maximum according to RFC. */
71 char *distributions;
72 size_t n = 0;
73
74 distributions = malloc (512);
75 if (distributions == NULL)
76 {
77 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
78 We need to destroy the list if error. */
79 nntp->io.ptr = nntp->io.buf;
80 nntp->state = MU_NNTP_ERROR;
81 list_destroy (*plist);
82 return ENOMEM;
83 }
84 while ((status = mu_nntp_readline (nntp, distributions, 512, &n)) == 0 && n > 0)
85 {
86 /* Nuke the trailing newline */
87 if (distributions[n - 1] == '\n')
88 distributions[n - 1] = '\0';
89 /* add to the list. */
90 list_append (*plist, strdup (distributions));
91 n = 0;
92 }
93 free (distributions);
94 MU_NNTP_CHECK_EAGAIN (nntp, status);
95 nntp->state = MU_NNTP_NO_STATE;
96 break;
97 }
98
99 /* They must deal with the error first by reopening. */
100 case MU_NNTP_ERROR:
101 status = ECANCELED;
102 break;
103
104 default:
105 status = EINPROGRESS;
106 }
107
108 return status;
109 }
110
111 int
112 mu_nntp_parse_list_distrib_pats (const char *buffer, unsigned long *weight, char **wildmat, char **distrib)
113 {
114 char *w;
115 char *d;
116 unsigned long dummy;
117
118 if (buffer == NULL || *buffer == '\0')
119 return EINVAL;
120
121 w = calloc(512, 1);
122 if (w == NULL)
123 return ENOMEM;
124
125 d = calloc(512, 1);
126 if (d == NULL)
127 {
128 free (w);
129 return ENOMEM;
130 }
131
132 if (weight == NULL)
133 weight = &dummy;
134
135 sscanf (buffer, "%ld:%511s:%511s", weight, w, d);
136
137 if (wildmat == NULL)
138 free (w);
139 else
140 *wildmat = w;
141
142 if (distrib == NULL)
143 free (d);
144 else
145 *distrib = d;
146 return 0;
147 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <mailutils/error.h>
28 #include <mailutils/sys/nntp.h>
29
30 /*
31 LIST xxxx command, return a list that contains the result.
32 It is the responsability of the caller to destroy the list(list_destroy).
33 */
34 int
35 mu_nntp_list_distributions (mu_nntp_t nntp, const char *wildmat, list_t *plist)
36 {
37 int status;
38
39 if (nntp == NULL)
40 return EINVAL;
41 if (plist == NULL)
42 return MU_ERR_OUT_PTR_NULL;
43
44 switch (nntp->state)
45 {
46 case MU_NNTP_NO_STATE:
47 if (wildmat == NULL || *wildmat == '\0')
48 status = mu_nntp_writeline (nntp, "LIST DISTRIBUTIONS\r\n");
49 else
50 status = mu_nntp_writeline (nntp, "LIST DISTRIBUTIONS %s\r\n", wildmat);
51 MU_NNTP_CHECK_ERROR (nntp, status);
52 mu_nntp_debug_cmd (nntp);
53 nntp->state = MU_NNTP_LIST_DISTRIBUTIONS;
54
55 case MU_NNTP_LIST_DISTRIBUTIONS:
56 status = mu_nntp_send (nntp);
57 MU_NNTP_CHECK_EAGAIN (nntp, status);
58 nntp->acknowledge = 0;
59 nntp->state = MU_NNTP_LIST_DISTRIBUTIONS_ACK;
60
61 case MU_NNTP_LIST_DISTRIBUTIONS_ACK:
62 status = mu_nntp_response (nntp, NULL, 0, NULL);
63 MU_NNTP_CHECK_EAGAIN (nntp, status);
64 mu_nntp_debug_ack (nntp);
65 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_LIST_FOLLOW);
66 status = list_create (plist);
67 MU_NNTP_CHECK_ERROR(nntp, status);
68 list_set_destroy_item(*plist, free);
69 nntp->state = MU_NNTP_LIST_DISTRIBUTIONS_RX;
70
71 case MU_NNTP_LIST_DISTRIBUTIONS_RX:
72 {
73 /* line are 512 octets maximum according to RFC. */
74 char *distributions;
75 size_t n = 0;
76
77 distributions = malloc (512);
78 if (distributions == NULL)
79 {
80 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
81 We need to destroy the list if error. */
82 nntp->io.ptr = nntp->io.buf;
83 nntp->state = MU_NNTP_ERROR;
84 list_destroy (*plist);
85 return ENOMEM;
86 }
87 while ((status = mu_nntp_readline (nntp, distributions, 512, &n)) == 0 && n > 0)
88 {
89 /* Nuke the trailing newline */
90 if (distributions[n - 1] == '\n')
91 distributions[n - 1] = '\0';
92 /* add to the list. */
93 list_append (*plist, strdup (distributions));
94 n = 0;
95 }
96 free (distributions);
97 MU_NNTP_CHECK_EAGAIN (nntp, status);
98 nntp->state = MU_NNTP_NO_STATE;
99 break;
100 }
101
102 /* They must deal with the error first by reopening. */
103 case MU_NNTP_ERROR:
104 status = ECANCELED;
105 break;
106
107 default:
108 status = EINPROGRESS;
109 }
110
111 return status;
112 }
113
114 int
115 mu_nntp_parse_list_distributions (const char *buffer, char **key, char **value)
116 {
117 char *k;
118 char *v;
119
120 if (buffer == NULL || *buffer == '\0')
121 return EINVAL;
122
123 k = calloc(512, 1);
124 if (k == NULL)
125 return ENOMEM;
126
127 v = calloc(512, 1);
128 if (v == NULL)
129 {
130 free (k);
131 return ENOMEM;
132 }
133
134 sscanf (buffer, "%511s %511s", k, v);
135
136 if (key == NULL)
137 free (k);
138 else
139 *key = k;
140
141 if (value == NULL)
142 free (v);
143 else
144 *value = v;
145 return 0;
146 }
...@@ -59,7 +59,7 @@ mu_nntp_list_extensions (mu_nntp_t nntp, list_t *plist) ...@@ -59,7 +59,7 @@ mu_nntp_list_extensions (mu_nntp_t nntp, list_t *plist)
59 status = mu_nntp_response (nntp, NULL, 0, NULL); 59 status = mu_nntp_response (nntp, NULL, 0, NULL);
60 MU_NNTP_CHECK_EAGAIN (nntp, status); 60 MU_NNTP_CHECK_EAGAIN (nntp, status);
61 mu_nntp_debug_ack (nntp); 61 mu_nntp_debug_ack (nntp);
62 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_LIST_FOLLOW); 62 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_EXTENSIONS_FOLLOW);
63 status = list_create (plist); 63 status = list_create (plist);
64 MU_NNTP_CHECK_ERROR(nntp, status); 64 MU_NNTP_CHECK_ERROR(nntp, status);
65 list_set_destroy_item(*plist, free); 65 list_set_destroy_item(*plist, free);
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <mailutils/error.h>
28 #include <mailutils/sys/nntp.h>
29
30 /*
31 LIST NEWSGROUPS command, return a list that contains the result.
32 It is the responsability of the caller to destroy the list(list_destroy).
33 */
34 int
35 mu_nntp_list_newsgroups (mu_nntp_t nntp, const char *wildmat, list_t *plist)
36 {
37 int status;
38
39 if (nntp == NULL)
40 return EINVAL;
41 if (plist == NULL)
42 return MU_ERR_OUT_PTR_NULL;
43
44 switch (nntp->state)
45 {
46 case MU_NNTP_NO_STATE:
47 if (wildmat == NULL || *wildmat == '\0')
48 status = mu_nntp_writeline (nntp, "LIST NEWSGROUPS\r\n");
49 else
50 status = mu_nntp_writeline (nntp, "LIST NEWSGROUPS %s\r\n", wildmat);
51 MU_NNTP_CHECK_ERROR (nntp, status);
52 mu_nntp_debug_cmd (nntp);
53 nntp->state = MU_NNTP_LIST_NEWSGROUPS;
54
55 case MU_NNTP_LIST_NEWSGROUPS:
56 status = mu_nntp_send (nntp);
57 MU_NNTP_CHECK_EAGAIN (nntp, status);
58 nntp->acknowledge = 0;
59 nntp->state = MU_NNTP_LIST_NEWSGROUPS_ACK;
60
61 case MU_NNTP_LIST_NEWSGROUPS_ACK:
62 status = mu_nntp_response (nntp, NULL, 0, NULL);
63 MU_NNTP_CHECK_EAGAIN (nntp, status);
64 mu_nntp_debug_ack (nntp);
65 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_LIST_FOLLOW);
66 status = list_create (plist);
67 MU_NNTP_CHECK_ERROR(nntp, status);
68 list_set_destroy_item(*plist, free);
69 nntp->state = MU_NNTP_LIST_NEWSGROUPS_RX;
70
71 case MU_NNTP_LIST_NEWSGROUPS_RX:
72 {
73 /* line are 512 octets maximum according to RFC. */
74 char *newsgroups;
75 size_t n = 0;
76
77 newsgroups = malloc (512);
78 if (newsgroups == NULL)
79 {
80 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
81 We need to destroy the list if error. */
82 nntp->io.ptr = nntp->io.buf;
83 nntp->state = MU_NNTP_ERROR;
84 list_destroy (*plist);
85 return ENOMEM;
86 }
87 while ((status = mu_nntp_readline (nntp, newsgroups, 512, &n)) == 0 && n > 0)
88 {
89 /* Nuke the trailing newline */
90 if (newsgroups[n - 1] == '\n')
91 newsgroups[n - 1] = '\0';
92 /* add to the list. */
93 list_append (*plist, strdup (newsgroups));
94 n = 0;
95 }
96 free (newsgroups);
97 MU_NNTP_CHECK_EAGAIN (nntp, status);
98 nntp->state = MU_NNTP_NO_STATE;
99 break;
100 }
101
102 /* They must deal with the error first by reopening. */
103 case MU_NNTP_ERROR:
104 status = ECANCELED;
105 break;
106
107 default:
108 status = EINPROGRESS;
109 }
110
111 return status;
112 }
113
114 int
115 mu_nntp_parse_list_newsgroups (const char *buffer, char **group, char **description)
116 {
117 char *name;
118 char *desc;
119
120 if (buffer == NULL || *buffer == '\0')
121 return EINVAL;
122
123 name = calloc(512, 1);
124 if (name == NULL)
125 return ENOMEM;
126
127 desc = calloc(512, 1);
128 if (desc == NULL)
129 {
130 free (name);
131 return ENOMEM;
132 }
133
134 sscanf (buffer, "%511s %511s", name, desc);
135
136 if (group == NULL)
137 free (name);
138 else
139 *group = name;
140
141 if (description == NULL)
142 free (desc);
143 else
144 *description = desc;
145 return 0;
146 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <mailutils/error.h>
28 #include <mailutils/sys/nntp.h>
29
30 /*
31 LIST EXTENSIONS command, return a list that contains the result.
32 It is the responsability of the caller to destroy the list(list_destroy).
33 */
34 int
35 mu_nntp_list_active_times (mu_nntp_t nntp, const char *wildmat, list_t *plist)
36 {
37 int status;
38
39 if (nntp == NULL)
40 return EINVAL;
41 if (plist == NULL)
42 return MU_ERR_OUT_PTR_NULL;
43
44 switch (nntp->state)
45 {
46 case MU_NNTP_NO_STATE:
47 if (wildmat == NULL || *wildmat == '\0')
48 status = mu_nntp_writeline (nntp, "LIST ACTIVE.TIMES\r\n");
49 else
50 status = mu_nntp_writeline (nntp, "LIST ACTIVE.TIMES %s\r\n", wildmat);
51 MU_NNTP_CHECK_ERROR (nntp, status);
52 mu_nntp_debug_cmd (nntp);
53 nntp->state = MU_NNTP_LIST_ACTIVE_TIMES;
54
55 case MU_NNTP_LIST_ACTIVE_TIMES:
56 status = mu_nntp_send (nntp);
57 MU_NNTP_CHECK_EAGAIN (nntp, status);
58 nntp->acknowledge = 0;
59 nntp->state = MU_NNTP_LIST_ACTIVE_TIMES_ACK;
60
61 case MU_NNTP_LIST_ACTIVE_TIMES_ACK:
62 status = mu_nntp_response (nntp, NULL, 0, NULL);
63 MU_NNTP_CHECK_EAGAIN (nntp, status);
64 mu_nntp_debug_ack (nntp);
65 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_LIST_FOLLOW);
66 status = list_create (plist);
67 MU_NNTP_CHECK_ERROR(nntp, status);
68 list_set_destroy_item(*plist, free);
69 nntp->state = MU_NNTP_LIST_ACTIVE_TIMES_RX;
70
71 case MU_NNTP_LIST_ACTIVE_TIMES_RX:
72 {
73 /* line are 512 octets maximum according to RFC. */
74 char *active;
75 size_t n = 0;
76
77 active = malloc (512);
78 if (active == NULL)
79 {
80 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
81 We need to destroy the list if error. */
82 nntp->io.ptr = nntp->io.buf;
83 nntp->state = MU_NNTP_ERROR;
84 list_destroy (*plist);
85 return ENOMEM;
86 }
87 while ((status = mu_nntp_readline (nntp, active, 512, &n)) == 0 && n > 0)
88 {
89 /* Nuke the trailing newline */
90 if (active[n - 1] == '\n')
91 active[n - 1] = '\0';
92 /* add to the list. */
93 list_append (*plist, strdup (active));
94 n = 0;
95 }
96 free (active);
97 MU_NNTP_CHECK_EAGAIN (nntp, status);
98 nntp->state = MU_NNTP_NO_STATE;
99 break;
100 }
101
102 /* They must deal with the error first by reopening. */
103 case MU_NNTP_ERROR:
104 status = ECANCELED;
105 break;
106
107 default:
108 status = EINPROGRESS;
109 }
110
111 return status;
112 }
113
114 int
115 mu_nntp_parse_list_active_times (const char *buffer, char **group, unsigned long *time, char **creator)
116 {
117 unsigned long dummy;
118 char *name;
119 char *owner;
120
121 if (buffer == NULL || *buffer == '\0')
122 return EINVAL;
123
124 name = calloc(512, 1);
125 if (name == NULL)
126 return ENOMEM;
127
128 owner = calloc(512, 1);
129 if (owner == NULL)
130 {
131 free (name);
132 return ENOMEM;
133 }
134
135 if (time == NULL)
136 time = &dummy;
137
138 sscanf (buffer, "%511s %ld %511s", name, time, owner);
139
140 if (group == NULL)
141 free (name);
142 else
143 *group = name;
144
145 if (creator == NULL)
146 free (owner);
147 else
148 *creator = owner;
149
150 return 0;
151 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <mailutils/sys/nntp.h>
26
27 int
28 mu_nntp_newgroups (mu_nntp_t nntp, unsigned int year, unsigned int month, unsigned int day,
29 unsigned int hour, unsigned int minute, unsigned int second, int is_gmt, list_t *plist)
30 {
31 int status;
32
33 if (nntp == NULL)
34 return EINVAL;
35
36 switch (nntp->state)
37 {
38 case MU_NNTP_NO_STATE:
39 if (is_gmt > 0)
40 status = mu_nntp_writeline (nntp, "NEWGROUPS %.4d%.2d%.2d %.2d%.2d%.2d GMT\r\n", year, month, day, hour, minute, second);
41 else
42 status = mu_nntp_writeline (nntp, "NEWGROUPS %.4d%.2d%.2d %.2d%.2d%.2d\r\n", year, month, day, hour, minute, second);
43 MU_NNTP_CHECK_ERROR (nntp, status);
44 mu_nntp_debug_cmd (nntp);
45 nntp->state = MU_NNTP_NEWGROUPS;
46
47 case MU_NNTP_NEWGROUPS:
48 status = mu_nntp_send (nntp);
49 MU_NNTP_CHECK_EAGAIN (nntp, status);
50 nntp->acknowledge = 0;
51 nntp->state = MU_NNTP_NEWGROUPS_ACK;
52
53 case MU_NNTP_NEWGROUPS_ACK:
54 status = mu_nntp_response (nntp, NULL, 0, NULL);
55 MU_NNTP_CHECK_EAGAIN (nntp, status);
56 mu_nntp_debug_ack (nntp);
57 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_NEWGROUPS_FOLLOW);
58
59 status = list_create (plist);
60 MU_NNTP_CHECK_ERROR(nntp, status);
61 list_set_destroy_item(*plist, free);
62 nntp->state = MU_NNTP_NEWGROUPS_RX;
63
64 case MU_NNTP_NEWGROUPS_RX:
65 {
66 /* line should not be over 512 octets maximum. */
67 char *lista;
68 size_t n = 0;
69
70 lista = malloc (512);
71 if (lista == NULL)
72 {
73 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
74 Do not use the macro we need to clear the list if errors. */
75 nntp->io.ptr = nntp->io.buf;
76 nntp->state = MU_NNTP_ERROR;
77 list_destroy (plist);
78 return ENOMEM;
79 }
80
81 while ((status = mu_nntp_readline (nntp, lista, 512, &n)) == 0 && n > 0)
82 {
83 /* Nuke the trailing newline */
84 if (lista[n - 1] == '\n')
85 lista[n - 1] = '\0';
86 /* add to the list. */
87 list_append (*plist, strdup (lista));
88 n = 0;
89 }
90 free (lista);
91 MU_NNTP_CHECK_EAGAIN (nntp, status);
92 nntp->state = MU_NNTP_NO_STATE;
93 break;
94 }
95
96 /* They must deal with the error first by reopening. */
97 case MU_NNTP_ERROR:
98 status = ECANCELED;
99 break;
100
101 default:
102 status = EINPROGRESS;
103 }
104
105 return status;
106 }
107
108 int
109 mu_nntp_parse_newgroups (const char *buffer, char **group, unsigned long *high, unsigned long *low, char *status)
110 {
111 return mu_nntp_parse_list_active (buffer, group, high, low, status);
112 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2004 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 2 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 Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <mailutils/sys/nntp.h>
26
27 int
28 mu_nntp_newnews (mu_nntp_t nntp, const char *wildmat, unsigned int year, unsigned int month, unsigned int day,
29 unsigned int hour, unsigned int minute, unsigned int second, int is_gmt, list_t *plist)
30 {
31 int status;
32
33 if (nntp == NULL)
34 return EINVAL;
35
36 switch (nntp->state)
37 {
38 case MU_NNTP_NO_STATE:
39 if (wildmat == NULL || *wildmat == '\0')
40 {
41 if (is_gmt > 0)
42 status = mu_nntp_writeline (nntp, "NEWNEWS %.4d%.2d%.2d %.2d%.2d%.2d GMT\r\n", year, month, day, hour, minute, second);
43 else
44 status = mu_nntp_writeline (nntp, "NEWNEWS %.4d%.2d%.2d %.2d%.2d%.2d\r\n", year, month, day, hour, minute, second);
45 }
46 else
47 {
48 if (is_gmt > 0)
49 {
50 status = mu_nntp_writeline (nntp, "NEWNEWS %s %.4d%.2d%.2d %.2d%.2d%.2d GMT\r\n", wildmat, year, month, day,
51 hour, minute, second);
52 }
53 else
54 {
55 status = mu_nntp_writeline (nntp, "NEWNEWS %s %.4d%.2d%.2d %.2d%.2d%.2d\r\n", wildmat, year, month, day,
56 hour, minute, second);
57 }
58 }
59 MU_NNTP_CHECK_ERROR (nntp, status);
60 mu_nntp_debug_cmd (nntp);
61 nntp->state = MU_NNTP_NEWNEWS;
62
63 case MU_NNTP_NEWNEWS:
64 status = mu_nntp_send (nntp);
65 MU_NNTP_CHECK_EAGAIN (nntp, status);
66 nntp->acknowledge = 0;
67 nntp->state = MU_NNTP_NEWNEWS_ACK;
68
69 case MU_NNTP_NEWNEWS_ACK:
70 status = mu_nntp_response (nntp, NULL, 0, NULL);
71 MU_NNTP_CHECK_EAGAIN (nntp, status);
72 mu_nntp_debug_ack (nntp);
73 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_NEWNEWS_FOLLOW);
74
75 status = list_create (plist);
76 MU_NNTP_CHECK_ERROR(nntp, status);
77 list_set_destroy_item(*plist, free);
78 nntp->state = MU_NNTP_NEWNEWS_RX;
79
80 case MU_NNTP_NEWNEWS_RX:
81 {
82 /* line should not be over 512 octets maximum. */
83 char *lista;
84 size_t n = 0;
85
86 lista = malloc (512);
87 if (lista == NULL)
88 {
89 /* MU_NNTP_CHECK_ERROR(nntp, ENOMEM);
90 Do not use the macro we need to clear the list if errors. */
91 nntp->io.ptr = nntp->io.buf;
92 nntp->state = MU_NNTP_ERROR;
93 list_destroy (plist);
94 return ENOMEM;
95 }
96
97 while ((status = mu_nntp_readline (nntp, lista, 512, &n)) == 0 && n > 0)
98 {
99 /* Nuke the trailing newline */
100 if (lista[n - 1] == '\n')
101 lista[n - 1] = '\0';
102 /* add to the list. */
103 list_append (*plist, strdup (lista));
104 n = 0;
105 }
106 free (lista);
107 MU_NNTP_CHECK_EAGAIN (nntp, status);
108 nntp->state = MU_NNTP_NO_STATE;
109 break;
110 }
111
112 /* They must deal with the error first by reopening. */
113 case MU_NNTP_ERROR:
114 status = ECANCELED;
115 break;
116
117 default:
118 status = EINPROGRESS;
119 }
120
121 return status;
122 }
1
2 /* GNU Mailutils -- a suite of utilities for electronic mail
3 Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <mailutils/sys/nntp.h>
27
28 int
29 mu_nntp_post (mu_nntp_t nntp, stream_t stream)
30 {
31 int status;
32 unsigned long dummy = 0;
33 char *buf;
34
35 if (nntp == NULL)
36 return EINVAL;
37
38 switch (nntp->state)
39 {
40 case MU_NNTP_NO_STATE:
41 status = mu_nntp_writeline (nntp, "POST\r\n");
42 MU_NNTP_CHECK_ERROR (nntp, status);
43 mu_nntp_debug_cmd (nntp);
44 nntp->state = MU_NNTP_POST;
45
46 case MU_NNTP_POST:
47 status = mu_nntp_send (nntp);
48 MU_NNTP_CHECK_EAGAIN (nntp, status);
49 nntp->acknowledge = 0;
50 nntp->state = MU_NNTP_POST_ACK;
51
52 case MU_NNTP_POST_ACK:
53 status = mu_nntp_response (nntp, NULL, 0, NULL);
54 MU_NNTP_CHECK_EAGAIN (nntp, status);
55 mu_nntp_debug_ack (nntp);
56 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_SEND_ARTICLE);
57 if (nntp->post.buf != NULL)
58 {
59 free (nntp->post.buf);
60 }
61 nntp->post.buf = calloc (1, 256);
62 if (nntp->post.buf == NULL)
63 {
64 MU_NNTP_CHECK_ERROR (nntp, ENOMEM);
65 }
66 nntp->post.len = 256;
67 nntp->post.offset = 0;
68 nntp->post.nread = 0;
69 nntp->post.sent_crlf = 0;
70 nntp->state = MU_NNTP_POST_0;
71
72 post_loop:
73 case MU_NNTP_POST_0:
74 status = stream_readline (stream, nntp->post.buf, nntp->post.len, nntp->post.offset, &(nntp->post.nread));
75 MU_NNTP_CHECK_EAGAIN (nntp, status);
76 nntp->post.offset += nntp->post.nread;
77 if (nntp->post.nread > 0)
78 {
79 if (nntp->post.buf[nntp->post.nread - 1] == '\n')
80 {
81 nntp->post.buf[nntp->post.nread - 1] = '\0';
82 if (nntp->post.sent_crlf && nntp->post.buf[0] == '.')
83 {
84 status = mu_nntp_writeline (nntp, ".%s\r\n", nntp->post.buf);
85 }
86 else
87 {
88 status = mu_nntp_writeline (nntp, "%s\r\n", nntp->post.buf);
89 }
90 nntp->post.sent_crlf = 1;
91 }
92 else
93 {
94 if (nntp->post.sent_crlf && nntp->post.buf[0] == '.')
95 {
96 status = mu_nntp_writeline (nntp, ".%s", nntp->post.buf);
97 }
98 else
99 {
100 status = mu_nntp_writeline (nntp, "%s", nntp->post.buf);
101 }
102 nntp->post.sent_crlf = 0;
103 }
104 MU_NNTP_CHECK_ERROR (nntp, status);
105 }
106 nntp->state = MU_NNTP_POST_1;
107
108 case MU_NNTP_POST_1:
109 status = mu_nntp_send (nntp);
110 MU_NNTP_CHECK_EAGAIN (nntp, status);
111 if (nntp->post.nread > 0)
112 {
113 goto post_loop;
114 }
115 if (nntp->post.sent_crlf)
116 status = mu_nntp_writeline (nntp, ".\r\n");
117 else
118 status = mu_nntp_writeline (nntp, "\r\n.\r\n");
119 if (nntp->post.buf != NULL)
120 {
121 free (nntp->post.buf);
122 nntp->post.buf = NULL;
123 nntp->post.len = 0;
124 nntp->post.offset = 0;
125 nntp->post.nread = 0;
126 nntp->post.sent_crlf = 0;
127 }
128 MU_NNTP_CHECK_ERROR (nntp, status);
129 nntp->state = MU_NNTP_POST_2;
130
131 case MU_NNTP_POST_2:
132 status = mu_nntp_send (nntp);
133 MU_NNTP_CHECK_EAGAIN (nntp, status);
134 nntp->state = MU_NNTP_POST_3;
135
136 case MU_NNTP_POST_3:
137 status = mu_nntp_response (nntp, NULL, 0, NULL);
138 MU_NNTP_CHECK_EAGAIN (nntp, status);
139 mu_nntp_debug_ack (nntp);
140 MU_NNTP_CHECK_CODE (nntp, MU_NNTP_RESP_CODE_ARTICLE_RECEIVED);
141 nntp->state = MU_NNTP_NO_STATE;
142 break;
143
144 /* They must deal with the error first by reopening. */
145 case MU_NNTP_ERROR:
146 status = ECANCELED;
147 break;
148
149 default:
150 status = EINPROGRESS;
151 }
152
153 return status;
154 }
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 #endif 20 #endif
21 21
22 #include <string.h> 22 #include <string.h>
23 #include <stdlib.h>
23 #include <errno.h> 24 #include <errno.h>
24 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
25 26
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 #include <stdlib.h> 24 #include <stdlib.h>
25 #include <mailutils/sys/nntp.h> 25 #include <mailutils/sys/nntp.h>
26 26
27 /* Implementation of the stream for TOP and RETR. */ 27 /* Implementation of the stream for HELP, ARTICLE, etc ... */
28 struct mu_nntp_stream 28 struct mu_nntp_stream
29 { 29 {
30 mu_nntp_t nntp; 30 mu_nntp_t nntp;
......