Changeset 5494:53d9210aa4ee
Legend:
- Unmodified
- Added
- Removed
-
imap/command.c
r5405 r5494 2 2 * Copyright (C) 1996-8 Michael R. Elkins <me@mutt.org> 3 3 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 4 * Copyright (C) 1999-200 6Brendan Cully <brendan@kublai.com>4 * Copyright (C) 1999-2008 Brendan Cully <brendan@kublai.com> 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify … … 38 38 39 39 /* forward declarations */ 40 static int cmd_start (IMAP_DATA* idata, const char* cmdstr, int flags); 41 static int cmd_queue_full (IMAP_DATA* idata); 42 static int cmd_queue (IMAP_DATA* idata, const char* cmdstr); 40 43 static IMAP_COMMAND* cmd_new (IMAP_DATA* idata); 41 44 static int cmd_status (const char *s); … … 68 71 }; 69 72 70 /* imap_cmd_queue: Add command to command queue. Fails if the queue is full. */71 int imap_cmd_queue (IMAP_DATA* idata, const char* cmdstr)72 {73 IMAP_COMMAND* cmd;74 75 if (idata->status == IMAP_FATAL)76 {77 cmd_handle_fatal (idata);78 return IMAP_CMD_BAD;79 }80 81 if (!(cmd = cmd_new (idata)))82 return IMAP_CMD_BAD;83 84 if (mutt_buffer_printf (idata->cmdbuf, "%s%s %s\r\n",85 idata->state == IMAP_IDLE ? "DONE\r\n" : "", cmd->seq, cmdstr) < 0)86 return IMAP_CMD_BAD;87 88 if (idata->state == IMAP_IDLE)89 idata->state = IMAP_SELECTED;90 91 return 0;92 }93 94 73 /* imap_cmd_start: Given an IMAP command, send it to the server. 95 74 * If cmdstr is NULL, sends queued commands. */ 96 75 int imap_cmd_start (IMAP_DATA* idata, const char* cmdstr) 97 76 { 98 int rc; 99 100 if (cmdstr && (rc = imap_cmd_queue (idata, cmdstr)) < 0) 101 return rc; 102 103 /* don't write old or empty commands */ 104 if (idata->cmdbuf->dptr == idata->cmdbuf->data) 105 return IMAP_CMD_BAD; 106 107 rc = mutt_socket_write (idata->conn, idata->cmdbuf->data); 108 idata->cmdbuf->dptr = idata->cmdbuf->data; 109 110 return (rc < 0) ? IMAP_CMD_BAD : 0; 77 return cmd_start (idata, cmdstr, 0); 111 78 } 112 79 … … 236 203 int rc; 237 204 238 if (idata->status == IMAP_FATAL) 205 if ((rc = cmd_start (idata, cmdstr, flags)) < 0) 206 return rc; 207 208 if (rc < 0) 239 209 { 240 210 cmd_handle_fatal (idata); … … 242 212 } 243 213 244 if (cmdstr && (rc = imap_cmd_queue (idata, cmdstr)) < 0) 245 return rc; 246 247 /* don't write old or empty commands */ 248 if (idata->cmdbuf->dptr == idata->cmdbuf->data) 249 return IMAP_CMD_BAD; 250 251 rc = mutt_socket_write_d (idata->conn, idata->cmdbuf->data, -1, 252 flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD); 253 idata->cmdbuf->dptr = idata->cmdbuf->data; 254 255 if (rc < 0) 256 { 257 cmd_handle_fatal (idata); 258 return -1; 259 } 214 if (flags & IMAP_CMD_QUEUE) 215 return 0; 260 216 261 217 do … … 324 280 } 325 281 282 /* imap_cmd_idle: Enter the IDLE state. */ 283 int imap_cmd_idle (IMAP_DATA* idata) 284 { 285 int rc; 286 287 imap_cmd_start (idata, "IDLE"); 288 do 289 rc = imap_cmd_step (idata); 290 while (rc == IMAP_CMD_CONTINUE); 291 292 if (rc == IMAP_CMD_RESPOND) 293 { 294 /* successfully entered IDLE state */ 295 idata->state = IMAP_IDLE; 296 /* queue automatic exit when next command is issued */ 297 mutt_buffer_printf (idata->cmdbuf, "DONE\r\n"); 298 rc = IMAP_CMD_OK; 299 } 300 if (rc != IMAP_CMD_OK) 301 { 302 dprint (1, (debugfile, "imap_cmd_idle: error starting IDLE\n")); 303 return -1; 304 } 305 306 return 0; 307 } 308 309 static int cmd_queue_full (IMAP_DATA* idata) 310 { 311 if ((idata->nextcmd + 1) % IMAP_PIPELINE_DEPTH == idata->lastcmd) 312 return 1; 313 314 return 0; 315 } 316 326 317 /* sets up a new command control block and adds it to the queue. 327 318 * Returns NULL if the pipeline is full. */ … … 330 321 IMAP_COMMAND* cmd; 331 322 332 if ( (idata->nextcmd + 1) % IMAP_PIPELINE_DEPTH == idata->lastcmd)333 { 334 dprint ( 2, (debugfile, "cmd_new: IMAP command queue full\n"));323 if (cmd_queue_full (idata)) 324 { 325 dprint (3, (debugfile, "cmd_new: IMAP command queue full\n")); 335 326 return NULL; 336 327 } … … 346 337 347 338 return cmd; 339 } 340 341 /* queues command. If the queue is full, attempts to drain it. */ 342 static int cmd_queue (IMAP_DATA* idata, const char* cmdstr) 343 { 344 IMAP_COMMAND* cmd; 345 int rc; 346 347 if (cmd_queue_full (idata)) 348 { 349 dprint (3, (debugfile, "Draining IMAP command pipeline\n")); 350 351 rc = imap_exec (idata, NULL, IMAP_CMD_FAIL_OK); 352 353 if (rc < 0 && rc != -2) 354 return rc; 355 } 356 357 if (!(cmd = cmd_new (idata))) 358 return IMAP_CMD_BAD; 359 360 if (mutt_buffer_printf (idata->cmdbuf, "%s %s\r\n", cmd->seq, cmdstr) < 0) 361 return IMAP_CMD_BAD; 362 363 return 0; 364 } 365 366 static int cmd_start (IMAP_DATA* idata, const char* cmdstr, int flags) 367 { 368 int rc; 369 370 if (idata->status == IMAP_FATAL) 371 { 372 cmd_handle_fatal (idata); 373 return -1; 374 } 375 376 if (cmdstr && ((rc = cmd_queue (idata, cmdstr)) < 0)) 377 return rc; 378 379 if (flags & IMAP_CMD_QUEUE) 380 return 0; 381 382 if (idata->cmdbuf->dptr == idata->cmdbuf->data) 383 return IMAP_CMD_BAD; 384 385 rc = mutt_socket_write_d (idata->conn, idata->cmdbuf->data, -1, 386 flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD); 387 idata->cmdbuf->dptr = idata->cmdbuf->data; 388 389 /* unidle when command queue is flushed */ 390 if (idata->state == IMAP_IDLE) 391 idata->state = IMAP_SELECTED; 392 393 return (rc < 0) ? IMAP_CMD_BAD : 0; 348 394 } 349 395 -
imap/imap.c
r5443 r5494 2 2 * Copyright (C) 1996-8 Michael R. Elkins <me@mutt.org> 3 3 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 4 * Copyright (C) 1999-200 7Brendan Cully <brendan@kublai.com>4 * Copyright (C) 1999-2008 Brendan Cully <brendan@kublai.com> 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify … … 348 348 } 349 349 if (!conn) 350 return NULL; /* this happens when the initial connection fails */350 return NULL; /* this happens when the initial connection fails */ 351 351 352 352 if (!idata) … … 384 384 { 385 385 /* capabilities may have changed */ 386 imap_ cmd_queue (idata, "CAPABILITY");386 imap_exec (idata, "CAPABILITY", IMAP_CMD_QUEUE); 387 387 /* get root delimiter, '/' as default */ 388 388 idata->delim = '/'; 389 imap_ cmd_queue (idata, "LIST \"\" \"\"");389 imap_exec (idata, "LIST \"\" \"\"", IMAP_CMD_QUEUE); 390 390 if (option (OPTIMAPCHECKSUBSCRIBED)) 391 imap_ cmd_queue (idata, "LSUB \"\" \"*\"");391 imap_exec (idata, "LSUB \"\" \"*\"", IMAP_CMD_QUEUE); 392 392 /* we may need the root delimiter before we open a mailbox */ 393 393 imap_exec (idata, NULL, IMAP_CMD_FAIL_OK); … … 599 599 { 600 600 snprintf (bufout, sizeof (bufout), "MYRIGHTS %s", buf); 601 imap_ cmd_queue (idata, bufout);601 imap_exec (idata, bufout, IMAP_CMD_QUEUE); 602 602 } 603 603 /* assume we have all rights if ACL is unavailable */ … … 1073 1073 rc++; 1074 1074 mutt_buffer_printf (buf, " +FLAGS.SILENT (%s)", name); 1075 imap_ cmd_queue (idata, buf->data);1075 imap_exec (idata, buf->data, IMAP_CMD_QUEUE); 1076 1076 } 1077 1077 buf->dptr = buf->data; … … 1081 1081 rc++; 1082 1082 mutt_buffer_printf (buf, " -FLAGS.SILENT (%s)", name); 1083 imap_ cmd_queue (idata, buf->data);1083 imap_exec (idata, buf->data, IMAP_CMD_QUEUE); 1084 1084 } 1085 1085 … … 1259 1259 if (expunge && ctx->closing) 1260 1260 { 1261 imap_ cmd_queue (idata, "CLOSE");1261 imap_exec (idata, "CLOSE", IMAP_CMD_QUEUE); 1262 1262 idata->state = IMAP_AUTHENTICATED; 1263 1263 } … … 1297 1297 * and the mailbox is unchanged, so we may have to close here */ 1298 1298 if (!ctx->deleted) 1299 imap_ cmd_queue (idata, "CLOSE");1299 imap_exec (idata, "CLOSE", IMAP_CMD_QUEUE); 1300 1300 if (idata->state == IMAP_IDLE) 1301 1301 { … … 1353 1353 && (idata->state != IMAP_IDLE || time(NULL) >= idata->lastread + ImapKeepalive)) 1354 1354 { 1355 imap_cmd_start (idata, "IDLE"); 1356 idata->state = IMAP_IDLE; 1357 do 1358 result = imap_cmd_step (idata); 1359 while (result == IMAP_CMD_CONTINUE); 1360 /* it's possible that we were notified and fetched mail before 1361 * getting to the +, in which case we've automatically unidled. */ 1362 if (result != IMAP_CMD_RESPOND && result != IMAP_CMD_OK) 1363 { 1364 dprint (1, (debugfile, "Error starting IDLE\n")); 1365 idata->state = IMAP_SELECTED; 1355 if (imap_cmd_idle (idata) < 0) 1366 1356 return -1; 1367 }1368 1357 } 1369 1358 if (idata->state == IMAP_IDLE) … … 1487 1476 "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged); 1488 1477 1489 if (imap_cmd_queue (idata, command) < 0) 1490 { 1491 /* pipeline must be full, drain it */ 1492 dprint (2, (debugfile, "IMAP command pipeline full, draining\n")); 1493 1494 if (imap_exec (idata, NULL, IMAP_CMD_FAIL_OK) == -1) 1495 dprint (1, (debugfile, "Error polling mailboxes\n")); 1496 1497 if (imap_cmd_queue (idata, command) < 0) { 1498 /* real trouble */ 1499 dprint (1, (debugfile, "Error queueing command\n")); 1500 return 0; 1501 } 1478 if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0) 1479 { 1480 dprint (1, (debugfile, "Error queueing command\n")); 1481 return 0; 1502 1482 } 1503 1483 } … … 1551 1531 if (queue) 1552 1532 { 1553 imap_ cmd_queue (idata, buf);1533 imap_exec (idata, buf, IMAP_CMD_QUEUE); 1554 1534 queued = 1; 1555 1535 return 0; -
imap/imap_private.h
r5120 r5494 1 1 /* 2 2 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 3 * Copyright (C) 1999-200 5Brendan Cully <brendan@kublai.com>3 * Copyright (C) 1999-2008 Brendan Cully <brendan@kublai.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify … … 70 70 #define IMAP_CMD_FAIL_OK (1<<0) 71 71 #define IMAP_CMD_PASS (1<<1) 72 #define IMAP_CMD_QUEUE (1<<2) 72 73 73 74 enum … … 244 245 245 246 /* command.c */ 246 int imap_cmd_queue (IMAP_DATA* idata, const char* cmdstr);247 247 int imap_cmd_start (IMAP_DATA* idata, const char* cmd); 248 248 int imap_cmd_step (IMAP_DATA* idata); … … 250 250 int imap_code (const char* s); 251 251 int imap_exec (IMAP_DATA* idata, const char* cmd, int flags); 252 int imap_cmd_idle (IMAP_DATA* idata); 252 253 253 254 /* message.c */ -
imap/message.c
r5283 r5494 1 1 /* 2 2 * Copyright (C) 1996-9 Brandon Long <blong@fiction.net> 3 * Copyright (C) 1999-200 7Brendan Cully <brendan@kublai.com>3 * Copyright (C) 1999-2008 Brendan Cully <brendan@kublai.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify … … 144 144 imap_cmd_start (idata, buf); 145 145 146 for (msgno = msgbegin; msgno <= msgend ; msgno++) 146 rc = IMAP_CMD_CONTINUE; 147 for (msgno = msgbegin; rc == IMAP_CMD_CONTINUE; msgno++) 147 148 { 148 149 mutt_progress_update (&progress, msgno + 1, -1);
