/*
 * libudev - interface to udev device information
 *
 * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
 * Copyright (C) 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

/*
 * DISCLAIMER - The file format mentioned here is private to udev/libudev,
 *              and may be changed without notice.
 *
 * The udev event queue is exported as a binary log file.
 * Each log record consists of a sequence number followed by the device path.
 *
 * When a new event is queued, its details are appended to the log.
 * When the event finishes, a second record is appended to the log
 * with the same sequence number but a devpath len of 0.
 *
 * Example:
 *        { 0x0000000000000001 }
 *        { 0x0000000000000001, 0x0019, "/devices/virtual/mem/null" },
 *        { 0x0000000000000002, 0x001b, "/devices/virtual/mem/random" },
 *        { 0x0000000000000001, 0x0000 },
 *        { 0x0000000000000003, 0x0019, "/devices/virtual/mem/zero" },
 *
 * Events 2 and 3 are still queued, but event 1 has finished.
 *
 * The queue does not grow indefinitely. It is periodically re-created
 * to remove finished events. Atomic rename() makes this transparent to readers.
 *
 * The queue file starts with a single sequence number which specifies the
 * minimum sequence number in the log that follows. Any events prior to this
 * sequence number have already finished.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <limits.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "libudev.h"
#include "libudev-private.h"

static int rebuild_queue_file(struct udev_queue_export *udev_queue_export);

struct udev_queue_export {
        struct udev *udev;
        int queued_count;        /* number of unfinished events exported in queue file */
        FILE *queue_file;
        unsigned long long int seqnum_max;        /* earliest sequence number in queue file */
        unsigned long long int seqnum_min;        /* latest sequence number in queue file */
        int waste_bytes;                        /* queue file bytes wasted on finished events */
};

struct udev_queue_export *udev_queue_export_new(struct udev *udev)
{
        struct udev_queue_export *udev_queue_export;
        unsigned long long int initial_seqnum;

        if (udev == NULL)
                return NULL;

        udev_queue_export = calloc(1, sizeof(struct udev_queue_export));
        if (udev_queue_export == NULL)
                return NULL;
        udev_queue_export->udev = udev;

        initial_seqnum = udev_get_kernel_seqnum(udev);
        udev_queue_export->seqnum_min = initial_seqnum;
        udev_queue_export->seqnum_max = initial_seqnum;

        udev_queue_export_cleanup(udev_queue_export);
        if (rebuild_queue_file(udev_queue_export) != 0) {
                free(udev_queue_export);
                return NULL;
        }

        return udev_queue_export;
}

struct udev_queue_export *udev_queue_export_unref(struct udev_queue_export *udev_queue_export)
{
        if (udev_queue_export == NULL)
                return NULL;
        if (udev_queue_export->queue_file != NULL)
                fclose(udev_queue_export->queue_file);
        free(udev_queue_export);
        return NULL;
}

void udev_queue_export_cleanup(struct udev_queue_export *udev_queue_export)
{
        char filename[UTIL_PATH_SIZE];

        if (udev_queue_export == NULL)
                return;
        util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.tmp", NULL);
        unlink(filename);
        util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.bin", NULL);
        unlink(filename);
}

static int skip_to(FILE *file, long offset)
{
        long old_offset;

        /* fseek may drop buffered data, avoid it for small seeks */
        old_offset = ftell(file);
        if (offset > old_offset && offset - old_offset <= BUFSIZ) {
                size_t skip_bytes = offset - old_offset;
                char buf[skip_bytes];

                if (fread(buf, skip_bytes, 1, file) != skip_bytes)
                        return -1;
        }

        return fseek(file, offset, SEEK_SET);
}

struct queue_devpaths {
        unsigned int devpaths_first;        /* index of first queued event */
        unsigned int devpaths_size;
        long devpaths[];                /* seqnum -> offset of devpath in queue file (or 0) */
};

/*
 * Returns a table mapping seqnum to devpath file offset for currently queued events.
 * devpaths[i] represents the event with seqnum = i + udev_queue_export->seqnum_min.
 */
static struct queue_devpaths *build_index(struct udev_queue_export *udev_queue_export)
{
        struct queue_devpaths *devpaths;
        unsigned long long int range;
        long devpath_offset;
        ssize_t devpath_len;
        unsigned long long int seqnum;
        unsigned long long int n;
        unsigned int i;

