199ca880aSopenharmony_ci/***
299ca880aSopenharmony_ci  This file is part of eudev, forked from systemd.
399ca880aSopenharmony_ci
499ca880aSopenharmony_ci  Copyright 2010-2012 Lennart Poettering
599ca880aSopenharmony_ci
699ca880aSopenharmony_ci  systemd is free software; you can redistribute it and/or modify it
799ca880aSopenharmony_ci  under the terms of the GNU Lesser General Public License as published by
899ca880aSopenharmony_ci  the Free Software Foundation; either version 2.1 of the License, or
999ca880aSopenharmony_ci  (at your option) any later version.
1099ca880aSopenharmony_ci
1199ca880aSopenharmony_ci  systemd is distributed in the hope that it will be useful, but
1299ca880aSopenharmony_ci  WITHOUT ANY WARRANTY; without even the implied warranty of
1399ca880aSopenharmony_ci  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1499ca880aSopenharmony_ci  Lesser General Public License for more details.
1599ca880aSopenharmony_ci
1699ca880aSopenharmony_ci  You should have received a copy of the GNU Lesser General Public License
1799ca880aSopenharmony_ci  along with systemd; If not, see <http://www.gnu.org/licenses/>.
1899ca880aSopenharmony_ci***/
1999ca880aSopenharmony_ci
2099ca880aSopenharmony_ci#include <errno.h>
2199ca880aSopenharmony_ci#include <sys/stat.h>
2299ca880aSopenharmony_ci#include <stdlib.h>
2399ca880aSopenharmony_ci#include <string.h>
2499ca880aSopenharmony_ci#include <assert.h>
2599ca880aSopenharmony_ci#include <unistd.h>
2699ca880aSopenharmony_ci
2799ca880aSopenharmony_ci#include "log.h"
2899ca880aSopenharmony_ci#include "macro.h"
2999ca880aSopenharmony_ci#include "util.h"
3099ca880aSopenharmony_ci#include "label.h"
3199ca880aSopenharmony_ci#include "path-util.h"
3299ca880aSopenharmony_ci#include "dev-setup.h"
3399ca880aSopenharmony_ci
3499ca880aSopenharmony_ciint dev_setup(const char *prefix, uid_t uid, gid_t gid) {
3599ca880aSopenharmony_ci        static const char symlinks[] =
3699ca880aSopenharmony_ci                "-/proc/kcore\0"     "/dev/core\0"
3799ca880aSopenharmony_ci                "/proc/self/fd\0"    "/dev/fd\0"
3899ca880aSopenharmony_ci                "/proc/self/fd/0\0"  "/dev/stdin\0"
3999ca880aSopenharmony_ci                "/proc/self/fd/1\0"  "/dev/stdout\0"
4099ca880aSopenharmony_ci                "/proc/self/fd/2\0"  "/dev/stderr\0";
4199ca880aSopenharmony_ci
4299ca880aSopenharmony_ci        const char *j, *k;
4399ca880aSopenharmony_ci        int r;
4499ca880aSopenharmony_ci
4599ca880aSopenharmony_ci        NULSTR_FOREACH_PAIR(j, k, symlinks) {
4699ca880aSopenharmony_ci                _cleanup_free_ char *link_name = NULL;
4799ca880aSopenharmony_ci                const char *n;
4899ca880aSopenharmony_ci
4999ca880aSopenharmony_ci                if (j[0] == '-') {
5099ca880aSopenharmony_ci                        j++;
5199ca880aSopenharmony_ci
5299ca880aSopenharmony_ci                        if (access(j, F_OK) < 0)
5399ca880aSopenharmony_ci                                continue;
5499ca880aSopenharmony_ci                }
5599ca880aSopenharmony_ci
5699ca880aSopenharmony_ci                if (prefix) {
5799ca880aSopenharmony_ci                        link_name = prefix_root(prefix, k);
5899ca880aSopenharmony_ci                        if (!link_name)
5999ca880aSopenharmony_ci                                return -ENOMEM;
6099ca880aSopenharmony_ci
6199ca880aSopenharmony_ci                        n = link_name;
6299ca880aSopenharmony_ci                } else
6399ca880aSopenharmony_ci                        n = k;
6499ca880aSopenharmony_ci
6599ca880aSopenharmony_ci                r = symlink_label(j, n);
6699ca880aSopenharmony_ci                if (r < 0)
6799ca880aSopenharmony_ci                        log_debug_errno(r, "Failed to symlink %s to %s: %m", j, n);
6899ca880aSopenharmony_ci
6999ca880aSopenharmony_ci                if (uid != UID_INVALID || gid != GID_INVALID)
7099ca880aSopenharmony_ci                        if (lchown(n, uid, gid) < 0)
7199ca880aSopenharmony_ci                                log_debug_errno(errno, "Failed to chown %s: %m", n);
7299ca880aSopenharmony_ci        }
7399ca880aSopenharmony_ci
7499ca880aSopenharmony_ci        return 0;
7599ca880aSopenharmony_ci}
76