static int automount_add_mount_links(Automount *a) { _cleanup_free_ char *parent = NULL; assert(a); parent = dirname_malloc(a->where); if (!parent) return -ENOMEM; return unit_require_mounts_for(UNIT(a), parent); }
static int generate_path(char **var, char **filenames) { char **filename; _cleanup_strv_free_ char **ans = NULL; int r; STRV_FOREACH(filename, filenames) { char *t; t = dirname_malloc(*filename); if (!t) return -ENOMEM; r = strv_consume(&ans, t); if (r < 0) return r; }
static int prepare_filename(const char *filename, char **ret) { int r; const char *name; _cleanup_free_ char *abspath = NULL; _cleanup_free_ char *dir = NULL; _cleanup_free_ char *with_instance = NULL; char *c; assert(filename); assert(ret); r = path_make_absolute_cwd(filename, &abspath); if (r < 0) return r; name = basename(abspath); if (!unit_name_is_valid(name, UNIT_NAME_ANY)) return -EINVAL; if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE)) { r = unit_name_replace_instance(name, "i", &with_instance); if (r < 0) return r; } dir = dirname_malloc(abspath); if (!dir) return -ENOMEM; if (with_instance) c = path_join(NULL, dir, with_instance); else c = path_join(NULL, dir, name); if (!c) return -ENOMEM; *ret = c; return 0; }
static int node_symlink(sd_device *dev, const char *node, const char *slink) { _cleanup_free_ char *slink_dirname = NULL, *target = NULL; const char *id_filename, *slink_tmp; struct stat stats; int r; assert(dev); assert(node); assert(slink); slink_dirname = dirname_malloc(slink); if (!slink_dirname) return log_oom(); /* use relative link */ r = path_make_relative(slink_dirname, node, &target); if (r < 0) return log_device_error_errno(dev, r, "Failed to get relative path from '%s' to '%s': %m", slink, node); /* preserve link with correct target, do not replace node of other device */ if (lstat(slink, &stats) == 0) { if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) { log_device_error(dev, "Conflicting device node '%s' found, link to '%s' will not be created.", slink, node); return -EOPNOTSUPP; } else if (S_ISLNK(stats.st_mode)) { _cleanup_free_ char *buf = NULL; if (readlink_malloc(slink, &buf) >= 0 && streq(target, buf)) { log_device_debug(dev, "Preserve already existing symlink '%s' to '%s'", slink, target); (void) label_fix(slink, LABEL_IGNORE_ENOENT); (void) utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW); return 0; } } } else { log_device_debug(dev, "Creating symlink '%s' to '%s'", slink, target); do { r = mkdir_parents_label(slink, 0755); if (!IN_SET(r, 0, -ENOENT)) break; mac_selinux_create_file_prepare(slink, S_IFLNK); if (symlink(target, slink) < 0) r = -errno; mac_selinux_create_file_clear(); } while (r == -ENOENT); if (r == 0) return 0; if (r < 0) log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s', trying to replace '%s': %m", slink, target, slink); } log_device_debug(dev, "Atomically replace '%s'", slink); r = device_get_id_filename(dev, &id_filename); if (r < 0) return log_device_error_errno(dev, r, "Failed to get id_filename: %m"); slink_tmp = strjoina(slink, ".tmp-", id_filename); (void) unlink(slink_tmp); do { r = mkdir_parents_label(slink_tmp, 0755); if (!IN_SET(r, 0, -ENOENT)) break; mac_selinux_create_file_prepare(slink_tmp, S_IFLNK); if (symlink(target, slink_tmp) < 0) r = -errno; mac_selinux_create_file_clear(); } while (r == -ENOENT); if (r < 0) return log_device_error_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink_tmp, target); if (rename(slink_tmp, slink) < 0) { r = log_device_error_errno(dev, errno, "Failed to rename '%s' to '%s' failed: %m", slink_tmp, slink); (void) unlink(slink_tmp); } return r; }
static long write_catalog(const char *database, Hashmap *h, struct strbuf *sb, CatalogItem *items, size_t n) { CatalogHeader header; _cleanup_fclose_ FILE *w = NULL; int r; _cleanup_free_ char *d, *p = NULL; size_t k; d = dirname_malloc(database); if (!d) return log_oom(); r = mkdir_p(d, 0775); if (r < 0) { log_error("Recursive mkdir %s: %s", d, strerror(-r)); return r; } r = fopen_temporary(database, &w, &p); if (r < 0) { log_error("Failed to open database for writing: %s: %s", database, strerror(-r)); return r; } zero(header); memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature)); header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)); header.catalog_item_size = htole64(sizeof(CatalogItem)); header.n_items = htole64(hashmap_size(h)); r = -EIO; k = fwrite(&header, 1, sizeof(header), w); if (k != sizeof(header)) { log_error("%s: failed to write header.", p); goto error; } k = fwrite(items, 1, n * sizeof(CatalogItem), w); if (k != n * sizeof(CatalogItem)) { log_error("%s: failed to write database.", p); goto error; } k = fwrite(sb->buf, 1, sb->len, w); if (k != sb->len) { log_error("%s: failed to write strings.", p); goto error; } fflush(w); if (ferror(w)) { log_error("%s: failed to write database.", p); goto error; } fchmod(fileno(w), 0644); if (rename(p, database) < 0) { log_error("rename (%s -> %s) failed: %m", p, database); r = -errno; goto error; } return ftell(w); error: unlink(p); return r; }