Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/cmd-append.c @ 296:d66aa1f1fb2d HEAD
Added fast-flag for mailbox opening, which doesn't do any index compressing
or cache updating. This flag is set when mailbox is opened by APPEND, COPY
or STATUS (ie. not SELECT/EXAMINE).
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 23 Sep 2002 13:42:20 +0300 |
parents | 06d6eca0a45f |
children | 20769b7516a2 |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "common.h" | |
117 | 4 #include "ioloop.h" |
0 | 5 #include "commands.h" |
6 #include "imap-parser.h" | |
119
2f67de235489
Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
117
diff
changeset
|
7 #include "imap-date.h" |
0 | 8 |
9 /* Returns -1 = error, 0 = need more data, 1 = successful. flags and | |
10 internal_date may be NULL as a result, but mailbox and msg_size are always | |
11 set when successful. */ | |
12 static int validate_args(Client *client, const char **mailbox, | |
13 ImapArgList **flags, const char **internal_date, | |
184 | 14 uoff_t *msg_size, unsigned int count) |
0 | 15 { |
16 ImapArg *args; | |
17 | |
18 i_assert(count >= 2 && count <= 4); | |
19 | |
20 *flags = NULL; | |
21 *internal_date = NULL; | |
22 | |
117 | 23 if (!client_read_args(client, count, IMAP_PARSE_FLAG_LITERAL_SIZE, |
24 &args)) | |
25 return 0; | |
0 | 26 |
27 switch (count) { | |
28 case 2: | |
29 /* do we have flags or internal date parameter? */ | |
30 if (args[1].type == IMAP_ARG_LIST || | |
31 args[1].type == IMAP_ARG_STRING) | |
32 return validate_args(client, mailbox, flags, | |
33 internal_date, msg_size, 3); | |
34 | |
35 break; | |
36 case 3: | |
37 /* do we have both flags and internal date? */ | |
38 if (args[1].type == IMAP_ARG_LIST && | |
39 args[2].type == IMAP_ARG_STRING) | |
40 return validate_args(client, mailbox, flags, | |
41 internal_date, msg_size, 4); | |
42 | |
43 if (args[1].type == IMAP_ARG_LIST) | |
44 *flags = args[1].data.list; | |
45 else if (args[1].type == IMAP_ARG_STRING) | |
46 *internal_date = args[1].data.str; | |
47 else | |
48 return -1; | |
49 break; | |
50 case 4: | |
51 /* we have all parameters */ | |
52 *flags = args[1].data.list; | |
53 *internal_date = args[2].data.str; | |
54 break; | |
55 default: | |
56 i_assert(0); | |
57 } | |
58 | |
59 /* check that mailbox and message arguments are ok */ | |
60 *mailbox = imap_arg_string(&args[0]); | |
61 if (*mailbox == NULL) | |
62 return -1; | |
63 | |
117 | 64 if (args[count-1].type != IMAP_ARG_LITERAL_SIZE) |
0 | 65 return -1; |
66 | |
117 | 67 *msg_size = args[count-1].data.literal_size; |
0 | 68 return 1; |
69 } | |
70 | |
71 int cmd_append(Client *client) | |
72 { | |
73 ImapArgList *flags_list; | |
74 Mailbox *box; | |
75 MailFlags flags; | |
76 time_t internal_date; | |
77 const char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT]; | |
78 const char *mailbox, *internal_date_str; | |
184 | 79 uoff_t msg_size; |
0 | 80 int failed; |
81 | |
82 /* <mailbox> [<flags>] [<internal date>] <message literal> */ | |
83 switch (validate_args(client, &mailbox, &flags_list, | |
84 &internal_date_str, &msg_size, 2)) { | |
85 case -1: | |
86 /* error */ | |
87 client_send_command_error(client, "Invalid APPEND arguments."); | |
88 return TRUE; | |
89 case 0: | |
90 /* need more data */ | |
91 return FALSE; | |
92 default: | |
93 } | |
94 | |
95 if (!client_parse_mail_flags(client, flags_list, &flags, custom_flags)) | |
96 return TRUE; | |
97 | |
117 | 98 if (internal_date_str == NULL) { |
99 /* no time given, default to now. */ | |
100 internal_date = ioloop_time; | |
119
2f67de235489
Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
117
diff
changeset
|
101 } else if (!imap_parse_datetime(internal_date_str, &internal_date)) { |
0 | 102 client_send_tagline(client, "BAD Invalid internal date."); |
103 return TRUE; | |
104 } | |
105 | |
106 if (client->mailbox != NULL && | |
107 strcmp(client->mailbox->name, mailbox) == 0) { | |
108 /* this mailbox is selected */ | |
109 box = client->mailbox; | |
110 } else { | |
111 /* open the mailbox */ | |
112 if (!client_verify_mailbox_name(client, mailbox, TRUE)) | |
113 return TRUE; | |
114 | |
115 box = client->storage->open_mailbox(client->storage, | |
296
d66aa1f1fb2d
Added fast-flag for mailbox opening, which doesn't do any index compressing
Timo Sirainen <tss@iki.fi>
parents:
237
diff
changeset
|
116 mailbox, FALSE, TRUE); |
0 | 117 if (box == NULL) { |
118 client_send_storage_error(client); | |
119 return TRUE; | |
120 } | |
121 } | |
122 | |
123 /* save the mail */ | |
124 failed = !box->save(box, flags, custom_flags, internal_date, | |
125 client->inbuf, msg_size); | |
126 if (box != client->mailbox) | |
127 box->close(box); | |
128 | |
237
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
129 if (failed) { |
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
130 client_send_storage_error(client); |
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
131 } else { |
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
132 client_sync_mailbox(client); |
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
133 client_send_tagline(client, "OK Append completed."); |
06d6eca0a45f
Fixes for no diskspace handling. seems to work now.
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
134 } |
0 | 135 return TRUE; |
136 } |