Removed R5 compatibility stuff, as it's not needed in our libroot.
Moved test main() into separate file under tests/. Fixed warnings, some cleanup. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10181 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,21 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* find_directory() replacement
|
* Copyright (c) 2004, François Revol.
|
||||||
* (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 <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
#include <StorageDefs.h>
|
|
||||||
#include <fs_info.h>
|
#include <fs_info.h>
|
||||||
|
#include <syscalls.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
/* use R5 undocumented syscalls to find mountpoints */
|
|
||||||
//#define USE_R5_SYSCALL_HACK
|
|
||||||
|
|
||||||
/* use pwents to find home */
|
/* use pwents to find home */
|
||||||
#define USE_PWENTS
|
#define USE_PWENTS
|
||||||
@@ -25,19 +25,6 @@
|
|||||||
//#define OSDIR "haiku" // :)
|
//#define OSDIR "haiku" // :)
|
||||||
//#define OSDIR "os"
|
//#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 */
|
/* /bin/strings rox */
|
||||||
static const char *os_dirs[] = {
|
static const char *os_dirs[] = {
|
||||||
@@ -63,7 +50,9 @@ OSDIR"/etc/sounds",
|
|||||||
* it should actually be something else than /boot/home even...
|
* it should actually be something else than /boot/home even...
|
||||||
*/
|
*/
|
||||||
//#define HOME "$h"
|
//#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[] = {
|
static const char *common_dirs[] = {
|
||||||
HOME"",
|
HOME"",
|
||||||
@@ -111,8 +100,10 @@ preferences
|
|||||||
apps
|
apps
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* make dir and parents if needed */
|
/** make dir and parents if needed */
|
||||||
static int mkdir_p(const char *path, mode_t mode)
|
|
||||||
|
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 slash = 0;
|
||||||
@@ -120,11 +111,12 @@ static int mkdir_p(const char *path, mode_t mode)
|
|||||||
char *p;
|
char *p;
|
||||||
struct stat st;
|
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;
|
return EINVAL;
|
||||||
|
|
||||||
memset(buffer, 0, B_PATH_NAME_LENGTH + 1);
|
memset(buffer, 0, B_PATH_NAME_LENGTH + 1);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
slash++;
|
slash++;
|
||||||
if (slash > plen)
|
if (slash > plen)
|
||||||
@@ -136,24 +128,24 @@ static int mkdir_p(const char *path, mode_t mode)
|
|||||||
slash = p - path;
|
slash = p - path;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strncpy(buffer, path, slash);
|
strncpy(buffer, path, slash);
|
||||||
//printf("path[0:%d] = %s\n", slash, buffer);
|
|
||||||
if (stat(buffer, &st) < 0) {
|
if (stat(buffer, &st) < 0) {
|
||||||
//perror("stat");
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (mkdir(buffer, mode) < 0) {
|
if (mkdir(buffer, mode) < 0)
|
||||||
//perror("mkdir");
|
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
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;
|
dev_t bootdev = -1;
|
||||||
struct fs_info finfo;
|
struct fs_info finfo;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@@ -164,6 +156,7 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch
|
|||||||
/* as with the R5 version, no on-stack buffer */
|
/* as with the R5 version, no on-stack buffer */
|
||||||
buffer = (char *)malloc(path_length);
|
buffer = (char *)malloc(path_length);
|
||||||
memset(buffer, 0, path_length);
|
memset(buffer, 0, path_length);
|
||||||
|
|
||||||
/* fiddle with non-boot volume for items that need it */
|
/* fiddle with non-boot volume for items that need it */
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case B_DESKTOP_DIRECTORY:
|
case B_DESKTOP_DIRECTORY:
|
||||||
@@ -176,46 +169,7 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch
|
|||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
if (device != bootdev) {
|
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);
|
err = _kern_entry_ref_to_path(device, finfo.root, /*"."*/ NULL, buffer, path_length);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/* use the user id to find the home folder */
|
/* use the user id to find the home folder */
|
||||||
/* done later */
|
/* done later */
|
||||||
@@ -226,6 +180,7 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch
|
|||||||
strncat(buffer, "/boot", path_length);
|
strncat(buffer, "/boot", path_length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err < B_OK) {
|
if (err < B_OK) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return err;
|
return err;
|
||||||
@@ -308,8 +263,6 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("template = '%s'\nbuffer = '%s'\n", template, buffer);
|
|
||||||
|
|
||||||
err = B_OK;
|
err = B_OK;
|
||||||
if (template) {
|
if (template) {
|
||||||
if (!strncmp(template, "$h", 2)) {
|
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;
|
struct passwd *pw;
|
||||||
// WARNING getpwuid() might not be threadsafe...
|
// WARNING getpwuid() might not be threadsafe...
|
||||||
pw = getpwuid(getuid());
|
pw = getpwuid(getuid());
|
||||||
if (pw) {
|
if (pw)
|
||||||
home = pw->pw_dir;
|
home = pw->pw_dir;
|
||||||
//printf("getpwuid %d %s\n", getuid(), home);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (!home) {
|
if (!home) {
|
||||||
/* use env var */
|
/* use env var */
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
//printf("getenv %s\n", home);
|
|
||||||
}
|
}
|
||||||
if (!home)
|
if (!home)
|
||||||
home = "/boot/home";
|
home = "/boot/home";
|
||||||
@@ -339,46 +289,20 @@ status_t find_directory (directory_which which, dev_t device, bool create_it, ch
|
|||||||
template += 2;
|
template += 2;
|
||||||
} else
|
} else
|
||||||
strcat(buffer, "/");
|
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);
|
strcat(buffer, template);
|
||||||
} else
|
} else
|
||||||
err = err ? err : E2BIG;
|
err = err ? err : E2BIG;
|
||||||
} else
|
} else
|
||||||
err = err ? err : ENOENT;
|
err = err ? err : ENOENT;
|
||||||
if (!err && create_it && (stat(buffer, &st) < 0))
|
|
||||||
|
if (!err && create_it && stat(buffer, &st) < 0)
|
||||||
err = mkdir_p(buffer, 0755);
|
err = mkdir_p(buffer, 0755);
|
||||||
if (!err)
|
if (!err)
|
||||||
strncpy(returned_path, buffer, path_length);
|
strncpy(returned_path, buffer, path_length);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* <AbsFab>
|
|
||||||
* testing testing testing... I can hear you darling!
|
|
||||||
* This is big-mother speaking !!!
|
|
||||||
* <AbsFab>
|
|
||||||
* 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
|
|
||||||
|
|||||||
Reference in New Issue
Block a user