~ubuntu-branches/debian/jessie/systemd/jessie

« back to all changes in this revision

Viewing changes to src/journal/journalctl.c

  • Committer: Package Import Robot
  • Author(s): Tollef Fog Heen, Tollef Fog Heen, Michael Biebl
  • Date: 2012-04-03 19:59:17 UTC
  • mfrom: (1.1.10) (6.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20120403195917-l532urrbg4pkreas
Tags: 44-1
[ Tollef Fog Heen ]
* New upstream version.
  - Backport 3492207: journal: PAGE_SIZE is not known on ppc and other
    archs
  - Backport 5a2a2a1: journal: react with immediate rotation to a couple
    of more errors
  - Backport 693ce21: util: never follow symlinks in rm_rf_children()
    Fixes CVE-2012-1174, closes: #664364
* Drop output message from init-functions hook, it's pointless.
* Only rmdir /lib/init/rw if it exists.
* Explicitly order debian-fixup before sysinit.target to prevent a
  possible race condition with the creation of sockets.  Thanks to
  Michael Biebl for debugging this.
* Always restart the initctl socket on upgrades, to mask sysvinit
  removing it.

[ Michael Biebl ]
* Remove workaround for non-interactive sessions from pam config again.
* Create compat /dev/initctl symlink in case we are upgrading from a system
  running a newer version of sysvinit (using /run/initctl) and sysvinit is
  replaced with systemd-sysv during the upgrade. Closes: #663219
* Install new man pages.
* Build-Depend on valac (>= 0.12) instead of valac-0.12. Closes: #663323

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
2
 
 
3
/***
 
4
  This file is part of systemd.
 
5
 
 
6
  Copyright 2011 Lennart Poettering
 
7
 
 
8
  systemd is free software; you can redistribute it and/or modify it
 
9
  under the terms of the GNU General Public License as published by
 
10
  the Free Software Foundation; either version 2 of the License, or
 
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
 
16
  General Public License for more details.
 
17
 
 
18
  You should have received a copy of the GNU General Public License
 
19
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
20
***/
 
21
 
 
22
#include <fcntl.h>
 
23
#include <errno.h>
 
24
#include <stddef.h>
 
25
#include <string.h>
 
26
#include <stdio.h>
 
27
#include <unistd.h>
 
28
#include <stdlib.h>
 
29
#include <sys/poll.h>
 
30
#include <time.h>
 
31
#include <getopt.h>
 
32
 
 
33
#include <systemd/sd-journal.h>
 
34
 
 
35
#include "log.h"
 
36
#include "util.h"
 
37
#include "build.h"
 
38
#include "pager.h"
 
39
#include "logs-show.h"
 
40
 
 
41
static OutputMode arg_output = OUTPUT_SHORT;
 
42
static bool arg_follow = false;
 
43
static bool arg_show_all = false;
 
44
static bool arg_no_pager = false;
 
45
static int arg_lines = -1;
 
46
static bool arg_no_tail = false;
 
47
static bool arg_new_id128 = false;
 
48
static bool arg_quiet = false;
 
49
 
 
50
static int help(void) {
 
51
 
 
52
        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
 
53
               "Send control commands to or query the journal.\n\n"
 
54
               "  -h --help           Show this help\n"
 
55
               "     --version        Show package version\n"
 
56
               "     --no-pager       Do not pipe output into a pager\n"
 
57
               "  -a --all            Show all fields, including long and unprintable\n"
 
58
               "  -f --follow         Follow journal\n"
 
59
               "  -n --lines=INTEGER  Journal entries to show\n"
 
60
               "     --no-tail        Show all lines, even in follow mode\n"
 
61
               "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
 
62
               "                      verbose, export, json, cat)\n"
 
63
               "  -q --quiet          Don't show privilege warning\n"
 
64
               "     --new-id128      Generate a new 128 Bit id\n",
 
65
               program_invocation_short_name);
 
66
 
 
67
        return 0;
 
68
}
 