        /* seek to the first event in the file */
        rewind(udev_queue_export->queue_file);
        udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum);

        /* allocate the table */
        range = udev_queue_export->seqnum_min - udev_queue_export->seqnum_max;
        if (range - 1 > INT_MAX) {
                err(udev_queue_export->udev, "queue file overflow\n");
                return NULL;
        }
        devpaths = calloc(1, sizeof(struct queue_devpaths) + (range + 1) * sizeof(long));
        if (devpaths == NULL)
                return NULL;
        devpaths->devpaths_size = range + 1;

        /* read all records and populate the table */
        for (;;) {
                if (udev_queue_read_seqnum(udev_queue_export->queue_file, &seqnum) < 0)
                        break;
                n = seqnum - udev_queue_export->seqnum_max;
                if (n >= devpaths->devpaths_size)
                        goto read_error;

                devpath_offset = ftell(udev_queue_export->queue_file);
                devpath_len = udev_queue_skip_devpath(udev_queue_export->queue_file);
                if (devpath_len < 0)
                        goto read_error;

                if (devpath_len > 0)
                        devpaths->devpaths[n] = devpath_offset;
                else
                        devpaths->devpaths[n] = 0;
        }

        /* find first queued event */
        for (i = 0; i < devpaths->devpaths_size; i++) {
                if (devpaths->devpaths[i] != 0)
                        break;
        }
        devpaths->devpaths_first = i;

        return devpaths;

read_error:
        err(udev_queue_export->udev, "queue file corrupted\n");
        free(devpaths);
        return NULL;
}

static int rebuild_queue_file(struct udev_queue_export *udev_queue_export)
{
        unsigned long long int seqnum;
        struct queue_devpaths *devpaths = NULL;
        char filename[UTIL_PATH_SIZE];
        char filename_tmp[UTIL_PATH_SIZE];
        FILE *new_queue_file = NULL;
        unsigned int i;

        /* read old queue file */
        if (udev_queue_export->queue_file != NULL) {
                dbg(udev_queue_export->udev, "compacting queue file, freeing %d bytes\n",
                                                udev_queue_export->waste_bytes);

                devpaths = build_index(udev_queue_export);
                if (devpaths != NULL)
                        udev_queue_export->seqnum_max += devpaths->devpaths_first;
        }
        if (devpaths == NULL) {
                dbg(udev_queue_export->udev, "creating empty queue file\n");
                udev_queue_export->queued_count = 0;
                udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;
        }

        /* create new queue file */
        util_strscpyl(filename_tmp, sizeof(filename_tmp), udev_get_run_path(udev_queue_export->udev), "/queue.tmp", NULL);
        new_queue_file = fopen(filename_tmp, "w+");
        if (new_queue_file == NULL)
                goto error;
        seqnum = udev_queue_export->seqnum_max;
        fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file);

        /* copy unfinished events only to the new file */
        if (devpaths != NULL) {
                for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) {
                        char devpath[UTIL_PATH_SIZE];
                        int err;
                        unsigned short devpath_len;

                        if (devpaths->devpaths[i] != 0)
                        {
                                skip_to(udev_queue_export->queue_file, devpaths->devpaths[i]);
                                err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath));
                                devpath_len = err;

                                fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file);
                                fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file);
                                fwrite(devpath, 1, devpath_len, new_queue_file);
                        }
                        seqnum++;
                }
                free(devpaths);
                devpaths = NULL;
        }
        fflush(new_queue_file);
        if (ferror(new_queue_file))
                goto error;

        /* rename the new file on top of the old one */
        util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue_export->udev), "/queue.bin", NULL);
        if (rename(filename_tmp, filename) != 0)
                goto error;

        if (udev_queue_export->queue_file != NULL)
                fclose(udev_queue_export->queue_file);
        udev_queue_export->queue_file = new_queue_file;
        udev_queue_export->waste_bytes = 0;

        return 0;

error:
        err(udev_queue_export->udev, "failed to create queue file: %m\n");
        udev_queue_export_cleanup(udev_queue_export);

        if (udev_queue_export->queue_file != NULL) {
                fclose(udev_queue_export->queue_file);
                udev_queue_export->queue_file = NULL;
        }
        if (new_queue_file != NULL)
                fclose(new_queue_file);

        if (devpaths != NULL)
                free(devpaths);
        udev_queue_export->queued_count = 0;
        udev_queue_export->waste_bytes = 0;
        udev_queue_export->seqnum_max = udev_queue_export->seqnum_min;

        return -1;
}

