48
49
/* length of binary representation of UUID */
49
50
#define UUID_LEN (sizeof(uuid_t))
51
static void usage(const char *progname)
53
fprintf(stderr, _("Usage: %s [-d] [-p pidfile] [-s socketpath] "
54
"[-T timeout]\n"), progname);
55
fprintf(stderr, _(" %s [-r|t] [-n num] [-s socketpath]\n"),
57
fprintf(stderr, _(" %s -k\n"), progname);
61
static void die(const char *msg)
52
static void __attribute__ ((__noreturn__)) usage(FILE * out)
54
fputs(_("\nUsage:\n"), out);
56
_(" %s [options]\n"), program_invocation_short_name);
58
fputs(_("\nOptions:\n"), out);
59
fputs(_(" -p, --pid <path> path to pid file\n"
60
" -s, --socket <path> path to socket\n"
61
" -T, --timeout <sec> specify inactivity timeout\n"
62
" -k, --kill kill running daemon\n"
63
" -r, --random test random-based generation\n"
64
" -t, --time test time-based generation\n"
65
" -n, --uuids <num> request number of uuids\n"
66
" -d, --debug run in debugging mode\n"
67
" -q, --quiet turn on quiet mode\n"
68
" -V, --version output version information and exit\n"
69
" -h, --help display this help and exit\n\n"), out);
71
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
67
74
static void create_daemon(void)
79
err(EXIT_FAILURE, "daemon");
75
82
if (setreuid(euid, euid) < 0)
83
err(EXIT_FAILURE, "setreuid");
79
86
static ssize_t read_all(int fd, char *buf, size_t count)
105
112
static void terminate_intr(int signo CODE_ATTR((unused)))
107
(void) unlink(cleanup_pidfile);
114
unlink(cleanup_pidfile);
108
115
if (cleanup_socket)
109
(void) unlink(cleanup_socket);
116
unlink(cleanup_socket);
113
120
static int call_daemon(const char *socket_path, int op, char *buf,
114
int buflen, int *num, const char **err_context)
121
size_t buflen, int *num, const char **err_context)
137
144
srv_addr.sun_family = AF_UNIX;
138
145
strncpy(srv_addr.sun_path, socket_path, sizeof(srv_addr.sun_path));
139
srv_addr.sun_path[sizeof(srv_addr.sun_path)-1] = '\0';
146
srv_addr.sun_path[sizeof(srv_addr.sun_path) - 1] = '\0';
141
148
if (connect(s, (const struct sockaddr *) &srv_addr,
142
149
sizeof(struct sockaddr_un)) < 0) {
149
156
if (op == UUIDD_OP_BULK_RANDOM_UUID) {
150
if ((*num)*UUID_LEN > buflen-4)
151
*num = (buflen-4) / UUID_LEN;
157
if ((*num) * UUID_LEN > buflen - 4)
158
*num = (buflen - 4) / UUID_LEN;
155
162
if ((op == UUIDD_OP_BULK_TIME_UUID) ||
156
163
(op == UUIDD_OP_BULK_RANDOM_UUID)) {
157
memcpy(op_buf+1, num, sizeof(int));
164
memcpy(op_buf + 1, num, sizeof(int));
158
165
op_len += sizeof(int);
236
243
fprintf(stderr, _("Failed to lock %s: %s\n"),
237
244
pidfile_path, strerror(errno));
240
247
ret = call_daemon(socket_path, 0, reply_buf, sizeof(reply_buf), 0, 0);
243
250
printf(_("uuidd daemon already running at pid %s\n"),
269
276
my_addr.sun_family = AF_UNIX;
270
277
strncpy(my_addr.sun_path, socket_path, sizeof(my_addr.sun_path));
271
my_addr.sun_path[sizeof(my_addr.sun_path)-1] = '\0';
272
(void) unlink(socket_path);
278
my_addr.sun_path[sizeof(my_addr.sun_path) - 1] = '\0';
273
280
save_umask = umask(0);
274
281
if (bind(s, (const struct sockaddr *) &my_addr,
275
282
sizeof(struct sockaddr_un)) < 0) {
278
285
_("Couldn't bind unix socket %s: %s\n"),
279
286
socket_path, strerror(errno));
282
(void) umask(save_umask);
284
291
if (listen(s, SOMAXCONN) < 0) {
286
293
fprintf(stderr, _("Couldn't listen on unix "
287
294
"socket %s: %s\n"), socket_path,
288
295
strerror(errno));
292
299
cleanup_socket = socket_path;
299
306
signal(SIGPIPE, SIG_IGN);
301
308
sprintf(reply_buf, "%8d\n", getpid());
302
if (ftruncate(fd_pidfile, 0)) {} /* Silence warn_unused_result */
309
if (ftruncate(fd_pidfile, 0)) {
310
/* Silence warn_unused_result */
303
312
write_all(fd_pidfile, reply_buf, strlen(reply_buf));
304
313
if (fd_pidfile > 1)
305
314
close(fd_pidfile); /* Unlock the pid file */
335
344
} else if (debug)
336
345
printf(_("operation %d\n"), op);
339
348
case UUIDD_OP_GETPID:
340
349
sprintf(reply_buf, "%d", getpid());
341
reply_len = strlen(reply_buf)+1;
350
reply_len = strlen(reply_buf) + 1;
343
352
case UUIDD_OP_GET_MAXOP:
344
353
sprintf(reply_buf, "%d", UUIDD_MAX_OP);
345
reply_len = strlen(reply_buf)+1;
354
reply_len = strlen(reply_buf) + 1;
347
356
case UUIDD_OP_TIME_UUID:
349
uuid__generate_time(uu, &num);
358
__uuid_generate_time(uu, &num);
351
360
uuid_unparse(uu, str);
352
361
printf(_("Generated time UUID: %s\n"), str);
357
366
case UUIDD_OP_RANDOM_UUID:
359
uuid__generate_random(uu, &num);
368
__uuid_generate_random(uu, &num);
361
370
uuid_unparse(uu, str);
362
371
printf(_("Generated random UUID: %s\n"), str);
365
374
reply_len = sizeof(uu);
367
376
case UUIDD_OP_BULK_TIME_UUID:
368
uuid__generate_time(uu, &num);
377
__uuid_generate_time(uu, &num);
370
379
uuid_unparse(uu, str);
371
printf(_("Generated time UUID %s and %d "
372
"following\n"), str, num - 1);
380
printf(P_("Generated time UUID %s "
381
"and %d following\n",
382
"Generated time UUID %s "
383
"and %d following\n", num - 1),
374
386
memcpy(reply_buf, uu, sizeof(uu));
375
387
reply_len = sizeof(uu);
376
memcpy(reply_buf+reply_len, &num, sizeof(num));
388
memcpy(reply_buf + reply_len, &num, sizeof(num));
377
389
reply_len += sizeof(num);
379
391
case UUIDD_OP_BULK_RANDOM_UUID:
384
if (num * UUID_LEN > (int) (sizeof(reply_buf)-sizeof(num)))
385
num = (sizeof(reply_buf)-sizeof(num)) / UUID_LEN;
386
uuid__generate_random((unsigned char *) reply_buf +
396
if (num * UUID_LEN > (int) (sizeof(reply_buf) - sizeof(num)))
397
num = (sizeof(reply_buf) - sizeof(num)) / UUID_LEN;
398
__uuid_generate_random((unsigned char *) reply_buf +
387
399
sizeof(num), &num);
389
printf(_("Generated %d UUIDs:\n"), num);
390
for (i=0, cp=reply_buf+sizeof(num);
391
i < num; i++, cp+=UUID_LEN) {
401
printf(P_("Generated %d UUID:\n",
402
"Generated %d UUIDs:\n", num), num);
403
for (i = 0, cp = reply_buf + sizeof(num);
405
i++, cp += UUID_LEN) {
392
406
uuid_unparse((unsigned char *)cp, str);
393
407
printf("\t%s\n", str);
425
static void __attribute__ ((__noreturn__)) unexpected_size(int size)
427
errx(EXIT_FAILURE, _("Unexpected reply length from server %d"), size);
411
430
int main(int argc, char **argv)
413
432
const char *socket_path = UUIDD_SOCKET_PATH;
422
441
int debug = 0, do_type = 0, do_kill = 0, num = 0;
423
442
int timeout = 0, quiet = 0, drop_privs = 0;
444
static const struct option longopts[] = {
445
{"pid", required_argument, NULL, 'p'},
446
{"socket", required_argument, NULL, 's'},
447
{"timeout", required_argument, NULL, 'T'},
448
{"kill", no_argument, NULL, 'k'},
449
{"random", no_argument, NULL, 'r'},
450
{"time", no_argument, NULL, 't'},
451
{"uuids", required_argument, NULL, 'n'},
452
{"debug", no_argument, NULL, 'd'},
453
{"quiet", no_argument, NULL, 'q'},
454
{"version", no_argument, NULL, 'V'},
455
{"help", no_argument, NULL, 'h'},
425
459
setlocale(LC_ALL, "");
426
460
bindtextdomain(PACKAGE, LOCALEDIR);
427
461
textdomain(PACKAGE);
429
while ((c = getopt (argc, argv, "dkn:qp:s:tT:r")) != EOF) {
464
getopt_long(argc, argv, "p:s:T:krtn:dqVh", longopts,
461
502
timeout = strtol(optarg, &tmp, 0);
462
503
if ((timeout < 0) || *tmp) {
463
504
fprintf(stderr, _("Bad number: %s\n"), optarg);
468
do_type = UUIDD_OP_RANDOM_UUID;
509
printf(_("%s from %s\n"),
510
program_invocation_short_name,
478
522
#ifdef HAVE_SETRESGID
479
523
if (setresgid(gid, gid, gid) < 0)
524
err(EXIT_FAILURE, "setresgid");
482
526
if (setregid(gid, gid) < 0)
527
err(EXIT_FAILURE, "setregid");
486
530
#ifdef HAVE_SETRESUID
487
531
if (setresuid(uid, uid, uid) < 0)
532
err(EXIT_FAILURE, "setresuid");
490
534
if (setreuid(uid, uid) < 0)
535
err(EXIT_FAILURE, "setreuid");
494
538
if (num && do_type) {
495
ret = call_daemon(socket_path, do_type+2, buf,
539
ret = call_daemon(socket_path, do_type + 2, buf,
496
540
sizeof(buf), &num, &err_context);
498
542
printf(_("Error calling uuidd daemon (%s): %s\n"),
499
543
err_context, strerror(errno));
502
546
if (do_type == UUIDD_OP_TIME_UUID) {
503
547
if (ret != sizeof(uu) + sizeof(num))
504
goto unexpected_size;
548
unexpected_size(ret);
506
550
uuid_unparse((unsigned char *) buf, str);
508
printf(_("%s and subsequent %d UUIDs\n"), str, num - 1);
552
printf(P_("%s and %d subsequent UUID\n",
553
"%s and %d subsequent UUIDs\n", num - 1),
510
556
printf(_("List of UUIDs:\n"));
512
if (ret != (int) (sizeof(num) + num*sizeof(uu)))
513
goto unexpected_size;
514
for (i=0; i < num; i++, cp+=UUID_LEN) {
558
if (ret != (int) (sizeof(num) + num * sizeof(uu)))
559
unexpected_size(ret);
560
for (i = 0; i < num; i++, cp += UUID_LEN) {
515
561
uuid_unparse((unsigned char *) cp, str);
516
562
printf("\t%s\n", str);
522
568
ret = call_daemon(socket_path, do_type, (char *) &uu,
548
591
_("Couldn't kill uuidd running "
549
592
"at pid %d: %s\n"), do_kill,
550
593
strerror(errno));
554
597
printf(_("Killed uuidd running at pid %d\n"),
560
603
server_loop(socket_path, pidfile_path, debug, timeout, quiet);