69
 
 
70
static int parse_argv(int argc, char *argv[]) {
 
71
 
 
72
        enum {
 
73
                ARG_VERSION = 0x100,
 
74
                ARG_NO_PAGER,
 
75
                ARG_NO_TAIL,
 
76
                ARG_NEW_ID128
 
77
        };
 
78
 
 
79
        static const struct option options[] = {
 
80
                { "help",      no_argument,       NULL, 'h'           },
 
81
                { "version" ,  no_argument,       NULL, ARG_VERSION   },
 
82
                { "no-pager",  no_argument,       NULL, ARG_NO_PAGER  },
 
83
                { "follow",    no_argument,       NULL, 'f'           },
 
84
                { "output",    required_argument, NULL, 'o'           },
 
85
                { "all",       no_argument,       NULL, 'a'           },
 
86
                { "lines",     required_argument, NULL, 'n'           },
 
87
                { "no-tail",   no_argument,       NULL, ARG_NO_TAIL   },
 
88
                { "new-id128", no_argument,       NULL, ARG_NEW_ID128 },
 
89
                { "quiet",     no_argument,       NULL, 'q'           },
 
90
                { NULL,        0,                 NULL, 0             }
 
91
        };
 
92
 
 
93
        int c, r;
 
94
 
 
95
        assert(argc >= 0);
 
96
        assert(argv);
 
97
 
 
98
        while ((c = getopt_long(argc, argv, "hfo:an:q", options, NULL)) >= 0) {
 
99
 
 
100
                switch (c) {
 
101
 
 
102
                case 'h':
 
103
                        help();
 
104
                        return 0;
 
105
 
 
106
                case ARG_VERSION:
 
107
                        puts(PACKAGE_STRING);
 
108
                        puts(DISTRIBUTION);
 
109
                        puts(SYSTEMD_FEATURES);
 
110
                        return 0;
 
111
 
 
112
                case ARG_NO_PAGER:
 
113
                        arg_no_pager = true;
 
114
                        break;
 
115
 
 
116
                case 'f':
 
117
                        arg_follow = true;
 
118
                        break;
 
119
 
 
120
                case 'o':
 
121
                        arg_output =  output_mode_from_string(optarg);
 
122
                        if (arg_output < 0) {
 
123
                                log_error("Unknown output '%s'.", optarg);
 
124
                                return -EINVAL;
 
125
                        }
 
126
 
 
127
                        break;
 
128
 
 
129
                case 'a':
 
130
                        arg_show_all = true;
 
131
                        break;
 
132
 
 
133
                case 'n':
 
134
                        r = safe_atoi(optarg, &arg_lines);
 
135
                        if (r < 0 || arg_lines < 0) {
 
136
                                log_error("Failed to parse lines '%s'", optarg);
 
137
                                return -EINVAL;
 
138
                        }
 
139
                        break;
 
140
 
 
141
                case ARG_NO_TAIL:
 
142
                        arg_no_tail = true;
 
143
                        break;
 
144
 
 
145
                case ARG_NEW_ID128:
 
146
                        arg_new_id128 = true;
 
147
                        break;
 
148
 
 
149
                case 'q':
 
150
                        arg_quiet = true;
 
151
                        break;
 
152
 
 
153
                case '?':
 
154
                        return -EINVAL;
 
155
 
 
156
                default:
 
157
                        log_error("Unknown option code %c", c);
 
158
                        return -EINVAL;
 
159
                }
 
160
        }
 
161
 
 
162
        if (arg_follow && !arg_no_tail && arg_lines < 0)
 
163
                arg_lines = 10;
 
164
 
 
165
        return 1;
 
166
}
 
167
 
 
168
static int generate_new_id128(void) {
 
169
        sd_id128_t id;
 
170
        int r;
 
171
        unsigned i;
 
172
 
 
173
        r = sd_id128_randomize(&id);
 
174
        if (r < 0) {
 
175
                log_error("Failed to generate ID: %s", strerror(-r));
 
176
                return r;
 
177
        }
 
178
 
 
179
        printf("As string:\n"
 
180
               SD_ID128_FORMAT_STR "\n\n"
 
181
               "As UUID:\n"
 
182
               "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
 
183
               "As macro:\n"
 
184
              "#define MESSAGE_XYZ SD_ID128_MAKE(",
 
185
               SD_ID128_FORMAT_VAL(id),
 
186
               SD_ID128_FORMAT_VAL(id));
 
187
 
 
188
        for (i = 0; i < 16; i++)
 
189
                printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
 
190
 
 
191
        fputs(")\n", stdout);
 
192
 
 
193
        return 0;
 
194
}
 
