]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/cat.c
Unify parse_argv style
[thirdparty/systemd.git] / src / journal / cat.c
CommitLineData
755a02c6
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2012 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
755a02c6
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
755a02c6 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
755a02c6
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <getopt.h>
24#include <assert.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include <errno.h>
abad76cc 28#include <fcntl.h>
755a02c6 29
73f860db 30#include "systemd/sd-journal.h"
755a02c6
LP
31
32#include "util.h"
33#include "build.h"
34
35static char *arg_identifier = NULL;
d508ac0b 36static int arg_priority = LOG_INFO;
755a02c6
LP
37static bool arg_level_prefix = true;
38
601185b4 39static void help(void) {
755a02c6
LP
40 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
41 "Execute process with stdout/stderr connected to the journal.\n\n"
42 " -h --help Show this help\n"
43 " --version Show package version\n"
44 " -t --identifier=STRING Set syslog identifier\n"
45 " -p --priority=PRIORITY Set priority value (0..7)\n"
601185b4
ZJS
46 " --level-prefix=BOOL Control whether level prefix shall be parsed\n"
47 , program_invocation_short_name);
755a02c6
LP
48}
49
50static int parse_argv(int argc, char *argv[]) {
51
52 enum {
53 ARG_VERSION = 0x100,
54 ARG_LEVEL_PREFIX
55 };
56
57 static const struct option options[] = {
58 { "help", no_argument, NULL, 'h' },
9aac0b2c 59 { "version", no_argument, NULL, ARG_VERSION },
755a02c6
LP
60 { "identifier", required_argument, NULL, 't' },
61 { "priority", required_argument, NULL, 'p' },
62 { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX },
eb9da376 63 {}
755a02c6
LP
64 };
65
66 int c;
67
68 assert(argc >= 0);
69 assert(argv);
70
601185b4 71 while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0)
755a02c6
LP
72
73 switch (c) {
74
75 case 'h':
601185b4
ZJS
76 help();
77 return 0;
755a02c6
LP
78
79 case ARG_VERSION:
80 puts(PACKAGE_STRING);
755a02c6
LP
81 puts(SYSTEMD_FEATURES);
82 return 0;
83
84 case 't':
85 free(arg_identifier);
86 if (isempty(optarg))
87 arg_identifier = NULL;
88 else {
89 arg_identifier = strdup(optarg);
0d0f0c50
SL
90 if (!arg_identifier)
91 return log_oom();
755a02c6
LP
92 }
93 break;
94
95 case 'p':
96 arg_priority = log_level_from_string(optarg);
97 if (arg_priority < 0) {
98 log_error("Failed to parse priority value.");
99 return arg_priority;
100 }
101 break;
102
103 case ARG_LEVEL_PREFIX: {
104 int k;
105
106 k = parse_boolean(optarg);
107 if (k < 0) {
108 log_error("Failed to parse level prefix value.");
109 return k;
110 }
111 arg_level_prefix = k;
112 break;
113 }
114
eb9da376 115 case '?':
755a02c6 116 return -EINVAL;
eb9da376
LP
117
118 default:
119 assert_not_reached("Unhandled option");
755a02c6 120 }
755a02c6
LP
121
122 return 1;
123}
124
125int main(int argc, char *argv[]) {
126 int r, fd = -1, saved_stderr = -1;
127
128 log_parse_environment();
129 log_open();
130
131 r = parse_argv(argc, argv);
132 if (r <= 0)
133 goto finish;
134
135 fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix);
136 if (fd < 0) {
9aac0b2c 137 log_error("Failed to create stream fd: %s", strerror(-fd));
755a02c6
LP
138 r = fd;
139 goto finish;
140 }
141
142 saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
143
144 if (dup3(fd, STDOUT_FILENO, 0) < 0 ||
145 dup3(fd, STDERR_FILENO, 0) < 0) {
9aac0b2c 146 log_error("Failed to duplicate fd: %m");
755a02c6
LP
147 r = -errno;
148 goto finish;
149 }
150
151 if (fd >= 3)
03e334a1 152 safe_close(fd);
755a02c6
LP
153
154 fd = -1;
155
156 if (argc <= optind)
157 execl("/bin/cat", "/bin/cat", NULL);
158 else
159 execvp(argv[optind], argv + optind);
160
9aac0b2c
LP
161 r = -errno;
162
755a02c6
LP
163 /* Let's try to restore a working stderr, so we can print the error message */
164 if (saved_stderr >= 0)
165 dup3(saved_stderr, STDERR_FILENO, 0);
166
9aac0b2c 167 log_error("Failed to execute process: %s", strerror(-r));
755a02c6
LP
168
169finish:
03e334a1
LP
170 safe_close(fd);
171 safe_close(saved_stderr);
755a02c6
LP
172
173 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
174}