static int write_queue_record(struct udev_queue_export *udev_queue_export,
                              unsigned long long int seqnum, const char *devpath, size_t devpath_len)
{
        unsigned short len;

        if (udev_queue_export->queue_file == NULL) {
                dbg(udev_queue_export->udev, "can't record event: queue file not available\n");
                return -1;
        }

        if (fwrite(&seqnum, sizeof(unsigned long long int), 1, udev_queue_export->queue_file) != 1)
                goto write_error;

        len = (devpath_len < USHRT_MAX) ? devpath_len : USHRT_MAX;
        if (fwrite(&len, sizeof(unsigned short), 1, udev_queue_export->queue_file) != 1)
                goto write_error;
        if (len > 0) {
                if (fwrite(devpath, 1, len, udev_queue_export->queue_file) != len)
                        goto write_error;
        }

        /* *must* flush output; caller may fork */
        if (fflush(udev_queue_export->queue_file) != 0)
                goto write_error;

        return 0;

write_error:
        /* if we failed half way through writing a record to a file,
           we should not try to write any further records to it. */
        err(udev_queue_export->udev, "error writing to queue file: %m\n");
        fclose(udev_queue_export->queue_file);
        udev_queue_export->queue_file = NULL;

        return -1;
}

enum device_state {
        DEVICE_QUEUED,
        DEVICE_FINISHED,
};

static inline size_t queue_record_size(size_t devpath_len)
{
        return sizeof(unsigned long long int) + sizeof(unsigned short int) + devpath_len;
}

static int update_queue(struct udev_queue_export *udev_queue_export,
                         struct udev_device *udev_device, enum device_state state)
{
        unsigned long long int seqnum = udev_device_get_seqnum(udev_device);
        const char *devpath = NULL;
        size_t devpath_len = 0;
        int bytes;
        int err;

        /* FINISHED records have a zero length devpath */
        if (state == DEVICE_QUEUED) {
                devpath = udev_device_get_devpath(udev_device);
                devpath_len = strlen(devpath);
        }

        /* recover from an earlier failed rebuild */
        if (udev_queue_export->queue_file == NULL) {
                if (rebuild_queue_file(udev_queue_export) != 0)
                        return -1;
        }

        /* if we're removing the last event from the queue, that's the best time to rebuild it */
        if (state != DEVICE_QUEUED && udev_queue_export->queued_count == 1) {
                /* we don't need to read the old queue file */
                fclose(udev_queue_export->queue_file);
                udev_queue_export->queue_file = NULL;
                rebuild_queue_file(udev_queue_export);
                return 0;
        }

        /* try to rebuild the queue files before they grow larger than one page. */
        bytes = ftell(udev_queue_export->queue_file) + queue_record_size(devpath_len);
        if ((udev_queue_export->waste_bytes > bytes / 2) && bytes > 4096)
                rebuild_queue_file(udev_queue_export);

        /* don't record a finished event, if we already dropped the event in a failed rebuild */
        if (seqnum < udev_queue_export->seqnum_max)
                return 0;

        /* now write to the queue */
        if (state == DEVICE_QUEUED) {
                udev_queue_export->queued_count++;
                udev_queue_export->seqnum_min = seqnum;
        } else {
                udev_queue_export->waste_bytes += queue_record_size(devpath_len) + queue_record_size(0);
                udev_queue_export->queued_count--;
        }
        err = write_queue_record(udev_queue_export, seqnum, devpath, devpath_len);

        /* try to handle ENOSPC */
        if (err != 0 && udev_queue_export->queued_count == 0) {
                udev_queue_export_cleanup(udev_queue_export);
                err = rebuild_queue_file(udev_queue_export);
        }

        return err;
}

static int update(struct udev_queue_export *udev_queue_export,
                  struct udev_device *udev_device, enum device_state state)
{
        if (update_queue(udev_queue_export, udev_device, state) != 0)
                return -1;

        return 0;
}

int udev_queue_export_device_queued(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
{
        return update(udev_queue_export, udev_device, DEVICE_QUEUED);
}

int udev_queue_export_device_finished(struct udev_queue_export *udev_queue_export, struct udev_device *udev_device)
{
        return update(udev_queue_export, udev_device, DEVICE_FINISHED);
}
