Outdated egg!
This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.
If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.
hfs+
Synopsis
hfs+ is a interface to the HFS+ filesystem on Mac OS X 10.4 and above.
The current implementation provides access to HFS+ extended attributes, including resource forks. It also implements an interface to copyfile(3).
Interface
Overview
All calls taking a FILE argument accept either a filename or an open POSIX file descriptor.
All calls taking an ATTRIBUTE argument accept either a string or a symbol.
All extended attribute calls allow the following options:
#:no-follow | Do not follow symlinks; operate on the symlink itself. |
list-extended-attributes
[procedure] (list-extended-attributes file . options)List extended attribute names of FILE.
Returns a list containing one string per attribute name.
(list-extended-attributes "examples.scm" #:no-follow) ; => ("com.apple.FinderInfo" "com.apple.ResourceFork")
get-extended-attribute
[procedure] (get-extended-attribute file attribute . options)Get the value of extended attribute ATTRIBUTE from FILE.
Returns a string representing the value. The string may contain binary data.
Returns #f if the attribute does not exist.
set-extended-attribute!
[procedure] (set-extended-attribute! file attribute value . options)Set extended attribute ATTRIBUTE on FILE to VALUE, and return an unspecified value.
VALUE may be a string or a blob.
In addition to #:no-follow, set-extended-attribute! allows the following two mutually-exclusive options:
#:create | Raise error if attribute exists. |
#:replace | Raise error if attribute does not exist. |
If neither option is specified, existing attribute values are silently overwritten.
(set-extended-attribute! "examples.scm" 'org.callcc "courtesy of Chicken") (get-extended-attribute "examples.scm" 'org.callcc) ; => "courtesy of Chicken"
remove-extended-attribute!
[procedure] (remove-extended-attribute! file attribute . options)Remove extended attribute ATTRIBUTE from FILE. By default, if ATTRIBUTE does not exist, an error is signaled.
remove-extended-attribute! also accepts the following options:
#:silent | Do not raise an error if the attribute is missing. |
The #:silent option is useful if, for example, you wish to truncate a resource fork but are not sure if one is already present. See below for an example.
copyfile
[procedure] (copyfile from to . options)Copies FROM file to TO file using the OS X copyfile(3) API, preserving HFS+ metadata as specified in copyfile OPTIONS. Always returns a true value, indicating success; failure will raise an error. In the current implementation, both FROM and TO must be filenames; ports are not accepted.
If the #:check option is given, copyfile will determine which metadata would be copied from the source, without copying it. It returns zero if there is no corresponding metadata, and a positive value if there is metadata to copy. Either way, the return value is true, indicating success.
If #:pack is given, copyfile serializes the desired metadata to an AppleDouble file named by the TO argument. #:unpack is the opposite of #:pack. This AppleDouble file is the same format as that produced when writing a file to a non-HFS+ filesystem, such as across a network to NFS or Samba. Because an AppleDouble file is always created when packing, even if there is no metadata to copy, you may wish to use #:check first to avoid this.
copyfile options
Refer to the copyfile(3) manpage for details.
These options specify which data to copy:
#:acls | COPYFILE_ACL | Copy ACLs |
#:stat | COPYFILE_STAT | Copy POSIX stat(2) items |
#:extended-attributes | COPYFILE_XATTR | Copy HFS+ extended attributes |
#:data | COPYFILE_DATA | Copy file data |
#:security | COPYFILE_SECURITY | Equivalent to #:acls #:stat |
#:metadata | COPYFILE_METADATA | Equivalent to #:extended-attributes #:security |
#:all | COPYFILE_ALL | Equivalent to #:metadata #:data |
These options are flags which affect the copy operation:
#:check | COPYFILE_CHECK | Dry-run; determine which metadata would be copied |
#:pack | COPYFILE_PACK | Pack metadata in FROM to TO in AppleDouble format |
#:unpack | COPYFILE_UNPACK | Apply packed metadata in FROM to TO |
#:exclusive | COPYFILE_EXCL | Raise error if TO already exists |
#:no-follow-source | COPYFILE_NOFOLLOW_SRC | Do not follow symlink on FROM |
#:no-follow-dest | COPYFILE_NOFOLLOW_DST | Do not follow symlink on TO |
#:no-follow | COPYFILE_NOFOLLOW | Equivalent to #:no-follow-source #:no-follow-dest |
#:move | COPYFILE_MOVE | Unlink FROM after the copy |
#:unlink | COPYFILE_UNLINK | Unlink TO prior to copy |
copyfile deficiencies
copyfile(3) is present on OS X 10.4, but not officially supported. On 10.4, we recommend using copyfile only to pack and unpack metadata to and from AppleDouble format. Certain options do not work properly: #:move has no effect; #:no-follow has no effect during a pack/unpack; #:data will fail with an error (and may even cause a segfault). There may be other deficiencies.
Utilities
get-extended-attributes
[procedure] (get-extended-attributes file . options)Returns an alist mapping attribute names (symbols) to values (strings).
(get-extended-attributes "examples.scm") ;=> ((com.apple.FinderInfo . "TEXTEMAx") (com.apple.ResourceFork . "courtesy of Chicken") (org.callcc . "courtesy of Chicken"))
clear-extended-attributes!
[procedure] (clear-extended-attributes! file . options)Remove all extended attributes from FILE.
copyfile-check
[procedure] (copyfile-check from . options)Determines if any metadata is present in FROM using the #:check option to copyfile. Returns a list of symbols denoting metadata types that are present, from the following possibilities:
acls | COPYFILE_ACL | ACLs |
stat | COPYFILE_STAT | POSIX stat(2) data |
extended-attributes | COPYFILE_XATTR | Extended attributes |
Note: another way to check merely for the presence of metadata is to use the #:check option to copyfile. A positive value means present, a zero value means not present.
Example:
#;> (copyfile-check "foo.txt" #:metadata) (acls stat extended-attributes) #;> (copyfile-check "foo.txt" #:extended-attributes) (extended-attributes) #;> (copyfile-check "bar.txt" #:metadata) () #;> (> (copyfile "foo.txt" #f #:check #:metadata) 0) #t #;> (> (copyfile "bar.txt" #f #:check #:metadata) 0) #f
pack-appledouble
[procedure] (pack-appledouble from to . options)Serialize all HFS+ metadata (extended attributes, ACLs, stat(2) data) in FROM to AppleDouble file TO. Returns false when no metadata was present (and does not write a file) or true if metadata was present (and a file is written). May also throw a file error.
Extra options are passed into copyfile; relevant ones might be #:exclusive, #:move and #:no-follow, although #:move and #:no-follow do not work correctly under Tiger.
unpack-appledouble
[procedure] (unpack-appledouble from to . options)Unserialize all HFS+ metadata in AppleDouble file FROM to TO. Always returns true, or throws an error on I/O error.
Errors
If the system API returns an unrecoverable error, a Scheme error will be raised. The exception is of type (exn file hfs+).
Notes
Resource forks
Special care is required when writing resource fork data. OS X will not truncate an existing resource fork if you write a shorter value, so you must remove the resource fork prior to writing.
Incorrect example:
$ echo -n "courtesy of the command-line" > examples.scm/rsrc $ csi -q -R hfs+ <<EOF (set-extended-attribute! "examples.scm" 'com.apple.ResourceFork "courtesy of Chicken") EOF $ cat examples.scm/rsrc ; echo courtesy of Chickenmand-line
Correct example:
$ echo -n "courtesy of the command-line" > examples.scm/rsrc $ csi -q -R hfs+ <<EOF (remove-extended-attribute! "examples.scm" 'com.apple.ResourceFork #:silent) (set-extended-attribute! "examples.scm" 'com.apple.ResourceFork "courtesy of Chicken" #:create) EOF $ cat examples.scm/rsrc ; echo courtesy of Chicken
Author
Jim Ursetto
Version history
- 0.3 Add copyfile interface
- 0.2 Add #:silent option to remove, clear-extended-attributes!
- 0.1 Initial release
License
BSD.
The Apple header copyfile.h is not present on Tiger, so it is included in the egg. The header is under the Apple Public Source License.