aft: Update mtime and file size on afhi changes.
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 23 Dec 2014 12:52:03 +0000 (12:52 +0000)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 30 Mar 2015 21:40:58 +0000 (21:40 +0000)
If the current audio file is re-added to the osl database, for example
because meta tags have changed, file size and modification time change.
However, the paraslash stat command still shows the old values because
currently the virtual streaming system calls fstat(2) only once when
the audio file is opened and keeps reporting the resulting mtime and
file size values until the file is closed.

This commit introduces make_inode_status_items() which is called
from make_status_items() on AFSI_CHANGE and AFHI_CHANGE events for
the current audio file. The new function calls stat(2) on the path
obtained from the current aft row. We can't use fstat(2) since (a)
we don't have an open file descriptor any more and (b) this would
not work anyway if the original file was overwritten.

Due to the new helper, mmd->mtime can be removed. We must keep
mmd->size though, since we need the original file size for the call
to munmap().

aft.c
command.c
server.h
vss.c

diff --git a/aft.c b/aft.c
index 0e86b12..59be56e 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1043,6 +1043,28 @@ out:
 static struct ls_data status_item_ls_data;
 static struct osl_row *current_aft_row;
 
+static void make_inode_status_items(struct para_buffer *pb)
+{
+       struct stat statbuf = {.st_size = 0};
+       char *path, mtime_str[30] = "\0";
+       struct tm mtime_tm;
+       int ret;
+
+       ret = get_audio_file_path_of_row(current_aft_row, &path);
+       if (ret < 0)
+               goto out;
+       ret = stat(path, &statbuf);
+       if (ret < 0)
+               goto out;
+       localtime_r(&statbuf.st_mtime, &mtime_tm);
+       ret = strftime(mtime_str, 29, "%b %d %Y", &mtime_tm);
+       assert(ret > 0); /* number of bytes placed in mtime_str */
+out:
+       /* We don't care too much about errors here */
+       (void)WRITE_STATUS_ITEM(pb, SI_MTIME, "%s\n", mtime_str);
+       (void)WRITE_STATUS_ITEM(pb, SI_FILE_SIZE, "%ld\n", statbuf.st_size / 1024);
+}
+
 static int make_status_items(void)
 {
        struct ls_options opts = {
@@ -1057,6 +1079,7 @@ static int make_status_items(void)
        ret = print_list_item(&status_item_ls_data, &opts, &pb, current_time);
        if (ret < 0)
                return ret;
+       make_inode_status_items(&pb);
        free(status_items);
        status_items = pb.buf;
        memset(&pb, 0, sizeof(pb));
@@ -1068,6 +1091,7 @@ static int make_status_items(void)
                status_items = NULL;
                return ret;
        }
+       make_inode_status_items(&pb);
        free(parser_friendly_status_items);
        parser_friendly_status_items = pb.buf;
        return 1;
index 2ef9c5a..0baad5d 100644 (file)
--- a/command.c
+++ b/command.c
@@ -112,21 +112,15 @@ static char *vss_get_status_flags(unsigned int flags)
 static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
                char **result)
 {
-       char mtime[30] = "";
        char *status, *flags; /* vss status info */
        /* nobody updates our version of "now" */
        long offset = (nmmd->offset + 500) / 1000;
        struct timeval current_time;
-       struct tm mtime_tm;
        struct para_buffer b = {.flags = parser_friendly? PBF_SIZE_PREFIX : 0};
 
        /* report real status */
        status = vss_status_tohuman(nmmd->vss_status_flags);
        flags = vss_get_status_flags(nmmd->vss_status_flags);
-       if (nmmd->size) { /* parent currently has an audio file open */
-               localtime_r(&nmmd->mtime, &mtime_tm);
-               strftime(mtime, 29, "%b %d %Y", &mtime_tm);
-       }
        clock_get_realtime(&current_time);
        /*
         * The calls to WRITE_STATUS_ITEM() below never fail because
@@ -134,8 +128,6 @@ static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
         * is not smart enough to prove this and complains nevertheless.
         * Casting the return value to void silences clang.
         */
-       (void)WRITE_STATUS_ITEM(&b, SI_FILE_SIZE, "%zu\n", nmmd->size / 1024);
-       (void)WRITE_STATUS_ITEM(&b, SI_MTIME, "%s\n", mtime);
        (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status);
        (void)WRITE_STATUS_ITEM(&b, SI_STATUS_FLAGS, "%s\n", flags);
        (void)WRITE_STATUS_ITEM(&b, SI_OFFSET, "%li\n", offset);
index a89e005..287614c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -52,8 +52,6 @@ struct sender_command_data{
 struct misc_meta_data {
        /** The size of the current audio file in bytes. */
        size_t size;
-       /** The last modification time of the current audio file. */
-       time_t mtime;
        /** The "old" status flags -- commands may only read them. */
        unsigned int vss_status_flags;
        /** The new status flags -- commands may set them. */
diff --git a/vss.c b/vss.c
index fc42ba6..ea075df 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -855,7 +855,6 @@ static void vss_eof(struct vss_task *vsst)
        mmd->afd.afhi.chunk_tv.tv_usec = 0;
        free(mmd->afd.afhi.chunk_table);
        mmd->afd.afhi.chunk_table = NULL;
-       mmd->mtime = 0;
        mmd->size = 0;
        mmd->events++;
 }
@@ -1011,7 +1010,6 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds)
                goto err;
        }
        mmd->size = statbuf.st_size;
-       mmd->mtime = statbuf.st_mtime;
        ret = para_mmap(mmd->size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
                passed_fd, 0, &vsst->map);
        if (ret < 0)