ccx-utils

Miscellaneous utilities written in C
git clone https://ccx.te2000.cz/git/ccx-utils
Log | Files | Refs

mtime_to_uuidv7.c (1555B)


      1 #include <stdint.h>
      2 #include <sys/stat.h> /* for stat(), struct stat */
      3 #include <unistd.h>   /* for getentropy() */
      4 #include <stdio.h>    /* for printf() */
      5 #include <fcntl.h>    /* Definition of AT_* constants */
      6 
      7 #include <skalibs/strerr.h>
      8 
      9 #define PROG "mtime_to_uuidv7"
     10 #define USAGE "mtime_to_uuidv7 [filename]"
     11 
     12 
     13 void uuidv7(struct timespec *ts, uint8_t* value) {
     14     // timestamp in ms
     15     uint64_t timestamp = (uint64_t)ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
     16 
     17     // random bytes
     18     if(getentropy(value, 16)) {
     19         strerr_dief1sys(111, "getentropy()");
     20     }
     21 
     22     // timestamp
     23     value[0] = (timestamp >> 40) & 0xFF;
     24     value[1] = (timestamp >> 32) & 0xFF;
     25     value[2] = (timestamp >> 24) & 0xFF;
     26     value[3] = (timestamp >> 16) & 0xFF;
     27     value[4] = (timestamp >> 8) & 0xFF;
     28     value[5] = timestamp & 0xFF;
     29 
     30     // version and variant
     31     value[6] = (value[6] & 0x0F) | 0x70;
     32     value[8] = (value[8] & 0x3F) | 0x80;
     33 }
     34 
     35 
     36 int main (int argc, char const *const *argv)
     37 {
     38     if (argc > 2) {
     39         strerr_dieusage(100, USAGE);
     40     }
     41     struct stat statinfo;
     42     if(argc == 2) {
     43         if(stat(argv[1], &statinfo)) {
     44             strerr_diefu2sys(111, "stat(): ", argv[1]);
     45         }
     46     } else {
     47         if(fstatat(0, "", &statinfo, AT_EMPTY_PATH)) {
     48             strerr_diefu1sys(111, "fstatat(stdin)");
     49         }
     50     }
     51 
     52     uint8_t uuid_val[16];
     53     uuidv7(&statinfo.st_mtim, uuid_val);
     54 
     55     for (size_t i = 0; i < 16; i++) {
     56         printf("%02x", uuid_val[i]);
     57     }
     58     printf("\n");
     59 
     60     return 0;
     61 }
     62 /* vim: sw=4 sts=4 et
     63 */