/*
 * 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.
 */

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

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

/**
 * SECTION:libudev-queue
 * @short_description: access to currently active events
 *
 * The udev daemon processes events asynchronously. All events which do not have
 * interdependencies run in parallel. This exports the current state of the
 * event processing queue, and the current event sequence numbers from the kernel
 * and the udev daemon.
 */

/**
 * udev_queue:
 *
 * Opaque object representing the current event queue in the udev daemon.
 */
struct udev_queue {
        struct udev *udev;
        int refcount;
        struct udev_list queue_list;
};

/**
 * udev_queue_new:
 * @udev: udev library context
 *
 * The initial refcount is 1, and needs to be decremented to
 * release the resources of the udev queue context.
 *
 * Returns: the udev queue context, or #NULL on error.
 **/
UDEV_EXPORT struct udev_queue *udev_queue_new(struct udev *udev)
{
        struct udev_queue *udev_queue;

        if (udev == NULL)
                return NULL;

        udev_queue = calloc(1, sizeof(struct udev_queue));
        if (udev_queue == NULL)
                return NULL;
        udev_queue->refcount = 1;
        udev_queue->udev = udev;
        udev_list_init(udev, &udev_queue->queue_list, false);
        return udev_queue;
}

/**
 * udev_queue_ref:
 * @udev_queue: udev queue context
 *
 * Take a reference of a udev queue context.
 *
 * Returns: the same udev queue context.
 **/
UDEV_EXPORT struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue)
{
        if (udev_queue == NULL)
                return NULL;
        udev_queue->refcount++;
        return udev_queue;
}

/**
 * udev_queue_unref:
 * @udev_queue: udev queue context
 *
 * Drop a reference of a udev queue context. If the refcount reaches zero,
 * the resources of the queue context will be released.
 **/
UDEV_EXPORT void udev_queue_unref(struct udev_queue *udev_queue)
{
        if (udev_queue == NULL)
                return;
        udev_queue->refcount--;
        if (udev_queue->refcount > 0)
                return;
        udev_list_cleanup(&udev_queue->queue_list);
        free(udev_queue);
}

/**
 * udev_queue_get_udev:
 * @udev_queue: udev queue context
 *
 * Retrieve the udev library context the queue context was created with.
 *
 * Returns: the udev library context.
 **/
UDEV_EXPORT struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
{
        if (udev_queue == NULL)
                return NULL;
        return udev_queue->udev;
}

unsigned long long int udev_get_kernel_seqnum(struct udev *udev)
{
        char filename[UTIL_PATH_SIZE];
        unsigned long long int seqnum;
        int fd;
        char buf[32];
        ssize_t len;

        util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), "/kernel/uevent_seqnum", NULL);
        fd = open(filename, O_RDONLY|O_CLOEXEC);
        if (fd < 0)
                return 0;
        len = read(fd, buf, sizeof(buf));
        close(fd);
        if (len <= 2)
                return 0;
        buf[len-1] = '\0';
        seqnum = strtoull(buf, NULL, 10);
        return seqnum;
}

/**
 * udev_queue_get_kernel_seqnum:
 * @udev_queue: udev queue context
 *
 * Returns: the current kernel event sequence number.
 **/
UDEV_EXPORT unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue)
{
        unsigned long long int seqnum;

        if (udev_queue == NULL)
                return -EINVAL;

        seqnum = udev_get_kernel_seqnum(udev_queue->udev);
        dbg(udev_queue->udev, "seqnum=%llu\n", seqnum);
        return seqnum;
}

int udev_queue_read_seqnum(FILE *queue_file, unsigned long long int *seqnum)
{
        if (fread(seqnum, sizeof(unsigned long long int), 1, queue_file) != 1)
                return -1;

        return 0;
}

ssize_t udev_queue_skip_devpath(FILE *queue_file)
{
        unsigned short int len;

        if (fread(&len, sizeof(unsigned short int), 1, queue_file) == 1) {
                char devpath[len];

                /* use fread to skip, fseek might drop buffered data */
                if (fread(devpath, 1, len, queue_file) == len)
                        return len;
        }

        return -1;
}

