2 * uuidparse.c --- Interpret uuid encoded information. This program
3 * violates the UUID abstraction barrier by reaching into the
6 * Based on libuuid/src/uuid_time.c
7 * Copyright (C) 1998, 1999 Theodore Ts'o.
9 * All alterations (C) 2017 Sami Kerola
10 * The 3-Clause BSD License
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, and the entire permission notice in its entirety,
17 * including the disclaimer of warranties.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote
22 * products derived from this software without specific prior
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
28 * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
31 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
41 #include <libsmartcols.h>
52 #include "closestream.h"
56 #include "timeutils.h"
69 const char *name
; /* header */
70 double whint
; /* width hint (N < 1 is in percent of termwidth) */
71 int flags
; /* SCOLS_FL_* */
75 /* columns descriptions */
76 static const struct colinfo infos
[] = {
77 [COL_UUID
] = {"UUID", UUID_STR_LEN
, 0, N_("unique identifier")},
78 [COL_VARIANT
] = {"VARIANT", 9, 0, N_("variant name")},
79 [COL_TYPE
] = {"TYPE", 10, 0, N_("type name")},
80 [COL_TIME
] = {"TIME", 31, 0, N_("timestamp")}
83 static int columns
[ARRAY_SIZE(infos
) * 2];
84 static size_t ncolumns
;
92 static void __attribute__((__noreturn__
)) usage(void)
96 fputs(USAGE_HEADER
, stdout
);
97 fprintf(stdout
, _(" %s [options] <uuid ...>\n"), program_invocation_short_name
);
99 fputs(USAGE_OPTIONS
, stdout
);
100 fputsln(_(" -J, --json use JSON output format"), stdout
);
101 fputsln(_(" -n, --noheadings don't print headings"), stdout
);
102 fputsln(_(" -o, --output <list> COLUMNS to display (see below)"), stdout
);
103 fputsln(_(" -r, --raw use the raw output format"), stdout
);
104 fprintf(stdout
, USAGE_HELP_OPTIONS(24));
106 fputs(USAGE_COLUMNS
, stdout
);
107 for (i
= 0; i
< ARRAY_SIZE(infos
); i
++)
108 fprintf(stdout
, " %8s %s\n", infos
[i
].name
, _(infos
[i
].help
));
110 fprintf(stdout
, USAGE_MAN_TAIL("uuidparse(1)"));
114 static int column_name_to_id(const char *name
, size_t namesz
)
120 for (i
= 0; i
< ARRAY_SIZE(infos
); i
++) {
121 const char *cn
= infos
[i
].name
;
122 if (!c_strncasecmp(name
, cn
, namesz
) && !*(cn
+ namesz
))
125 warnx(_("unknown column: %s"), name
);
129 static int get_column_id(size_t num
)
131 assert(num
< ncolumns
);
132 assert(columns
[num
] < (int)ARRAY_SIZE(infos
));
136 static const struct colinfo
*get_column_info(int num
)
138 return &infos
[get_column_id(num
)];
141 static void fill_table_row(struct libscols_table
*tb
, char const *const uuid
)
143 static struct libscols_line
*ln
;
147 int variant
= -1, type
= -1;
152 ln
= scols_table_new_line(tb
, NULL
);
154 errx(EXIT_FAILURE
, _("failed to allocate output line"));
156 if (uuid_parse(uuid
, buf
))
159 variant
= uuid_variant(buf
);
160 type
= uuid_type(buf
);
163 for (i
= 0; i
< ncolumns
; i
++) {
166 switch (get_column_id(i
)) {
172 str
= xstrdup(_("invalid"));
176 case UUID_VARIANT_NCS
:
177 str
= xstrdup("NCS");
179 case UUID_VARIANT_DCE
:
180 str
= xstrdup("DCE");
182 case UUID_VARIANT_MICROSOFT
:
183 str
= xstrdup("Microsoft");
186 str
= xstrdup(_("other"));
191 str
= xstrdup(_("invalid"));
194 if (variant
!= UUID_VARIANT_DCE
)
197 case UUID_TYPE_DCE_NIL
:
198 if (uuid_is_null(buf
))
199 str
= xstrdup(_("nil"));
201 str
= xstrdup(_("unknown"));
203 case UUID_TYPE_DCE_TIME
:
204 str
= xstrdup(_("time-based"));
206 case UUID_TYPE_DCE_TIME_V6
:
207 str
= xstrdup(_("time-v6"));
209 case UUID_TYPE_DCE_TIME_V7
:
210 str
= xstrdup(_("time-v7"));
212 case UUID_TYPE_DCE_SECURITY
:
213 str
= xstrdup("DCE");
215 case UUID_TYPE_DCE_MD5
:
216 str
= xstrdup(_("name-based"));
218 case UUID_TYPE_DCE_RANDOM
:
219 str
= xstrdup(_("random"));
221 case UUID_TYPE_DCE_SHA1
:
222 str
= xstrdup(_("sha1-based"));
224 case UUID_TYPE_DCE_VENDOR
:
225 str
= xstrdup(_("vendor"));
228 str
= xstrdup(_("unknown"));
233 str
= xstrdup(_("invalid"));
236 if (variant
!= UUID_VARIANT_DCE
)
238 if (type
== UUID_TYPE_DCE_TIME
||
239 type
== UUID_TYPE_DCE_TIME_V6
||
240 type
== UUID_TYPE_DCE_TIME_V7
) {
242 char date_buf
[ISO_BUFSIZ
];
245 strtimeval_iso(&tv
, ISO_TIMESTAMP_COMMA
,
246 date_buf
, sizeof(date_buf
));
247 str
= xstrdup(date_buf
);
253 if (str
&& scols_line_refer_data(ln
, i
, str
))
254 errx(EXIT_FAILURE
, _("failed to add output data"));
258 static void print_output(struct control
const *const ctrl
, int argc
,
261 struct libscols_table
*tb
;
265 tb
= scols_new_table();
267 err(EXIT_FAILURE
, _("failed to allocate output table"));
270 scols_table_enable_json(tb
, 1);
271 scols_table_set_name(tb
, "uuids");
273 scols_table_enable_noheadings(tb
, ctrl
->no_headings
);
274 scols_table_enable_raw(tb
, ctrl
->raw
);
276 for (i
= 0; i
< ncolumns
; i
++) {
277 const struct colinfo
*col
= get_column_info(i
);
279 if (!scols_table_new_column(tb
, col
->name
, col
->whint
,
282 _("failed to initialize output column"));
285 for (i
= 0; i
< (size_t) argc
; i
++)
286 fill_table_row(tb
, argv
[i
]);
289 char uuid
[UUID_STR_LEN
];
291 while (scanf(" %36[^ \t\n]%*c", uuid
) && !feof(stdin
))
292 fill_table_row(tb
, uuid
);
294 scols_print_table(tb
);
295 scols_unref_table(tb
);
298 int main(int argc
, char **argv
)
300 struct control ctrl
= { 0 };
304 static const struct option longopts
[] = {
305 {"json", no_argument
, NULL
, 'J'},
306 {"noheadings", no_argument
, NULL
, 'n'},
307 {"output", required_argument
, NULL
, 'o'},
308 {"raw", no_argument
, NULL
, 'r'},
309 {"version", no_argument
, NULL
, 'V'},
310 {"help", no_argument
, NULL
, 'h'},
313 static const ul_excl_t excl
[] = {
317 int excl_st
[ARRAY_SIZE(excl
)] = UL_EXCL_STATUS_INIT
;
319 setlocale(LC_ALL
, "");
320 bindtextdomain(PACKAGE
, LOCALEDIR
);
322 close_stdout_atexit();
324 while ((c
= getopt_long(argc
, argv
, "Jno:rVh", longopts
, NULL
)) != -1) {
325 err_exclusive_options(c
, longopts
, excl
, excl_st
);
331 ctrl
.no_headings
= 1;
341 print_version(EXIT_SUCCESS
);
345 errtryhelp(EXIT_FAILURE
);
351 columns
[ncolumns
++] = COL_UUID
;
352 columns
[ncolumns
++] = COL_VARIANT
;
353 columns
[ncolumns
++] = COL_TYPE
;
354 columns
[ncolumns
++] = COL_TIME
;
357 && string_add_to_idarray(outarg
, columns
, ARRAY_SIZE(columns
),
358 &ncolumns
, column_name_to_id
) < 0)
361 print_output(&ctrl
, argc
, argv
);