Part of Netatalk's AppleDouble implementatation. More...
#include <arpa/inet.h>#include <errno.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <sys/param.h>#include <atalk/adouble.h>#include <atalk/compat.h>#include <atalk/ea.h>#include <atalk/errchk.h>#include <atalk/logger.h>#include <atalk/unix.h>#include <atalk/util.h>#include <atalk/volume.h>Data Structures | |
| struct | entry |
Functions | |
| static int | ad_mkrf (const char *path) |
| Takes a path to an AppleDouble file and creates the parent .AppleDouble directory. | |
| static int | ad_header_read (const char *path, struct adouble *ad, const struct stat *hst) |
| static int | ad_header_upgrade (struct adouble *ad, const char *name) |
| static int | ad_header_read_ea (const char *path, struct adouble *ad, const struct stat *hst) |
| static int | ad_header_upgrade_ea (struct adouble *ad, const char *name) |
| off_t | ad_reso_size (const char *path, int adflags, struct adouble *ad) |
| static int | ad_mkrf_osx (const char *path) |
| const char * | adflags2logstr (int adflags) |
| const char * | openflags2logstr (int oflags) |
| static uint32_t | get_eid (uint32_t eid) |
| int | ad_init_offsets (struct adouble *ad) |
| static int | new_ad_header (struct adouble *ad, const char *path, struct stat *stp, int adflags) |
| static int | parse_entries (struct adouble *ad, uint16_t nentries, size_t valid_data_len) |
| Read an AppleDouble buffer. | |
| int | ad_valid_header_osx (const char *path) |
| static int | ad_convert_pread_full (struct ad_fd *adf, void *buf, size_t count, off_t offset) |
| Read an exact byte range from an AppleDouble fork. | |
| static int | ad_convert_pwrite_full (struct ad_fd *adf, const void *buf, size_t count, off_t offset) |
| Write an exact byte range to an AppleDouble fork. | |
| static int | ad_convert_move_rfork (struct ad_fd *adf, off_t src, off_t dst, off_t len) |
| Move a resource fork towards the start of its AppleDouble file. | |
| static int | ad_convert_osx (const char *path, struct adouble *ad, const struct stat *hst) |
| Convert from Apple's ._ file to Netatalk. | |
| static int | ad_header_read_osx (const char *path, struct adouble *ad, struct stat *hst) |
| static int | ad_chown (const char *path, struct stat *stbuf) |
| if we are root change path user/ group | |
| static int | ad_mode_st (const char *path, mode_t *mode, struct stat *stbuf) |
| static int | ad_error (struct adouble *ad, int adflags) |
| Error handling for adouble header(=metadata) file open error. | |
| static int | ad2openflags (const struct adouble *ad, int adfile, int adflags) |
| Map ADFLAGS to open() flags. | |
| static int | ad_open_df (const char *path, int adflags, mode_t mode, struct adouble *ad) |
| static int | ad_open_hf_v2 (const char *path, int adflags, mode_t mode, struct adouble *ad) |
| static int | ad_open_hf_ea (const char *path, int adflags, int mode, struct adouble *ad) |
| static int | ad_open_hf (const char *path, int adflags, int mode, struct adouble *ad) |
| static int | ad_open_rf_v2 (const char *path, int adflags, int mode, struct adouble *ad) |
| static int | ad_open_rf_ea (const char *path, int adflags, int mode, struct adouble *ad) |
| static int | ad_open_rf (const char *path, int adflags, int mode, struct adouble *ad) |
| Open resource fork. | |
| static bool | ad_entry_check_size (uint32_t eid, size_t bufsize, uint32_t off, uint32_t got_len) |
| bool | ad_entry_fits (const struct adouble *ad, int eid, uint32_t len) |
Whether an entry of len bytes fits at eid's offset in ad. | |
| void * | ad_entry (const struct adouble *ad, int eid) |
| off_t | ad_getentryoff (const struct adouble *ad, int eid) |
| const char * | ad_path_ea (const char *path, int adflags) |
| const char * | ad_path_osx (const char *path, int adflags) |
| const char * | ad_path (const char *path, int adflags) |
| Put the .AppleDouble where it needs to be: | |
| char * | ad_dir (const char *path) |
| Support inherited protection modes for AppleDouble files. The supplied mode is ANDed with the parent directory's mask value in lieu of "umask", and that value is returned. | |
| int | ad_setfuid (const uid_t id) |
| uid_t | ad_getfuid (void) |
| int | ad_stat (const char *path, struct stat *stbuf) |
| int | ad_mode (const char *path, mode_t mode) |
| int | ad_mkdir (const char *path, mode_t mode) |
| static void | ad_init_func (struct adouble *ad) |
| void | ad_init_old (struct adouble *ad, int flags, int options) |
| void | ad_init (struct adouble *ad, const struct vol *vol) |
| int | ad_open (struct adouble *ad, const char *path, int adflags,...) |
| Open data-, metadata(header)- or resource fork. | |
| int | ad_metadata (const char *name, int flags, struct adouble *adp) |
| open metadata, possibly as root | |
| int | ad_metadataat (int dirfd, const char *name, int flags, struct adouble *adp) |
| int | ad_refresh (const char *path, struct adouble *ad) |
| int | ad_openat (struct adouble *ad, int dirfd, const char *path, int adflags,...) |
| mode_t | ad_hf_mode (mode_t mode) |
Variables | |
| static uid_t | default_uid = -1 |
| static struct adouble_fops | ad_adouble |
| static struct adouble_fops | ad_adouble_ea |
| static const struct entry | entry_order2 [ADEID_NUM_V2+1] |
| static const struct entry | entry_order_ea [ADEID_NUM_EA+1] |
Part of Netatalk's AppleDouble implementatation.
| #define ADEDLEN_INIT 0 |
initial lengths of some of the fields
| #define ADEDOFF_AFPFILEI (ADEDOFF_DID + ADEDLEN_DID) |
| #define ADEDOFF_AFPFILEI_EA (ADEDOFF_FILEDATESI_EA + ADEDLEN_FILEDATESI) |
| #define ADEDOFF_COMMENT_EA (ADEDOFF_FINDERI_EA + ADEDLEN_FINDERI) |
| #define ADEDOFF_COMMENT_V2 (ADEDOFF_NAME_V2 + ADEDLEN_NAME) |
| #define ADEDOFF_DID (ADEDOFF_FINDERI_V2 + ADEDLEN_FINDERI) |
| #define ADEDOFF_FILEDATESI (ADEDOFF_COMMENT_V2 + ADEDLEN_COMMENT) |
| #define ADEDOFF_FILEDATESI_EA (ADEDOFF_COMMENT_EA + ADEDLEN_COMMENT) |
| #define ADEDOFF_FILLER (ADEDOFF_VERSION + ADEDLEN_VERSION) |
| #define ADEDOFF_FINDERI_EA (AD_HEADER_LEN + ADEID_NUM_EA * AD_ENTRY_LEN) |
| #define ADEDOFF_FINDERI_V2 (ADEDOFF_FILEDATESI + ADEDLEN_FILEDATESI) |
| #define ADEDOFF_MAGIC (0) |
| #define ADEDOFF_NAME_V2 (AD_HEADER_LEN + ADEID_NUM_V2*AD_ENTRY_LEN) |
| #define ADEDOFF_NENTRIES (ADEDOFF_FILLER + ADEDLEN_FILLER) |
| #define ADEDOFF_PRIVDEV (ADEDOFF_PRODOSFILEI + ADEDLEN_PRODOSFILEI) |
| #define ADEDOFF_PRIVDEV_EA (ADEDOFF_AFPFILEI_EA + ADEDLEN_AFPFILEI) |
| #define ADEDOFF_PRIVID (ADEDOFF_PRIVSYN + ADEDLEN_PRIVSYN) |
| #define ADEDOFF_PRIVID_EA (ADEDOFF_PRIVSYN_EA + ADEDLEN_PRIVSYN) |
| #define ADEDOFF_PRIVINO (ADEDOFF_PRIVDEV + ADEDLEN_PRIVDEV) |
| #define ADEDOFF_PRIVINO_EA (ADEDOFF_PRIVDEV_EA + ADEDLEN_PRIVDEV) |
| #define ADEDOFF_PRIVSYN (ADEDOFF_PRIVINO + ADEDLEN_PRIVINO) |
| #define ADEDOFF_PRIVSYN_EA (ADEDOFF_PRIVINO_EA + ADEDLEN_PRIVINO) |
| #define ADEDOFF_PRODOSFILEI (ADEDOFF_SHORTNAME + ADEDLEN_SHORTNAME) |
| #define ADEDOFF_RFORK_V2 (ADEDOFF_PRIVID + ADEDLEN_PRIVID) |
| #define ADEDOFF_SHORTNAME (ADEDOFF_AFPFILEI + ADEDLEN_AFPFILEI) |
| #define ADEDOFF_VERSION (ADEDOFF_MAGIC + ADEDLEN_MAGIC) |
| #define ADFLAGS2LOGSTRBUFSIZ 128 |
| #define DEFMASK 07700 |
be conservative
| #define EMULATE_SUIDDIR |
| #define OPENFLAGS2LOGSTRBUFSIZ 128 |
| #define TIMEWARP_DELTA 157680000 |
this is to prevent changing timezones from causing problems with localtime volumes. the screw-up is 30 years. we use a delta of 5 years
|
static |
Map ADFLAGS to open() flags.
| [in] | ad | the adouble structure |
| [in] | adfile | the file you really want to open: ADFLAGS_DF or ADFLAGS_HF |
| [in] | adflags | flags from ad_open(..., adflags, ...) |
|
static |
if we are root change path user/ group
| path | pathname to chown |
| stbuf | parent directory inode |
use fstat and fchown or lchown with linux?
|
static |
Move a resource fork towards the start of its AppleDouble file.
The caller must validate both ranges and ensure src is not before dst. Copying proceeds forwards in bounded chunks so overlapping ranges are safe when moving data towards the start of the file.
| [in] | adf | open AppleDouble fork to modify |
| [in] | src | source range offset |
| [in] | dst | destination range offset |
| [in] | len | number of bytes to move |
|
static |
Convert from Apple's ._ file to Netatalk.
Apple's AppleDouble may contain a FinderInfo entry longer then 32 bytes containing packed xattrs. Netatalk can't deal with that, so we simply discard the packed xattrs.
As we call ad_open() which might result in a recursion, just to be sure use static variable in_conversion to check for that.
|
static |
Read an exact byte range from an AppleDouble fork.
Retries interrupted and short reads. Reaching EOF before count bytes have been read is reported as an I/O error.
| [in] | adf | open AppleDouble fork |
| [out] | buf | destination buffer |
| [in] | count | number of bytes to read |
| [in] | offset | starting file offset |
|
static |
Write an exact byte range to an AppleDouble fork.
Retries interrupted and short writes. A zero-length write before count bytes have been written is reported as an I/O error.
| [in] | adf | open AppleDouble fork |
| [in] | buf | source buffer |
| [in] | count | number of bytes to write |
| [in] | offset | starting file offset |
| char * ad_dir | ( | const char * | path | ) |
Support inherited protection modes for AppleDouble files. The supplied mode is ANDed with the parent directory's mask value in lieu of "umask", and that value is returned.
|
static |
| bool ad_entry_fits | ( | const struct adouble * | ad, |
| int | eid, | ||
| uint32_t | len | ||
| ) |
Whether an entry of len bytes fits at eid's offset in ad.
ad_entry()'s bounds check against a caller-supplied length, so a destination can be checked before its length is committed.
|
static |
Error handling for adouble header(=metadata) file open error.
We're called because opening ADFLAGS_HF caused an error.
| off_t ad_getentryoff | ( | const struct adouble * | ad, |
| int | eid | ||
| ) |
| uid_t ad_getfuid | ( | void | ) |
|
static |
|
static |
|
static |
Read an ._ file, only uses the resofork, finderinfo is taken from EA
|
static |
|
static |
| mode_t ad_hf_mode | ( | mode_t | mode | ) |
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 |
| int ad_init_offsets | ( | struct adouble * | ad | ) |
Initialize offset pointers
| void ad_init_old | ( | struct adouble * | ad, |
| int | flags, | ||
| int | options | ||
| ) |
| int ad_metadata | ( | const char * | name, |
| int | flags, | ||
| struct adouble * | adp | ||
| ) |
open metadata, possibly as root
Return only metadata but try very hard i.e. at first try as user, then try as root.
| name | name of file/dir |
| flags | ADFLAGS_DIR: name is a directory ADFLAGS_CHECK_OF: test if name is open by us or another afpd process |
| adp | pointer to struct adouble |
| int ad_metadataat | ( | int | dirfd, |
| const char * | name, | ||
| int | flags, | ||
| struct adouble * | adp | ||
| ) |
openat like wrapper for ad_metadata
| int ad_mkdir | ( | const char * | path, |
| mode_t | mode | ||
| ) |
Use mkdir() with mode bits taken from ad_mode().
|
static |
Takes a path to an AppleDouble file and creates the parent .AppleDouble directory.
Example:
path: "/path/.AppleDouble/file" => mkdir("/path/.AppleDouble/") (in ad_mkdir())
|
static |
| int ad_mode | ( | const char * | path, |
| mode_t | mode | ||
| ) |
return access right of path parent directory
|
static |
return access right and inode of path parent directory
| int ad_open | ( | struct adouble * | ad, |
| const char * | path, | ||
| int | adflags, | ||
| ... | |||
| ) |
Open data-, metadata(header)- or resource fork.
You must call ad_init() before ad_open, usually you'll just call it like this:
Open a files data fork, metadata fork or resource fork.
| [in,out] | ad | pointer to struct adouble |
| [in] | path | Path to file or directory |
| [in] | adflags | Flags specifying which fork to open, can be or'd (see below) |
| [in] | ... | mode used with O_CREATE |
Regular adflags:
Access mode for the forks:
Creation flags:
Special flags:
The open mode flags (rw vs ro) have to take into account all the following requirements:
we remember open fds for files because me must avoid a single close releasing fcntl locks for other fds of the same file
|
static |
|
static |
|
static |
|
static |
|
static |
Open resource fork.
|
static |
|
static |
| int ad_openat | ( | struct adouble * | ad, |
| int | dirfd, | ||
| const char * | path, | ||
| int | adflags, | ||
| ... | |||
| ) |
| const char * ad_path | ( | const char * | path, |
| int | adflags | ||
| ) |
Put the .AppleDouble where it needs to be:
| const char * ad_path_ea | ( | const char * | path, |
| int | adflags | ||
| ) |
| const char * ad_path_osx | ( | const char * | path, |
| int | adflags | ||
| ) |
| int ad_refresh | ( | const char * | path, |
| struct adouble * | ad | ||
| ) |
| off_t ad_reso_size | ( | const char * | path, |
| int | adflags, | ||
| struct adouble * | ad | ||
| ) |
Get resofork length for adouble:ea, parameter 'ad' may be NULL
| int ad_setfuid | ( | const uid_t | id | ) |
| int ad_stat | ( | const char * | path, |
| struct stat * | stbuf | ||
| ) |
stat path parent directory
| int ad_valid_header_osx | ( | const char * | path | ) |
| const char * adflags2logstr | ( | int | adflags | ) |
|
static |
|
static |
| const char * openflags2logstr | ( | int | oflags | ) |
|
static |
Read an AppleDouble buffer.
|
static |
|
static |
|
static |
|
static |
|
static |