195
 
 
196
int main(int argc, char *argv[]) {
 
197
        int r, i, fd;
 
198
        sd_journal *j = NULL;
 
199
        unsigned line = 0;
 
200
        bool need_seek = false;
 
201
 
 
202
        log_parse_environment();
 
203
        log_open();
 
204
 
 
205
        r = parse_argv(argc, argv);
 
206
        if (r <= 0)
 
207
                goto finish;
 
208
 
 
209
        if (arg_new_id128) {
 
210
                r = generate_new_id128();
 
211
                goto finish;
 
212
        }
 
213
 
 
214
#ifdef HAVE_ACL
 
215
        if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0)
 
216
                log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this message off.");
 
217
#endif
 
218
 
 
219
        r = sd_journal_open(&j, 0);
 
220
        if (r < 0) {
 
221
                log_error("Failed to open journal: %s", strerror(-r));
 
222
                goto finish;
 
223
        }
 
224
 
 
225
        for (i = optind; i < argc; i++) {
 
226
                r = sd_journal_add_match(j, argv[i], strlen(argv[i]));
 
227
                if (r < 0) {
 
228
                        log_error("Failed to add match: %s", strerror(-r));
 
229
                        goto finish;
 
230
                }
 
231
        }
 
232
 
 
233
        fd = sd_journal_get_fd(j);
 
234
        if (fd < 0) {
 
235
                log_error("Failed to get wakeup fd: %s", strerror(-fd));
 
236
                goto finish;
 
237
        }
 
238
 
 
239
        if (arg_lines >= 0) {
 
240
                r = sd_journal_seek_tail(j);
 
241
                if (r < 0) {
 
242
                        log_error("Failed to seek to tail: %s", strerror(-r));
 
243
                        goto finish;
 
244
                }
 
245
 
 
246
                r = sd_journal_previous_skip(j, arg_lines);
 
247
        } else {
 
248
                r = sd_journal_seek_head(j);
 
249
                if (r < 0) {
 
250
                        log_error("Failed to seek to head: %s", strerror(-r));
 
251
                        goto finish;
 
252
                }
 
253
 
 
254
                r = sd_journal_next(j);
 
255
        }
 
256
 
 
257
        if (r < 0) {
 
258
                log_error("Failed to iterate through journal: %s", strerror(-r));
 
259
                goto finish;
 
260
        }
 
261
 
 
262
        if (!arg_no_pager && !arg_follow) {
 
263
                columns();
 
264
                pager_open();
 
265
        }
 
266
 
 
267
        if (arg_output == OUTPUT_JSON) {
 
268
                fputc('[', stdout);
 
269
                fflush(stdout);
 
270
        }
 
271
 
 
272
        for (;;) {
 
273
                for (;;) {
 
274
                        if (need_seek) {
 
275
                                r = sd_journal_next(j);
 
276
                                if (r < 0) {
 
277
                                        log_error("Failed to iterate through journal: %s", strerror(-r));
 
278
                                        goto finish;
 
279
                                }
 
280
                        }
 
281
 
 
282
                        if (r == 0)
 
283
                                break;
 
284
 
 
285
                        line ++;
 
286
 
 
287
                        r = output_journal(j, arg_output, line, 0, arg_show_all);
 
288
                        if (r < 0)
 
289
                                goto finish;
 
290
 
 
291
                        need_seek = true;
 
292
                }
 
293
 
 
294
                if (!arg_follow)
 
295
                        break;
 
296
 
 
297
                r = fd_wait_for_event(fd, POLLIN, (usec_t) -1);
 
298
                if (r < 0) {
 
299
                        log_error("Couldn't wait for event: %s", strerror(-r));
 
300
                        goto finish;
 
301
                }
 
302
 
 
303
                r = sd_journal_process(j);
 
304
                if (r < 0) {
 
305
                        log_error("Failed to process: %s", strerror(-r));
 
306
                        goto finish;
 
307
                }
 
308
        }
 
309
 
 
310
        if (arg_output == OUTPUT_JSON)
 
311
                fputs("\n]\n", stdout);
 
312
 
 
313
finish:
 
314
        if (j)
 
315
                sd_journal_close(j);
 
316
 
 
317
        pager_close();
 
318
 
 
319
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
320
}