diff --git a/src/kernel/libroot/os/find_directory.c b/src/kernel/libroot/os/find_directory.c index 69fa634297..b947df18f9 100644 --- a/src/kernel/libroot/os/find_directory.c +++ b/src/kernel/libroot/os/find_directory.c @@ -1,21 +1,21 @@ /* - * find_directory() replacement - * (c) 2004, François Revol. + * Copyright (c) 2004, François Revol. + * Distributed under the terms of the MIT license. */ +// ToDo: that call should probably implemented by and in the kernel as well. + #include -#include #include +#include + #include #include #include #include #include #include -#include -/* use R5 undocumented syscalls to find mountpoints */ -//#define USE_R5_SYSCALL_HACK /* use pwents to find home */ #define USE_PWENTS @@ -25,19 +25,6 @@ //#define OSDIR "haiku" // :) //#define OSDIR "os" -#ifdef COMPILE_FOR_R5 -#define USE_R5_SYSCALL_HACK -#undef USE_PWENTS -#endif - - -#ifdef USE_R5_SYSCALL_HACK -// un* are unknown params -extern int _kopen_vn_(dev_t d, ino_t i, long un1, long un2, long un3); -extern int _kopendir_(int fromfd, long un1, long un2); -extern status_t _kreaddir_(int dir, struct dirent *dent, size_t dentlen, long count); -extern status_t _kclosedir_(int dir); -#endif /* /bin/strings rox */ static const char *os_dirs[] = { @@ -63,7 +50,9 @@ OSDIR"/etc/sounds", * it should actually be something else than /boot/home even... */ //#define HOME "$h" -#define HOME "home" +#define HOME "common" + // ToDo: this is for now and might be changed back to "home" + // (or even something else) later static const char *common_dirs[] = { HOME"", @@ -111,20 +100,23 @@ preferences apps */ -/* make dir and parents if needed */ -static int mkdir_p(const char *path, mode_t mode) +/** make dir and parents if needed */ + +static int +mkdir_p(const char *path, mode_t mode) { - char buffer[B_PATH_NAME_LENGTH+1]; + char buffer[B_PATH_NAME_LENGTH + 1]; int slash = 0; int plen = 0; char *p; struct stat st; -//return 0; - if (!path || ((plen=strlen(path)) > B_PATH_NAME_LENGTH)) + if (!path || ((plen = strlen(path)) > B_PATH_NAME_LENGTH)) return EINVAL; - memset(buffer, 0, B_PATH_NAME_LENGTH+1); + + memset(buffer, 0, B_PATH_NAME_LENGTH + 1); errno = 0; + while (1) { slash++; if (slash > plen) @@ -136,24 +128,24 @@ static int mkdir_p(const char *path, mode_t mode) slash = p - path; else continue; + strncpy(buffer, path, slash); -//printf("path[0:%d] = %s\n", slash, buffer); if (stat(buffer, &st) < 0) { -//perror("stat"); errno = 0; - if (mkdir(buffer, mode) < 0) { -//perror("mkdir"); + if (mkdir(buffer, mode) < 0) return errno; - } } } return 0; } -status_t find_directory (directory_which which, dev_t device, bool create_it, char *returned_path, int32 path_length) + +status_t +find_directory(directory_which which, dev_t device, bool create_it, + char *returned_path, int32 path_length) { - status_t err; + status_t err = B_OK; dev_t bootdev = -1; struct fs_info finfo; struct stat st; @@ -164,152 +156,113 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch /* as with the R5 version, no on-stack buffer */ buffer = (char *)malloc(path_length); memset(buffer, 0, path_length); + /* fiddle with non-boot volume for items that need it */ switch (which) { - case B_DESKTOP_DIRECTORY: - case B_TRASH_DIRECTORY: - bootdev = dev_for_path("/boot"); - if (device <= 0) - device = bootdev; - if (fs_stat_dev(device, &finfo) < B_OK) { - free(buffer); - return ENODEV; - } - if (device != bootdev) { -#ifdef USE_R5_SYSCALL_HACK - int fd; - int dir; - /* do weird stuff to find the path to the mountpoint of the device - * basically: - * - open the mountpoint, - * - get a DIR* from it, - * - read the first entry (.), - * - and get the path from the dirent. - */ - fd = _kopen_vn_(device, finfo.root, 0, 0, 1); - if (fd >= 0) { - dir = _kopendir_(fd, 0, 1); - close(fd); - if (dir) { - status_t err; - struct { - struct dirent d; - char n[B_FILE_NAME_LENGTH]; - } dent; - // NOT threadsafe readdir(dir); - err = _kreaddir_(dir, &dent.d, sizeof(dent), 1); - _kclosedir_(dir); - if (err>0) { - err = get_path_for_dirent(&dent, buffer, path_length); - if (err >= 0) { - int i = strlen(buffer); - if ((i > 2) && !strcmp(&buffer[i-2], "/.")) - buffer[i-2] = '\0'; - err = 0; - } - } else - err = ENODEV; - } else - err = ENODEV; - } else - err = ENODEV; -#else - err = _kern_entry_ref_to_path(device, finfo.root, /*"."*/ NULL, buffer, path_length); -#endif - } else { - /* use the user id to find the home folder */ - /* done later */ + case B_DESKTOP_DIRECTORY: + case B_TRASH_DIRECTORY: + bootdev = dev_for_path("/boot"); + if (device <= 0) + device = bootdev; + if (fs_stat_dev(device, &finfo) < B_OK) { + free(buffer); + return ENODEV; + } + if (device != bootdev) { + err = _kern_entry_ref_to_path(device, finfo.root, /*"."*/ NULL, buffer, path_length); + } else { + /* use the user id to find the home folder */ + /* done later */ + strncat(buffer, "/boot", path_length); + } + break; + default: strncat(buffer, "/boot", path_length); - } - break; - default: - strncat(buffer, "/boot", path_length); - break; + break; } + if (err < B_OK) { free(buffer); return err; } switch (which) { - case B_DESKTOP_DIRECTORY: - if (!strcmp(finfo.fsh_name, "bfs")) - template = "$h/Desktop"; - break; - case B_TRASH_DIRECTORY: - if (!strcmp(finfo.fsh_name, "bfs")) - template = "$h/Desktop/Trash"; - else if (!strcmp(finfo.fsh_name, "dos")) - template = "RECYCLED/_BEOS_"; - break; - case B_BEOS_DIRECTORY: - case B_BEOS_SYSTEM_DIRECTORY: - case B_BEOS_ADDONS_DIRECTORY: - case B_BEOS_BOOT_DIRECTORY: - case B_BEOS_FONTS_DIRECTORY: - case B_BEOS_LIB_DIRECTORY: - case B_BEOS_SERVERS_DIRECTORY: - case B_BEOS_APPS_DIRECTORY: - case B_BEOS_BIN_DIRECTORY: - case B_BEOS_ETC_DIRECTORY: - case B_BEOS_DOCUMENTATION_DIRECTORY: - case B_BEOS_PREFERENCES_DIRECTORY: - case B_BEOS_TRANSLATORS_DIRECTORY: - case B_BEOS_MEDIA_NODES_DIRECTORY: - case B_BEOS_SOUNDS_DIRECTORY: - template = os_dirs[which - B_BEOS_DIRECTORY]; - break; - case B_COMMON_DIRECTORY: - case B_COMMON_SYSTEM_DIRECTORY: - case B_COMMON_ADDONS_DIRECTORY: - case B_COMMON_BOOT_DIRECTORY: - case B_COMMON_FONTS_DIRECTORY: - case B_COMMON_LIB_DIRECTORY: - case B_COMMON_SERVERS_DIRECTORY: - case B_COMMON_BIN_DIRECTORY: - case B_COMMON_ETC_DIRECTORY: - case B_COMMON_DOCUMENTATION_DIRECTORY: - case B_COMMON_SETTINGS_DIRECTORY: - case B_COMMON_DEVELOP_DIRECTORY: - case B_COMMON_LOG_DIRECTORY: - case B_COMMON_SPOOL_DIRECTORY: - case B_COMMON_TEMP_DIRECTORY: - case B_COMMON_VAR_DIRECTORY: - case B_COMMON_TRANSLATORS_DIRECTORY: - case B_COMMON_MEDIA_NODES_DIRECTORY: - case B_COMMON_SOUNDS_DIRECTORY: - template = common_dirs[which - B_COMMON_DIRECTORY]; - break; - case B_USER_DIRECTORY: - case B_USER_CONFIG_DIRECTORY: - case B_USER_ADDONS_DIRECTORY: - case B_USER_BOOT_DIRECTORY: - case B_USER_FONTS_DIRECTORY: - case B_USER_LIB_DIRECTORY: - case B_USER_SETTINGS_DIRECTORY: - case B_USER_DESKBAR_DIRECTORY: - case B_USER_PRINTERS_DIRECTORY: - case B_USER_TRANSLATORS_DIRECTORY: - case B_USER_MEDIA_NODES_DIRECTORY: - case B_USER_SOUNDS_DIRECTORY: - template = user_dirs[which - B_USER_DIRECTORY]; - break; - case B_APPS_DIRECTORY: - template = "apps"; - break; - case B_PREFERENCES_DIRECTORY: - template = "preferences"; - break; - case B_UTILITIES_DIRECTORY: - template = "utilities"; - break; - default: - free(buffer); - return EINVAL; + case B_DESKTOP_DIRECTORY: + if (!strcmp(finfo.fsh_name, "bfs")) + template = "$h/Desktop"; + break; + case B_TRASH_DIRECTORY: + if (!strcmp(finfo.fsh_name, "bfs")) + template = "$h/Desktop/Trash"; + else if (!strcmp(finfo.fsh_name, "dos")) + template = "RECYCLED/_BEOS_"; + break; + case B_BEOS_DIRECTORY: + case B_BEOS_SYSTEM_DIRECTORY: + case B_BEOS_ADDONS_DIRECTORY: + case B_BEOS_BOOT_DIRECTORY: + case B_BEOS_FONTS_DIRECTORY: + case B_BEOS_LIB_DIRECTORY: + case B_BEOS_SERVERS_DIRECTORY: + case B_BEOS_APPS_DIRECTORY: + case B_BEOS_BIN_DIRECTORY: + case B_BEOS_ETC_DIRECTORY: + case B_BEOS_DOCUMENTATION_DIRECTORY: + case B_BEOS_PREFERENCES_DIRECTORY: + case B_BEOS_TRANSLATORS_DIRECTORY: + case B_BEOS_MEDIA_NODES_DIRECTORY: + case B_BEOS_SOUNDS_DIRECTORY: + template = os_dirs[which - B_BEOS_DIRECTORY]; + break; + case B_COMMON_DIRECTORY: + case B_COMMON_SYSTEM_DIRECTORY: + case B_COMMON_ADDONS_DIRECTORY: + case B_COMMON_BOOT_DIRECTORY: + case B_COMMON_FONTS_DIRECTORY: + case B_COMMON_LIB_DIRECTORY: + case B_COMMON_SERVERS_DIRECTORY: + case B_COMMON_BIN_DIRECTORY: + case B_COMMON_ETC_DIRECTORY: + case B_COMMON_DOCUMENTATION_DIRECTORY: + case B_COMMON_SETTINGS_DIRECTORY: + case B_COMMON_DEVELOP_DIRECTORY: + case B_COMMON_LOG_DIRECTORY: + case B_COMMON_SPOOL_DIRECTORY: + case B_COMMON_TEMP_DIRECTORY: + case B_COMMON_VAR_DIRECTORY: + case B_COMMON_TRANSLATORS_DIRECTORY: + case B_COMMON_MEDIA_NODES_DIRECTORY: + case B_COMMON_SOUNDS_DIRECTORY: + template = common_dirs[which - B_COMMON_DIRECTORY]; + break; + case B_USER_DIRECTORY: + case B_USER_CONFIG_DIRECTORY: + case B_USER_ADDONS_DIRECTORY: + case B_USER_BOOT_DIRECTORY: + case B_USER_FONTS_DIRECTORY: + case B_USER_LIB_DIRECTORY: + case B_USER_SETTINGS_DIRECTORY: + case B_USER_DESKBAR_DIRECTORY: + case B_USER_PRINTERS_DIRECTORY: + case B_USER_TRANSLATORS_DIRECTORY: + case B_USER_MEDIA_NODES_DIRECTORY: + case B_USER_SOUNDS_DIRECTORY: + template = user_dirs[which - B_USER_DIRECTORY]; + break; + case B_APPS_DIRECTORY: + template = "apps"; + break; + case B_PREFERENCES_DIRECTORY: + template = "preferences"; + break; + case B_UTILITIES_DIRECTORY: + template = "utilities"; + break; + default: + free(buffer); + return EINVAL; } - //printf("template = '%s'\nbuffer = '%s'\n", template, buffer); - err = B_OK; if (template) { if (!strncmp(template, "$h", 2)) { @@ -322,15 +275,12 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch struct passwd *pw; // WARNING getpwuid() might not be threadsafe... pw = getpwuid(getuid()); - if (pw) { + if (pw) home = pw->pw_dir; -//printf("getpwuid %d %s\n", getuid(), home); - } #endif if (!home) { /* use env var */ home = getenv("HOME"); -//printf("getenv %s\n", home); } if (!home) home = "/boot/home"; @@ -339,46 +289,20 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch template += 2; } else strcat(buffer, "/"); - if (!err && strlen(buffer)+2+strlen(template) < path_length) { - //strcat(buffer, "/"); + + if (!err && strlen(buffer) + 2 + strlen(template) < (uint32)path_length) { strcat(buffer, template); } else - err = err?err:E2BIG; + err = err ? err : E2BIG; } else - err = err?err:ENOENT; - if (!err && create_it && (stat(buffer, &st) < 0)) + err = err ? err : ENOENT; + + if (!err && create_it && stat(buffer, &st) < 0) err = mkdir_p(buffer, 0755); if (!err) strncpy(returned_path, buffer, path_length); + free(buffer); return err; } -/* - * testing testing testing... I can hear you darling! - * This is big-mother speaking !!! - * - * cc -DMAIN_FOR_TEST -DCOMPILE_FOR_R5 find_directory.c -o find_directory - */ - -#ifdef MAIN_FOR_TEST -int main(int argc, char **argv) -{ - status_t err; - int i; - dev_t dev = -1; - char buffer[B_PATH_NAME_LENGTH]; - //printf("mkdir %d\n", mkdir_p(argv[1], 0755)); - //perror("mkdir"); - - if (argc > 1) - dev = dev_for_path(argv[1]); - for (i = B_DESKTOP_DIRECTORY; i < B_UTILITIES_DIRECTORY; i++) { - err = find_directory((directory_which)i, dev, false, buffer, B_PATH_NAME_LENGTH); - if (err) - continue; - printf("dir[%04d] = '%s'\n", i, buffer); - } - return 0; -} -#endif