Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:20

0001 /*
0002  * uuid_time.c --- Interpret the time field from a uuid.  This program
0003  *  violates the UUID abstraction barrier by reaching into the guts
0004  *  of a UUID and interpreting it.
0005  *
0006  * Copyright (C) 1998, 1999 Theodore Ts'o.
0007  *
0008  * %Begin-Header%
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, and the entire permission notice in its entirety,
0014  *    including the disclaimer of warranties.
0015  * 2. Redistributions in binary form must reproduce the above copyright
0016  *    notice, this list of conditions and the following disclaimer in the
0017  *    documentation and/or other materials provided with the distribution.
0018  * 3. The name of the author may not be used to endorse or promote
0019  *    products derived from this software without specific prior
0020  *    written permission.
0021  *
0022  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
0023  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0024  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
0025  * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
0028  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0029  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0030  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0032  * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
0033  * DAMAGE.
0034  * %End-Header%
0035  */
0036 
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040 
0041 #ifdef _WIN32
0042 #define _WIN32_WINNT 0x0500
0043 #include <windows.h>
0044 #define UUID MYUUID
0045 #endif
0046 
0047 #include <stdio.h>
0048 #ifdef HAVE_UNISTD_H
0049 #include <unistd.h>
0050 #endif
0051 #include <stdlib.h>
0052 #include <sys/types.h>
0053 #ifdef HAVE_SYS_TIME_H
0054 #include <sys/time.h>
0055 #endif
0056 #include <time.h>
0057 
0058 #include "uuidP.h"
0059 
0060 time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
0061 {
0062     struct timeval      tv;
0063     struct uuid     uuid;
0064     uint32_t        high;
0065     uint64_t        clock_reg;
0066 
0067     uuid_unpack(uu, &uuid);
0068 
0069     high = uuid.time_mid | ((uint32_t)(uuid.time_hi_and_version & 0xFFF) << 16);
0070     clock_reg = uuid.time_low | ((uint64_t) high << 32);
0071 
0072     clock_reg -= (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
0073     tv.tv_sec = clock_reg / 10000000;
0074     tv.tv_usec = (clock_reg % 10000000) / 10;
0075 
0076     if (ret_tv)
0077         *ret_tv = tv;
0078 
0079     return tv.tv_sec;
0080 }
0081 
0082 int uuid_type(const uuid_t uu)
0083 {
0084     struct uuid     uuid;
0085 
0086     uuid_unpack(uu, &uuid);
0087     return ((uuid.time_hi_and_version >> 12) & 0xF);
0088 }
0089 
0090 int uuid_variant(const uuid_t uu)
0091 {
0092     struct uuid     uuid;
0093     int         var;
0094 
0095     uuid_unpack(uu, &uuid);
0096     var = uuid.clock_seq;
0097 
0098     if ((var & 0x8000) == 0)
0099         return UUID_VARIANT_NCS;
0100     if ((var & 0x4000) == 0)
0101         return UUID_VARIANT_DCE;
0102     if ((var & 0x2000) == 0)
0103         return UUID_VARIANT_MICROSOFT;
0104     return UUID_VARIANT_OTHER;
0105 }
0106 
0107 #ifdef DEBUG
0108 static const char *variant_string(int variant)
0109 {
0110     switch (variant) {
0111     case UUID_VARIANT_NCS:
0112         return "NCS";
0113     case UUID_VARIANT_DCE:
0114         return "DCE";
0115     case UUID_VARIANT_MICROSOFT:
0116         return "Microsoft";
0117     default:
0118         return "Other";
0119     }
0120 }
0121 
0122 
0123 int
0124 main(int argc, char **argv)
0125 {
0126     uuid_t      buf;
0127     time_t      time_reg;
0128     struct timeval  tv;
0129     int     type, variant;
0130 
0131     if (argc != 2) {
0132         fprintf(stderr, "Usage: %s uuid\n", argv[0]);
0133         exit(1);
0134     }
0135     if (uuid_parse(argv[1], buf)) {
0136         fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
0137         exit(1);
0138     }
0139     variant = uuid_variant(buf);
0140     type = uuid_type(buf);
0141     time_reg = uuid_time(buf, &tv);
0142 
0143     printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
0144     if (variant != UUID_VARIANT_DCE) {
0145         printf("Warning: This program only knows how to interpret "
0146                "DCE UUIDs.\n\tThe rest of the output is likely "
0147                "to be incorrect!!\n");
0148     }
0149     printf("UUID type is %d", type);
0150     switch (type) {
0151     case 1:
0152         printf(" (time based)\n");
0153         break;
0154     case 2:
0155         printf(" (DCE)\n");
0156         break;
0157     case 3:
0158         printf(" (name-based)\n");
0159         break;
0160     case 4:
0161         printf(" (random)\n");
0162         break;
0163     default:
0164         printf("\n");
0165     }
0166     if (type != 1) {
0167         printf("Warning: not a time-based UUID, so UUID time "
0168                "decoding will likely not work!\n");
0169     }
0170     printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
0171            ctime(&time_reg));
0172 
0173     return 0;
0174 }
0175 #endif