ssize_t udev_queue_read_devpath(FILE *queue_file, char *devpath, size_t size)
{
        unsigned short int read_bytes = 0;
        unsigned short int len;

        if (fread(&len, sizeof(unsigned short int), 1, queue_file) != 1)
                return -1;

        read_bytes = (len < size - 1) ? len : size - 1;
        if (fread(devpath, 1, read_bytes, queue_file) != read_bytes)
                return -1;
        devpath[read_bytes] = '\0';

        /* if devpath was too long, skip unread characters */
        if (read_bytes != len) {
                unsigned short int skip_bytes = len - read_bytes;
                char buf[skip_bytes];

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

        return read_bytes;
}

static FILE *open_queue_file(struct udev_queue *udev_queue, unsigned long long int *seqnum_start)
{
        char filename[UTIL_PATH_SIZE];
        FILE *queue_file;

        util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev_queue->udev), "/queue.bin", NULL);
        queue_file = fopen(filename, "re");
        if (queue_file == NULL)
                return NULL;

        if (udev_queue_read_seqnum(queue_file, seqnum_start) < 0) {
                err(udev_queue->udev, "corrupt queue file\n");
                fclose(queue_file);
                return NULL;
        }

        return queue_file;
}

/**
 * udev_queue_get_udev_seqnum:
 * @udev_queue: udev queue context
 *
 * Returns: the last known udev event sequence number.
 **/
UDEV_EXPORT unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue)
{
        unsigned long long int seqnum_udev;
        FILE *queue_file;

        queue_file = open_queue_file(udev_queue, &seqnum_udev);
        if (queue_file == NULL)
                return 0;

        for (;;) {
                unsigned long long int seqnum;
                ssize_t devpath_len;

                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
                        break;
                devpath_len = udev_queue_skip_devpath(queue_file);
                if (devpath_len < 0)
                        break;
                if (devpath_len > 0)
                        seqnum_udev = seqnum;
        }

        fclose(queue_file);
        return seqnum_udev;
}

/**
 * udev_queue_get_udev_is_active:
 * @udev_queue: udev queue context
 *
 * Returns: a flag indicating if udev is active.
 **/
UDEV_EXPORT int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
{
        unsigned long long int seqnum_start;
        FILE *queue_file;

        queue_file = open_queue_file(udev_queue, &seqnum_start);
        if (queue_file == NULL)
                return 0;

        fclose(queue_file);
        return 1;
}

/**
 * udev_queue_get_queue_is_empty:
 * @udev_queue: udev queue context
 *
 * Returns: a flag indicating if udev is currently handling events.
 **/
UDEV_EXPORT int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
{
        unsigned long long int seqnum_kernel;
        unsigned long long int seqnum_udev = 0;
        int queued = 0;
        int is_empty = 0;
        FILE *queue_file;

        if (udev_queue == NULL)
                return -EINVAL;
        queue_file = open_queue_file(udev_queue, &seqnum_udev);
        if (queue_file == NULL)
                return 1;

        for (;;) {
                unsigned long long int seqnum;
                ssize_t devpath_len;

                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
                        break;
                devpath_len = udev_queue_skip_devpath(queue_file);
                if (devpath_len < 0)
                        break;

                if (devpath_len > 0) {
                        queued++;
                        seqnum_udev = seqnum;
                } else {
                        queued--;
                }
        }

        if (queued > 0) {
                dbg(udev_queue->udev, "queue is not empty\n");
                goto out;
        }

        seqnum_kernel = udev_queue_get_kernel_seqnum(udev_queue);
        if (seqnum_udev < seqnum_kernel) {
                dbg(udev_queue->udev, "queue is empty but kernel events still pending [%llu]<->[%llu]\n",
                                      seqnum_kernel, seqnum_udev);
                goto out;
        }

        dbg(udev_queue->udev, "queue is empty\n");
        is_empty = 1;

out:
        fclose(queue_file);
        return is_empty;
}

