X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Fatalk%2Fadouble.h;h=f279d28cc67fb1a691c2320656e1cb2fbb14a1cd;hb=ff7264380507bde532394739d3744130f6d85df8;hp=6913ddcdcfc22ce788b8aeacb8ae0d47d0a043d4;hpb=15c1fc2f2328736dd428ec3be37c893d8ee2e065;p=netatalk.git diff --git a/include/atalk/adouble.h b/include/atalk/adouble.h index 6913ddcd..f279d28c 100644 --- a/include/atalk/adouble.h +++ b/include/atalk/adouble.h @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. * @@ -46,14 +46,13 @@ #include #include -#include /* version info */ #define AD_VERSION2 0x00020000 #define AD_VERSION_EA 0x00020002 /* default */ -#define AD_VERSION AD_VERSION2 +#define AD_VERSION AD_VERSION_EA /* * AppleDouble entry IDs. @@ -97,7 +96,7 @@ #define ADEDLEN_VERSION 4 #define ADEDLEN_FILLER 16 #define ADEDLEN_NENTRIES 2 -#define AD_HEADER_LEN (ADEDLEN_MAGIC + ADEDLEN_VERSION + ADEDLEN_FILLER + ADEDLEN_NENTRIES) +#define AD_HEADER_LEN (ADEDLEN_MAGIC + ADEDLEN_VERSION + ADEDLEN_FILLER + ADEDLEN_NENTRIES) /* 26 */ #define AD_ENTRY_LEN 12 /* size of a single entry header */ /* field widths */ @@ -118,7 +117,8 @@ #define ADEDLEN_PRIVID 4 #define ADEID_NUM_V2 13 -#define ADEID_NUM_EA 5 +#define ADEID_NUM_EA 8 +#define ADEID_NUM_OSX 2 #define AD_DATASZ2 (AD_HEADER_LEN + ADEDLEN_NAME + ADEDLEN_COMMENT + ADEDLEN_FILEI + \ ADEDLEN_FINDERI + ADEDLEN_DID + ADEDLEN_AFPFILEI + ADEDLEN_SHORTNAME + \ @@ -128,13 +128,20 @@ #error bad size for AD_DATASZ2 #endif -#define AD_DATASZ_EA (AD_HEADER_LEN + (ADEID_NUM_EA * AD_ENTRY_LEN) + ADEDLEN_FINDERI + \ - ADEDLEN_COMMENT + ADEDLEN_FILEDATESI + ADEDLEN_AFPFILEI + ADEDLEN_PRIVID) +#define AD_DATASZ_EA (AD_HEADER_LEN + (ADEID_NUM_EA * AD_ENTRY_LEN) + \ + ADEDLEN_FINDERI + ADEDLEN_COMMENT + ADEDLEN_FILEDATESI + ADEDLEN_AFPFILEI + \ + ADEDLEN_PRIVDEV + ADEDLEN_PRIVINO + ADEDLEN_PRIVSYN + ADEDLEN_PRIVID) -#if AD_DATASZ_EA != 342 +#if AD_DATASZ_EA != 402 #error bad size for AD_DATASZ_EA #endif +#define AD_DATASZ_OSX (AD_HEADER_LEN + (ADEID_NUM_OSX * AD_ENTRY_LEN) + ADEDLEN_FINDERI) + +#if AD_DATASZ_OSX != 82 +#error bad size for AD_DATASZ_OSX +#endif + #define AD_DATASZ_MAX 1024 #if AD_VERSION == AD_VERSION2 @@ -143,7 +150,12 @@ #define AD_DATASZ AD_DATASZ_EA #endif -#define RFORK_EA_ALLOCSIZE (128*1024) /* 128k */ +/* fallback for ad:ea on filesystems without fds for EAs, like old adouble:osx */ +#define ADEDOFF_FINDERI_OSX (AD_HEADER_LEN + ADEID_NUM_OSX*AD_ENTRY_LEN) +#define ADEDOFF_RFORK_OSX (ADEDOFF_FINDERI_OSX + ADEDLEN_FINDERI) + +/* special fd value used to indicate an open fork file is a (not open) symlink */ +#define AD_SYMLINK -2 typedef uint32_t cnid_t; @@ -159,17 +171,11 @@ typedef struct adf_lock_t { } adf_lock_t; struct ad_fd { - int adf_fd; /* -1: invalid, -2: symlink */ -#ifndef HAVE_PREAD - off_t adf_off; -#endif + int adf_fd; /* -1: invalid, AD_SYMLINK: symlink */ char *adf_syml; int adf_flags; - int adf_excl; -#if 0 adf_lock_t *adf_lock; int adf_refcount, adf_lockcount, adf_lockmax; -#endif }; /* some header protection */ @@ -182,7 +188,7 @@ struct adouble_fops { const char *(*ad_path)(const char *, int); int (*ad_mkrf)(const char *); int (*ad_rebuild_header)(struct adouble *); - int (*ad_header_read)(struct adouble *, struct stat *); + int (*ad_header_read)(const char *, struct adouble *, const struct stat *); int (*ad_header_upgrade)(struct adouble *, const char *); }; @@ -191,24 +197,29 @@ struct adouble { uint32_t ad_version; /* Official adouble version number */ char ad_filler[16]; struct ad_entry ad_eid[ADEID_MAX]; + struct ad_fd ad_data_fork; /* the data fork */ + struct ad_fd ad_resource_fork; /* adouble:v2 -> the adouble file * - * adouble:ea -> the rfork EA */ - struct ad_fd ad_metadata_fork; /* adouble:v2 -> unused * - * adouble:ea -> the metadata EA */ - struct ad_fd *ad_md; /* either ad_resource or ad_metadata */ - int ad_flags; /* Our adouble version info (AD_VERSION*) */ + * adouble:ea -> the EA fd */ + + struct ad_fd *ad_rfp; /* adouble:v2 -> ad_resource_fork * + * adouble:ea -> ad_resource_fork */ + + struct ad_fd *ad_mdp; /* adouble:v2 -> ad_resource_fork * + * adouble:ea -> ad_data_fork */ + + int ad_vers; /* Our adouble version info (AD_VERSION*) */ int ad_adflags; /* ad_open flags adflags like ADFLAGS_DIR */ uint32_t ad_inited; int ad_options; int ad_refcount; /* multiple forks may open one adouble */ - void *ad_resforkbuf; /* buffer for AD_VERSION_EA ressource fork */ - size_t ad_resforkbufsize; /* size of ad_resforkbuf */ + int ad_data_refcount; + int ad_meta_refcount; + int ad_reso_refcount; off_t ad_rlen; /* ressource fork len with AFP 3.0 * * the header parameter size is too small. */ - char *ad_m_name; /* mac name for open fork */ - int ad_m_namelen; - bstring ad_fullpath; /* fullpath of file, adouble:ea need this */ + char *ad_name; /* mac name (maccharset or UTF8-MAC) */ struct adouble_fops *ad_ops; uint16_t ad_open_forks; /* open forks (by others) */ char ad_data[AD_DATASZ_MAX]; @@ -218,14 +229,26 @@ struct adouble { #define ADFLAGS_RF (1<<1) #define ADFLAGS_HF (1<<2) #define ADFLAGS_DIR (1<<3) -#define ADFLAGS_NOHF (1<<4) /* not an error if no ressource fork */ +#define ADFLAGS_NOHF (1<<4) /* not an error if no metadata fork */ +#define ADFLAGS_NORF (1<<5) /* not an error if no ressource fork */ #define ADFLAGS_CHECK_OF (1<<6) /* check for open forks from us and other afpd's */ +#define ADFLAGS_SETSHRMD (1<<7) /* setting share mode must be done with excl fcnt lock, + which implies that the file must be openend rw. + If it can't be opened rw (eg EPERM or EROFS) it will + be opened ro and the fcntl locks will be shared, that + at least prevent other users who have rw access to the + file from placing excl locks. */ +#define ADFLAGS_RDWR (1<<8) /* open read/write */ +#define ADFLAGS_RDONLY (1<<9) /* open read only */ +#define ADFLAGS_CREATE (1<<10) /* create file, open called with O_CREAT */ +#define ADFLAGS_EXCL (1<<11) /* exclusive open, open called with O_EXCL */ +#define ADFLAGS_TRUNC (1<<12) /* truncate, open called with O_TRUNC */ #define ADVOL_NODEV (1 << 0) -#define ADVOL_CACHE (1 << 1) +#define ADVOL_RO (1 << 1) #define ADVOL_UNIXPRIV (1 << 2) /* adouble unix priv */ #define ADVOL_INVDOTS (1 << 3) /* dot files (.DS_Store) are invisible) */ -#define ADVOL_NOADOUBLE (1 << 4) +#define ADVOL_FOLLO_SYML (1 << 4) /* lock flags */ #define ADLOCK_CLR (0) @@ -236,39 +259,28 @@ struct adouble { #define ADLOCK_FILELOCK (1<<3) /* we use this so that we can use the same mechanism for both byte - * locks and file synchronization locks. i do this by co-opting either - * first bits on 32-bit machines or shifting above the last bit on - * 64-bit machines. this only matters for the data fork. */ -#if defined(TRY_64BITOFF_T) && (~0UL > 0xFFFFFFFFU) -/* synchronization locks */ -#define AD_FILELOCK_BASE (0x80000000) -#else + * locks and file synchronization locks. */ #if _FILE_OFFSET_BITS == 64 -#define AD_FILELOCK_BASE (0x7FFFFFFFFFFFFFFFULL - 9) +#define AD_FILELOCK_BASE (UINT64_C(0x7FFFFFFFFFFFFFFF) - 9) #else -#define AD_FILELOCK_BASE (0x7FFFFFFF -9) -#endif +#define AD_FILELOCK_BASE (UINT32_C(0x7FFFFFFF) - 9) #endif -/* FIXME: - * AD_FILELOCK_BASE case - */ -#if _FILE_OFFSET_BITS == 64 -#define BYTELOCK_MAX (0x7FFFFFFFFFFFFFFFULL) -#else -/* Tru64 is an always-64-bit OS; version 4.0 does not set _FILE_OFFSET_BITS */ -#if defined(TRU64) -#define BYTELOCK_MAX (0x7FFFFFFFFFFFFFFFULL) -#else -#define BYTELOCK_MAX (0x7FFFFFFFU) -#endif -#endif +#define BYTELOCK_MAX (AD_FILELOCK_BASE - 1) +/* datafork and rsrcfork sharemode locks */ #define AD_FILELOCK_OPEN_WR (AD_FILELOCK_BASE + 0) #define AD_FILELOCK_OPEN_RD (AD_FILELOCK_BASE + 1) -#define AD_FILELOCK_DENY_WR (AD_FILELOCK_BASE + 2) -#define AD_FILELOCK_DENY_RD (AD_FILELOCK_BASE + 3) -#define AD_FILELOCK_OPEN_NONE (AD_FILELOCK_BASE + 4) +#define AD_FILELOCK_RSRC_OPEN_WR (AD_FILELOCK_BASE + 2) +#define AD_FILELOCK_RSRC_OPEN_RD (AD_FILELOCK_BASE + 3) + +#define AD_FILELOCK_DENY_WR (AD_FILELOCK_BASE + 4) +#define AD_FILELOCK_DENY_RD (AD_FILELOCK_BASE + 5) +#define AD_FILELOCK_RSRC_DENY_WR (AD_FILELOCK_BASE + 6) +#define AD_FILELOCK_RSRC_DENY_RD (AD_FILELOCK_BASE + 7) + +#define AD_FILELOCK_OPEN_NONE (AD_FILELOCK_BASE + 8) +#define AD_FILELOCK_RSRC_OPEN_NONE (AD_FILELOCK_BASE + 9) /* time stuff. we overload the bits a little. */ #define AD_DATE_CREATE 0 @@ -336,89 +348,80 @@ struct adouble { #define AD_AFPFILEI_GROUP (1 << 1) /* ignore group */ #define AD_AFPFILEI_BLANKACCESS (1 << 2) /* blank access permissions */ +/* + * String identifiers for the 16 AppleDouble filler bytes + */ +#define AD_FILLER_NETATALK "Netatalk " +#define AD_FILLER_OSX "Mac OS X" + #define ad_data_fileno(ad) ((ad)->ad_data_fork.adf_fd) -#define ad_reso_fileno(ad) ((ad)->ad_resource_fork.adf_fd) -#define ad_meta_fileno(ad) ((ad)->ad_md->adf_fd) +#define ad_reso_fileno(ad) ((ad)->ad_rfp->adf_fd) +#define ad_meta_fileno(ad) ((ad)->ad_mdp->adf_fd) + +/* -1: not open, AD_SYMLINK (-2): it's a symlink */ +#define AD_DATA_OPEN(ad) (((ad)->ad_data_refcount) && (ad_data_fileno(ad) >= 0)) +#define AD_META_OPEN(ad) (((ad)->ad_meta_refcount) && (ad_meta_fileno(ad) >= 0)) +#define AD_RSRC_OPEN(ad) (((ad)->ad_reso_refcount) && (ad_reso_fileno(ad) >= 0)) #define ad_getversion(ad) ((ad)->ad_version) #define ad_getentrylen(ad,eid) ((ad)->ad_eid[(eid)].ade_len) #define ad_setentrylen(ad,eid,len) ((ad)->ad_eid[(eid)].ade_len = (len)) -#define ad_getentryoff(ad,eid) ((ad)->ad_eid[(eid)].ade_off) +#define ad_setentryoff(ad,eid,off) ((ad)->ad_eid[(eid)].ade_off = (off)) #define ad_entry(ad,eid) ((caddr_t)(ad)->ad_data + (ad)->ad_eid[(eid)].ade_off) -#define ad_get_RF_flags(ad) ((ad)->ad_resource_fork.adf_flags) -#define ad_get_MD_flags(ad) ((ad)->ad_md->adf_flags) +#define ad_get_RF_flags(ad) ((ad)->ad_rfp->adf_flags) +#define ad_get_MD_flags(ad) ((ad)->ad_mdp->adf_flags) /* Refcounting open forks using one struct adouble */ #define ad_ref(ad) (ad)->ad_refcount++ #define ad_unref(ad) --((ad)->ad_refcount) +#define ad_get_syml_opt(ad) (((ad)->ad_options & ADVOL_FOLLO_SYML) ? 0 : O_NOFOLLOW) + /* ad_flush.c */ -extern int ad_rebuild_adouble_header (struct adouble *); -extern int ad_rebuild_sfm_header (struct adouble *); +extern int ad_rebuild_adouble_header_v2(struct adouble *); +extern int ad_rebuild_adouble_header_ea(struct adouble *); +extern int ad_rebuild_adouble_header_osx(struct adouble *ad, char *adbuf); extern int ad_copy_header (struct adouble *, struct adouble *); extern int ad_flush (struct adouble *); extern int ad_close (struct adouble *, int); +extern int fsetrsrcea(struct adouble *ad, int fd, const char *eaname, const void *value, size_t size, int flags); /* ad_lock.c */ extern int ad_testlock (struct adouble *adp, int eid, off_t off); extern uint16_t ad_openforks(struct adouble *adp, uint16_t); -extern int ad_excl_lock (struct adouble *adp, uint32_t eid); - -extern int ad_lock(struct adouble *, uint32_t eid, int type, off_t off, off_t len, int user); -extern void ad_unlock(struct adouble *, int user); -extern int ad_tmplock(struct adouble *, uint32_t eid, int type, off_t off, off_t len, int user); +extern int ad_lock(struct adouble *, uint32_t eid, int type, off_t off, off_t len, int fork); +extern void ad_unlock(struct adouble *, int fork, int unlckbrl); +extern int ad_tmplock(struct adouble *, uint32_t eid, int type, off_t off, off_t len, int fork); /* ad_open.c */ -extern const char *oflags2logstr(int oflags); +extern off_t ad_getentryoff(const struct adouble *ad, int eid); extern const char *adflags2logstr(int adflags); extern int ad_setfuid (const uid_t ); extern uid_t ad_getfuid (void ); extern char *ad_dir (const char *); extern const char *ad_path (const char *, int); extern const char *ad_path_ea (const char *, int); -extern int ad_mode (const char *, int); -extern int ad_mkdir (const char *, int); -extern void ad_init (struct adouble *, int, int ); +extern const char *ad_path_osx (const char *path, int adflags); +extern int ad_mode (const char *, mode_t); +extern int ad_mkdir (const char *, mode_t); +struct vol; +extern void ad_init (struct adouble *, const struct vol * restrict); +extern void ad_init_old (struct adouble *ad, int flags, int options); +extern int ad_init_offsets(struct adouble *ad); extern int ad_open (struct adouble *ad, const char *path, int adflags, ...); extern int ad_openat (struct adouble *, int dirfd, const char *path, int adflags, ...); -extern int ad_refresh (struct adouble *); +extern int ad_refresh (const char *path, struct adouble *); extern int ad_stat (const char *, struct stat *); extern int ad_metadata (const char *, int, struct adouble *); extern int ad_metadataat (int, const char *, int, struct adouble *); +extern mode_t ad_hf_mode(mode_t mode); +extern int ad_valid_header_osx(const char *path); +extern off_t ad_reso_size(const char *path, int adflags, struct adouble *ad); -#if 0 -#define ad_open_metadata(name, flags, mode, adp)\ - ad_open(name, ADFLAGS_HF | (flags), O_RDWR |(mode), 0666, (adp)) -#endif - -#define ad_close_metadata(adp) ad_close( (adp), ADFLAGS_HF) - -/* build a resource fork mode from the data fork mode: - * remove X mode and extend header to RW if R or W (W if R for locking), - */ -static inline mode_t ad_hf_mode (mode_t mode) -{ - mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH); - /* fnctl lock need write access */ - if ((mode & S_IRUSR)) - mode |= S_IWUSR; - if ((mode & S_IRGRP)) - mode |= S_IWGRP; - if ((mode & S_IROTH)) - mode |= S_IWOTH; - - /* if write mode set add read mode */ - if ((mode & S_IWUSR)) - mode |= S_IRUSR; - if ((mode & S_IWGRP)) - mode |= S_IRGRP; - if ((mode & S_IWOTH)) - mode |= S_IROTH; - - return mode; -} +/* ad_conv.c */ +extern int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, const char **newpath); /* ad_read.c/ad_write.c */ extern int sys_ftruncate(int fd, off_t length); @@ -428,7 +431,8 @@ extern ssize_t ad_write(struct adouble *, uint32_t, off_t, int, const char *, si extern ssize_t adf_pread(struct ad_fd *, void *, size_t, off_t); extern ssize_t adf_pwrite(struct ad_fd *, const void *, size_t, off_t); extern int ad_dtruncate(struct adouble *, off_t); -extern int ad_rtruncate(struct adouble *, off_t); +extern int ad_rtruncate(struct adouble *, const char *, off_t); +extern int copy_fork(int eid, struct adouble *add, struct adouble *ads); /* ad_size.c */ extern off_t ad_size (const struct adouble *, uint32_t ); @@ -443,7 +447,7 @@ extern int ad_setdate(struct adouble *, unsigned int, uint32_t); extern int ad_getdate(const struct adouble *, unsigned int, uint32_t *); /* ad_attr.c */ -extern int ad_setattr(const struct adouble *, uint16_t); +extern int ad_setattr(const struct adouble *, const uint16_t); extern int ad_getattr(const struct adouble *, uint16_t *); extern int ad_setname(struct adouble *, const char *); extern int ad_setid(struct adouble *, dev_t dev, ino_t ino, uint32_t, uint32_t, const void *); @@ -453,11 +457,8 @@ extern uint32_t ad_forcegetid(struct adouble *adp); #ifdef WITH_SENDFILE extern int ad_readfile_init(const struct adouble *ad, int eid, off_t *off, int end); #endif - -#if 0 -#ifdef HAVE_SENDFILE_WRITE -extern ssize_t ad_writefile(struct adouble *, int, int, off_t, int, size_t); -#endif /* HAVE_SENDFILE_WRITE */ -#endif /* 0 */ +#ifdef WITH_RECVFILE +extern ssize_t ad_recvfile(struct adouble *ad, int eid, int sock, off_t off, size_t len, int); +#endif #endif /* _ATALK_ADOUBLE_H */