builtins.c revision 58903013084b649fa81e9fd3310517d0e35e7c5d
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/*
2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2008 The Android Open Source Project
3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License.
6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at
7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software
11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and
14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License.
15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */
16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/types.h>
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/stat.h>
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <fcntl.h>
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <unistd.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <string.h>
225bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <stdio.h>
235bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <linux/kd.h>
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <errno.h>
2543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber#include <sys/socket.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <netinet/in.h>
275bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <linux/if.h>
285bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <arpa/inet.h>
295bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <stdlib.h>
305bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <sys/mount.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/resource.h>
323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#include <linux/loop.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <cutils/partition_utils.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <sys/system_properties.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#ifdef HAVE_SELINUX
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <selinux/selinux.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <selinux/label.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
401173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "init.h"
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "keywords.h"
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "property_service.h"
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "devices.h"
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "init_parser.h"
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "util.h"
479b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber#include "log.h"
489b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <private/android_filesystem_config.h>
505bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Hubervoid add_environment(const char *name, const char *value);
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberextern int init_module(void *, unsigned long, const char *);
541aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
551aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberstatic int write_file(const char *path, const char *value)
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int fd, ret, len;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fd = open(path, O_WRONLY|O_CREAT, 0622);
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
619b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    if (fd < 0)
629b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        return -errno;
639b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
649b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    len = strlen(value);
659b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
6643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    do {
6743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        ret = write(fd, value, len);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } while (ret < 0 && errno == EINTR);
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    close(fd);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ret < 0) {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -errno;
735bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    } else {
745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        return 0;
755bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    }
765bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
775bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
785bc087c573c70c84c6a39946457590b42d392a33Andreas Huberstatic int _open(const char *path)
795bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int fd;
819b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fd = open(path, O_RDONLY | O_NOFOLLOW);
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (fd < 0)
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        fd = open(path, O_WRONLY | O_NOFOLLOW);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    return fd;
871173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
881173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
891173118eace0e9e347cb007f0da817cee87579edGlenn Kastenstatic int _chown(const char *path, unsigned int uid, unsigned int gid)
901173118eace0e9e347cb007f0da817cee87579edGlenn Kasten{
911173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    int fd;
921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    int ret;
931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    fd = _open(path);
951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (fd < 0) {
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -1;
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ret = fchown(fd, uid, gid);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ret < 0) {
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int errno_copy = errno;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        close(fd);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        errno = errno_copy;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -1;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    close(fd);
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    return 0;
110b408222bd9479c291874b607acae1425d6154fe7Andreas Huber}
11143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
11243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberstatic int _chmod(const char *path, mode_t mode)
11343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber{
114b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    int fd;
11543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int ret;
11643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
1171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    fd = _open(path);
1181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (fd < 0) {
1191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -1;
1201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
12143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
12243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    ret = fchmod(fd, mode);
12343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (ret < 0) {
12443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        int errno_copy = errno;
12543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        close(fd);
12643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        errno = errno_copy;
12753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        return -1;
1281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
12953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
13053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    close(fd);
1311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
1321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
13353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
13453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
13553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huberstatic int insmod(const char *filename, char *options)
1361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber{
1371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    void *module;
1381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    unsigned size;
13953df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    int ret;
14053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
14153df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    module = read_file(filename, &size);
14253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if (!module)
14353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        return -1;
14453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
14553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    ret = init_module(module, size, options);
14653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    free(module);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return ret;
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1511aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int setkey(struct kbentry *kbe)
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int fd, ret;
1555bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
1565bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    fd = open("/dev/tty0", O_RDWR | O_SYNC);
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (fd < 0)
1585bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        return -1;
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ret = ioctl(fd, KDSKBENT, kbe);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1621173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    close(fd);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return ret;
1641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int __ifupdown(const char *interface, int up)
1671173118eace0e9e347cb007f0da817cee87579edGlenn Kasten{
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct ifreq ifr;
1691173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    int s, ret;
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    strlcpy(ifr.ifr_name, interface, IFNAMSIZ);
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    s = socket(AF_INET, SOCK_DGRAM, 0);
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (s < 0)
1751aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -1;
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ret = ioctl(s, SIOCGIFFLAGS, &ifr);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (ret < 0) {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        goto done;
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (up)
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ifr.ifr_flags |= IFF_UP;
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    else
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ifr.ifr_flags &= ~IFF_UP;
18643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
18743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    ret = ioctl(s, SIOCSIFFLAGS, &ifr);
1881aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
1891aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberdone:
19032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    close(s);
19132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    return ret;
1921aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
1935bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void service_start_if_not_disabled(struct service *svc)
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!(svc->flags & SVC_DISABLED)) {
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        service_start(svc, NULL);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2011aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_chdir(int nargs, char **args)
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    chdir(args[1]);
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_chroot(int nargs, char **args)
2081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber{
2091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    chroot(args[1]);
2101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
2111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
2121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_class_start(int nargs, char **args)
2145bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
2155bc087c573c70c84c6a39946457590b42d392a33Andreas Huber        /* Starting a class does not start services
21643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber         * which are explicitly disabled.  They must
21743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber         * be started individually.
21843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber         */
2195bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    service_for_each_class(args[1], service_start_if_not_disabled);
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2225bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_class_stop(int nargs, char **args)
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
2255bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    service_for_each_class(args[1], service_stop);
2261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
2271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
2281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
2291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_class_reset(int nargs, char **args)
2301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber{
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    service_for_each_class(args[1], service_reset);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_domainname(int nargs, char **args)
2365bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return write_file("/proc/sys/kernel/domainname", args[1]);
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_exec(int nargs, char **args)
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return -1;
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_export(int nargs, char **args)
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    add_environment(args[1], args[2]);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_hostname(int nargs, char **args)
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return write_file("/proc/sys/kernel/hostname", args[1]);
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2565bc087c573c70c84c6a39946457590b42d392a33Andreas Huberint do_ifup(int nargs, char **args)
2575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
2585bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    return __ifupdown(args[1], 1);
2595bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic int do_insmod_inner(int nargs, char **args, int opt_len)
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
2641aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    char options[opt_len + 1];
26553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    int i;
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2671aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    options[0] = '\0';
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (nargs > 2) {
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strcpy(options, args[2]);
2701aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        for (i = 3; i < nargs; ++i) {
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            strcat(options, " ");
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            strcat(options, args[i]);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2741aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2761aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return insmod(args[1], options);
2771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
27853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_insmod(int nargs, char **args)
28053df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber{
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int i;
28253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    int size = 0;
28353df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber
28453df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    if (nargs > 2) {
28553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber        for (i = 2; i < nargs; ++i)
28653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber            size += strlen(args[i]) + 1;
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
2893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    return do_insmod_inner(nargs, args, size);
2902c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber}
29131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
29231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huberint do_mkdir(int nargs, char **args)
29331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber{
2942c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber    mode_t mode = 0755;
29531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    int ret;
29631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2972c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber    /* mkdir <path> [mode] [owner] [group] */
29831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
29931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    if (nargs >= 3) {
3002c2814b900a61fa07ddfff860b143fbbe9c740e9Andreas Huber        mode = strtoul(args[2], 0, 8);
30131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
30231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
30331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    ret = mkdir(args[1], mode);
3043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    /* chmod in case the directory already exists */
30531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    if (ret == -1 && errno == EEXIST) {
30631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        ret = _chmod(args[1], mode);
30731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
30831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    if (ret == -1) {
30931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        return -errno;
31031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
31131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
31231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    if (nargs >= 4) {
31331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        uid_t uid = decode_uid(args[3]);
31431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        gid_t gid = -1;
31531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
31631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        if (nargs == 5) {
31731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            gid = decode_uid(args[4]);
31831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
31931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
32031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        if (_chown(args[1], uid, gid) < 0) {
32131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            return -errno;
32231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
32331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
32431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
32531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    return 0;
32631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
32731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3283831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huberstatic struct {
3291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    const char *name;
3303831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    unsigned flag;
3313831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber} mount_flags[] = {
3323831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "noatime",    MS_NOATIME },
3333831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "nosuid",     MS_NOSUID },
3343831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "nodev",      MS_NODEV },
3353831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "nodiratime", MS_NODIRATIME },
3363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "ro",         MS_RDONLY },
3373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "rw",         0 },
3383831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "remount",    MS_REMOUNT },
3393831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { "defaults",   0 },
3403831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    { 0,            0 },
3413831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber};
3423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
343c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber#define DATA_MNT_POINT "/data"
344c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
345c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber/* mount <type> <device> <path> <flags ...> <options> */
346c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huberint do_mount(int nargs, char **args)
347c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber{
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char tmp[64];
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char *source, *target, *system;
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char *options = NULL;
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    unsigned flags = 0;
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int n, i;
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int wait = 0;
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (n = 4; n < nargs; n++) {
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (i = 0; mount_flags[i].name; i++) {
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!strcmp(args[n], mount_flags[i].name)) {
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                flags |= mount_flags[i].flag;
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!mount_flags[i].name) {
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!strcmp(args[n], "wait"))
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                wait = 1;
366c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            /* if our last argument isn't a flag, wolf it up as an option string */
367c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            else if (n + 1 == nargs)
368c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                options = args[n];
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    system = args[1];
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    source = args[2];
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    target = args[3];
375c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
376c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (!strncmp(source, "mtd@", 4)) {
377c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        n = mtd_name_to_number(source + 4);
378c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        if (n < 0) {
379c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            return -1;
380c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        }
381c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
382c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        sprintf(tmp, "/dev/block/mtdblock%d", n);
383c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (wait)
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            wait_for_file(tmp, COMMAND_RETRY_TIMEOUT);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mount(tmp, target, system, flags, options) < 0) {
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return -1;
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
38943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
39043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        goto exit_success;
39143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    } else if (!strncmp(source, "loop@", 5)) {
39243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        int mode, loop, fd;
39343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        struct loop_info info;
39443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
39543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
39643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        fd = open(source + 5, mode);
39743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (fd < 0) {
39843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            return -1;
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (n = 0; ; n++) {
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sprintf(tmp, "/dev/block/loop%d", n);
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            loop = open(tmp, mode);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (loop < 0) {
4051aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                return -1;
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            /* if it is a blank loop device */
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                /* if it becomes our loop device */
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    close(fd);
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (mount(tmp, target, system, flags, options) < 0) {
4151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                        ioctl(loop, LOOP_CLR_FD, 0);
4161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                        close(loop);
4171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                        return -1;
4181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    }
4191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    close(loop);
4211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                    goto exit_success;
4221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber                }
4231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            }
4241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            close(loop);
4261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
4271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
4281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        close(fd);
4291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        ERROR("out of loopback devices");
4301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -1;
4311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
4321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (wait)
4331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            wait_for_file(source, COMMAND_RETRY_TIMEOUT);
4341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (mount(source, target, system, flags, options) < 0) {
4351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            /* If this fails, it may be an encrypted filesystem
4361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * or it could just be wiped.  If wiped, that will be
4371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * handled later in the boot process.
4381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * We only support encrypting /data.  Check
4391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * if we're trying to mount it, and if so,
4401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * assume it's encrypted, mount a tmpfs instead.
4411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * Then save the orig mount parms in properties
4421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * for vold to query when it mounts the real
4431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             * encrypted /data.
4441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber             */
4451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            if (!strcmp(target, DATA_MNT_POINT) && !partition_wiped(source)) {
44643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                const char *tmpfs_options;
44743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
44843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                tmpfs_options = property_get("ro.crypto.tmpfs_options");
44943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
45043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                if (mount("tmpfs", target, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
45122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber                    tmpfs_options) < 0) {
45243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                    return -1;
45343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                }
45443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
45543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                /* Set the property that triggers the framework to do a minimal
45643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 * startup and ask the user for a password
45743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                 */
45843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                property_set("ro.crypto.state", "encrypted");
45943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                property_set("vold.decrypt", "1");
46043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            } else {
46143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber                return -1;
46243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber            }
46343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        }
46443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
46543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (!strcmp(target, DATA_MNT_POINT)) {
466b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            char fs_flags[32];
467b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
468b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            /* Save the original mount options */
469b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            property_set("ro.crypto.fs_type", system);
470b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            property_set("ro.crypto.fs_real_blkdev", source);
471b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            property_set("ro.crypto.fs_mnt_point", target);
472b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            if (options) {
473b408222bd9479c291874b607acae1425d6154fe7Andreas Huber                property_set("ro.crypto.fs_options", options);
474b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            }
475b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            snprintf(fs_flags, sizeof(fs_flags), "0x%8.8x", flags);
476b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            property_set("ro.crypto.fs_flags", fs_flags);
477b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
478b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    }
479b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huberexit_success:
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /* If not running encrypted, then set the property saying we are
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * unencrypted, and also trigger the action for a nonencrypted system.
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcmp(target, DATA_MNT_POINT)) {
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *prop;
4863831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4873831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        prop = property_get("ro.crypto.state");
4883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        if (! prop) {
4893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            prop = "notset";
4903831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        }
4913831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        if (strcmp(prop, "encrypted")) {
4923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            property_set("ro.crypto.state", "unencrypted");
4933831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber            action_for_each_trigger("nonencrypted", action_add_queue_tail);
4943831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        }
4951aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
4963831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
4973831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    return 0;
4983831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
49922fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber}
5003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
5013831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huberint do_setcon(int nargs, char **args) {
5023831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#ifdef HAVE_SELINUX
50322fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    if (is_selinux_enabled() <= 0)
5043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return 0;
5053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    if (setcon(args[1]) < 0) {
5063831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber        return -errno;
5073831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber    }
5083831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber#endif
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
5101aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
5111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_setenforce(int nargs, char **args) {
5131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber#ifdef HAVE_SELINUX
5141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (is_selinux_enabled() <= 0)
5151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return 0;
5161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (security_setenforce(atoi(args[1])) < 0) {
5171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -errno;
51822fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber    }
5191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber#endif
5201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
5211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
5221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_setkey(int nargs, char **args)
5241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber{
5251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    struct kbentry kbe;
5261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    kbe.kb_table = strtoul(args[1], 0, 0);
5271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    kbe.kb_index = strtoul(args[2], 0, 0);
5281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    kbe.kb_value = strtoul(args[3], 0, 0);
5291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return setkey(&kbe);
53043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
53143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
53243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberint do_setprop(int nargs, char **args)
53343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber{
53443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    const char *name = args[1];
53543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    const char *value = args[2];
5361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    char prop_val[PROP_VALUE_MAX];
5371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    int ret;
5381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
5391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    ret = expand_props(prop_val, value, sizeof(prop_val));
5401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (ret) {
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ERROR("cannot expand '%s' while assigning to '%s'\n", value, name);
5421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -EINVAL;
5431aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
5441aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    property_set(name, prop_val);
5451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
5461aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
5471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_setrlimit(int nargs, char **args)
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
5505bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    struct rlimit limit;
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int resource;
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    resource = atoi(args[1]);
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    limit.rlim_cur = atoi(args[2]);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    limit.rlim_max = atoi(args[3]);
5555bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    return setrlimit(resource, &limit);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5575bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_start(int nargs, char **args)
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct service *svc;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    svc = service_find_by_name(args[1]);
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (svc) {
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        service_start(svc, NULL);
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5651173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    return 0;
5661173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_stop(int nargs, char **args)
5695bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct service *svc;
57143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    svc = service_find_by_name(args[1]);
57243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (svc) {
57343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        service_stop(svc);
57443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
57543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    return 0;
57643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
57743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
57843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberint do_restart(int nargs, char **args)
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct service *svc;
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    svc = service_find_by_name(args[1]);
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (svc) {
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        service_stop(svc);
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        service_start(svc, NULL);
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
58653df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    return 0;
58753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_trigger(int nargs, char **args)
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    action_for_each_trigger(args[1], action_add_queue_tail);
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5945bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_symlink(int nargs, char **args)
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return symlink(args[1], args[2]);
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6005bc087c573c70c84c6a39946457590b42d392a33Andreas Huberint do_rm(int nargs, char **args)
6015bc087c573c70c84c6a39946457590b42d392a33Andreas Huber{
6025bc087c573c70c84c6a39946457590b42d392a33Andreas Huber    return unlink(args[1]);
6035bc087c573c70c84c6a39946457590b42d392a33Andreas Huber}
6045bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
60553df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huberint do_rmdir(int nargs, char **args)
6061aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber{
60753df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber    return rmdir(args[1]);
60853df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber}
60932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
61032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huberint do_sysclktz(int nargs, char **args)
61132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber{
61232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    struct timezone tz;
61332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
61432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (nargs != 2)
61532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        return -1;
61632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
61732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    memset(&tz, 0, sizeof(tz));
61832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    tz.tz_minuteswest = atoi(args[1]);
61932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (settimeofday(NULL, &tz))
62032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        return -1;
62132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    return 0;
62232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber}
62332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
62432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huberint do_write(int nargs, char **args)
62532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber{
62632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    const char *path = args[1];
62732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    const char *value = args[2];
62832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    char prop_val[PROP_VALUE_MAX];
62932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    int ret;
63032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
63132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    ret = expand_props(prop_val, value, sizeof(prop_val));
63232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    if (ret) {
63332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        ERROR("cannot expand '%s' while writing to '%s'\n", value, path);
6341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -EINVAL;
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return write_file(path, prop_val);
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_copy(int nargs, char **args)
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber{
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char *buffer = NULL;
64243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    int rc = 0;
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int fd1 = -1, fd2 = -1;
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct stat info;
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int brtw, brtr;
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    char *p;
6471aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (nargs != 3)
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -1;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (stat(args[1], &info) < 0)
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -1;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((fd1 = open(args[1], O_RDONLY)) < 0)
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        goto out_err;
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((fd2 = open(args[2], O_WRONLY|O_CREAT|O_TRUNC, 0660)) < 0)
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        goto out_err;
65943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!(buffer = malloc(info.st_size)))
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        goto out_err;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    p = buffer;
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    brtr = info.st_size;
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while(brtr) {
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        rc = read(fd1, p, brtr);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (rc < 0)
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            goto out_err;
66932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (rc == 0)
67032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            break;
67132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        p += rc;
67232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        brtr -= rc;
67332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
67432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
67532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    p = buffer;
67632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    brtw = info.st_size;
67732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    while(brtw) {
67832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        rc = write(fd2, p, brtw);
67932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (rc < 0)
68032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            goto out_err;
68132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        if (rc == 0)
68232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            break;
68332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        p += rc;
68432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        brtw -= rc;
68532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    }
68632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
68732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    rc = 0;
68832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    goto out;
68932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huberout_err:
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    rc = -1;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huberout:
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (buffer)
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        free(buffer);
69443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (fd1 >= 0)
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        close(fd1);
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (fd2 >= 0)
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        close(fd2);
69843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    return rc;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
70043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint do_chown(int nargs, char **args) {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /* GID is optional. */
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (nargs == 3) {
70443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        if (_chown(args[2], decode_uid(args[1]), -1) < 0)
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return -errno;
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (nargs == 4) {
7071aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (_chown(args[3], decode_uid(args[1]), decode_uid(args[2])) < 0)
7081aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            return -errno;
7091aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    } else {
71043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return -1;
7111aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
7121aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
7131aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
7141aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7151aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberstatic mode_t get_mode(const char *s) {
7161aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mode_t mode = 0;
7171aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    while (*s) {
7181aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        if (*s >= '0' && *s <= '7') {
7191aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            mode = (mode<<3) | (*s-'0');
7201aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        } else {
7211aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber            return -1;
7221aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        }
7231aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        s++;
7241aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
7251aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return mode;
7261aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
7271aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7281aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_chmod(int nargs, char **args) {
7291aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    mode_t mode = get_mode(args[1]);
7301aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (_chmod(args[2], mode) < 0) {
7311aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber        return -errno;
7321aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    }
7331aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    return 0;
7341aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber}
7351aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huberint do_restorecon(int nargs, char **args) {
7371aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber#ifdef HAVE_SELINUX
7381aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    char *secontext = NULL;
7391aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    struct stat sb;
7401aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    int i;
7411aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber
7421aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber    if (is_selinux_enabled() <= 0 || !sehandle)
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return 0;
744
745    for (i = 1; i < nargs; i++) {
746        if (lstat(args[i], &sb) < 0)
747            return -errno;
748        if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0)
749            return -errno;
750        if (lsetfilecon(args[i], secontext) < 0) {
751            freecon(secontext);
752            return -errno;
753        }
754        freecon(secontext);
755    }
756#endif
757    return 0;
758}
759
760int do_setsebool(int nargs, char **args) {
761#ifdef HAVE_SELINUX
762    SELboolean *b = alloca(nargs * sizeof(SELboolean));
763    char *v;
764    int i;
765
766    if (is_selinux_enabled() <= 0)
767        return 0;
768
769    for (i = 1; i < nargs; i++) {
770        char *name = args[i];
771        v = strchr(name, '=');
772        if (!v) {
773            ERROR("setsebool: argument %s had no =\n", name);
774            return -EINVAL;
775        }
776        *v++ = 0;
777        b[i-1].name = name;
778        if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on"))
779            b[i-1].value = 1;
780        else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off"))
781            b[i-1].value = 0;
782        else {
783            ERROR("setsebool: invalid value %s\n", v);
784            return -EINVAL;
785        }
786    }
787
788    if (security_set_boolean_list(nargs - 1, b, 0) < 0)
789        return -errno;
790#endif
791    return 0;
792}
793
794int do_loglevel(int nargs, char **args) {
795    if (nargs == 2) {
796        klog_set_level(atoi(args[1]));
797        return 0;
798    }
799    return -1;
800}
801
802int do_load_persist_props(int nargs, char **args) {
803    if (nargs == 1) {
804        load_persist_props();
805        return 0;
806    }
807    return -1;
808}
809
810int do_wait(int nargs, char **args)
811{
812    if (nargs == 2) {
813        return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT);
814    }
815    return -1;
816}
817