/**
 * udev_queue_get_seqnum_sequence_is_finished:
 * @udev_queue: udev queue context
 * @start: first event sequence number
 * @end: last event sequence number
 *
 * Returns: a flag indicating if any of the sequence numbers in the given range is currently active.
 **/
UDEV_EXPORT int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
                                               unsigned long long int start, unsigned long long int end)
{
        unsigned long long int seqnum;
        ssize_t devpath_len;
        int unfinished;
        FILE *queue_file;

        if (udev_queue == NULL)
                return -EINVAL;
        queue_file = open_queue_file(udev_queue, &seqnum);
        if (queue_file == NULL)
                return 1;
        if (start < seqnum)
                start = seqnum;
        if (start > end) {
                fclose(queue_file);
                return 1;
        }
        if (end - start > INT_MAX - 1) {
                fclose(queue_file);
                return -EOVERFLOW;
        }

        /*
         * we might start with 0, and handle the initial seqnum
         * only when we find an entry in the queue file
         **/
        unfinished = end - start;

        do {
                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
                        break;
                devpath_len = udev_queue_skip_devpath(queue_file);
                if (devpath_len < 0)
                        break;

                /*
                 * we might start with an empty or re-build queue file, where
                 * the initial seqnum is not recorded as finished
                 */
                if (start == seqnum && devpath_len > 0)
                        unfinished++;

                if (devpath_len == 0) {
                        if (seqnum >= start && seqnum <= end)
                                unfinished--;
                }
        } while (unfinished > 0);

        fclose(queue_file);

        return (unfinished == 0);
}

/**
 * udev_queue_get_seqnum_is_finished:
 * @udev_queue: udev queue context
 * @seqnum: sequence number
 *
 * Returns: a flag indicating if the given sequence number is currently active.
 **/
UDEV_EXPORT int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum)
{
        if (!udev_queue_get_seqnum_sequence_is_finished(udev_queue, seqnum, seqnum))
                return 0;

        dbg(udev_queue->udev, "seqnum: %llu finished\n", seqnum);
        return 1;
}

/**
 * udev_queue_get_queued_list_entry:
 * @udev_queue: udev queue context
 *
 * Returns: the first entry of the list of queued events.
 **/
UDEV_EXPORT struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
{
        unsigned long long int seqnum;
        FILE *queue_file;

        if (udev_queue == NULL)
                return NULL;
        udev_list_cleanup(&udev_queue->queue_list);

        queue_file = open_queue_file(udev_queue, &seqnum);
        if (queue_file == NULL)
                return NULL;

        for (;;) {
                char syspath[UTIL_PATH_SIZE];
                char *s;
                size_t l;
                ssize_t len;
                char seqnum_str[32];
                struct udev_list_entry *list_entry;

                if (udev_queue_read_seqnum(queue_file, &seqnum) < 0)
                        break;
                snprintf(seqnum_str, sizeof(seqnum_str), "%llu", seqnum);

                s = syspath;
                l = util_strpcpyl(&s, sizeof(syspath), udev_get_sys_path(udev_queue->udev), NULL);
                len = udev_queue_read_devpath(queue_file, s, l);
                if (len < 0)
                        break;

                if (len > 0) {
                        udev_list_entry_add(&udev_queue->queue_list, syspath, seqnum_str);
                } else {
                        udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_queue->queue_list)) {
                                if (strcmp(seqnum_str, udev_list_entry_get_value(list_entry)) == 0) {
                                        udev_list_entry_delete(list_entry);
                                        break;
                                }
                        }
                }
        }
        fclose(queue_file);

        return udev_list_get_entry(&udev_queue->queue_list);
}

struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue);
UDEV_EXPORT struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue)
{
        errno = ENOSYS;
        return NULL;
}
