int mail_session_update_parse(const char *const *args, const char **error_r) { struct mail_session *session; struct mail_stats stats, diff_stats; const char *error; /* <session guid> [key=value ..] */ if (mail_session_get(args[0], &session, error_r) < 0) return -1; if (mail_stats_parse(args+1, &stats, error_r) < 0) { *error_r = t_strdup_printf("UPDATE-SESSION %s %s: %s", session->user->name, session->service, *error_r); return -1; } if (!mail_stats_diff(&session->stats, &stats, &diff_stats, &error)) { *error_r = t_strdup_printf("UPDATE-SESSION %s %s: stats shrank: %s", session->user->name, session->service, error); return -1; } mail_session_refresh(session, &diff_stats); return 0; }
int mail_session_update_parse(const char *const *args, const char **error_r) { struct mail_session *session; struct stats *new_stats, *diff_stats; buffer_t *buf; const char *error; /* <session id> <stats> */ if (mail_session_get(args[0], &session, error_r) < 0) return -1; buf = buffer_create_dynamic(pool_datastack_create(), 256); if (args[1] == NULL || base64_decode(args[1], strlen(args[1]), NULL, buf) < 0) { *error_r = t_strdup_printf("UPDATE-SESSION %s %s %s: Invalid base64 input", session->user->name, session->service, session->id); return -1; } new_stats = stats_alloc(pool_datastack_create()); diff_stats = stats_alloc(pool_datastack_create()); if (!stats_import(buf->data, buf->used, session->stats, new_stats, &error)) { *error_r = t_strdup_printf("UPDATE-SESSION %s %s %s: %s", session->user->name, session->service, session->id, error); return -1; } if (!stats_diff(session->stats, new_stats, diff_stats, &error)) { *error_r = t_strdup_printf("UPDATE-SESSION %s %s %s: stats shrank: %s", session->user->name, session->service, session->id, error); i_panic("%s", *error_r); return -1; } mail_session_refresh(session, diff_stats); return 0; }
int mail_command_update_parse(const char *const *args, const char **error_r) { struct mail_session *session; struct mail_command *cmd; struct stats *new_stats, *diff_stats; buffer_t *buf; const char *error; unsigned int i, cmd_id; bool done = FALSE, continued = FALSE; /* <session guid> <cmd id> [d] <name> <args> <stats> <session guid> <cmd id> c[d] <stats> */ if (str_array_length(args) < 3) { *error_r = "UPDATE-CMD: Too few parameters"; return -1; } if (mail_session_get(args[0], &session, error_r) < 0) return -1; if (str_to_uint(args[1], &cmd_id) < 0 || cmd_id == 0) { *error_r = "UPDATE-CMD: Invalid command id"; return -1; } for (i = 0; args[2][i] != '\0'; i++) { switch (args[2][i]) { case 'd': done = TRUE; break; case 'c': continued = TRUE; break; default: *error_r = "UPDATE-CMD: Invalid flags parameter"; return -1; } } cmd = mail_command_find(session, cmd_id); if (!continued) { /* new command */ if (cmd != NULL) { *error_r = "UPDATE-CMD: Duplicate new command id"; return -1; } if (str_array_length(args) < 5) { *error_r = "UPDATE-CMD: Too few parameters"; return -1; } cmd = mail_command_add(session, args[3], args[4]); cmd->id = cmd_id; session->highest_cmd_id = I_MAX(session->highest_cmd_id, cmd_id); session->num_cmds++; session->user->num_cmds++; session->user->domain->num_cmds++; if (session->ip != NULL) session->ip->num_cmds++; mail_global_stats.num_cmds++; args += 5; } else { if (cmd == NULL) { /* already expired command, ignore */ i_warning("UPDATE-CMD: Already expired"); return 0; } args += 3; cmd->last_update = ioloop_timeval; } buf = t_buffer_create(256); if (args[0] == NULL || base64_decode(args[0], strlen(args[0]), NULL, buf) < 0) { *error_r = t_strdup_printf("UPDATE-CMD: Invalid base64 input"); return -1; } new_stats = stats_alloc(pool_datastack_create()); diff_stats = stats_alloc(pool_datastack_create()); if (!stats_import(buf->data, buf->used, cmd->stats, new_stats, &error)) { *error_r = t_strdup_printf("UPDATE-CMD: %s", error); return -1; } if (!stats_diff(cmd->stats, new_stats, diff_stats, &error)) { *error_r = t_strdup_printf("UPDATE-CMD: stats shrank: %s", error); return -1; } stats_add(cmd->stats, diff_stats); if (done) { cmd->id = 0; mail_command_unref(&cmd); } mail_session_refresh(session, NULL); return 0; }