rfkill.c revision 354806fb4632575fe2e399dd90ca607c9c127f3b
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering/***
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering This file is part of systemd.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering Copyright 2013 Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering systemd is free software; you can redistribute it and/or modify it
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering under the terms of the GNU Lesser General Public License as published by
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering (at your option) any later version.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering systemd is distributed in the hope that it will be useful, but
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering Lesser General Public License for more details.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering You should have received a copy of the GNU Lesser General Public License
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering***/
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "util.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "mkdir.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "fileio.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "libudev.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering#include "udev-util.h"
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poetteringint main(int argc, char *argv[]) {
25300b5a1fcf54674a69d0f4ab08925be00b0227Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *device = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *saved = NULL, *escaped_name = NULL, *escaped_path_id = NULL;
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering const char *name, *path_id;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering int r;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (argc != 3) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("This program requires two arguments.");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_set_target(LOG_TARGET_AUTO);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_parse_environment();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_open();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering umask(0022);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = mkdir_p("/var/lib/systemd/rfkill", 0755);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to create rfkill directory: %s", strerror(-r));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering udev = udev_new();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!udev) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering errno = 0;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering device = udev_device_new_from_subsystem_sysname(udev, "rfkill", argv[2]);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!device) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (errno != 0)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to get rfkill device '%s': %m", argv[2]);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering else
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering name = udev_device_get_sysattr_value(device, "name");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!name) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("rfkill device has no name?");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering escaped_name = cescape(name);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!escaped_name) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering path_id = udev_device_get_property_value(device, "ID_PATH");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (path_id) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering escaped_path_id = cescape(path_id);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!escaped_path_id) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering saved = strjoin("/var/lib/systemd/rfkill/", escaped_path_id, ":", escaped_name, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering saved = strjoin("/var/lib/systemd/rfkill/", escaped_name, NULL);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!saved) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_oom();
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (streq(argv[1], "load")) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering _cleanup_free_ char *value = NULL;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!shall_restore_state())
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_SUCCESS;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = read_one_line_file(saved, &value);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r == -ENOENT)
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_SUCCESS;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to read %s: %s", saved, strerror(-r));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = udev_device_set_sysattr_value(device, "soft", value);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to write system attribute: %s", strerror(-r));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else if (streq(argv[1], "save")) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering const char *value;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering value = udev_device_get_sysattr_value(device, "soft");
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (!value) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to read system attribute: %s", strerror(-r));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering r = write_string_file(saved, value);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering if (r < 0) {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Failed to write %s: %s", saved, strerror(-r));
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering } else {
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering log_error("Unknown verb %s.", argv[1]);
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_FAILURE;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering }
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering return EXIT_SUCCESS;
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering}
b6e676ce41508e2aeea22202fc8f234126177f52Lennart Poettering