int main(int argc, char **argv) { const char *socket_path = UUIDD_SOCKET_PATH; const char *pidfile_path = NULL; const char *pidfile_path_param = NULL; const char *err_context; char buf[1024], *cp; char str[UUID_STR_LEN]; uuid_t uu; int i, c, ret; int do_type = 0, do_kill = 0, num = 0; int no_pid = 0; int s_flag = 0; struct uuidd_cxt_t uuidd_cxt = { .timeout = 0 }; static const struct option longopts[] = { {"pid", required_argument, NULL, 'p'}, {"socket", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 'T'}, {"kill", no_argument, NULL, 'k'}, {"random", no_argument, NULL, 'r'}, {"time", no_argument, NULL, 't'}, {"uuids", required_argument, NULL, 'n'}, {"no-pid", no_argument, NULL, 'P'}, {"no-fork", no_argument, NULL, 'F'}, {"socket-activation", no_argument, NULL, 'S'}, {"debug", no_argument, NULL, 'd'}, {"quiet", no_argument, NULL, 'q'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((c = getopt_long(argc, argv, "p:s:T:krtn:PFSdqVh", longopts, NULL)) != -1) { switch (c) { case 'd': uuidd_cxt.debug = 1; break; case 'k': do_kill++; break; case 'n': num = strtou32_or_err(optarg, _("failed to parse --uuids")); break; case 'p': pidfile_path_param = optarg; break; case 'P': no_pid = 1; break; case 'F': uuidd_cxt.no_fork = 1; break; case 'S': #ifdef USE_SOCKET_ACTIVATION uuidd_cxt.no_sock = 1; uuidd_cxt.no_fork = 1; no_pid = 1; #else errx(EXIT_FAILURE, _("uuidd has been built without " "support for socket activation")); #endif break; case 'q': uuidd_cxt.quiet = 1; break; case 'r': do_type = UUIDD_OP_RANDOM_UUID; break; case 's': socket_path = optarg; s_flag = 1; break; case 't': do_type = UUIDD_OP_TIME_UUID; break; case 'T': uuidd_cxt.timeout = strtou32_or_err(optarg, _("failed to parse --timeout")); break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case 'h': usage(stdout); default: usage(stderr); } } if (no_pid && pidfile_path_param && !uuidd_cxt.quiet) warnx(_("Both --pid and --no-pid specified. Ignoring --no-pid.")); if (!no_pid && !pidfile_path_param) pidfile_path = UUIDD_PIDFILE_PATH; else if (pidfile_path_param) pidfile_path = pidfile_path_param; /* custom socket path and socket-activation make no sense */ if (s_flag && uuidd_cxt.no_sock && !uuidd_cxt.quiet) warnx(_("Both --socket-activation and --socket specified. " "Ignoring --socket.")); if (num && do_type) { ret = call_daemon(socket_path, do_type + 2, buf, sizeof(buf), &num, &err_context); if (ret < 0) err(EXIT_FAILURE, _("error calling uuidd daemon (%s)"), err_context); if (do_type == UUIDD_OP_TIME_UUID) { if (ret != sizeof(uu) + sizeof(num)) unexpected_size(ret); uuid_unparse((unsigned char *) buf, str); printf(P_("%s and %d subsequent UUID\n", "%s and %d subsequent UUIDs\n", num - 1), str, num - 1); } else { printf(_("List of UUIDs:\n")); cp = buf + 4; if (ret != (int) (sizeof(num) + num * sizeof(uu))) unexpected_size(ret); for (i = 0; i < num; i++, cp += UUID_LEN) { uuid_unparse((unsigned char *) cp, str); printf("\t%s\n", str); } } return EXIT_SUCCESS; } if (do_type) { ret = call_daemon(socket_path, do_type, (char *) &uu, sizeof(uu), 0, &err_context); if (ret < 0) err(EXIT_FAILURE, _("error calling uuidd daemon (%s)"), err_context); if (ret != sizeof(uu)) unexpected_size(ret); uuid_unparse(uu, str); printf("%s\n", str); return EXIT_SUCCESS; } if (do_kill) { ret = call_daemon(socket_path, UUIDD_OP_GETPID, buf, sizeof(buf), 0, NULL); if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) { ret = kill(do_kill, SIGTERM); if (ret < 0) { if (!uuidd_cxt.quiet) warn(_("couldn't kill uuidd running " "at pid %d"), do_kill); return EXIT_FAILURE; } if (!uuidd_cxt.quiet) printf(_("Killed uuidd running at pid %d.\n"), do_kill); } return EXIT_SUCCESS; } server_loop(socket_path, pidfile_path, &uuidd_cxt); return EXIT_SUCCESS; }
int main(int argc, char **argv) { const char *socket_path = UUIDD_SOCKET_PATH; const char *pidfile_path = UUIDD_PIDFILE_PATH; const char *err_context; char buf[1024], *cp; char str[UUID_STR_LEN], *tmp; uuid_t uu; uid_t uid; gid_t gid; int i, c, ret; int debug = 0, do_type = 0, do_kill = 0, num = 0; int timeout = 0, quiet = 0, drop_privs = 0; static const struct option longopts[] = { {"pid", required_argument, NULL, 'p'}, {"socket", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 'T'}, {"kill", no_argument, NULL, 'k'}, {"random", no_argument, NULL, 'r'}, {"time", no_argument, NULL, 't'}, {"uuids", required_argument, NULL, 'n'}, {"debug", no_argument, NULL, 'd'}, {"quiet", no_argument, NULL, 'q'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt_long(argc, argv, "p:s:T:krtn:dqVh", longopts, NULL)) != -1) { switch (c) { case 'd': debug++; drop_privs = 1; break; case 'k': do_kill++; drop_privs = 1; break; case 'n': num = strtol(optarg, &tmp, 0); if ((num < 1) || *tmp) { fprintf(stderr, _("Bad number: %s\n"), optarg); return EXIT_FAILURE; } break; case 'p': pidfile_path = optarg; drop_privs = 1; break; case 'q': quiet++; break; case 'r': do_type = UUIDD_OP_RANDOM_UUID; drop_privs = 1; break; case 's': socket_path = optarg; drop_privs = 1; break; case 't': do_type = UUIDD_OP_TIME_UUID; drop_privs = 1; break; case 'T': timeout = strtol(optarg, &tmp, 0); if ((timeout < 0) || *tmp) { fprintf(stderr, _("Bad number: %s\n"), optarg); return EXIT_FAILURE; } break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); return EXIT_SUCCESS; case 'h': usage(stdout); default: usage(stderr); } } uid = getuid(); if (uid && drop_privs) { gid = getgid(); #ifdef HAVE_SETRESGID if (setresgid(gid, gid, gid) < 0) err(EXIT_FAILURE, "setresgid"); #else if (setregid(gid, gid) < 0) err(EXIT_FAILURE, "setregid"); #endif #ifdef HAVE_SETRESUID if (setresuid(uid, uid, uid) < 0) err(EXIT_FAILURE, "setresuid"); #else if (setreuid(uid, uid) < 0) err(EXIT_FAILURE, "setreuid"); #endif } if (num && do_type) { ret = call_daemon(socket_path, do_type + 2, buf, sizeof(buf), &num, &err_context); if (ret < 0) { printf(_("Error calling uuidd daemon (%s): %m\n"), err_context); return EXIT_FAILURE; } if (do_type == UUIDD_OP_TIME_UUID) { if (ret != sizeof(uu) + sizeof(num)) unexpected_size(ret); uuid_unparse((unsigned char *) buf, str); printf(P_("%s and %d subsequent UUID\n", "%s and %d subsequent UUIDs\n", num - 1), str, num - 1); } else { printf(_("List of UUIDs:\n")); cp = buf + 4; if (ret != (int) (sizeof(num) + num * sizeof(uu))) unexpected_size(ret); for (i = 0; i < num; i++, cp += UUID_LEN) { uuid_unparse((unsigned char *) cp, str); printf("\t%s\n", str); } } return EXIT_SUCCESS; } if (do_type) { ret = call_daemon(socket_path, do_type, (char *) &uu, sizeof(uu), 0, &err_context); if (ret < 0) { printf(_("Error calling uuidd daemon (%s): %m\n"), err_context); return EXIT_FAILURE; } if (ret != sizeof(uu)) unexpected_size(ret); uuid_unparse(uu, str); printf("%s\n", str); return EXIT_SUCCESS; } if (do_kill) { ret = call_daemon(socket_path, 0, buf, sizeof(buf), 0, 0); if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) { ret = kill(do_kill, SIGTERM); if (ret < 0) { if (!quiet) fprintf(stderr, _("Couldn't kill uuidd running " "at pid %d: %m\n"), do_kill); return EXIT_FAILURE; } if (!quiet) printf(_("Killed uuidd running at pid %d\n"), do_kill); } return EXIT_SUCCESS; } server_loop(socket_path, pidfile_path, debug, timeout, quiet); return EXIT_SUCCESS; }