/* $Cambridge: hermes/src/prayer/cmd/cmd_checkpoint.c,v 1.3 2008/09/16 09:59:55 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */

#include "prayer_session.h"

/* Unix Date conversion is ghastly. Stole following from c-client */

static char *current_time(void)
{
    static char current[64];
    time_t tn = time(0);
    struct tm *t = gmtime(&tn);
    int zone = t->tm_hour * 60 + t->tm_min;
    int julian = t->tm_yday;
    t = localtime(&tn);         /* get local time now */
    /* minus UTC minutes since midnight */
    zone = t->tm_hour * 60 + t->tm_min - zone;
    /* julian can be one of:
     *  36x  local time is December 31, UTC is January 1, offset -24 hours
     *    1  local time is 1 day ahead of UTC, offset +24 hours
     *    0  local time is same day as UTC, no offset
     *   -1  local time is 1 day behind UTC, offset -24 hours
     * -36x  local time is January 1, UTC is December 31, offset +24 hours
     */
    if ((julian = t->tm_yday - julian) != 0)
        zone += ((julian < 0) == (abs(julian) == 1)) ? -24 * 60 : 24 * 60;
    /* output the time */

    sprintf(current, "%02d:%02d:%02d %+03d%02d",
            t->tm_hour, t->tm_min, t->tm_sec, zone / 60, abs(zone) % 60);

    return (current);
}

void cmd_checkpoint(struct session *session)
{
    struct request *request = session->request;
    MAILSTREAM *stream = session->stream;
    struct msgmap *zm = session->zm;
    unsigned long count = zm->nmsgs;
    time_t last, now;

    if (stream == session->inbox_stream)
        last = session->inbox_last_ping_time;
    else if (stream == session->draft_stream)
        last = session->draft_last_ping_time;
    else
        last = session->other_last_ping_time;

    now = time(NIL);

    if ((last > 0) && (now > last) && ((now - last) < 5)) {
        /* Prevent denial of service attack */
        session_message(session, "No new mail at %s", current_time());
        session_redirect(session, request, "list");
        return;
    }

    if (!ml_check(session, stream)) {
        session_redirect(session, request, "restart");
        return;
    }
    msgmap_update(session->zm);

    if (stream == session->inbox_stream)
        session->inbox_last_ping_time = now;
    else if (stream == session->draft_stream)
        session->draft_last_ping_time = now;
    else
        session->other_last_ping_time = now;

    if (zm->nmsgs > count) {
        session->current = zm->nmsgs;
        session_message(session, "New mail has arrived at %s",
                        current_time());
        session_redirect(session, request, "list");
    } else {
        session_message(session, "No new mail at %s", current_time());
        session_redirect(session, request, "list");
    }
}
