MODALIAS=acpi:LNXCPU:
  "   ˆl–ß=¿J	µ2ÛR‚ œP\h
˜´oÃƒh¹ÂÁ      4:2
  "   	ˆl–ß=¿J	µ2ÛR‚ œP\h˜´oÄƒh¹ÃÂ      	4:39
  9   ˆl–Ým_JJh¥ ² ¸È®2ò˜´oÅƒm‘3a–ß=¿J	µ2ÛR‚ œP!¸Û—˜´oÄ Ë    # NFS RPC client -- RFC 1094

# XXX This is not yet complete.
# XXX Only GETATTR, SETTTR, LOOKUP and READDIR are supported.

# (See mountclient.py for some hints on how to write RPC clients in
# Python in general)

import rpc
from rpc import UDPClient, TCPClient
from mountclient import FHSIZE, MountPacker, MountUnpacker

NFS_PROGRAM = 100003
NFS_VERSION = 2

# enum stat
NFS_OK = 0
# (...many error values...)

# enum ftype
NFNON = 0
NFREG = 1
NFDIR = 2
NFBLK = 3
NFCHR = 4
NFLNK = 5


class NFSPacker(MountPacker):

    def pack_sattrargs(self, sa):
        file, attributes = sa
        self.pack_fhandle(file)
        self.pack_sattr(attributes)

    def pack_sattr(self, sa):
        mode, uid, gid, size, atime, mtime = sa
        self.pack_uint(mode)
        self.pack_uint(uid)
        self.pack_uint(gid)
        self.pack_uint(size)
        self.pack_timeval(atime)
        self.pack_timeval(mtime)

    def pack_diropargs(self, da):
        dir, name = da
        self.pack_fhandle(dir)
        self.pack_string(name)

    def pack_readdirargs(self, ra):
        dir, cookie, count = ra
        self.pack_fhandle(dir)
        self.pack_uint(cookie)
        self.pack_uint(count)

    def pack_timeval(self, tv):
        secs, usecs = tv
        self.pack_uint(secs)
        self.pack_uint(usecs)


class NFSUnpacker(MountUnpacker):

    def unpack_readdirres(self):
        status = self.unpack_enum()
        if status == NFS_OK:
            entries = self.unpack_list(self.unpack_entry)
            eof = self.unpack_bool()
            rest = (entries, eof)
        else:
            rest = None
        return (status, rest)

    def unpack_entry(self):
        fileid = self.unpack_uint()
        name = self.unpack_string()
        cookie = self.unpack_uint()
        return (fileid, name, cookie)

    def unpack_diropres(self):
        status = self.unpack_enum()
        if status == NFS_OK:
            fh = self.unpack_fhandle()
            fa = self.unpack_fattr()
            rest = (fh, fa)
        else:
            rest = None
        return (status, rest)

    def unpack_attrstat(self):
        status = self.unpack_enum()
        if status == NFS_OK:
            attributes = self.unpack_fattr()
        else:
            attributes = None
        return status, attributes

    def unpack_fattr(self):
        type = self.unpack_enum()
        mode = self.unpack_uint()
        nlink = self.unpack_uint()
        uid = self.unpack_uint()
        gid = self.unpack_uint()
        size = self.unpack_uint()
        blocksize = self.unpack_uint()
        rdev = self.unpack_uint()
        blocks = self.unpack_uint()
        fsid = self.unpack_uint()
        fileid = self.unpack_uint()
        atime = self.unpack_timeval()
        mtime = self.unpack_timeval()
        ctime = self.unpack_timeval()
        return (type, mode, nlink, uid, gid, size, blocksize, \
                rdev, blocks, fsid, fileid, atime, mtime, ctime)

    def unpack_timeval(self):
        secs = self.unpack_uint()
        usecs = self.unpack_uint()
        return (secs, usecs)


class NFSClient(UDPClient):

    def __init__(self, host):
        UDPClient.__init__(self, host, NFS_PROGRAM, NFS_VERSION)

    def addpackers(self):
        self.packer = NFSPacker()
        self.unpacker = NFSUnpacker('')

    def mkcred(self):
        if self.cred is None:
            self.cred = rpc.AUTH_UNIX, rpc.make_auth_unix_default()
        return self.cred

    def Getattr(self, fh):
        return self.make_call(1, fh, \
                self.packer.pack_fhandle, \
                self.unpacker.unpack_attrstat)

    def Setattr(self, sa):
        return self.make_call(2, sa, \
                self.packer.pack_sattrargs, \
                self.unpacker.unpack_attrstat)

    # Root() is obsolete

    def Lookup(self, da):
        return self.make_call(4, da, \
                