]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/rc-local-generator/rc-local-generator.c
use "Out of memory." consistantly (or with "\n")
[thirdparty/systemd.git] / src / rc-local-generator / rc-local-generator.c
CommitLineData
15673083
MS
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 Copyright 2011 Michal Schmidt
8
9 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
15673083
MS
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 17 Lesser General Public License for more details.
15673083 18
5430f7f2 19 You should have received a copy of the GNU Lesser General Public License
15673083
MS
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <errno.h>
24#include <stdio.h>
25#include <unistd.h>
26
27#include "log.h"
28#include "util.h"
49e942b2 29#include "mkdir.h"
15673083
MS
30
31#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
04b6f7c1 32#define SCRIPT_PATH_START "/etc/rc.d/rc.local"
15673083 33#elif defined(TARGET_SUSE)
04b6f7c1 34#define SCRIPT_PATH_START "/etc/init.d/boot.local"
15673083
MS
35#endif
36
04b6f7c1
LP
37#define SCRIPT_PATH_STOP "/sbin/halt.local"
38
15673083
MS
39const char *arg_dest = "/tmp";
40
04b6f7c1 41static int add_symlink(const char *service, const char *where) {
15673083
MS
42 char *from = NULL, *to = NULL;
43 int r;
44
45 assert(service);
46
47 asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
04b6f7c1 48 asprintf(&to, "%s/%s.wants/%s", arg_dest, where, service);
15673083
MS
49
50 if (!from || !to) {
669241a0 51 log_error("Out of memory.");
15673083
MS
52 r = -ENOMEM;
53 goto finish;
54 }
55
d2e54fae 56 mkdir_parents_label(to, 0755);
15673083
MS
57
58 r = symlink(from, to);
59 if (r < 0) {
60 if (errno == EEXIST)
61 r = 0;
62 else {
63 log_error("Failed to create symlink from %s to %s: %m", from, to);
64 r = -errno;
65 }
66 }
67
68finish:
15673083
MS
69 free(from);
70 free(to);
71
72 return r;
73}
74
75static bool file_is_executable(const char *f) {
76 struct stat st;
77
78 if (stat(f, &st) < 0)
79 return false;
80
81 return S_ISREG(st.st_mode) && (st.st_mode & 0111);
82}
83
84int main(int argc, char *argv[]) {
15673083
MS
85 int r = EXIT_SUCCESS;
86
07719a21
LP
87 if (argc > 1 && argc != 4) {
88 log_error("This program takes three or no arguments.");
15673083
MS
89 return EXIT_FAILURE;
90 }
91
07719a21
LP
92 if (argc > 1)
93 arg_dest = argv[1];
94
a6903061 95 log_set_target(LOG_TARGET_SAFE);
15673083
MS
96 log_parse_environment();
97 log_open();
98
07719a21 99 umask(0022);
15673083 100
04b6f7c1 101 if (file_is_executable(SCRIPT_PATH_START)) {
15673083
MS
102 log_debug("Automatically adding rc-local.service.");
103
04b6f7c1 104 if (add_symlink("rc-local.service", "multi-user.target") < 0)
15673083 105 r = EXIT_FAILURE;
04b6f7c1 106 }
15673083 107
04b6f7c1
LP
108 if (file_is_executable(SCRIPT_PATH_STOP)) {
109 log_debug("Automatically adding halt-local.service.");
110
111 if (add_symlink("halt-local.service", "final.target") < 0)
112 r = EXIT_FAILURE;
15673083
MS
113 }
114
115 return r;
116}