#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sdi/locator.h>
#include <sdi/log.h>
#include "cwd.h"
#include <idl4glue.h>
#include "if/iflocator.h"
extern "C" {
L4_ThreadId_t __cwd_server = L4_nilthread;
objectid_t __cwd_handle = 0;
char *getcwd(char *buf, size_t size)
{
char *envcwd = getenv("CWD");
if (!envcwd)
envcwd = "/";
size_t el = strlen(envcwd);
if(el > size-1) {
errno = ERANGE;
return NULL;
}
if (buf == NULL) {
if (size > 0)
el = size;
buf = reinterpret_cast<char*> (malloc(el + 1));
} else {
if (el > size)
el = size - 1;
}
snprintf(buf, el+1, "%s", envcwd);
return buf;
}
int chdir(const char* path)
{
setenv("CWD", path, 1);
__resolve_cwd();
return 0;
}
void __resolve_cwd()
{
char buf[128];
if(!L4_IsNilThread(__cwd_server))
return;
getcwd(buf, sizeof(buf));
if(GetObject(getcwd(buf, sizeof(buf)), IF_DIRECTORY_ID, &__cwd_server, &__cwd_handle) != OK)
{
LogMessage("Warning: couldn't resolve current working directory\n");
__cwd_server = GetLocator();
__cwd_handle = ROOT_DIRECTORY_HANDLE;
}
}
int __resolve_parentdir(const char* path, interfaceid_t iid,
L4_ThreadId_t* server, objectid_t* handle)
{
size_t len = strlen(path);
char buf[len + 1];
memcpy(buf, path, len+1);
int slash = static_cast<int> (len);
for( ; slash >= 0; --slash) {
if(buf[slash] == '/') {
buf[slash] = 0;
break;
}
}
if(slash < 0)
return __resolve_path("/", iid, server, handle);
return __resolve_path(buf, iid, server, handle);
}
const char* __basename(const char* path)
{
int slash = strlen(path);
for( ; slash >= 0; --slash) {
if(path[slash] == '/')
return path + slash + 1;
}
return path;
}
int __resolve_path(const char* path, interfaceid_t iid, L4_ThreadId_t* server, objectid_t* handle)
{
if(path[0] == '/') {
if(GetObject(path, iid, server, handle) != OK) {
LogMessage("Path '%s' not found", path);
errno = ENOENT;
return -1;
}
return 0;
}
__resolve_cwd();
if(GetObject2(__cwd_server, __cwd_handle, path, iid, server, handle) != OK) {
LogMessage("Path '%s' not found", path);
errno = ENOENT;
return -1;
}
return 0;
}
}