rc-local-generator.c revision 49e942b2bc9fdedba79cd266a076ce9c9d91fc13
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering/***
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering This file is part of systemd.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Copyright 2010 Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Copyright 2011 Michal Schmidt
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering under the terms of the GNU General Public License as published by
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering the Free Software Foundation; either version 2 of the License, or
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering (at your option) any later version.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is distributed in the hope that it will be useful, but
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering General Public License for more details.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering You should have received a copy of the GNU General Public License
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering***/
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering#include <errno.h>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include <stdio.h>
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include <unistd.h>
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "log.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "util.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include "mkdir.h"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#define SCRIPT_PATH "/etc/rc.d/rc.local"
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering#elif defined(TARGET_SUSE)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#define SCRIPT_PATH "/etc/init.d/boot.local"
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#endif
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringconst char *arg_dest = "/tmp";
e7d179acb9f50dec4a16c6c222dd147d7e53c6bbLennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic int add_symlink(const char *service) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering char *from = NULL, *to = NULL;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering int r;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering assert(service);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering asprintf(&to, "%s/multi-user.target.wants/%s", arg_dest, service);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering if (!from || !to) {
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering log_error("Out of memory");
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering r = -ENOMEM;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering goto finish;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering }
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering mkdir_parents(to, 0755);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = symlink(from, to);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (r < 0) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (errno == EEXIST)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering r = 0;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering else {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering log_error("Failed to create symlink from %s to %s: %m", from, to);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering r = -errno;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering }
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringfinish:
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering free(from);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering free(to);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering return r;
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering}
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringstatic bool file_is_executable(const char *f) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering struct stat st;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (stat(f, &st) < 0)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return false;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return S_ISREG(st.st_mode) && (st.st_mode & 0111);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering}
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringint main(int argc, char *argv[]) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering int r = EXIT_SUCCESS;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (argc > 2) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering log_error("This program takes one or no arguments.");
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return EXIT_FAILURE;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering }
105e151299dc1208855380be2b22d0db2d66ebc6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering log_set_target(LOG_TARGET_AUTO);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering log_parse_environment();
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering log_open();
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (argc > 1)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering arg_dest = argv[1];
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (file_is_executable(SCRIPT_PATH)) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering log_debug("Automatically adding rc-local.service.");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (add_symlink("rc-local.service") < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering r = EXIT_FAILURE;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return r;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering