]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/getty-generator/getty-generator.c
bootchart items
[thirdparty/systemd.git] / src / getty-generator / getty-generator.c
CommitLineData
2a796654
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 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
2a796654
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.
2a796654 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
2a796654
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <string.h>
23#include <errno.h>
24#include <unistd.h>
25
26#include "log.h"
27#include "util.h"
49e942b2 28#include "mkdir.h"
2a796654 29#include "unit-name.h"
5dc4c17f 30#include "virt.h"
2a796654 31
6a39419f 32static const char *arg_dest = "/tmp";
2a796654
LP
33
34static int add_symlink(const char *fservice, const char *tservice) {
35 char *from = NULL, *to = NULL;
36 int r;
37
4dc380d1
LP
38 assert(fservice);
39 assert(tservice);
40
07719a21 41 from = strappend(SYSTEM_DATA_UNIT_PATH "/", fservice);
b7def684 42 to = strjoin(arg_dest,"/getty.target.wants/", tservice, NULL);
2a796654
LP
43
44 if (!from || !to) {
0d0f0c50 45 r = log_oom();
2a796654
LP
46 goto finish;
47 }
48
d2e54fae 49 mkdir_parents_label(to, 0755);
2a796654 50
a17b785b
LP
51 r = symlink(from, to);
52 if (r < 0) {
53 if (errno == EEXIST)
3c20189a 54 /* In case console=hvc0 is passed this will very likely result in EEXIST */
a17b785b
LP
55 r = 0;
56 else {
57 log_error("Failed to create symlink from %s to %s: %m", from, to);
58 r = -errno;
59 }
2a796654
LP
60 }
61
62finish:
63
64 free(from);
65 free(to);
66
67 return r;
68}
69
4dc380d1
LP
70static int add_serial_getty(const char *tty) {
71 char *n;
72 int r;
73
74 assert(tty);
75
76 log_debug("Automatically adding serial getty for /dev/%s.", tty);
77
78 n = unit_name_replace_instance("serial-getty@.service", tty);
0d0f0c50
SL
79 if (!n)
80 return log_oom();
4dc380d1
LP
81
82 r = add_symlink("serial-getty@.service", n);
83 free(n);
84
85 return r;
86}
87
2a796654 88int main(int argc, char *argv[]) {
3c20189a
LP
89
90 static const char virtualization_consoles[] =
91 "hvc0\0"
92 "xvc0\0"
93 "hvsi0\0";
94
2a796654
LP
95 int r = EXIT_SUCCESS;
96 char *active;
3c20189a 97 const char *j;
2a796654 98
07719a21
LP
99 if (argc > 1 && argc != 4) {
100 log_error("This program takes three or no arguments.");
2a796654
LP
101 return EXIT_FAILURE;
102 }
103
07719a21
LP
104 if (argc > 1)
105 arg_dest = argv[1];
106
a6903061 107 log_set_target(LOG_TARGET_SAFE);
2a796654
LP
108 log_parse_environment();
109 log_open();
110
4c12626c
LP
111 umask(0022);
112
2a796654 113 if (detect_container(NULL) > 0) {
6705c2df 114 log_debug("Automatically adding console shell.");
2a796654 115
337eebb9 116 if (add_symlink("console-getty.service", "console-getty.service") < 0)
2a796654
LP
117 r = EXIT_FAILURE;
118
119 /* Don't add any further magic if we are in a container */
120 goto finish;
121 }
122
123 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
124 const char *tty;
125
a17b785b
LP
126 tty = strrchr(active, ' ');
127 if (tty)
2a796654
LP
128 tty ++;
129 else
130 tty = active;
131
132 /* Automatically add in a serial getty on the kernel
133 * console */
a705d085 134 if (isempty(tty) || tty_is_vc(tty))
3c20189a
LP
135 free(active);
136 else {
3c20189a 137 int k;
2a796654
LP
138
139 /* We assume that gettys on virtual terminals are
140 * started via manual configuration and do this magic
141 * only for non-VC terminals. */
142
4dc380d1 143 k = add_serial_getty(tty);
3c20189a
LP
144 free(active);
145
3c20189a
LP
146 if (k < 0) {
147 r = EXIT_FAILURE;
148 goto finish;
149 }
150 }
2a796654
LP
151 }
152
153 /* Automatically add in a serial getty on the first
154 * virtualizer console */
3c20189a 155 NULSTR_FOREACH(j, virtualization_consoles) {
4dc380d1 156 char *p;
3c20189a 157 int k;
2a796654 158
3c20189a 159 if (asprintf(&p, "/sys/class/tty/%s", j) < 0) {
0d0f0c50 160 log_oom();
2a796654 161 r = EXIT_FAILURE;
3c20189a
LP
162 goto finish;
163 }
980fc73d 164
3c20189a
LP
165 k = access(p, F_OK);
166 free(p);
167
168 if (k < 0)
169 continue;
980fc73d 170
4dc380d1 171 k = add_serial_getty(j);
3c20189a
LP
172 if (k < 0) {
173 r = EXIT_FAILURE;
174 goto finish;
175 }
2a796654
LP
176 }
177
178finish:
179 return r;
180}