Commit 38ff814b authored by Srinivasa Ragavan's avatar Srinivasa Ragavan

Adds mobile support to camel. Fetch limited mails on pop/imapx.

parent 769e47bd
......@@ -1855,6 +1855,22 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s,
return ret == 0 ? 0 : -1;
}
/**
* camel_folder_summary_sort_uids
*
* Sort the summary UIDS as per the folder requirements. This is mostly for backends use.
* They client would hardly have a need to call this function.
**/
void
camel_folder_summary_sort_uids (CamelFolderSummary *s)
{
struct _CamelFolderSummaryPrivate *p = CAMEL_FOLDER_SUMMARY_GET_PRIVATE(s);
camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
camel_folder_sort_uids (s->folder, s->uids);
camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
}
static void
mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, gint ncol, gchar ** cols, gchar ** name)
{
......
......@@ -362,6 +362,9 @@ void camel_folder_summary_touch(CamelFolderSummary *summary);
/* add a new raw summary item */
void camel_folder_summary_add (CamelFolderSummary *summary, CamelMessageInfo *info);
/* Sort the uids within the summary to meet the backend's need. */
void camel_folder_summary_sort_uids (CamelFolderSummary *s);
/* Peek from mem only */
CamelMessageInfo * camel_folder_summary_peek_info (CamelFolderSummary *s, const gchar *uid);
......
......@@ -1721,6 +1721,85 @@ camel_folder_has_summary_capability (CamelFolder *folder)
return folder->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY;
}
/**
* camel_folder_fetch_old_messages:
* @folder: a #CamelFolder
* @count: Number of messages to fetch
* @error: return location for a #GError, or %NULL
*
* Fetches more (old) messages if the Folder is operating in mobile mode.
*
* Returns: #gboolean TRUE if there are more messages to fetch, FALSE otherwise.
**/
gboolean
camel_folder_fetch_old_messages (CamelFolder *folder,
int count,
GError **error)
{
CamelFolderClass *class;
gboolean ret;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
class = CAMEL_FOLDER_GET_CLASS (folder);
/* Backends that don't support mobile mode will always have all old messages. So lets return FALSE*/
if (class->fetch_old_messages == NULL)
return FALSE;
camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
ret = class->fetch_old_messages (folder, count, error);
camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
if (ret && camel_debug_start (":folder")) {
printf ("CamelFolder:fetch_old_message ('%s') = %d\n",
camel_folder_get_full_name (folder), ret);
camel_debug_end ();
}
return ret;
}
/**
* camel_folder_purge_old_messages:
* @folder: a #CamelFolder
* @error: return location for a #GError, or %NULL
*
* Purge old messages that are downloaded the oldest to conserve space.
*
* Returns: #gboolean TRUE if messages are purged, FALSE otherwise.
**/
gboolean
camel_folder_purge_old_messages (CamelFolder *folder,
GError **error)
{
CamelFolderClass *class;
gboolean ret;
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);
class = CAMEL_FOLDER_GET_CLASS (folder);
if (class->purge_old_messages == NULL)
return FALSE;
camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
ret = class->purge_old_messages (folder, error);
camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
if (ret && camel_debug_start (":folder")) {
printf ("CamelFolder:purge_old_message ('%s') = %d\n",
camel_folder_get_full_name (folder), ret);
camel_debug_end ();
}
return ret;
}
/* UIDs stuff */
/**
......
......@@ -202,6 +202,11 @@ struct _CamelFolderClass {
GError **error);
void (*search_free) (CamelFolder *folder,
GPtrArray *result);
gboolean (*fetch_old_messages) (CamelFolder *folder,
int count,
GError **error);
gboolean (*purge_old_messages) (CamelFolder *folder,
GError **error);
CamelMessageInfo *
(*get_message_info) (CamelFolder *folder,
const gchar *uid);
......@@ -331,6 +336,11 @@ gint camel_folder_get_deleted_message_count
GPtrArray * camel_folder_get_summary (CamelFolder *folder);
void camel_folder_free_summary (CamelFolder *folder,
GPtrArray *array);
gboolean camel_folder_fetch_old_messages (CamelFolder *folder,
int count,
GError **error);
gboolean camel_folder_purge_old_messages (CamelFolder *folder,
GError **error);
/* uid based access operations */
CamelMimeMessage *
......
......@@ -83,6 +83,25 @@ extern gchar *camel_provider_type_name[CAMEL_NUM_PROVIDER_TYPES];
**/
#define CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER (1 << 9)
/**
* CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES
* Download limited set of emails instead of operating on full cache.
**/
#define CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES (1 << 10)
/**
* CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH
* Support to fetch messages in batch
**/
#define CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH (1 << 11)
/**
* CAMEL_PROVIDER_SUPPORTS_PURGE_OLD_MESSAGES
* Support to remove oldest downloaded messages to conserve space.
**/
#define CAMEL_PROVIDER_SUPPORTS_PURGE_OLD_MESSAGES (1 << 12)
/* Flags for url_flags. "ALLOW" means the config dialog will let the
* user configure it. "NEED" implies "ALLOW" but means the user must
* configure it. Service code can assume that any url part for which
......
......@@ -530,6 +530,46 @@ imapx_search_by_expression (CamelFolder *folder, const gchar *expression, GError
return matches;
}
static gboolean
imapx_fetch_old_messages (CamelFolder *folder, int count, GError **error)
{
CamelStore *parent_store;
CamelIMAPXStore *istore;
CamelIMAPXServer *server;
gboolean ret = FALSE;
parent_store = camel_folder_get_parent_store (folder);
istore = CAMEL_IMAPX_STORE (parent_store);
if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
g_set_error (
error, CAMEL_SERVICE_ERROR,
CAMEL_SERVICE_ERROR_UNAVAILABLE,
_("You must be working online to complete this operation"));
return FALSE;
}
if (!camel_service_connect((CamelService *)istore, error))
return FALSE;
server = camel_imapx_store_get_server(istore, camel_folder_get_full_name (folder), error);
if (server != NULL) {
ret = camel_imapx_server_fetch_old_messages (server, folder, count, error);
camel_imapx_store_op_done (istore, server, camel_folder_get_full_name (folder));
g_object_unref(server);
}
return ret;
}
static gboolean
imapx_purge_old_messages (CamelFolder *folder, GError **error)
{
/* Not implemented now */
return FALSE;
}
static void
camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
{
......@@ -553,6 +593,8 @@ camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
folder_class->append_message = imapx_append_message;
folder_class->transfer_messages_to = imapx_transfer_messages_to;
folder_class->get_filename = imapx_get_filename;
folder_class->fetch_old_messages = imapx_fetch_old_messages;
folder_class->purge_old_messages = imapx_purge_old_messages;
}
static void
......
......@@ -91,7 +91,10 @@ static CamelProvider imapx_provider = {
"mail",
CAMEL_PROVIDER_IS_REMOTE | CAMEL_PROVIDER_IS_SOURCE |
CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL,
CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_SUPPORTS_SSL |
CAMEL_PROVIDER_SUPPORTS_MOBILE_DEVICES |
CAMEL_PROVIDER_SUPPORTS_BATCH_FETCH |
CAMEL_PROVIDER_SUPPORTS_PURGE_OLD_MESSAGES,
CAMEL_URL_NEED_USER | CAMEL_URL_NEED_HOST | CAMEL_URL_ALLOW_AUTH,
......
......@@ -73,6 +73,7 @@
#define BATCH_FETCH_COUNT 500
#define MAX_COMMAND_LEN 1000
#define FIRST_TIME_DOWNLOAD 100
extern gint camel_application_is_exiting;
......@@ -200,6 +201,7 @@ enum {
IMAPX_JOB_CREATE_FOLDER = 1<<11,
IMAPX_JOB_DELETE_FOLDER = 1<<12,
IMAPX_JOB_RENAME_FOLDER = 1<<13,
IMAPX_JOB_FETCH_OLD_MESSAGES = 1 << 14,
};
/* Operations on the store (folder_tree) will have highest priority as we know for sure they are sync
......@@ -265,6 +267,7 @@ struct _CamelIMAPXJob {
/* used for biulding uidset stuff */
gint index;
gint last_index;
gint fetch_old_msg_count;
gboolean update_unseen;
struct _uidset_state uidset;
/* changes during refresh */
......@@ -891,10 +894,10 @@ static gboolean duplicate_fetch_or_refresh(CamelIMAPXServer *is, CamelIMAPXComma
if (!ic->job)
return FALSE;
if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO)))
if (!(ic->job->type & (IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO|IMAPX_JOB_FETCH_OLD_MESSAGES)))
return FALSE;
if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL)) {
if (imapx_match_active_job (is, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_FETCH_OLD_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL)) {
c(printf("Not yet sending duplicate fetch/refresh %s command\n", ic->name));
return TRUE;
}
......@@ -1146,6 +1149,7 @@ imapx_job_matches (CamelFolder *folder, CamelIMAPXJob *job, guint32 type, const
return TRUE;
break;
case IMAPX_JOB_FETCH_NEW_MESSAGES:
case IMAPX_JOB_FETCH_OLD_MESSAGES:
case IMAPX_JOB_REFRESH_INFO:
case IMAPX_JOB_SYNC_CHANGES:
case IMAPX_JOB_EXPUNGE:
......@@ -1417,7 +1421,7 @@ imapx_untagged(CamelIMAPXServer *imap, GError **error)
}
if ((finfo->got & FETCH_FLAGS) && !(finfo->got & FETCH_HEADER)) {
CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_FETCH_OLD_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
/* This is either a refresh_info job, check to see if it is and update
if so, otherwise it must've been an unsolicited response, so update
the summary to match */
......@@ -1486,7 +1490,7 @@ imapx_untagged(CamelIMAPXServer *imap, GError **error)
}
if ((finfo->got & (FETCH_HEADER|FETCH_UID)) == (FETCH_HEADER|FETCH_UID)) {
CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
CamelIMAPXJob *job = imapx_match_active_job (imap, IMAPX_JOB_FETCH_NEW_MESSAGES|IMAPX_JOB_FETCH_OLD_MESSAGES|IMAPX_JOB_REFRESH_INFO, NULL);
/* This must be a refresh info job as well, but it has asked for
new messages to be added to the index */
......@@ -1524,7 +1528,7 @@ imapx_untagged(CamelIMAPXServer *imap, GError **error)
mid = (min + max)/2;
r = &g_array_index(infos, struct _refresh_info, mid);
if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES)
if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES || job->type == IMAPX_JOB_FETCH_OLD_MESSAGES)
cmp = imapx_refresh_info_uid_cmp (finfo->uid, r->uid, !imap->descending);
else
cmp = imapx_refresh_info_uid_cmp (finfo->uid, r->uid, TRUE);
......@@ -2237,6 +2241,7 @@ imapx_server_fetch_new_messages (CamelIMAPXServer *is,
job->noreply = async;
job->u.refresh_info.changes = camel_folder_change_info_new();
job->u.refresh_info.update_unseen = update_unseen;
job->u.refresh_info.fetch_old_msg_count = -1;
job->op = camel_operation_registered ();
success = imapx_submit_job (is, job, error);
......@@ -3600,6 +3605,8 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
}
if (camel_folder_change_info_changed(job->u.refresh_info.changes)) {
if (is->descending)
camel_folder_summary_sort_uids (ic->job->folder->summary);
imapx_update_store_summary (job->folder);
camel_folder_summary_save_to_db (job->folder->summary, NULL);
camel_folder_changed (job->folder, job->u.refresh_info.changes);
......@@ -3608,6 +3615,7 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
camel_folder_change_info_clear(job->u.refresh_info.changes);
if (i<infos->len) {
int total = camel_folder_summary_count (job->folder->summary);
camel_imapx_command_free (ic);
ic = camel_imapx_command_new(is, "FETCH", job->folder, "UID FETCH ");
......@@ -3616,7 +3624,9 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
ic->pri = job->pri - 1;
job->u.refresh_info.last_index = i;
for (;i<infos->len;i++) {
/* If its mobile client, when total=0 (new account setup) fetch only a limited mails,
* on futher attempts download all new mails. */
for (;i<infos->len && (total || !is->mobile || i< FIRST_TIME_DOWNLOAD);i++) {
gint res;
struct _refresh_info *r = &g_array_index(infos, struct _refresh_info, i);
......@@ -3630,8 +3640,8 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
}
}
}
job->u.refresh_info.index = i;
printf("Existing : %d Gonna fetch in %s for %d/%d\n", total, camel_folder_get_full_name(job->folder), i, infos->len);
job->u.refresh_info.index = infos->len;
if (imapx_uidset_done(&job->u.refresh_info.uidset, ic)) {
camel_imapx_command_add(ic, " (RFC822.SIZE RFC822.HEADER)");
imapx_command_queue(is, ic);
......@@ -3663,7 +3673,7 @@ imapx_command_step_fetch_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
g_free(r->uid);
}
g_array_free(job->u.refresh_info.infos, TRUE);
if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES)
if (job->type == IMAPX_JOB_FETCH_NEW_MESSAGES || job->type == IMAPX_JOB_FETCH_OLD_MESSAGES)
camel_folder_change_info_free (job->u.refresh_info.changes);
imapx_job_done (is, job);
......@@ -3866,13 +3876,14 @@ static void
imapx_job_scan_changes_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
{
CamelIMAPXCommand *ic;
gchar *uid = camel_folder_summary_uid_from_index (job->folder->summary, 0);
camel_operation_start (
job->op, _("Scanning for changed messages in %s"),
camel_folder_get_name (job->folder));
ic = camel_imapx_command_new (is, "FETCH", job->folder,
"UID FETCH 1:* (UID FLAGS)");
"UID FETCH %s:* (UID FLAGS)", uid);
ic->job = job;
ic->complete = imapx_job_scan_changes_done;
ic->pri = job->pri;
......@@ -3899,6 +3910,11 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is, CamelIMAPXCommand *
}
if (camel_folder_change_info_changed(ic->job->u.refresh_info.changes)) {
/* If we fetched old messages, the summary must be sorted internally from
* old to new. Otherwise it appends old uids to the end.
**/
if (ic->job->type == IMAPX_JOB_FETCH_OLD_MESSAGES || is->descending)
camel_folder_summary_sort_uids (ic->job->folder->summary);
imapx_update_store_summary (ic->job->folder);
camel_folder_summary_save_to_db (ic->job->folder->summary, NULL);
camel_folder_changed (ic->job->folder, ic->job->u.refresh_info.changes);
......@@ -3933,8 +3949,8 @@ exception:
}
static void
imapx_command_fetch_new_uids_done (CamelIMAPXServer *is,
CamelIMAPXCommand *ic)
imapx_command_fetch_uids_descending_done (CamelIMAPXServer *is,
CamelIMAPXCommand *ic)
{
CamelIMAPXJob *job = ic->job;
GArray *infos = job->u.refresh_info.infos;
......@@ -3976,7 +3992,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
ic->pri = job->pri;
if (is->descending)
ic->complete = imapx_command_fetch_new_uids_done;
ic->complete = imapx_command_fetch_uids_descending_done;
else
ic->complete = imapx_command_step_fetch_done;
......@@ -3992,6 +4008,44 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
imapx_command_queue (is, ic);
}
static void
imapx_job_fetch_old_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
{
CamelIMAPXCommand *ic;
CamelFolder *folder = job->folder;
CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
guint32 total, diff;
gchar *start_uid = NULL, *end_uid = NULL;
total = camel_folder_summary_count (folder->summary);
diff = ifolder->exists_on_server - total;
if (total > 0) {
unsigned long long uidl;
start_uid = camel_folder_summary_uid_from_index (folder->summary, 0);
uidl = strtoull(start_uid, NULL, 10);
end_uid = g_strdup_printf("%lld", (uidl-job->u.refresh_info.fetch_old_msg_count > 0) ? (uidl-job->u.refresh_info.fetch_old_msg_count) : 1);
} else {
/* */
g_error("Shouldn't call fetch old messages without anything. ");
}
camel_operation_start (
job->op, _("Fetching summary information for old messages in %s"),
camel_folder_get_name (folder));
ic = camel_imapx_command_new (is, "FETCH", job->folder,
"UID FETCH %s:%s (RFC822.SIZE RFC822.HEADER FLAGS)", start_uid, end_uid);
ic->pri = job->pri;
ic->complete = imapx_command_fetch_new_messages_done;
g_free (start_uid);
g_free (end_uid);
ic->job = job;
imapx_command_queue (is, ic);
}
static void
imapx_job_refresh_info_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
{
......@@ -5002,6 +5056,13 @@ camel_imapx_server_new(CamelStore *store, CamelURL *url)
else
is->descending = FALSE;
if (camel_url_get_param (url, "mobile"))
is->mobile = TRUE;
else
is->mobile = FALSE;
printf("Enabled for Mobile devices? :%d Descending? :%d\n", is->mobile, is->descending);
return is;
}
......@@ -5357,6 +5418,32 @@ camel_imapx_server_refresh_info (CamelIMAPXServer *is, CamelFolder *folder, GErr
return success;
}
gboolean
camel_imapx_server_fetch_old_messages (CamelIMAPXServer *is,
CamelFolder *folder,
int count,
GError **error)
{
CamelIMAPXJob *job;
gboolean success;
job = g_malloc0(sizeof(*job));
job->type = IMAPX_JOB_FETCH_OLD_MESSAGES;
job->start = imapx_job_fetch_old_messages_start;
job->folder = folder;
job->noreply = FALSE;
job->u.refresh_info.changes = camel_folder_change_info_new();
job->u.refresh_info.update_unseen = TRUE;
job->u.refresh_info.fetch_old_msg_count = count;
job->op = camel_operation_registered ();
success = imapx_submit_job (is, job, error);
g_free (job);
return success;
}
static void
imapx_sync_free_user(GArray *user_set)
{
......
......@@ -121,6 +121,7 @@ struct _CamelIMAPXServer {
/* order in which new messages would be fetched */
gboolean descending;
gboolean mobile;
/* used to synchronize duplicate get_message requests */
GCond *fetch_cond;
......@@ -155,6 +156,11 @@ GPtrArray * camel_imapx_server_list (CamelIMAPXServer *is,
gboolean camel_imapx_server_refresh_info (CamelIMAPXServer *is,
CamelFolder *folder,
GError **error);
gboolean camel_imapx_server_fetch_old_messages
(CamelIMAPXServer *is,
CamelFolder *folder,
int count,
GError **error);
gboolean camel_imapx_server_sync_changes (CamelIMAPXServer *is,
CamelFolder *folder,
GError **error);
......
......@@ -36,7 +36,8 @@
#include "camel-pop3-folder.h"
#include "camel-pop3-store.h"
#define d(x)
#define d(x) if (camel_debug("pop")) x;
#define FIRST_TIME_DOWNLOAD 40
static gboolean pop3_refresh_info (CamelFolder *folder, GError **error);
static gboolean pop3_sync (CamelFolder *folder, gboolean expunge, GError **error);
......@@ -45,6 +46,7 @@ static GPtrArray *pop3_get_uids (CamelFolder *folder);
static CamelMimeMessage *pop3_get_message (CamelFolder *folder, const gchar *uid, GError **error);
static gboolean pop3_set_message_flags (CamelFolder *folder, const gchar *uid, guint32 flags, guint32 set);
static gchar * pop3_get_filename (CamelFolder *folder, const gchar *uid, GError **error);
static gboolean pop3_fetch_old_messages (CamelFolder *folder, int count, GError **error);
G_DEFINE_TYPE (CamelPOP3Folder, camel_pop3_folder, CAMEL_TYPE_FOLDER)
......@@ -99,6 +101,7 @@ camel_pop3_folder_class_init (CamelPOP3FolderClass *class)
folder_class->free_uids = camel_folder_free_shallow;
folder_class->get_filename = pop3_get_filename;
folder_class->get_message = pop3_get_message;
folder_class->fetch_old_messages = pop3_fetch_old_messages;
folder_class->set_message_flags = pop3_set_message_flags;
}
......@@ -111,6 +114,9 @@ CamelFolder *
camel_pop3_folder_new (CamelStore *parent, GError **error)
{
CamelFolder *folder;
CamelURL *url;
CamelPOP3Folder *pop3_folder;
CamelService *service;
d(printf("opening pop3 INBOX folder\n"));
......@@ -119,6 +125,30 @@ camel_pop3_folder_new (CamelStore *parent, GError **error)
"full-name", "inbox", "name", "inbox",
"parent-store", parent, NULL);
pop3_folder = (CamelPOP3Folder *)folder;
service = (CamelService *) parent;
/* This decides if the POP3 downloads entire content or a limited content. */
url = service->url;
if (camel_url_get_param(url, "mobile"))
pop3_folder->mobile = TRUE;
else
pop3_folder->mobile = FALSE;
pop3_folder->fetch_more = 0;
if (pop3_folder->mobile) {
/* Setup Keyfile */
char *path, *root;
pop3_folder->key_file = g_key_file_new();
root = camel_session_get_storage_path (camel_service_get_session(service), service, NULL);
path = g_build_filename (root, "uidconfig", NULL);
g_key_file_load_from_file (pop3_folder->key_file, path, G_KEY_FILE_NONE, NULL);
g_free (path);
g_free(root);
}
/* mt-ok, since we dont have the folder-lock for new() */
if (!camel_folder_refresh_info (folder, error)) { /* mt-ok */
g_object_unref (folder);
......@@ -184,9 +214,14 @@ cmd_list(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
CamelStore *parent_store;
CamelPOP3Store *pop3_store;
CamelPOP3FolderInfo *fi;
int i=0, total, last_uid=-1;
CamelPOP3Folder *pop3_folder;
CamelService *service;
parent_store = camel_folder_get_parent_store (folder);
pop3_store = CAMEL_POP3_STORE (parent_store);
pop3_folder = (CamelPOP3Folder *)folder;
service = (CamelService *) parent_store;
do {
ret = camel_pop3_stream_line(stream, &line, &len);
......@@ -198,12 +233,94 @@ cmd_list(CamelPOP3Engine *pe, CamelPOP3Stream *stream, gpointer data)
fi->index = ((CamelPOP3Folder *)folder)->uids->len;
if ((pop3_store->engine->capa & CAMEL_POP3_CAP_UIDL) == 0)
fi->cmd = camel_pop3_engine_command_new(pe, CAMEL_POP3_COMMAND_MULTI, cmd_builduid, fi, "TOP %u 0\r\n", id);
g_ptr_array_add(((CamelPOP3Folder *)folder)->uids, fi);
g_hash_table_insert(((CamelPOP3Folder *)folder)->uids_id, GINT_TO_POINTER(id), fi);
g_ptr_array_add(pop3_folder->uids, fi);
g_hash_table_insert(pop3_folder->uids_id, GINT_TO_POINTER(id), fi);
}
}
} while (ret>0);
}
/* Trim the list for mobile devices*/
if (pop3_folder->mobile) {
gboolean save_uid = FALSE;
d(printf("*********** Mobile mode *************\n"));
d(printf("Total Count: %s: %d\n", service->url->host, pop3_folder->uids->len));
/* Preserve the first message's ID */
fi = pop3_folder->uids->pdata[0];
pop3_folder->first_id = fi->id;
total = pop3_folder->uids->len;
if (pop3_folder->key_file) {
last_uid = g_key_file_get_integer (pop3_folder->key_file, "UIDConfig", "last-saved-uid", NULL);
if (!last_uid) {
/* First time downloading the POP folder, lets just download only a batch. */
last_uid = -1;
}
d(printf("Last stored' first uid: %d\n", last_uid));
}