]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
Improve lastplayed time format for ls and stat output.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index a5da1a929e8c5c34920aab8d798d1a7f64cb3e68..8df2bc6091e55945843e7a93b0eec7f4f5cbf2b3 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -241,19 +241,12 @@ enum audio_file_table_columns {
        NUM_AFT_COLUMNS
 };
 
-/**
- * Compare two osl objects pointing to hash values.
- *
- * \param obj1 Pointer to the first hash object.
- * \param obj2 Pointer to the second hash object.
- *
- * \return The values required for an osl compare function.
- *
- * \sa osl_compare_func, uint32_compare().
- */
-static int aft_hash_compare(const struct osl_object *obj1, const struct osl_object *obj2)
+/* compare function for the hash column */
+static int aft_hash_compare(const struct osl_object *obj1,
+               const struct osl_object *obj2)
 {
-       return hash_compare((unsigned char *)obj1->data, (unsigned char *)obj2->data);
+       return hash_compare((unsigned char *)obj1->data,
+               (unsigned char *)obj2->data);
 }
 
 static struct osl_column_description aft_cols[] = {
@@ -684,6 +677,11 @@ static int get_local_time(uint64_t *seconds, char *buf, size_t size,
        time_t current_time, enum ls_listing_mode lm)
 {
        struct tm t;
+       /*
+        * Omit year but show time if the given value is closer to the current
+        * time than this many seconds.
+        */
+       const time_t m = 6 * 30 * 24 * 3600; /* six months */
 
        if (!localtime_r((time_t *)seconds, &t))
                return -E_LOCALTIME;
@@ -692,12 +690,12 @@ static int get_local_time(uint64_t *seconds, char *buf, size_t size,
                        return -E_STRFTIME;
                return 1;
        }
-       if (*seconds + 6 * 30 * 24 * 3600 > current_time) {
+       if (*seconds > current_time - m && *seconds < current_time + m) {
                if (!strftime(buf, size, "%b %e %k:%M", &t))
                        return -E_STRFTIME;
                return 1;
        }
-       if (!strftime(buf, size, "%b %e  %Y", &t))
+       if (!strftime(buf, size, "%b %e %Y", &t))
                return -E_STRFTIME;
        return 1;
 }
@@ -1365,18 +1363,26 @@ int com_ls(struct command_context *cc)
                        i++;
                        break;
                }
+               /*
+                * Compatibility: Prior to 0.5.5 it was necessary to specify
+                * the listing mode without the '=' character as in -lv, for
+                * example. Now the variant with '=' is preferred and
+                * documented but we still accept the old way to specify the
+                * listing mode.
+                *
+                * Support for the legacy syntax can be dropped at 0.6.0
+                * or later.
+                */
                if (!strncmp(arg, "-l", 2)) {
-                       if (!*(arg + 2)) {
-                               mode = LS_MODE_LONG;
-                               continue;
-                       }
-                       if (*(arg + 3))
-                               return -E_AFT_SYNTAX;
-                       switch(*(arg + 2)) {
+                       arg += 2;
+                       if (*arg == '=')
+                               arg++;
+                       switch (*arg) {
                        case 's':
                                mode = LS_MODE_SHORT;
                                continue;
                        case 'l':
+                       case '\0':
                                mode = LS_MODE_LONG;
                                continue;
                        case 'v':
@@ -1411,10 +1417,12 @@ int com_ls(struct command_context *cc)
                        flags |= LS_FLAG_UNIXDATE;
                        continue;
                }
+               /* The compatibility remark above applies also to -s. */
                if (!strncmp(arg, "-s", 2)) {
-                       if (!*(arg + 2) || *(arg + 3))
-                               return -E_AFT_SYNTAX;
-                       switch(*(arg + 2)) {
+                       arg += 2;
+                       if (*arg == '=')
+                               arg++;
+                       switch (*arg) {
                        case 'p':
                                sort = LS_SORT_BY_PATH;
                                continue;
@@ -1497,16 +1505,16 @@ static int find_path_brother(const char *path, struct osl_row **result)
 
 /** The format of the data stored by save_audio_file_data(). */
 enum com_add_buffer_offsets {
-       /** afhi (if present) starts here. */
+       /* afhi (if present) starts at this offset. */
        CAB_AFHI_OFFSET_POS = 0,
        /** Start of the chunk table (if present). */
-       CAB_CHUNKS_OFFSET_POS = 2,
-       /** Audio format id. */
-       CAB_AUDIO_FORMAT_OFFSET = 4,
+       CAB_CHUNKS_OFFSET_POS = 4,
        /** Flags given to the add command. */
-       CAB_FLAGS_OFFSET = 5,
+       CAB_FLAGS_OFFSET = 8,
+       /** Audio format id. */
+       CAB_AUDIO_FORMAT_ID_OFFSET = 12,
        /** The hash of the audio file being added. */
-       CAB_HASH_OFFSET = 9,
+       CAB_HASH_OFFSET = 13,
        /** Start of the path of the audio file. */
        CAB_PATH_OFFSET = (CAB_HASH_OFFSET + HASH_SIZE),
 };
@@ -1527,27 +1535,23 @@ static void save_add_callback_buffer(unsigned char *hash, const char *path,
        size_t size = CAB_PATH_OFFSET + path_len + afhi_size
                + sizeof_chunk_table(afhi);
        char *buf = para_malloc(size);
-       uint16_t pos;
-
-       write_u8(buf + CAB_AUDIO_FORMAT_OFFSET, audio_format_num);
-       write_u32(buf + CAB_FLAGS_OFFSET, flags);
-
-       memcpy(buf + CAB_HASH_OFFSET, hash, HASH_SIZE);
-       strcpy(buf + CAB_PATH_OFFSET, path);
+       uint32_t pos;
 
        pos = CAB_PATH_OFFSET + path_len;
-       PARA_DEBUG_LOG("size: %zu, afhi starts at %d\n", size, pos);
-       PARA_DEBUG_LOG("last afhi byte: %p, pos %zu\n", buf + pos + afhi_size - 1,
-               pos + afhi_size - 1);
-       write_u16(buf + CAB_AFHI_OFFSET_POS, pos);
+       write_u32(buf + CAB_AFHI_OFFSET_POS, pos);
        save_afhi(afhi, buf + pos);
-
        pos += afhi_size;
-       PARA_DEBUG_LOG("size: %zu, chunks start at %d\n", size, pos);
-       write_u16(buf + CAB_CHUNKS_OFFSET_POS, pos);
+
+       write_u32(buf + CAB_CHUNKS_OFFSET_POS, pos);
        if (afhi)
                save_chunk_table(afhi, buf + pos);
-       PARA_DEBUG_LOG("last byte in buf: %p\n", buf + size - 1);
+
+       write_u32(buf + CAB_FLAGS_OFFSET, flags);
+       write_u8(buf + CAB_AUDIO_FORMAT_ID_OFFSET, audio_format_num);
+
+       memcpy(buf + CAB_HASH_OFFSET, hash, HASH_SIZE);
+       strcpy(buf + CAB_PATH_OFFSET, path);
+
        obj->data = buf;
        obj->size = size;
 }
@@ -1684,8 +1688,8 @@ static int com_add_callback(struct afs_callback_arg *aca)
                        goto out;
        }
        /* no hs or force mode, child must have sent afhi */
-       afhi_offset = read_u16(buf + CAB_AFHI_OFFSET_POS);
-       chunks_offset = read_u16(buf + CAB_CHUNKS_OFFSET_POS);
+       afhi_offset = read_u32(buf + CAB_AFHI_OFFSET_POS);
+       chunks_offset = read_u32(buf + CAB_CHUNKS_OFFSET_POS);
 
        objs[AFTCOL_AFHI].data = buf + afhi_offset;
        objs[AFTCOL_AFHI].size = chunks_offset - afhi_offset;
@@ -1732,7 +1736,7 @@ static int com_add_callback(struct afs_callback_arg *aca)
        if (flags & ADD_FLAG_VERBOSE)
                para_printf(&aca->pbout, "new file\n");
        default_afsi.last_played = time(NULL) - 365 * 24 * 60 * 60;
-       default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_OFFSET);
+       default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_ID_OFFSET);
 
        objs[AFTCOL_AFSI].data = &afsi_buf;
        objs[AFTCOL_AFSI].size = AFSI_SIZE;
@@ -2415,7 +2419,8 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
        if (!cad.add_mask && !cad.del_mask)
                goto out;
        pmd.patterns.data = p;
-       assert(p < (char *)aca->query.data + aca->query.size);
+       if (p >= (char *)aca->query.data + aca->query.size)
+               goto out;
        pmd.patterns.size = (char *)aca->query.data + aca->query.size - p;
        ret = for_each_matching_row(&pmd);
        if (ret < 0)