/*
* NAME: filesys.c
* DESCRIPTION: provide access to the filesystem from MOO
*/
/*
* NAME: resolve()
* DESCRIPTION: return an absolute pathname from a relative path and base
*/
string resolve(string path, string base_dir)
{
string name, subpath;
string *components, *newpath;
int i, j, sz;
if (base_dir == 0 || strlen(base_dir) == 0)
base_dir = "/";
else if (base_dir[0] != '/')
error("Arg 2 absolute pathname expected (got \"" + base_dir + "\")");
if (path == 0 || strlen(path) == 0)
return base_dir;
if (path[0] != '/')
path = base_dir + "/" + path;
components = explode(path, "/");
newpath = allocate(sz = sizeof(components));
for (i = 0, j = 0; i < sz; ++i)
{
switch (path = components[i])
{
case ".":
case "":
continue;
case "..":
j = (j == 0 ? 0 : j - 1);
break;
default:
newpath[j++] = path;
}
}
return "/" + (j > 0 ? implode(newpath[0 .. j - 1], "/") : "");
}
/*
* NAME: list()
* DESCRIPTION: return a list of files in the filesystem
*/
string *list(string path)
{
mixed **dir;
string *files;
int i;
dir = get_dir(path);
files = dir[0];
for (i = sizeof(files); i--; )
if (dir[1][i] == -2)
files[i] += "/";
return files;
}
/*
* NAME: basename()
* DESCRIPTION: return the trailing part of a pathname
*/
string basename(string path)
{
string *list;
int sz;
if (path == 0)
return 0;
list = explode(path, "/");
sz = strlen(path);
if (sz > 0 && path[sz - 1] == '/')
list += ({ "." });
sz = sizeof(list);
return (sz > 0) ? list[sz - 1] : ".";
}
/*
* NAME: is_dir()
* DESCRIPTION: return 1 iff a path exists and is a directory
*/
int is_dir(string path)
{
mixed **stat;
stat = get_dir(path);
return sizeof(stat[0]) == 1 &&
stat[0][0] == basename(path) && stat[1][0] == -2;
}
/*
* NAME: is_file()
* DESCRIPTION: return 1 iff a path exists and is not a directory
*/
int is_file(string path)
{
mixed **stat;
stat = get_dir(path);
return sizeof(stat[0]) == 1 &&
stat[0][0] == basename(path) && stat[1][0] >= 0;
}
/*
* NAME: is_binary()
* DESCRIPTION: return 1 iff a file contains binary data
*/
int is_binary(string path)
{
string buf;
int i;
buf = read_file(path, 0, 512);
if (buf == 0)
return 0;
for (i = strlen(buf); i--; )
{
int c;
c = buf[i];
if ((c < ' ' || c > '~') &&
c != '\n' && c != '\t')
return 1;
}
return 0;
}
/*
* NAME: file_size()
* DESCRIPTION: return the size of a file, in bytes
*/
int file_size(string path)
{
mixed **stat;
stat = get_dir(path);
return (sizeof(stat[0]) == 1 && stat[0][0] == basename(path)) ?
stat[1][0] : -1;
}
/*
* NAME: read()
* DESCRIPTION: return all lines of a file
*/
string *read(string file)
{
if (! is_file(file))
return 0;
return explode(read_file(file), "\n");
}
/*
* NAME: append()
* DESCRIPTION: add to the end of a file
*/
int append(string file, string *text)
{
return write_file(file, implode(text, "\n") + "\n");
}
/*
* NAME: write()
* DESCRIPTION: overwrite a file with text
*/
int write(string file, string *text)
{
remove_file(file);
return append(file, text);
}
/*
* NAME: remove()
* DESCRIPTION: delete a file
*/
int remove(string file)
{
return remove_file(file);
}
/*
* NAME: rename()
* DESCRIPTION: change the name of a file
*/
int rename(string oldname, string newname)
{
return rename_file(oldname, newname);
}
/*
* NAME: mkdir()
* DESCRIPTION: create a new directory
*/
int mkdir(string name)
{
return make_dir(name);
}
/*
* NAME: rmdir()
* DESCRIPTION: delete a directory
*/
int rmdir(string name)
{
return remove_dir(name);
}