2015-10-26 21:16:26 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
/***
|
|
|
|
This file is part of systemd.
|
|
|
|
|
|
|
|
Copyright 2010 Lennart Poettering
|
|
|
|
|
|
|
|
systemd is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
systemd is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
2015-11-18 22:46:33 +01:00
|
|
|
#include <limits.h>
|
2015-11-30 21:43:37 +01:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
2015-10-27 14:58:05 +01:00
|
|
|
#include <sys/inotify.h>
|
|
|
|
#include <sys/types.h>
|
2015-10-26 21:16:26 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "time-util.h"
|
|
|
|
|
|
|
|
int unlink_noerrno(const char *path);
|
|
|
|
|
|
|
|
int rmdir_parents(const char *path, const char *stop);
|
|
|
|
|
|
|
|
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
|
|
|
|
|
|
|
|
int readlinkat_malloc(int fd, const char *p, char **ret);
|
|
|
|
int readlink_malloc(const char *p, char **r);
|
|
|
|
int readlink_value(const char *p, char **ret);
|
|
|
|
int readlink_and_make_absolute(const char *p, char **r);
|
2016-11-18 21:35:21 +01:00
|
|
|
int readlink_and_canonicalize(const char *p, const char *root, char **r);
|
install: follow unit file symlinks in /usr, but not /etc when looking for [Install] data
Some distributions use alias unit files via symlinks in /usr to cover
for legacy service names. With this change we'll allow "systemctl
enable" on such aliases.
Previously, our rule was that symlinks are user configuration that
"systemctl enable" + "systemctl disable" creates and removes, while unit
files is where the instructions to do so are store. As a result of the
rule we'd never read install information through symlinks, since that
would mix enablement state with installation instructions.
Now, the new rule is that only symlinks inside of /etc are
configuration. Unit files, and symlinks in /usr are now valid for
installation instructions.
This patch is quite a rework of the whole install logic, and makes the
following addional changes:
- Adds a complete test "test-instal-root" that tests the install logic
pretty comprehensively.
- Never uses canonicalize_file_name(), because that's incompatible with
operation relative to a specific root directory.
- unit_file_get_state() is reworked to return a proper error, and
returns the state in a call-by-ref parameter. This cleans up confusion
between the enum type and errno-like errors.
- The new logic puts a limit on how long to follow unit file symlinks:
it will do so only for 64 steps at max.
- The InstallContext object's fields are renamed to will_process and
has_processed (will_install and has_installed) since they are also
used for deinstallation and all kinds of other operations.
- The root directory is always verified before use.
- install.c is reordered to place the exported functions together.
- Stricter rules are followed when traversing symlinks: the unit suffix
must say identical, and it's not allowed to link between regular units
and templated units.
- Various modernizations
- The "invalid" unit file state has been renamed to "bad", in order to
avoid confusion between UNIT_FILE_INVALID and
_UNIT_FILE_STATE_INVALID. Given that the state should normally not be
seen and is not documented this should not be a problematic change.
The new name is now documented however.
Fixes #1375, #1718, #1706
2015-10-08 22:31:56 +02:00
|
|
|
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
|
2015-10-26 21:16:26 +01:00
|
|
|
|
|
|
|
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
|
|
|
|
|
|
|
int fchmod_umask(int fd, mode_t mode);
|
|
|
|
|
|
|
|
int fd_warn_permissions(const char *path, int fd);
|
|
|
|
|
|
|
|
#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
|
|
|
|
|
|
|
|
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
|
|
|
|
int touch(const char *path);
|
|
|
|
|
|
|
|
int symlink_idempotent(const char *from, const char *to);
|
|
|
|
|
|
|
|
int symlink_atomic(const char *from, const char *to);
|
|
|
|
int mknod_atomic(const char *path, mode_t mode, dev_t dev);
|
|
|
|
int mkfifo_atomic(const char *path, mode_t mode);
|
|
|
|
|
|
|
|
int get_files_in_directory(const char *path, char ***list);
|
2015-10-27 14:58:05 +01:00
|
|
|
|
2016-07-26 17:23:28 +02:00
|
|
|
int tmp_dir(const char **ret);
|
|
|
|
int var_tmp_dir(const char **ret);
|
2016-06-30 16:59:06 +02:00
|
|
|
|
2015-10-27 14:58:05 +01:00
|
|
|
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
|
|
|
|
|
|
|
|
#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
|
|
|
|
for ((e) = &buffer.ev; \
|
|
|
|
(uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
|
|
|
|
(e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
|
|
|
|
|
|
|
|
union inotify_event_buffer {
|
|
|
|
struct inotify_event ev;
|
|
|
|
uint8_t raw[INOTIFY_EVENT_MAX];
|
|
|
|
};
|
2016-04-25 00:18:27 +02:00
|
|
|
|
|
|
|
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
2016-09-24 12:41:30 +02:00
|
|
|
|
2016-11-29 16:49:30 +01:00
|
|
|
enum {
|
|
|
|
CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
|
2016-11-29 18:02:45 +01:00
|
|
|
CHASE_NON_EXISTING = 2, /* If set, it's OK if the path doesn't actually exist. */
|
2016-11-29 16:49:30 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
|