]> git.ipfire.org Git - thirdparty/util-linux.git/blame - misc-utils/uuidd.c
textual: use UTIL_LINUX_VERSION everywhere
[thirdparty/util-linux.git] / misc-utils / uuidd.c
CommitLineData
69045d3d
KZ
1/*
2 * uuidd.c --- UUID-generation daemon
3 *
4 * Copyright (C) 2007 Theodore Ts'o
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
10 */
11#include <stdio.h>
12#ifdef HAVE_STDLIB_H
13#include <stdlib.h>
14#endif
15#include <unistd.h>
16#include <inttypes.h>
17#include <errno.h>
ea091bed 18#include <err.h>
69045d3d
KZ
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/socket.h>
22#include <sys/un.h>
23#include <fcntl.h>
24#include <signal.h>
25#include <string.h>
26#ifdef HAVE_GETOPT_H
27#include <getopt.h>
28#else
29extern int getopt(int argc, char * const argv[], const char *optstring);
30extern char *optarg;
31extern int optind;
32#endif
33
34#include "uuid.h"
35#include "uuidd.h"
e12c9866 36#include "all-io.h"
f6f3dc78 37#include "c.h"
c05a80ca 38#include "closestream.h"
bbe289c4
PU
39
40#ifdef USE_SOCKET_ACTIVATION
41#include "sd-daemon.h"
42#endif
43
69045d3d
KZ
44#include "nls.h"
45
46#ifdef __GNUC__
47#define CODE_ATTR(x) __attribute__(x)
48#else
49#define CODE_ATTR(x)
50#endif
51
a8f13198
PU
52/* length of textual representation of UUID, including trailing \0 */
53#define UUID_STR_LEN 37
54
55/* length of binary representation of UUID */
56#define UUID_LEN (sizeof(uuid_t))
57
881a0f6b
PU
58/* server loop control structure */
59struct uuidd_cxt_t {
60 int timeout;
61 unsigned int debug: 1,
62 quiet: 1,
63 no_fork: 1,
64 no_sock: 1;
65};
66
f0ef0b58 67static void __attribute__ ((__noreturn__)) usage(FILE * out)
69045d3d 68{
c63a92b8
KZ
69 fputs(_("\nUsage:\n"), out);
70 fprintf(out,
71 _(" %s [options]\n"), program_invocation_short_name);
f0ef0b58 72
c63a92b8 73 fputs(_("\nOptions:\n"), out);
bbe289c4
PU
74 fputs(_(" -p, --pid <path> path to pid file\n"
75 " -s, --socket <path> path to socket\n"
76 " -T, --timeout <sec> specify inactivity timeout\n"
77 " -k, --kill kill running daemon\n"
78 " -r, --random test random-based generation\n"
79 " -t, --time test time-based generation\n"
80 " -n, --uuids <num> request number of uuids\n"
81 " -P, --no-pid do not create pid file\n"
82 " -F, --no-fork do not daemonize using double-fork\n"
83 " -S, --socket-activation do not create listening socket\n"
84 " -d, --debug run in debugging mode\n"
85 " -q, --quiet turn on quiet mode\n"
86 " -V, --version output version information and exit\n"
87 " -h, --help display this help and exit\n\n"), out);
f0ef0b58
SK
88
89 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
69045d3d
KZ
90}
91
69045d3d
KZ
92static void create_daemon(void)
93{
69045d3d
KZ
94 uid_t euid;
95
f7c297b8 96 if (daemon(0, 0))
ea091bed 97 err(EXIT_FAILURE, "daemon");
69045d3d 98
69045d3d
KZ
99 euid = geteuid();
100 if (setreuid(euid, euid) < 0)
ea091bed 101 err(EXIT_FAILURE, "setreuid");
69045d3d
KZ
102}
103
69045d3d
KZ
104static const char *cleanup_pidfile, *cleanup_socket;
105
106static void terminate_intr(int signo CODE_ATTR((unused)))
107{
0abfbd9c
PU
108 if (cleanup_pidfile)
109 unlink(cleanup_pidfile);
69045d3d 110 if (cleanup_socket)
f7c297b8 111 unlink(cleanup_socket);
41dc5bc0 112 exit(EXIT_SUCCESS);
69045d3d
KZ
113}
114
115static int call_daemon(const char *socket_path, int op, char *buf,
c3bfedc3 116 size_t buflen, int *num, const char **err_context)
69045d3d
KZ
117{
118 char op_buf[8];
119 int op_len;
120 int s;
121 ssize_t ret;
122 int32_t reply_len = 0;
123 struct sockaddr_un srv_addr;
124
78314078
PU
125 if (((op == UUIDD_OP_BULK_TIME_UUID) ||
126 (op == UUIDD_OP_BULK_RANDOM_UUID)) && !num) {
69045d3d
KZ
127 if (err_context)
128 *err_context = _("bad arguments");
129 errno = EINVAL;
130 return -1;
131 }
132
133 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
134 if (err_context)
135 *err_context = _("socket");
136 return -1;
137 }
138
139 srv_addr.sun_family = AF_UNIX;
140 strncpy(srv_addr.sun_path, socket_path, sizeof(srv_addr.sun_path));
f7c297b8 141 srv_addr.sun_path[sizeof(srv_addr.sun_path) - 1] = '\0';
69045d3d
KZ
142
143 if (connect(s, (const struct sockaddr *) &srv_addr,
144 sizeof(struct sockaddr_un)) < 0) {
145 if (err_context)
146 *err_context = _("connect");
147 close(s);
148 return -1;
149 }
150
78314078 151 if (op == UUIDD_OP_BULK_RANDOM_UUID) {
f7c297b8
SK
152 if ((*num) * UUID_LEN > buflen - 4)
153 *num = (buflen - 4) / UUID_LEN;
69045d3d
KZ
154 }
155 op_buf[0] = op;
156 op_len = 1;
78314078
PU
157 if ((op == UUIDD_OP_BULK_TIME_UUID) ||
158 (op == UUIDD_OP_BULK_RANDOM_UUID)) {
f7c297b8 159 memcpy(op_buf + 1, num, sizeof(int));
69045d3d
KZ
160 op_len += sizeof(int);
161 }
162
163 ret = write_all(s, op_buf, op_len);
38674931 164 if (ret < 0) {
69045d3d
KZ
165 if (err_context)
166 *err_context = _("write");
167 close(s);
168 return -1;
169 }
170
171 ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
172 if (ret < 0) {
173 if (err_context)
174 *err_context = _("read count");
175 close(s);
176 return -1;
177 }
c3bfedc3 178 if (reply_len < 0 || (size_t) reply_len > buflen) {
69045d3d
KZ
179 if (err_context)
180 *err_context = _("bad response length");
181 close(s);
182 return -1;
183 }
184 ret = read_all(s, (char *) buf, reply_len);
185
78314078 186 if ((ret > 0) && (op == UUIDD_OP_BULK_TIME_UUID)) {
a8f13198
PU
187 if (reply_len >= (int) (UUID_LEN + sizeof(int)))
188 memcpy(buf + UUID_LEN, num, sizeof(int));
69045d3d
KZ
189 else
190 *num = -1;
191 }
78314078 192 if ((ret > 0) && (op == UUIDD_OP_BULK_RANDOM_UUID)) {
faab2be3 193 if (reply_len >= (int) sizeof(int))
69045d3d
KZ
194 memcpy(buf, num, sizeof(int));
195 else
196 *num = -1;
197 }
198
199 close(s);
200
201 return ret;
202}
203
c4536355
PU
204/*
205 * Exclusively create and open a pid file with path @pidfile_path
206 *
207 * Set cleanup_pidfile global variable for the cleanup
208 * handler. @pidfile_path must not be NULL.
209 *
210 * Return file descriptor of the created pid_file.
211 */
212static int create_pidfile(const char *pidfile_path, int quiet)
69045d3d 213{
c4536355
PU
214 int fd_pidfile;
215 struct flock fl;
69045d3d
KZ
216
217 fd_pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0664);
218 if (fd_pidfile < 0) {
219 if (!quiet)
960cf573
PU
220 fprintf(stderr, _("Failed to open/create %s: %m\n"),
221 pidfile_path);
41dc5bc0 222 exit(EXIT_FAILURE);
69045d3d
KZ
223 }
224 cleanup_pidfile = pidfile_path;
c4536355 225
69045d3d
KZ
226 fl.l_type = F_WRLCK;
227 fl.l_whence = SEEK_SET;
228 fl.l_start = 0;
229 fl.l_len = 0;
230 fl.l_pid = 0;
231 while (fcntl(fd_pidfile, F_SETLKW, &fl) < 0) {
232 if ((errno == EAGAIN) || (errno == EINTR))
233 continue;
234 if (!quiet)
960cf573 235 fprintf(stderr, _("Failed to lock %s: %m\n"), pidfile_path);
41dc5bc0 236 exit(EXIT_FAILURE);
69045d3d 237 }
c4536355
PU
238
239 return fd_pidfile;
240}
241
75a94e8b
PU
242/*
243 * Create AF_UNIX, SOCK_STREAM socket and bind to @socket_path
244 *
245 * If @will_fork is true, then make sure the descriptor
246 * of the socket is >2, so that it wont be later closed
247 * during create_daemon().
248 *
249 * Return file descriptor corresponding to created socket.
250 */
251static int create_socket(const char *socket_path, int will_fork, int quiet)
c4536355 252{
75a94e8b 253 struct sockaddr_un my_addr;
c4536355 254 mode_t save_umask;
75a94e8b 255 int s;
69045d3d
KZ
256
257 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
258 if (!quiet)
960cf573 259 fprintf(stderr, _("Couldn't create unix stream socket: %m"));
41dc5bc0 260 exit(EXIT_FAILURE);
69045d3d
KZ
261 }
262
fdb3e93c
TT
263 /*
264 * Make sure the socket isn't using fd numbers 0-2 to avoid it
265 * getting closed by create_daemon()
266 */
75a94e8b 267 while (will_fork && s <= 2) {
fdb3e93c 268 s = dup(s);
2d169242 269 if (s < 0)
ea091bed 270 err(EXIT_FAILURE, "dup");
fdb3e93c
TT
271 }
272
69045d3d
KZ
273 /*
274 * Create the address we will be binding to.
275 */
276 my_addr.sun_family = AF_UNIX;
277 strncpy(my_addr.sun_path, socket_path, sizeof(my_addr.sun_path));
f7c297b8
SK
278 my_addr.sun_path[sizeof(my_addr.sun_path) - 1] = '\0';
279 unlink(socket_path);
69045d3d
KZ
280 save_umask = umask(0);
281 if (bind(s, (const struct sockaddr *) &my_addr,
282 sizeof(struct sockaddr_un)) < 0) {
283 if (!quiet)
284 fprintf(stderr,
960cf573 285 _("Couldn't bind unix socket %s: %m\n"), socket_path);
41dc5bc0 286 exit(EXIT_FAILURE);
69045d3d 287 }
f7c297b8 288 umask(save_umask);
75a94e8b 289 cleanup_socket = socket_path;
69045d3d 290
75a94e8b
PU
291 return s;
292}
293
294static void server_loop(const char *socket_path, const char *pidfile_path,
881a0f6b 295 const struct uuidd_cxt_t *uuidd_cxt)
75a94e8b
PU
296{
297 struct sockaddr_un from_addr;
298 socklen_t fromlen;
299 int32_t reply_len = 0;
300 uuid_t uu;
301 char reply_buf[1024], *cp;
302 char op, str[UUID_STR_LEN];
bbe289c4
PU
303 int i, ns, len, num;
304 int s = 0;
75a94e8b
PU
305 int fd_pidfile = -1;
306 int ret;
307
bbe289c4 308#ifdef USE_SOCKET_ACTIVATION
881a0f6b 309 if (!uuidd_cxt->no_sock) /* no_sock implies no_fork and no_pid */
bbe289c4
PU
310#endif
311 {
75a94e8b 312
bbe289c4
PU
313 signal(SIGALRM, terminate_intr);
314 alarm(30);
315 if (pidfile_path)
881a0f6b 316 fd_pidfile = create_pidfile(pidfile_path, uuidd_cxt->quiet);
75a94e8b 317
bbe289c4
PU
318 ret = call_daemon(socket_path, UUIDD_OP_GETPID, reply_buf,
319 sizeof(reply_buf), 0, NULL);
320 if (ret > 0) {
881a0f6b 321 if (!uuidd_cxt->quiet)
18c68d70
PU
322 fprintf(stderr,
323 _("uuidd daemon already running at pid %s\n"),
bbe289c4
PU
324 reply_buf);
325 exit(EXIT_FAILURE);
326 }
327 alarm(0);
328
881a0f6b
PU
329 s = create_socket(socket_path,
330 (!uuidd_cxt->debug || !uuidd_cxt->no_fork),
331 uuidd_cxt->quiet);
bbe289c4 332 if (listen(s, SOMAXCONN) < 0) {
881a0f6b 333 if (!uuidd_cxt->quiet)
bbe289c4
PU
334 fprintf(stderr, _("Couldn't listen on unix "
335 "socket %s: %m\n"), socket_path);
336 exit(EXIT_FAILURE);
337 }
338
881a0f6b 339 if (!uuidd_cxt->debug && !uuidd_cxt->no_fork)
bbe289c4
PU
340 create_daemon();
341
342 if (pidfile_path) {
343 sprintf(reply_buf, "%8d\n", getpid());
344 ignore_result( ftruncate(fd_pidfile, 0) );
345 write_all(fd_pidfile, reply_buf, strlen(reply_buf));
346 if (fd_pidfile > 1)
347 close(fd_pidfile); /* Unlock the pid file */
348 }
75a94e8b 349
69045d3d
KZ
350 }
351
69045d3d
KZ
352 signal(SIGHUP, terminate_intr);
353 signal(SIGINT, terminate_intr);
354 signal(SIGTERM, terminate_intr);
355 signal(SIGALRM, terminate_intr);
356 signal(SIGPIPE, SIG_IGN);
357
bbe289c4 358#ifdef USE_SOCKET_ACTIVATION
881a0f6b 359 if (uuidd_cxt->no_sock) {
bbe289c4
PU
360 if (sd_listen_fds(0) != 1) {
361 fprintf(stderr, _("No or too many file descriptors received.\n"));
362 exit(EXIT_FAILURE);
363 }
364
365 s = SD_LISTEN_FDS_START + 0;
f7c297b8 366 }
bbe289c4 367#endif
69045d3d
KZ
368
369 while (1) {
370 fromlen = sizeof(from_addr);
881a0f6b
PU
371 if (uuidd_cxt->timeout > 0)
372 alarm(uuidd_cxt->timeout);
69045d3d
KZ
373 ns = accept(s, (struct sockaddr *) &from_addr, &fromlen);
374 alarm(0);
375 if (ns < 0) {
376 if ((errno == EAGAIN) || (errno == EINTR))
377 continue;
2d169242 378 else
ea091bed 379 err(EXIT_FAILURE, "accept");
69045d3d
KZ
380 }
381 len = read(ns, &op, 1);
382 if (len != 1) {
383 if (len < 0)
384 perror("read");
385 else
18c68d70 386 fprintf(stderr, _("Error reading from client, "
69045d3d
KZ
387 "len = %d\n"), len);
388 goto shutdown_socket;
389 }
78314078
PU
390 if ((op == UUIDD_OP_BULK_TIME_UUID) ||
391 (op == UUIDD_OP_BULK_RANDOM_UUID)) {
69045d3d
KZ
392 if (read_all(ns, (char *) &num, sizeof(num)) != 4)
393 goto shutdown_socket;
881a0f6b 394 if (uuidd_cxt->debug)
18c68d70 395 fprintf(stderr, _("operation %d, incoming num = %d\n"),
69045d3d 396 op, num);
881a0f6b 397 } else if (uuidd_cxt->debug)
18c68d70 398 fprintf(stderr, _("operation %d\n"), op);
69045d3d 399
f7c297b8 400 switch (op) {
69045d3d
KZ
401 case UUIDD_OP_GETPID:
402 sprintf(reply_buf, "%d", getpid());
f7c297b8 403 reply_len = strlen(reply_buf) + 1;
69045d3d
KZ
404 break;
405 case UUIDD_OP_GET_MAXOP:
406 sprintf(reply_buf, "%d", UUIDD_MAX_OP);
f7c297b8 407 reply_len = strlen(reply_buf) + 1;
69045d3d
KZ
408 break;
409 case UUIDD_OP_TIME_UUID:
410 num = 1;
70b989c2 411 __uuid_generate_time(uu, &num);
881a0f6b 412 if (uuidd_cxt->debug) {
69045d3d 413 uuid_unparse(uu, str);
18c68d70 414 fprintf(stderr, _("Generated time UUID: %s\n"), str);
69045d3d
KZ
415 }
416 memcpy(reply_buf, uu, sizeof(uu));
417 reply_len = sizeof(uu);
418 break;
419 case UUIDD_OP_RANDOM_UUID:
420 num = 1;
c544aa2c 421 __uuid_generate_random(uu, &num);
881a0f6b 422 if (uuidd_cxt->debug) {
69045d3d 423 uuid_unparse(uu, str);
18c68d70 424 fprintf(stderr, _("Generated random UUID: %s\n"), str);
69045d3d
KZ
425 }
426 memcpy(reply_buf, uu, sizeof(uu));
427 reply_len = sizeof(uu);
428 break;
429 case UUIDD_OP_BULK_TIME_UUID:
70b989c2 430 __uuid_generate_time(uu, &num);
881a0f6b 431 if (uuidd_cxt->debug) {
69045d3d 432 uuid_unparse(uu, str);
18c68d70
PU
433 fprintf(stderr, P_("Generated time UUID %s "
434 "and %d following\n",
435 "Generated time UUID %s "
436 "and %d following\n", num - 1),
0149cd84 437 str, num - 1);
69045d3d
KZ
438 }
439 memcpy(reply_buf, uu, sizeof(uu));
440 reply_len = sizeof(uu);
f7c297b8 441 memcpy(reply_buf + reply_len, &num, sizeof(num));
69045d3d
KZ
442 reply_len += sizeof(num);
443 break;
444 case UUIDD_OP_BULK_RANDOM_UUID:
445 if (num < 0)
446 num = 1;
447 if (num > 1000)
448 num = 1000;
f7c297b8
SK
449 if (num * UUID_LEN > (int) (sizeof(reply_buf) - sizeof(num)))
450 num = (sizeof(reply_buf) - sizeof(num)) / UUID_LEN;
70b989c2 451 __uuid_generate_random((unsigned char *) reply_buf +
c544aa2c 452 sizeof(num), &num);
881a0f6b 453 if (uuidd_cxt->debug) {
18c68d70
PU
454 fprintf(stderr, P_("Generated %d UUID:\n",
455 "Generated %d UUIDs:\n", num), num);
f7c297b8
SK
456 for (i = 0, cp = reply_buf + sizeof(num);
457 i < num;
458 i++, cp += UUID_LEN) {
69045d3d 459 uuid_unparse((unsigned char *)cp, str);
18c68d70 460 fprintf(stderr, "\t%s\n", str);
69045d3d
KZ
461 }
462 }
a8f13198 463 reply_len = (num * UUID_LEN) + sizeof(num);
69045d3d
KZ
464 memcpy(reply_buf, &num, sizeof(num));
465 break;
466 default:
881a0f6b 467 if (uuidd_cxt->debug)
18c68d70 468 fprintf(stderr, _("Invalid operation %d\n"), op);
69045d3d
KZ
469 goto shutdown_socket;
470 }
471 write_all(ns, (char *) &reply_len, sizeof(reply_len));
472 write_all(ns, reply_buf, reply_len);
473 shutdown_socket:
474 close(ns);
475 }
476}
477
2fb35353
SK
478static void __attribute__ ((__noreturn__)) unexpected_size(int size)
479{
480 errx(EXIT_FAILURE, _("Unexpected reply length from server %d"), size);
481}
482
69045d3d
KZ
483int main(int argc, char **argv)
484{
485 const char *socket_path = UUIDD_SOCKET_PATH;
0abfbd9c
PU
486 const char *pidfile_path = NULL;
487 const char *pidfile_path_param = NULL;
69045d3d
KZ
488 const char *err_context;
489 char buf[1024], *cp;
a8f13198 490 char str[UUID_STR_LEN], *tmp;
69045d3d 491 uuid_t uu;
69045d3d 492 int i, c, ret;
4b1cf29d
KZ
493 int do_type = 0, do_kill = 0, num = 0;
494 int no_pid = 0;
495 int s_flag = 0;
496
497 struct uuidd_cxt_t uuidd_cxt = { .timeout = 0 };
69045d3d 498
f0ef0b58
SK
499 static const struct option longopts[] = {
500 {"pid", required_argument, NULL, 'p'},
501 {"socket", required_argument, NULL, 's'},
502 {"timeout", required_argument, NULL, 'T'},
503 {"kill", no_argument, NULL, 'k'},
504 {"random", no_argument, NULL, 'r'},
505 {"time", no_argument, NULL, 't'},
506 {"uuids", required_argument, NULL, 'n'},
0abfbd9c 507 {"no-pid", no_argument, NULL, 'P'},
e1cf3ebe 508 {"no-fork", no_argument, NULL, 'F'},
bbe289c4 509 {"socket-activation", no_argument, NULL, 'S'},
f0ef0b58
SK
510 {"debug", no_argument, NULL, 'd'},
511 {"quiet", no_argument, NULL, 'q'},
512 {"version", no_argument, NULL, 'V'},
513 {"help", no_argument, NULL, 'h'},
514 {NULL, 0, NULL, 0}
515 };
516
69045d3d
KZ
517 setlocale(LC_ALL, "");
518 bindtextdomain(PACKAGE, LOCALEDIR);
519 textdomain(PACKAGE);
c05a80ca 520 atexit(close_stdout);
69045d3d 521
f0ef0b58 522 while ((c =
bbe289c4 523 getopt_long(argc, argv, "p:s:T:krtn:PFSdqVh", longopts,
f0ef0b58 524 NULL)) != -1) {
69045d3d
KZ
525 switch (c) {
526 case 'd':
4b1cf29d 527 uuidd_cxt.debug = 1;
69045d3d
KZ
528 break;
529 case 'k':
530 do_kill++;
69045d3d
KZ
531 break;
532 case 'n':
533 num = strtol(optarg, &tmp, 0);
38cf5001 534 if ((num < 1) || *tmp) {
69045d3d 535 fprintf(stderr, _("Bad number: %s\n"), optarg);
41dc5bc0 536 return EXIT_FAILURE;
69045d3d 537 }
b747e886 538 break;
69045d3d 539 case 'p':
0abfbd9c 540 pidfile_path_param = optarg;
0abfbd9c
PU
541 break;
542 case 'P':
543 no_pid = 1;
69045d3d 544 break;
e1cf3ebe 545 case 'F':
4b1cf29d 546 uuidd_cxt.no_fork = 1;
e1cf3ebe 547 break;
bbe289c4
PU
548 case 'S':
549#ifdef USE_SOCKET_ACTIVATION
4b1cf29d
KZ
550 uuidd_cxt.no_sock = 1;
551 uuidd_cxt.no_fork = 1;
bbe289c4
PU
552 no_pid = 1;
553#else
554 fprintf(stderr,
555 _("uuidd has been built without support for socket activation.\n"));
556 return EXIT_FAILURE;
557#endif
558 break;
69045d3d 559 case 'q':
4b1cf29d 560 uuidd_cxt.quiet = 1;
69045d3d 561 break;
3c062294
BS
562 case 'r':
563 do_type = UUIDD_OP_RANDOM_UUID;
3c062294 564 break;
69045d3d
KZ
565 case 's':
566 socket_path = optarg;
bbe289c4 567 s_flag = 1;
69045d3d
KZ
568 break;
569 case 't':
570 do_type = UUIDD_OP_TIME_UUID;
69045d3d
KZ
571 break;
572 case 'T':
4b1cf29d
KZ
573 uuidd_cxt.timeout = strtol(optarg, &tmp, 0);
574 if (uuidd_cxt.timeout < 0 || *tmp) {
69045d3d 575 fprintf(stderr, _("Bad number: %s\n"), optarg);
41dc5bc0 576 return EXIT_FAILURE;
69045d3d
KZ
577 }
578 break;
f0ef0b58 579 case 'V':
e421313d 580 printf(UTIL_LINUX_VERSION);
f0ef0b58
SK
581 return EXIT_SUCCESS;
582 case 'h':
583 usage(stdout);
69045d3d 584 default:
f0ef0b58 585 usage(stderr);
69045d3d
KZ
586 }
587 }
0abfbd9c 588
4b1cf29d 589 if (no_pid && pidfile_path_param && !uuidd_cxt.quiet)
0abfbd9c
PU
590 fprintf(stderr, _("Both --pid and --no-pid specified. "
591 "Ignoring --no-pid.\n"));
592
593 if (!no_pid && !pidfile_path_param)
594 pidfile_path = UUIDD_PIDFILE_PATH;
595 else if (pidfile_path_param)
596 pidfile_path = pidfile_path_param;
597
bbe289c4 598 /* custom socket path and socket-activation make no sense */
4b1cf29d 599 if (s_flag && uuidd_cxt.no_sock && !uuidd_cxt.quiet)
bbe289c4
PU
600 fprintf(stderr, _("Both --socket-activation and --socket specified. "
601 "Ignoring --socket\n"));
0abfbd9c 602
69045d3d 603 if (num && do_type) {
f7c297b8 604 ret = call_daemon(socket_path, do_type + 2, buf,
69045d3d
KZ
605 sizeof(buf), &num, &err_context);
606 if (ret < 0) {
960cf573 607 printf(_("Error calling uuidd daemon (%s): %m\n"), err_context);
41dc5bc0 608 return EXIT_FAILURE;
69045d3d
KZ
609 }
610 if (do_type == UUIDD_OP_TIME_UUID) {
611 if (ret != sizeof(uu) + sizeof(num))
2fb35353 612 unexpected_size(ret);
69045d3d
KZ
613
614 uuid_unparse((unsigned char *) buf, str);
615
0149cd84
BS
616 printf(P_("%s and %d subsequent UUID\n",
617 "%s and %d subsequent UUIDs\n", num - 1),
618 str, num - 1);
69045d3d 619 } else {
333ec749 620 printf(_("List of UUIDs:\n"));
69045d3d 621 cp = buf + 4;
f7c297b8 622 if (ret != (int) (sizeof(num) + num * sizeof(uu)))
2fb35353 623 unexpected_size(ret);
f7c297b8 624 for (i = 0; i < num; i++, cp += UUID_LEN) {
69045d3d
KZ
625 uuid_unparse((unsigned char *) cp, str);
626 printf("\t%s\n", str);
627 }
628 }
41dc5bc0 629 return EXIT_SUCCESS;
69045d3d
KZ
630 }
631 if (do_type) {
632 ret = call_daemon(socket_path, do_type, (char *) &uu,
633 sizeof(uu), 0, &err_context);
634 if (ret < 0) {
960cf573 635 printf(_("Error calling uuidd daemon (%s): %m\n"), err_context);
41dc5bc0 636 return EXIT_FAILURE;
69045d3d 637 }
2fb35353
SK
638 if (ret != sizeof(uu))
639 unexpected_size(ret);
640
69045d3d
KZ
641 uuid_unparse(uu, str);
642
643 printf("%s\n", str);
41dc5bc0 644 return EXIT_SUCCESS;
69045d3d
KZ
645 }
646
647 if (do_kill) {
2e9b39ef 648 ret = call_daemon(socket_path, UUIDD_OP_GETPID, buf, sizeof(buf), 0, NULL);
69045d3d
KZ
649 if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) {
650 ret = kill(do_kill, SIGTERM);
651 if (ret < 0) {
4b1cf29d 652 if (!uuidd_cxt.quiet)
69045d3d
KZ
653 fprintf(stderr,
654 _("Couldn't kill uuidd running "
960cf573 655 "at pid %d: %m\n"), do_kill);
41dc5bc0 656 return EXIT_FAILURE;
69045d3d 657 }
4b1cf29d 658 if (!uuidd_cxt.quiet)
69045d3d
KZ
659 printf(_("Killed uuidd running at pid %d\n"),
660 do_kill);
661 }
41dc5bc0 662 return EXIT_SUCCESS;
69045d3d
KZ
663 }
664
881a0f6b 665 server_loop(socket_path, pidfile_path, &uuidd_cxt);
41dc5bc0 666 return EXIT_SUCCESS;
69045d3d 667}