netatalk  4.5.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
ea_ad.c File Reference
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <atalk/adouble.h>
#include <atalk/afp.h>
#include <atalk/compat.h>
#include <atalk/ea.h>
#include <atalk/logger.h>
#include <atalk/unix.h>
#include <atalk/util.h>
#include <atalk/vfs.h>
#include <atalk/volume.h>

Functions

static mode_t ea_header_mode (mode_t mode)
static mode_t ea_mode (mode_t mode)
static char * mtoupath (const struct vol *vol, const char *mpath)
static int ea_attrname_invalid (const char *func, const char *attruname)
static int unpack_header (struct ea *ea)
 unpack and verify header file data buffer at ea->ea_data into struct ea
static int pack_header (struct ea *ea)
 pack everything from struct ea into buffer at ea->ea_data
static int ea_addentry (struct ea *ea, const char *attruname, size_t attrsize, int bitmap)
 add one EA into ea->ea_entries[]
static int write_ea (const struct ea *ea, const char *attruname, const char *ibuf, size_t attrsize)
 write an EA to disk
static int ea_delentry (struct ea *ea, const char *attruname)
 delete one EA from ea->ea_entries[]
static int delete_ea_file (const struct ea *ea, const char *eaname)
 delete EA file from disk
char * ea_path (const struct ea *ea, const char *eaname, int macname)
 return name of ea header filename
int ea_open (const struct vol *vol, const char *uname, eaflags_t eaflags, struct ea *ea)
 open EA header file, create if it doesnt exits and called with O_CREATE
int ea_openat (const struct vol *vol, int dirfd, const char *uname, eaflags_t eaflags, struct ea *ea)
 openat like wrapper for ea_open, takes a additional file descriptor
int ea_close (struct ea *ea)
 flushes and closes an ea handle
int get_easize (const struct vol *vol, char *rbuf, size_t *rbuflen, const char *uname, int oflag, const char *attruname, int fd)
 get size of an EA
int get_eacontent (const struct vol *vol, char *rbuf, size_t *rbuflen, const char *uname, int oflag, const char *attruname, int maxreply, int fd)
 copy EA into rbuf
int list_eas (const struct vol *vol, char *attrnamebuf, size_t *buflen, const char *uname, int oflag, int fd)
 copy names of EAs into attrnamebuf
int set_ea (const struct vol *vol, const char *uname, const char *attruname, const char *ibuf, size_t attrsize, int oflag, int fd)
 set a Solaris native EA
int remove_ea (const struct vol *vol, const char *uname, const char *attruname, int oflag, int fd)
 remove a EA from a file
int ea_deletefile (const struct vol *vol, int dirfd, const char *file)
int ea_renamefile (const struct vol *vol, int dirfd, const char *src, const char *dst)
int ea_copyfile (const struct vol *vol, int sfd, const char *src, const char *dst)
 copy EAs
int ea_chown (const struct vol *vol, const char *path, uid_t uid, gid_t gid)
int ea_chmod_file (const struct vol *vol, const char *name, mode_t mode, struct stat *st)
int ea_chmod_dir (const struct vol *vol, const char *name, mode_t mode, struct stat *st)

Detailed Description

Store Extended Attributes inside .AppleDouble folders as follows:

filename "fileWithEAs" with EAs "testEA1" and "testEA2"

  • create header with with the format struct adouble_ea_ondisk, the file is written to ".AppleDouble/fileWithEAs::EA"
  • store EAs in files "fileWithEAs::EA::testEA1" and "fileWithEAs::EA::testEA2"

Function Documentation

◆ delete_ea_file()

int delete_ea_file ( const struct ea * ea,
const char * eaname )
static

delete EA file from disk

Parameters
[in]eastruct ea handle
[in]eanameEA name
Returns
0 on success, -1 on error

◆ ea_addentry()

int ea_addentry ( struct ea * ea,
const char * attruname,
size_t attrsize,
int bitmap )
static

add one EA into ea->ea_entries[]

Parameters
[in,out]eapointer to struct ea
[in]attrunamename of EA
[in]attrsizesize of ea
[in]bitmapbitmap from FP func
Returns
new number of EA entries, -1 on error
Note
Grow array ea->ea_entries[]. If ea->ea_entries is still NULL, start allocating. Otherwise realloc and put entry at the end. Increments ea->ea_count.

◆ ea_attrname_invalid()

