
=head1 NAME

AFS::ukernel - Usermode cache manager for AFS

=head1 SYNOPSIS

  use AFS::ukernel;
  use POSIX;
  AFS::ukernel::uafs_Setup("/afs");
  AFS::ukernel::uafs_ParseArgs($args);
  AFS::ukernel::uafs_Run();
  $fd = AFS::ukernel::uafs_open($path, POSIX::O_RDONLY);

=head1 DESCRIPTION

AFS::ukernel contains the Perl bindings for libuafs. It allows Perl
scripts to access files in AFS just like a normal AFS client would
(including cache management and all), without the need of a kernel
module.

This documentation does not cover all subroutines in AFS::ukernel. It
just serves to provide documentation on semantics or functionality that
is specific to the AFS::ukernel, or differs from the semantics or
functionality of libuafs proper in some way. See the libuafs API or
documentation for the rest of the subroutines, as they will behave the
same here as in libuafs.

=head1 SUBROUTINES

Any subroutine that returns an error should set errno. This is easily
accessible in Perl for error messages via the C<$!> variable, which
expands to the human-readable error string corresponding to the current
value of errno.

=over

=item $code = AFS::ukernel::uafs_ParseArgs($args)

Call this after uafs_Setup() but before uafs_Run(). C<$args> is a single
string of whitespace-separated arguments. The arguments accepted are the
same as those accepted by the L<afsd(8)> program, and have the same
meaning.

The C<$args> string is broken into individual arguments by libcmd,
according to the normal shell-like quoting and whitespace rules.

uafs_ParseArgs() returns 0 on success, and nonzero otherwise.

=item $fd = AFS::ukernel::uafs_open($path, $flags[, $mode])

Opens C<$path> using open flags C<$flags>. The passed C<$flags> are
interpreted just like L<open(2)>'s flags; symbolic constants can be
found in the L<POSIX> module, for example C<POSIX::O_RDONLY>.

C<$mode> is the mode the specified C<$path> will be created with if you
are creating a new file. If it is unspecified, it defaults to 0. If it
is specified and the call does not create a new file, it is ignored.

Returns a nonnegative file descriptor on success, and -1 on error.

=item ($code, $data) = AFS::ukernel::uafs_read($fd, $len)

=item ($code, $data) = AFS::ukernel::uafs_pread($fd, $len, $offset)

Reads at most C<$len> bytes from the file correcponding to the file
descriptor C<$fd>. On success, returns C<$data> as the string of data
read, and C<$code> as the number of bytes read. On error, returns
C<$data> as an empty string, and C<$code> as -1.

L<uafs_pread> reads starting from the offset C<$offset>.

=item ($code, @stats) = AFS::ukernel::uafs_stat($path)

=item ($code, @stats) = AFS::ukernel::uafs_lstat($path)

=item ($code, @stats) = AFS::ukernel::uafs_fstat($fd)

L<stat(2)>s, L<lstat(2)>s, or L<fstat(2)>s a file. On success, C<$code>
is 0, and C<@stats> is a 13-element list that contains the stat
information for the file. The order and meaning of the elements in
C<@stats> is the same as those returned by the builtin Perl stat
function. On error, C<$code> is nonzero.

=item ($code, $link) = AFS::ukernel::uafs_readlink($path, $len)

Reads the contents of the link in the symlink C<$path>. On success,
C<$code> is 0, and the link data is returned in the string C<$link>,
which will be at most C<$len> bytes long. On error, C<$code> is nonzero,
and C<$link> is the empty string.

=item ($name, $ino, $off, $reclen) = AFS::ukernel::uafs_readdir($dir)

Reads a directory entry from the directory represented by the directory
pointer C<$dir>. On success, the returned C<$name> is the name of the
file entry, C<$ino> is the inode number, C<$off> is the offset of the
entry, and C<$reclen> is the length of the entry name. On error,
C<$name> is the empty string, and all other returned values are 0.

=back

=head1 EXAMPLES

Here is a small program to read the first 4096 bytes of
/afs/localcell/user/adeason/file, and print them out:

  use strict;
  use AFS::ukernel;
  use POSIX;

  my $path = "/afs/localcell/user/adeason/afile";
  my $str;
  my $code;
  my $fd;

  $code = AFS::ukernel::uafs_Setup("/afs");
  $code == 0 or die("uafs_Setup: $!\n");

  $code = AFS::ukernel::uafs_ParseArgs("-afsdb -cachedir /tmp/mycache");
  $code == 0 or die("uafs_ParseArgs: $!\n");

  $code = AFS::ukernel::uafs_Run();
  $code == 0 or due("uafs_Run: $!\n");

  $fd = AFS::ukernel::uafs_open($path, POSIX::O_RDONLY);
  $fd >=0 or die("uafs_open: $fname: $!\n");

  ($code, $str) = AFS::ukernel::uafs_read($fd, 4096);
  $code >= 0 or die("uafs_read: $!\n");

  $code = AFS::ukernel::uafs_close($fd);
  $code == 0 or die("uafs_close: $!\n");

  print "The first 4096 bytes of $path are:\n$str\n";

  AFS::ukernel::uafs_Shutdown();

=head1 COPYRIGHT

Copyright 2010 Sine Nomine Associates <http://www.sinenomine.net/>

This documentation is covered by the BSD License as written in the
doc/LICENSE file. This man page was written by Andrew Deason for
OpenAFS.
