lpmoo-1.2/etc/
lpmoo-1.2/mudlib/
lpmoo-1.2/mudlib/etc/
lpmoo-1.2/mudlib/include/
lpmoo-1.2/mudlib/include/moo/
lpmoo-1.2/mudlib/lpc/
lpmoo-1.2/mudlib/std/auto/
lpmoo-1.2/mudlib/std/bfuns/
/*
 * 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);
}