1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 2010-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 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <mailutils/errno.h>
25 #include <mailutils/assoc.h>
26 #include <mailutils/stream.h>
27 #include <mailutils/imap.h>
28 #include <mailutils/imaputil.h>
29 #include <mailutils/sys/imap.h>
30 
31 int
mu_imap_store_flags(mu_imap_t imap,int uid,mu_msgset_t msgset,int op,int flags)32 mu_imap_store_flags (mu_imap_t imap, int uid, mu_msgset_t msgset,
33 		     int op, int flags)
34 {
35   int status;
36   static char *cmd[] = { "FLAGS", "+FLAGS", "-FLAGS" };
37 
38   if (imap == NULL || (op & MU_IMAP_STORE_OPMASK) >= MU_ARRAY_SIZE (cmd))
39     return EINVAL;
40   if (!imap->io)
41     return MU_ERR_NO_TRANSPORT;
42   if (imap->session_state < MU_IMAP_SESSION_SELECTED)
43     return MU_ERR_SEQ;
44 
45   switch (imap->client_state)
46     {
47     case MU_IMAP_CLIENT_READY:
48       status = _mu_imap_tag_next (imap);
49       MU_IMAP_CHECK_EAGAIN (imap, status);
50       mu_imapio_printf (imap->io, "%s ", imap->tag_str);
51       if (uid)
52 	mu_imapio_printf (imap->io, "UID ");
53       mu_imapio_printf (imap->io, "STORE ");
54       mu_imapio_send_msgset (imap->io, msgset);
55       mu_imapio_printf (imap->io, " %s", cmd[op & MU_IMAP_STORE_OPMASK]);
56       if (op & MU_IMAP_STORE_SILENT)
57 	mu_imapio_printf (imap->io, ".SILENT");
58       mu_imapio_printf (imap->io, " ");
59       mu_imapio_send_flags (imap->io, flags);
60       mu_imapio_printf (imap->io, "\r\n");
61       status = mu_imapio_last_error (imap->io);
62       MU_IMAP_CHECK_ERROR (imap, status);
63       MU_IMAP_FCLR (imap, MU_IMAP_RESP);
64       imap->client_state = MU_IMAP_CLIENT_STORE_RX;
65 
66     case MU_IMAP_CLIENT_STORE_RX:
67       /* FIXME: Handle unsolicited responses */
68       status = _mu_imap_response (imap, NULL, NULL);
69       MU_IMAP_CHECK_EAGAIN (imap, status);
70       switch (imap->response)
71 	{
72 	case MU_IMAP_OK:
73 	  status = 0;
74 	  break;
75 
76 	case MU_IMAP_NO:
77 	  status = MU_ERR_FAILURE;
78 	  break;
79 
80 	case MU_IMAP_BAD:
81 	  status = MU_ERR_BADREPLY;
82 	  break;
83 	}
84       imap->client_state = MU_IMAP_CLIENT_READY;
85       break;
86 
87     default:
88       status = EINPROGRESS;
89     }
90   return status;
91 }
92