int ea_attrname_invalid ( const char * func,
const char * attruname )
static

◆ ea_chmod_dir()

int ea_chmod_dir ( const struct vol * vol,
const char * name,
mode_t mode,
struct stat * st )

◆ ea_chmod_file()

int ea_chmod_file ( const struct vol * vol,
const char * name,
mode_t mode,
struct stat * st )

◆ ea_chown()

int ea_chown ( const struct vol * vol,
const char * path,
uid_t uid,
gid_t gid )

◆ ea_close()

int ea_close ( struct ea * ea)

flushes and closes an ea handle

Parameters
[in,out]eapointer to ea handle
Returns
0 on success, -1 on error
Note
Flushes and then closes and frees all resouces held by ea handle. Pack data in ea into ea_data, then write ea_data to disk

◆ ea_copyfile()

int ea_copyfile ( const struct vol * vol,
int sfd,
const char * src,
const char * dst )

copy EAs

Parameters
[in]volcurrent volume
[in]sfdsource file descriptor
[in]srcsource path
[in]dstdestination path
Returns
AFP code AFP_OK on success or appropriate AFP error code
Note
Copies EAs from source file to dest file.

◆ ea_delentry()

int ea_delentry ( struct ea * ea,
const char * attruname )
static

delete one EA from ea->ea_entries[]

Parameters
[in,out]eapointer to struct ea
[in]attrunameEA name
Returns
new number of EA entries, -1 on error
Note
Remove entry from ea->ea_entries[]. Decrement ea->ea_count. Marks it as unused just by freeing name and setting it to NULL. ea_close and pack_buffer must honor this.

◆ ea_deletefile()

int ea_deletefile ( const struct vol * vol,
int dirfd,
const char * file )

◆ ea_header_mode()

mode_t ea_header_mode ( mode_t mode)
inlinestatic

Build mode for EA header from file mode

◆ ea_mode()

mode_t ea_mode ( mode_t mode)
inlinestatic

Build mode for EA file from file mode

◆ ea_open()

int ea_open ( const struct vol * vol,
const char * uname,
eaflags_t eaflags,
struct ea * ea )

open EA header file, create if it doesnt exits and called with O_CREATE

Parameters
[in]volcurrent volume
[in]unamefilename for which we have to open a header
[in]eaflagsflag to control open behavior:
  • EA_CREATE: create if it doesn't exist (without it won't be created)
  • EA_RDONLY: open read only
  • EA_RDWR: open read/write
  • Either EA_RDONLY or EA_RDWR MUST be requested
[out]eapointer to a struct ea that we fill
Returns
0 on success, -1 on misc error with errno = EFAULT, -2 if no EA header exists with errno = ENOENT
Note
opens header file and stores fd in ea->ea_fd. Size of file is put into ea->ea_size. number of EAs is stored in ea->ea_count. flags are remembered in ea->ea_flags. file is either read or write locked depending on the open flags. When you're done with struct ea you must call ea_close on it.

◆ ea_openat()

int ea_openat ( const struct vol * vol,
int dirfd,
const char * uname,
eaflags_t eaflags,
struct ea * ea )

openat like wrapper for ea_open, takes a additional file descriptor

Parameters
[in]volcurrent volume
[in]dirfdopenat like file descriptor
[in]unamefilename for which we have to open a header
[in]eaflagsflag to control open behavior:
  • EA_CREATE: create if it doesn't exist (without it won't be created)
  • EA_RDONLY: open read only
  • EA_RDWR: open read/write
  • Either EA_RDONLY or EA_RDWR MUST be requested
[out]eapointer to a struct ea that we fill
Returns
0 on success, -1 on misc error with errno = EFAULT, -2 if no EA header exists with errno = ENOENT
Note
opens header file and stores fd in ea->ea_fd. Size of file is put into ea->ea_size. number of EAs is stored in ea->ea_count. flags are remembered in ea->ea_flags. file is either read or write locked depending on the open flags. When you're done with struct ea you must call ea_close on it.

◆ ea_path()

char * ea_path ( const struct ea * ea,
const char * eaname,
int macname )

return name of ea header filename

