The guestfs_write_file / write-file command uses an XDR string type to pass the buffer content. Unfortunately we discovered after making this choice that XDR strings cannot contain ASCII NUL characters, which means that write-file cannot be used to write binary files. Current workaround is to use the guestfs_upload command instead to upload arbitrary binary files to the guest filesystem. We need to implement BufferIn/Out parameters, as discussed in the TODO file.
Moving upstream, since it's a "known limitiation" with the API which has a workaround
I'll make an extended attempt at explaining what this bug is all about, since it affects FUSE access (bug 592883). In libguestfs there is a protocol which is used to send and receive messages between the library and the daemon (which runs inside qemu). This protocol uses Sun XDR, the same basic protocol as NFS, NIS etc. In the protocol, we normally encode C 'char *' as the XDR string type. When we first implemented this we didn't realize that these are C strings, terminated by \0 characters. (This is because at the protocol level, they _are_ sent as len word + data, but the C-level XDR library has the limitation that it works out the length word using strlen). Anyway, we need to use the XDR 'opaque' type. It's exactly the same as 'string' at the wire level, but in the XDR library it is encoded using an explicit length, and therefore it can contain \0 bytes. To avoid complicating existing string parameters, we need to add to the generator a new arg type, BufferIn, which will take a (const char *, size_t) pair and send an opaque value over the wire. This will allow us to fix write-file, and implement a pwrite API. (Currently it's not possible to implement the pwrite call in the API because it would fail if the buffer being written contained any \0 byte). With a pwrite call, we could implement the FUSE write system call.
Proposed fix posted upstream: https://www.redhat.com/archives/libguestfs/2010-May/msg00108.html