]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/cat.c
util: split out escaping code into escape.[ch]
[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
755a02c6 22#include <errno.h>
abad76cc 23#include <fcntl.h>
3f6fd1ba
LP
24#include <getopt.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
755a02c6 28
3f6fd1ba 29#include "sd-journal.h"
755a02c6
LP
30
31#include "util.h"
755a02c6
LP
32
33static char *arg_identifier = NULL;
d508ac0b 34static int arg_priority = LOG_INFO;
755a02c6
LP
35static bool arg_level_prefix = true;
36
601185b4 37static void help(void) {
755a02c6
LP
38 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
39 "Execute process with stdout/stderr connected to the journal.\n\n"
40 " -h --help Show this help\n"
41 " --version Show package version\n"
42 " -t --identifier=STRING Set syslog identifier\n"
43 " -p --priority=PRIORITY Set priority value (0..7)\n"
601185b4
ZJS
44 " --level-prefix=BOOL Control whether level prefix shall be parsed\n"
45 , program_invocation_short_name);
755a02c6
LP
46}
47
48static int parse_argv(int argc, char *argv[]) {
49
50 enum {
51 ARG_VERSION = 0x100,
52 ARG_LEVEL_PREFIX
53 };
54
55 static const struct option options[] = {
56 { "help", no_argument, NULL, 'h' },
9aac0b2c 57 { "version", no_argument, NULL, ARG_VERSION },
755a02c6
LP
58 { "identifier", required_argument, NULL, 't' },
59 { "priority", required_argument, NULL, 'p' },
60 { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX },
eb9da376 61 {}
755a02c6
LP
62 };
63
64 int c;
65
66 assert(argc >= 0);
67 assert(argv);
68
601185b4 69 while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0)
755a02c6
LP
70
71 switch (c) {
72
73 case 'h':
601185b4
ZJS
74 help();
75 return 0;
755a02c6
LP
76
77 case ARG_VERSION:
3f6fd1ba 78 return version();
755a02c6
LP
79
80 case 't':
81 free(arg_identifier);
82 if (isempty(optarg))
83 arg_identifier = NULL;
84 else {
85 arg_identifier = strdup(optarg);
0d0f0c50
SL
86 if (!arg_identifier)
87 return log_oom();
755a02c6
LP
88 }
89 break;
90
91 case 'p':
92 arg_priority = log_level_from_string(optarg);
93 if (arg_priority < 0) {
94 log_error("Failed to parse priority value.");
e4603df5 95 return -EINVAL;
755a02c6
LP
96 }
97 break;
98
99 case ARG_LEVEL_PREFIX: {
100 int k;
101
102 k = parse_boolean(optarg);
939c173f
LP
103 if (k < 0)
104 return log_error_errno(k, "Failed to parse level prefix value.");
105
755a02c6
LP
106 arg_level_prefix = k;
107 break;
108 }
109
eb9da376 110 case '?':
755a02c6 111 return -EINVAL;
eb9da376
LP
112
113 default:
114 assert_not_reached("Unhandled option");
755a02c6 115 }
755a02c6
LP
116
117 return 1;
118}
119
120int main(int argc, char *argv[]) {
939c173f
LP
121 _cleanup_close_ int fd = -1, saved_stderr = -1;
122 int r;
755a02c6
LP
123
124 log_parse_environment();
125 log_open();
126
127 r = parse_argv(argc, argv);
128 if (r <= 0)
129 goto finish;
130
131 fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix);
132 if (fd < 0) {
939c173f 133 r = log_error_errno(fd, "Failed to create stream fd: %m");
755a02c6
LP
134 goto finish;
135 }
136
137 saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
138
139 if (dup3(fd, STDOUT_FILENO, 0) < 0 ||
140 dup3(fd, STDERR_FILENO, 0) < 0) {
76ef789d 141 r = log_error_errno(errno, "Failed to duplicate fd: %m");
755a02c6
LP
142 goto finish;
143 }
144
145 if (fd >= 3)
03e334a1 146 safe_close(fd);
755a02c6
LP
147 fd = -1;
148
149 if (argc <= optind)
939c173f 150 (void) execl("/bin/cat", "/bin/cat", NULL);
755a02c6 151 else
939c173f 152 (void) execvp(argv[optind], argv + optind);
9aac0b2c
LP
153 r = -errno;
154
755a02c6
LP
155 /* Let's try to restore a working stderr, so we can print the error message */
156 if (saved_stderr >= 0)
939c173f 157 (void) dup3(saved_stderr, STDERR_FILENO, 0);
755a02c6 158
da927ba9 159 log_error_errno(r, "Failed to execute process: %m");
755a02c6
LP
160
161finish:
755a02c6
LP
162 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
163}