Parameters
[in]eaea handle
[in]eanamename of EA or NULL
[in]macnameif != 0 call mtoupath on eaname
Returns
pointer to name in static buffer, NULL on error
Note
- Calls ad_open, copies buffer, appends "::EA" and if supplied append eanme
  • Files: "file" -> "file/.AppleDouble/file::EA"
  • Dirs: "dir" -> "dir/.AppleDouble/.Parent::EA"
  • "file" with EA "myEA" -> "file/.AppleDouble/file::EA:myEA"

◆ ea_renamefile()

int ea_renamefile ( const struct vol * vol,
int dirfd,
const char * src,
const char * dst )

◆ get_eacontent()

int get_eacontent ( const struct vol * vol,
char * rbuf,
size_t * rbuflen,
const char * uname,
int oflag,
const char * attruname,
int maxreply,
int fd )

copy EA into rbuf

Parameters
[in]volcurrent volume
[out]rbufDSI reply buffer
[in,out]rbuflencurrent length of data in reply buffer
[in]unamefilename
[in]oflaglink and create flag
[in]attrunamename of attribute
[in]maxreplymaximum EA size as of current specs/real-life
[in]fdfile descriptor
Returns
AFP code: AFP_OK on success or appropriate AFP error code
Note
Copies EA into rbuf. Increments *rbuflen accordingly.

◆ get_easize()

int get_easize ( const struct vol * vol,
char * rbuf,
size_t * rbuflen,
const char * uname,
int oflag,
const char * attruname,
int fd )

get size of an EA

Parameters
[in]volcurrent volume
[out]rbufDSI reply buffer
[in,out]rbuflencurrent length of data in reply buffer
[in]unamefilename
[in]oflaglink and create flag
[in]attrunamename of attribute
[in]fdfile descriptor
Returns
AFP code: AFP_OK on success or appropriate AFP error code
Note
Copies EA size into rbuf in network order. Increments *rbuflen +4.

◆ list_eas()

int list_eas ( const struct vol * vol,
char * attrnamebuf,
size_t * buflen,
const char * uname,
int oflag,
int fd )

copy names of EAs into attrnamebuf

Parameters
[in]volcurrent volume
[out]attrnamebufstore names a consecutive C strings here
[in,out]buflenlength of names in attrnamebuf
[in]unamefilename
[in]oflaglink and create flag
[in]fdfile descriptor
Returns
AFP code: AFP_OK on success or appropriate AFP error code
Note
Copies names of all EAs of uname as consecutive C strings into rbuf. Increments *buflen accordingly.

◆ mtoupath()

char * mtoupath ( const struct vol * vol,
const char * mpath )
static

◆ pack_header()

int pack_header ( struct ea * ea)
static

pack everything from struct ea into buffer at ea->ea_data

Parameters
[in,out]eahandle to struct ea
Returns
0 on success, -1 on error
Note
adjust ea->ea_count in case an ea entry deletetion is detected

◆ remove_ea()

int remove_ea ( const struct vol * vol,
const char * uname,
const char * attruname,
int oflag,
int fd )

remove a EA from a file

Parameters
[in]volcurrent volume
[in]unamefilename
[in]attrunameEA name
[in]oflaglink and create flag
[in]fdfile descriptor
Returns
AFP code: AFP_OK on success or appropriate AFP error code
Note
Removes EA attruname from file uname.

◆ set_ea()

int set_ea ( const struct vol * vol,
const char * uname,
const char * attruname,
const char * ibuf,
size_t attrsize,
int oflag,
int fd )

set a Solaris native EA

Parameters
[in]volcurrent volume
[in]unamefilename
[in]attrunameEA name
[in]ibufbuffer with EA content
[in]attrsizelength EA in ibuf
[in]oflaglink and create flag
[in]fdfile descriptor
Returns
AFP code: AFP_OK on success or appropriate AFP error code
Note
Copies names of all EAs of uname as consecutive C strings into rbuf. Increments *rbuflen accordingly.

◆ unpack_header()

int unpack_header ( struct ea * ea)
static

unpack and verify header file data buffer at ea->ea_data into struct ea

Parameters
[in,out]eahandle to struct ea
Returns
0 on success, -1 on error
Note
Verifies magic and version.

◆ write_ea()

int write_ea ( const struct ea * ea,
const char * attruname,
const char * ibuf,
size_t attrsize )
static

write an EA to disk

Parameters
[in]eastruct ea handle
[in]attrunameEA name
[in]ibufbuffer with EA content
[in]attrsizesize of EA
Returns
0 on success, -1 on error
Note
Creates/overwrites EA file.