Changeset 15278 in project for release/4/hfs+/trunk/hfs+.scm


Ignore:
Timestamp:
07/31/09 00:49:53 (12 years ago)
Author:
Jim Ursetto
Message:

hfs+: update to version 0.3 (copyfile)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • release/4/hfs+/trunk/hfs+.scm

    r15012 r15278  
    11;;; HFS+ extended attribute interface
    22
     3;; Copyright (c) 2009 Jim Ursetto.  All Rights Reserved.
     4;; License: BSD.  However, see copyfile.h, which is included
     5;; in this distribution, and is under the APSL.
     6
    37#> #include <sys/xattr.h>
     8   /* copyfile.h can be obtained from
     9    * http://www.opensource.apple.com/source/Libc/Libc-391.5.18/darwin/copyfile.h */
     10   #include "copyfile.h"
    411   #include <errno.h>
    512<#
     
    2128  remove-extended-attribute!
    2229  get-extended-attributes
    23   clear-extended-attributes!)
     30  clear-extended-attributes!
     31  copyfile copyfile-check
     32  pack-appledouble unpack-appledouble)
    2433
    2534(import scheme chicken foreign)
     
    5867  (foreign-lambda int fremovexattr int (const c-string) int))
    5968
     69(define _copyfile
     70  (foreign-lambda int copyfile (const c-string) (const c-string) c-pointer int))
     71
    6072(define-foreign-enum-type (xattr-options int)
    6173  (xattr-options->int int->xattr-options)
     
    6476  ((replace xattr/replace) XATTR_REPLACE)
    6577  ((silent xattr/silent) "0")  ; hack -- not a real API option :)
     78  )
     79
     80(define-foreign-enum-type (copyfile-options int)
     81  (copyfile-options->int int->copyfile-options)
     82  ((acl copyfile/acl) COPYFILE_ACL)
     83  ((stat copyfile/stat) COPYFILE_STAT)
     84  ((xattr copyfile/xattr) COPYFILE_XATTR)
     85  ((data copyfile/data) COPYFILE_DATA)
     86  ((security copyfile/security) COPYFILE_SECURITY)
     87  ((metadata copyfile/metadata) COPYFILE_METADATA)
     88  ((all copyfile/all) COPYFILE_ALL)
     89  ((check copyfile/check) COPYFILE_CHECK)
     90  ((pack copyfile/pack) COPYFILE_PACK)
     91  ((unpack copyfile/unpack) COPYFILE_UNPACK)
     92  ((exclusive copyfile/excl) COPYFILE_EXCL)
     93  ((no-follow-source copyfile/no-follow-source) COPYFILE_NOFOLLOW_SRC)
     94  ((no-follow-dest copyfile/no-follow-dest) COPYFILE_NOFOLLOW_DST)
     95  ((move copyfile/move) COPYFILE_MOVE)
     96  ((unlink copyfile/unlink) COPYFILE_UNLINK)
     97  ((no-follow copyfile/no-follow) COPYFILE_NOFOLLOW)
     98;;   ((silent copyfile/silent) "0")  ; hack -- not a real API option :)
    6699  )
    67100
     
    82115(define errno/exist (foreign-value "EEXIST" int))
    83116
    84 ;;; Base API
     117;;; Base API - Extended attributes
    85118
    86119;; Accepted options: #:no-follow (or 'no-follow) to prevent following symlink; if passing
     
    203236             (void))))))
    204237
     238;;; Base API - Copyfile
     239
     240;; [copyfile is not officially supported on Tiger and, although metadata pack/unpack
     241;;  to AppleDouble files seems to work fine, copying actual data via #:data or #:all
     242;;  will throw a spurious error or crash.  #:move doesn't seem to work, but #:excl does.
     243;;  #:no-follow is ignored for packing (critical) and unpacking (not).]
     244
     245;; Copies FROM file to TO file using OS X copyfile(3) API,
     246;; preserving HFS+ metadata as specified in copyfile OPTIONS.
     247(define (copyfile from to . options)
     248  (let ((c-options (copyfile-options->int options)))
     249    (let ((rv (_copyfile from to #f c-options)))
     250      (cond ((< rv 0)
     251             (xattr-error (update-errno) 'copyfile
     252                          from to))
     253            (else rv)))))
     254
    205255;;; Utilities
    206256
     
    223273;;   ...)
    224274
     275;; Pack/unpack all HFS+ metadata (xattrs, acls, POSIX stat).  If no
     276;; error occurs, pack returns #f when no metadata was present (and
     277;; does not write a file) or #t if metadata was present (and a file is
     278;; written).  Unpack always returns #t.  Extra options are passed into
     279;; copyfile; relevant ones might be #:excl, #:move and #:no-follow,
     280;; although #:move and #:no-follow do not work correctly under Tiger.
     281(define (pack-appledouble from to . options)
     282  (if (= 0 (apply copyfile from #f #:check #:metadata options))
     283      #f
     284      (and (apply copyfile from to #:pack #:metadata options) #t)))
     285(define (unpack-appledouble from to . options)
     286  (and (apply copyfile from to #:unpack #:metadata options) #t))
     287
     288;; Return a list of symbols denoting the attributes that WOULD be
     289;; copied from the FROM file, according to the OPTIONS provided.
     290;; Example call: (copyfile-check "foo.txt" #:metadata)
     291;; Example return: '(acl stat extended-attributes) meaning
     292;; COPYFILE_ACL, COPYFILE_STAT, COPYFILE_XATTR.
     293(define (copyfile-check from . options)
     294  (let ((options (cons 'check options)))
     295    (let ((rv (apply copyfile from #f options)))
     296      (cond ((= rv 0) '())
     297            ((> rv 0)
     298             ;; enumtypes won't decompose into their component bitfields
     299             ;; we could also case all 8 possibilities
     300             `(,@(if (= 0 (bitwise-and rv copyfile/acl)) '() '(acls))
     301               ,@(if (= 0 (bitwise-and rv copyfile/stat)) '() '(stat))
     302               ,@(if (= 0 (bitwise-and rv copyfile/xattr)) '() '(extended-attributes))))
     303            (else (error 'copyfile-check "unexpected copyfile return value" rv))))))
    225304
    226305)
Note: See TracChangeset for help on using the changeset viewer.