+ExecContext *unit_get_exec_context(Unit *u) {
+ size_t offset;
+ assert(u);
+
+ if (u->type < 0)
+ return NULL;
+
+ offset = UNIT_VTABLE(u)->exec_context_offset;
+ if (offset <= 0)
+ return NULL;
+
+ return (ExecContext*) ((uint8_t*) u + offset);
+}
+
+KillContext *unit_get_kill_context(Unit *u) {
+ size_t offset;
+ assert(u);
+
+ if (u->type < 0)
+ return NULL;
+
+ offset = UNIT_VTABLE(u)->kill_context_offset;
+ if (offset <= 0)
+ return NULL;
+
+ return (KillContext*) ((uint8_t*) u + offset);
+}
+
+CGroupContext *unit_get_cgroup_context(Unit *u) {
+ size_t offset;
+
+ if (u->type < 0)
+ return NULL;
+
+ offset = UNIT_VTABLE(u)->cgroup_context_offset;
+ if (offset <= 0)
+ return NULL;
+
+ return (CGroupContext*) ((uint8_t*) u + offset);
+}
+
+ExecRuntime *unit_get_exec_runtime(Unit *u) {
+ size_t offset;
+
+ if (u->type < 0)
+ return NULL;
+
+ offset = UNIT_VTABLE(u)->exec_runtime_offset;
+ if (offset <= 0)
+ return NULL;
+
+ return *(ExecRuntime**) ((uint8_t*) u + offset);
+}
+
+static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
+ if (u->manager->running_as == SYSTEMD_USER) {
+ int r;
+
+ if (mode == UNIT_PERSISTENT && !transient)
+ r = user_config_home(dir);
+ else
+ r = user_runtime_dir(dir);
+
+ if (r == 0)
+ return -ENOENT;
+ return r;
+ }
+
+ if (mode == UNIT_PERSISTENT && !transient)
+ *dir = strdup("/etc/systemd/system");
+ else
+ *dir = strdup("/run/systemd/system");
+ if (!*dir)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int unit_drop_in_file(Unit *u,
+ UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
+ _cleanup_free_ char *dir = NULL;
+ int r;
+
+ assert(u);
+
+ r = unit_drop_in_dir(u, mode, u->transient, &dir);
+ if (r < 0)
+ return r;
+
+ return drop_in_file(dir, u->id, 50, name, p, q);
+}
+
+int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
+
+ _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL;
+ int r;
+
+ assert(u);
+
+ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+ return 0;
+
+ r = unit_drop_in_dir(u, mode, u->transient, &dir);
+ if (r < 0)
+ return r;
+
+ r = write_drop_in(dir, u->id, 50, name, data);
+ if (r < 0)
+ return r;
+
+ r = drop_in_file(dir, u->id, 50, name, &p, &q);
+ if (r < 0)
+ return r;
+
+ r = strv_extend(&u->dropin_paths, q);
+ if (r < 0)
+ return r;
+
+ strv_sort(u->dropin_paths);
+ strv_uniq(u->dropin_paths);
+
+ u->dropin_mtime = now(CLOCK_REALTIME);
+
+ return 0;
+}
+
+int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
+ _cleanup_free_ char *p = NULL;
+ va_list ap;
+ int r;
+
+ assert(u);
+ assert(name);
+ assert(format);
+
+ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+ return 0;
+
+ va_start(ap, format);
+ r = vasprintf(&p, format, ap);
+ va_end(ap);
+
+ if (r < 0)
+ return -ENOMEM;
+
+ return unit_write_drop_in(u, mode, name, p);
+}
+
+int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
+ _cleanup_free_ char *ndata = NULL;
+
+ assert(u);
+ assert(name);
+ assert(data);
+
+ if (!UNIT_VTABLE(u)->private_section)
+ return -EINVAL;
+
+ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+ return 0;
+
+ ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
+ if (!ndata)
+ return -ENOMEM;
+
+ return unit_write_drop_in(u, mode, name, ndata);
+}
+
+int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
+ _cleanup_free_ char *p = NULL;
+ va_list ap;
+ int r;
+
+ assert(u);
+ assert(name);
+ assert(format);
+
+ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+ return 0;
+
+ va_start(ap, format);
+ r = vasprintf(&p, format, ap);
+ va_end(ap);
+
+ if (r < 0)
+ return -ENOMEM;
+
+ return unit_write_drop_in_private(u, mode, name, p);
+}
+
+int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
+ _cleanup_free_ char *p = NULL, *q = NULL;
+ int r;
+
+ assert(u);
+
+ if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
+ return 0;
+
+ r = unit_drop_in_file(u, mode, name, &p, &q);
+ if (r < 0)
+ return r;
+
+ if (unlink(q) < 0)
+ r = errno == ENOENT ? 0 : -errno;
+ else
+ r = 1;
+
+ rmdir(p);
+ return r;
+}
+
+int unit_make_transient(Unit *u) {