bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "test-lib.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "path-util.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "unlink-directory.h"
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi#include "str.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include <unistd.h>
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen#include <fcntl.h>
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include <stdlib.h>
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include <sys/stat.h>
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#define TEMP_DIRNAME ".test-path-util"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainenstatic const char *tmpdir;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic const char *cwd;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic const char *link1;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic const char *link2;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic const char *link3;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainenstatic const char *link4;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_local_path(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *expected = t_strconcat(cwd, "/README.md", NULL);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("README.md", cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, expected);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_absolute_path_no_change(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("/", "/", &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, "/");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to(cwd, cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic int path_height(const char *p)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi int n;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi for (n = 0; *p != '\0'; ++p)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi n += *p == '/';
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi return n;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_travel_to_root(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi int l = path_height(cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = cwd;
9b5576a265cbadb1f0b3c3d5e40e928e1fed1ec9Timo Sirainen for (npath = cwd; l != 0; l--) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *error;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_idx(t_normpath_to("../", npath, &npath, &error) == 0, l);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi }
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, "/");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_extra_slashes(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to(".", cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("./", cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to(".////", cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_nonexistent_path(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *expected = t_strconcat(cwd, "/nonexistent", NULL);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("nonexistent", cwd, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, expected);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_realpath_to("nonexistent", cwd, &npath, &error) == -1);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(error != NULL);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_relative_dotdot(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen const char *rel_path = "../"TEMP_DIRNAME;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to(rel_path, tmpdir, &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, tmpdir);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("..", tmpdir, &npath, &error) == 0);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("../", tmpdir, &npath, &error) == 0);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("../.", tmpdir, &npath, &error) == 0);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen test_assert_strcmp(npath, cwd);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_link1(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen const char *old_dir, *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_realpath_to(link1, "/", &npath, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(npath, tmpdir);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen /* .../link1/link1/child */
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_assert(t_realpath_to(t_strconcat(link1, "/link1/child", NULL),
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen "/", &npath, &error) == 0);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_assert_strcmp(npath, t_strconcat(tmpdir, "/child", NULL));
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen /* relative link1/link1/child */
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (t_get_working_dir(&old_dir, &error) < 0)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_fatal("t_get_working_dir() failed: %s", error);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (chdir(tmpdir) < 0)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_fatal("chdir(%s) failed: %m", tmpdir);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_assert(t_realpath(t_strconcat("link1", "/link1/child", NULL),
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen &npath, &error) == 0);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (chdir(old_dir) < 0)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_fatal("chdir(%s) failed: %m", old_dir);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen}
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainenstatic void test_link4(void)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen{
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen const char *npath = NULL, *error = NULL;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_assert(t_realpath_to(t_strconcat(link1, "/link4/child", NULL),
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen "/", &npath, &error) == 0);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_assert_strcmp(npath, t_strconcat(tmpdir, "/child", NULL));
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_link_loop(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *npath = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi errno = 0;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_realpath_to(link2, "/", &npath, &error) == -1);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(errno == ELOOP);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(error != NULL);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_abspath_vs_normpath(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *abs = t_abspath_to("../../bin", "/usr/lib/");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(abs, "/usr/lib//../../bin");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *norm = NULL, *error = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_normpath_to("../../bin", "/usr///lib/", &norm, &error) == 0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert_strcmp(norm, "/bin");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainenstatic void create_links(const char *tmpdir)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen{
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen link1 = t_strconcat(tmpdir, "/link1", NULL);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek if (symlink(tmpdir, link1) < 0)
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_fatal("symlink(%s, %s) failed: %m", tmpdir, link1);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen const char *link1_child = t_strconcat(link1, "/child", NULL);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen int fd = creat(link1_child, 0600);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (fd == -1)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_fatal("creat(%s) failed: %m", link1_child);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_close_fd(&fd);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek /* link2 and link3 point to each other to create a loop */
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek link2 = t_strconcat(tmpdir, "/link2", NULL);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek link3 = t_strconcat(tmpdir, "/link3", NULL);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek if (symlink(link3, link2) < 0)
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_fatal("symlink(%s, %s) failed: %m", link3, link2);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek if (symlink(link2, link3) < 0)
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_fatal("symlink(%s, %s) failed: %m", link2, link3);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen /* link4 points to link1 */
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen link4 = t_strconcat(tmpdir, "/link4", NULL);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek if (symlink("link1", link4) < 0)
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_fatal("symlink(link1, %s) failed: %m", link4);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen}
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_link_alloc(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi#define COMPONENT_COMPONENT "/component-component"
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi const char *o_tmpdir;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi /* idea here is to make sure component-component
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi would optimally hit to the nearest_power value.
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi it has to be big enough to cause requirement for
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi allocation in t_realpath. */
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi string_t *basedir = t_str_new(256);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi str_append(basedir, cwd);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi str_append(basedir, "/"TEMP_DIRNAME);
dead275d577c87b8f8ba476a7709db758dfffb9bTimo Sirainen size_t len = nearest_power(I_MAX(127, str_len(basedir) + strlen(COMPONENT_COMPONENT) + 1)) -
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi strlen(COMPONENT_COMPONENT);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi while(str_len(basedir) < len) {
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi str_append(basedir, COMPONENT_COMPONENT);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi (void)mkdir(str_c(basedir), 0700);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi }
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi o_tmpdir = tmpdir;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi tmpdir = str_c(basedir);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen create_links(tmpdir);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi test_link1();
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi test_link_loop();
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi tmpdir = o_tmpdir;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi}
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainenstatic void test_link_alloc2(void)
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen{
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen const char *o_tmpdir;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen /* try enough different sized base directory lengths so the code
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen hits the different reallocations and tests for off-by-one errors */
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen string_t *basedir = t_str_new(256);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen str_append(basedir, cwd);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen str_append(basedir, "/"TEMP_DIRNAME);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen str_append_c(basedir, '/');
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen size_t base_len = str_len(basedir);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen o_tmpdir = tmpdir;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen /* path_normalize() initially allocates 128 bytes, so we'll test paths
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen up to that length+1. */
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen unsigned char buf[128+1];
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen memset(buf, 'x', sizeof(buf));
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen for (size_t i = 1; i <= sizeof(buf); i++) {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen str_truncate(basedir, base_len);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen str_append_n(basedir, buf, i);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen tmpdir = str_c(basedir);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen (void)mkdir(str_c(basedir), 0700);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen create_links(tmpdir);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen test_link1();
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen test_link_loop();
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen }
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen tmpdir = o_tmpdir;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen}
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainenstatic void test_cleanup(void)
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen{
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen const char *error;
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if (unlink_directory(tmpdir, UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0)
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen i_error("unlink_directory() failed: %s", error);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen}
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void test_init(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *error;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_assert(t_get_working_dir(&cwd, &error) == 0);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen tmpdir = t_strconcat(cwd, "/"TEMP_DIRNAME, NULL);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen test_cleanup();
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if (mkdir(tmpdir, 0700) < 0) {
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen i_fatal("mkdir: %m");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi }
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen create_links(tmpdir);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomivoid test_path_util(void)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_begin("test_path_util");
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi alarm(20);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_init();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_local_path();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_absolute_path_no_change();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_travel_to_root();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_extra_slashes();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_nonexistent_path();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_relative_dotdot();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_link1();
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen test_link4();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_link_loop();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_abspath_vs_normpath();
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi test_link_alloc();
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen test_link_alloc2();
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen test_cleanup();
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi alarm(0);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi test_end();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}