netatalk  4.4.0
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
directory.h File Reference
#include <arpa/inet.h>
#include <dirent.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <atalk/directory.h>
#include <atalk/globals.h>
#include "volume.h"

Go to the source code of this file.

Data Structures

struct  maccess

Macros

#define DIRPBIT_ATTR   0
#define DIRPBIT_PDID   1
#define DIRPBIT_CDATE   2
#define DIRPBIT_MDATE   3
#define DIRPBIT_BDATE   4
#define DIRPBIT_FINFO   5
#define DIRPBIT_LNAME   6
#define DIRPBIT_SNAME   7
#define DIRPBIT_DID   8
#define DIRPBIT_OFFCNT   9
#define DIRPBIT_UID   10
#define DIRPBIT_GID   11
#define DIRPBIT_ACCESS   12
#define DIRPBIT_PDINFO   13
#define DIRPBIT_UNIXPR   15
#define FILDIRBIT_ISDIR   (1 << 7)
#define FILDIRBIT_ISFILE   (0)
#define CNID(a, b)
#define AR_USEARCH   (1<<0)
#define AR_UREAD   (1<<1)
#define AR_UWRITE   (1<<2)
#define AR_UOWN   (1<<7)

Typedefs

typedef int(* dir_loop) (struct dirent *, char *, void *)

Functions

void dir_free_invalid_q (void)
 Free the queue with invalid struct dirs.
struct dirdir_new (const char *mname, const char *uname, const struct vol *, cnid_t pdid, cnid_t did, bstring fullpath, struct stat *)
 Construct struct dir.
void dir_free (struct dir *)
 Free a struct dir and all its members.
struct dirdir_add (struct vol *, const struct dir *, struct path *, int)
 Create struct dir from struct path.
int dir_modify (const struct vol *vol, struct dir *dir, cnid_t pdid, cnid_t did, const char *new_mname, const char *new_uname, bstring pdir_fullpath)
int dir_remove (const struct vol *vol, struct dir *dir)
 Remove a file/directory from dircache.
struct dirdirlookup (const struct vol *, cnid_t)
 Resolve a DID.
struct dirdirlookup_bypath (const struct vol *vol, const char *path)
int movecwd (const struct vol *, struct dir *)
 chdir() to dir
struct pathcname (struct vol *, struct dir *, char **)
 Resolve a catalog node name path.
int deletecurdir (struct vol *)
mode_t mtoumode (struct maccess *)
int getdirparams (const AFPObj *obj, const struct vol *, uint16_t, struct path *, struct dir *, char *, size_t *)
int setdirparams (struct vol *, struct path *, uint16_t, char *)
int renamedir (struct vol *, int, char *, char *, struct dir *, char *)
 Rename a directory.
int path_error (struct path *, int error)
void setdiroffcnt (struct dir *dir, struct stat *st, uint32_t count)
int dirreenumerate (struct dir *dir, struct stat *st)
int for_each_dirent (const struct vol *, char *, dir_loop, void *)
int check_access (const AFPObj *obj, struct vol *, char *name, int mode)
int file_access (const AFPObj *obj, struct vol *vol, struct path *path, int mode)
int netatalk_unlink (const char *name)
 system unlink with afp error code.
char * check_dirent (const struct vol *, char *)
int afp_createdir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_opendir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_setdirparams (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_closedir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_mapid (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_mapname (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_syncdir (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_enumerate (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_enumerate_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_enumerate_ext2 (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_catsearch (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
int afp_catsearch_ext (AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)

Variables

q_tinvalid_dircache_entries

Macro Definition Documentation

◆ AR_UOWN

#define AR_UOWN   (1<<7)

◆ AR_UREAD

#define AR_UREAD   (1<<1)

◆ AR_USEARCH

#define AR_USEARCH   (1<<0)

◆ AR_UWRITE

#define AR_UWRITE   (1<<2)

◆ CNID

#define CNID ( a,
b )
Value:
((a)->st_ino & 0xffffffff)

◆ DIRPBIT_ACCESS

#define DIRPBIT_ACCESS   12

◆ DIRPBIT_ATTR

#define DIRPBIT_ATTR   0

◆ DIRPBIT_BDATE

#define DIRPBIT_BDATE   4

◆ DIRPBIT_CDATE

#define DIRPBIT_CDATE   2

◆ DIRPBIT_DID

#define DIRPBIT_DID   8

◆ DIRPBIT_FINFO

#define DIRPBIT_FINFO   5

◆ DIRPBIT_GID

#define DIRPBIT_GID   11

◆ DIRPBIT_LNAME

#define DIRPBIT_LNAME   6

◆ DIRPBIT_MDATE

#define DIRPBIT_MDATE   3

◆ DIRPBIT_OFFCNT

#define DIRPBIT_OFFCNT   9

◆ DIRPBIT_PDID

#define DIRPBIT_PDID   1

◆ DIRPBIT_PDINFO

#define DIRPBIT_PDINFO   13

ProDOS Info

◆ DIRPBIT_SNAME

#define DIRPBIT_SNAME   7

◆ DIRPBIT_UID

#define DIRPBIT_UID   10

◆ DIRPBIT_UNIXPR

#define DIRPBIT_UNIXPR   15

◆ FILDIRBIT_ISDIR

#define FILDIRBIT_ISDIR   (1 << 7)

is a directory

◆ FILDIRBIT_ISFILE

#define FILDIRBIT_ISFILE   (0)

is a file

Typedef Documentation

◆ dir_loop

typedef int(* dir_loop) (struct dirent *, char *, void *)

Function Documentation

◆ afp_catsearch()

int afp_catsearch ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_catsearch_ext()

int afp_catsearch_ext ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_closedir()

int afp_closedir ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_createdir()

int afp_createdir ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_enumerate()

int afp_enumerate ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_enumerate_ext()

int afp_enumerate_ext ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_enumerate_ext2()

int afp_enumerate_ext2 ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_mapid()

int afp_mapid ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_mapname()

int afp_mapname ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_opendir()

int afp_opendir ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_setdirparams()

int afp_setdirparams ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ afp_syncdir()

int afp_syncdir ( AFPObj * obj,
char * ibuf,
size_t ibuflen,
char * rbuf,
size_t * rbuflen )

◆ check_access()

int check_access ( const AFPObj * obj,
struct vol * vol,
char * path,
int mode )
extern

We can't use unix file's perm to support Apple's inherited protection modes. If we aren't the file's owner we can't change its perms when moving it and smb nfs,... don't even try.

◆ check_dirent()

char * check_dirent ( const struct vol * vol,
char * name )
extern
Bug
Doesn't work with dangling symlink i.e.:
  • Move a folder with a dangling symlink in the trash
  • empty the trash

afp_enumerate return an empty listing but offspring count != 0 in afp_getdirparams and the Mac doesn't try to call afp_delete!

See also
https://sourceforge.net/p/netatalk/bugs/97/

◆ cname()

struct path * cname ( struct vol * vol,
struct dir * dir,
char ** cpath )
extern

Resolve a catalog node name path.

  1. Evaluate path type
  2. Move to start dir, if we can't, it might be e.g. because of EACCES, build path from dirname, so e.g. getdirparams has sth it can chew on. curdir is dir parent then. All this is done in path_from_dir().
  3. Parse next cnode name in path, cases:
  4. single "\0" -> do nothing
  5. two or more consecutive "\0" -> chdir("..") one or more times
  6. cnode name -> copy it to path.m_name
  7. Get unix name from mac name
  8. Special handling of request with did 1
  9. stat the cnode name
  10. If it's not there, it's probably an afp_createfile|dir, return with curdir = dir parent, struct path = dirname
  11. If it's there and it's a file, it must should be the last element of the requested path. Return with curdir = cnode name parent dir, struct path = filename
  12. Treat symlinks like files, don't follow them
  13. If it's a dir:
  14. Search the dircache for it
  15. If it's not in the cache, create a struct dir for it and add it to the cache
  16. chdir into the dir and
  17. set m_name to the mac equivalent of "."
  18. goto 3

◆ deletecurdir()

int deletecurdir ( struct vol * vol)
extern

delete an empty directory

◆ dir_add()

struct dir * dir_add ( struct vol * vol,
const struct dir * dir,
struct path * path,
int len )
extern

Create struct dir from struct path.

Create a new struct dir from struct path. Then add it to the cache.

  1. Open adouble file, get CNID from it.
  2. Search the database, hinting with the CNID from (1).
  3. Build fullpath and create struct dir.
  4. Add it to the cache.
Parameters
[in]volpointer to struct vol, possibly modified in callee
[in]dirpointer to parent directory
[in,out]pathpointer to struct path with valid path->u_name
[in]lenstrlen of path->u_name
Returns
Pointer to new struct dir or NULL on error.
Note
Function also assigns path->m_name from path->u_name.

◆ dir_free()

void dir_free ( struct dir * dir)
extern

Free a struct dir and all its members.

Parameters
dir(rw) pointer to struct dir

◆ dir_free_invalid_q()

void dir_free_invalid_q ( void )
extern

Free the queue with invalid struct dirs.

Note
This gets called at the end of every AFP func.

◆ dir_modify()

int dir_modify ( const struct vol * vol,
struct dir * dir,
cnid_t pdid,
cnid_t did,
const char * new_mname,
const char * new_uname,
bstring pdir_fullpath )
extern

◆ dir_new()

struct dir * dir_new ( const char * m_name,
const char * u_name,
const struct vol * vol,
cnid_t pdid,
cnid_t did,
bstring path,
struct stat * st )
extern

Construct struct dir.

Construct struct dir from parameters.

Parameters
[in]m_namedirectory name in UTF8-dec
[in]u_namedirectory name in server side encoding
[in]volpointer to struct vol
[in]pdidParent CNID
[in]didCNID
[in]pathFull unix path to object
[in]ststruct stat of object
Returns
pointer to new struct dir or NULL on error
Note
Most of the time mac name and unix name are the same.

◆ dir_remove()

int dir_remove ( const struct vol * vol,
struct dir * dir )
extern

Remove a file/directory from dircache.

  1. Check the dir
  2. Remove it from the cache
  3. Queue it for removal
  4. If it's a request to remove curdir, mark curdir as invalid
  5. Mark it as invalid
Parameters
[in]volvolume pointer
[in,out]dirdirectory/file entry to remove from cache
Returns
0 on success

◆ dirlookup()

struct dir * dirlookup ( const struct vol * vol,
cnid_t did )
extern

Resolve a DID.

Resolve a DID, allocate a struct dir for it

  1. Check for special CNIDs 0 (invalid), 1 and 2.
    1. Check if the DID is in the cache.
    2. Check if it's really a dir because we cache files too.
  2. If it's not in the cache resolve it via the database.
  3. Build complete server-side path to the dir.
  4. Check if it exists and is a directory.
  5. Create the struct dir and populate it.
  6. Add it to the cache.
Parameters
[in]volpointer to struct vol
[in]didDID to resolve
Returns
pointer to struct dir

◆ dirlookup_bypath()

struct dir * dirlookup_bypath ( const struct vol * vol,
const char * path )
extern

◆ dirreenumerate()

int dirreenumerate ( struct dir * dir,
struct stat * st )
extern

◆ file_access()

int file_access ( const AFPObj * obj,
struct vol * vol,
struct path * path,
int mode )
extern

◆ for_each_dirent()

int for_each_dirent ( const struct vol * vol,
char * name,
dir_loop fn,
void * data )
extern

◆ getdirparams()

int getdirparams ( const AFPObj * obj,
const struct vol * vol,
uint16_t bitmap,
struct path * s_path,
struct dir * dir,
char * buf,
size_t * buflen )
extern

◆ movecwd()

int movecwd ( const struct vol * vol,
struct dir * dir )
extern

chdir() to dir

Parameters
[in]volpointer to struct vol
[in]dirpointer to struct dir
Returns
0 on success, -1 on error with afp_errno set appropriately

◆ mtoumode()

mode_t mtoumode ( struct maccess * ma)
extern

◆ netatalk_unlink()

int netatalk_unlink ( const char * name)
extern

system unlink with afp error code.

Note
ENOENT is not an error.

◆ path_error()

int path_error ( struct path * path,
int error )
extern

◆ renamedir()

int renamedir ( struct vol * vol,
int dirfd,
char * src,
char * dst,
struct dir * newparent,
char * newname )
extern

Rename a directory.

Parameters
volvolume
dirfd-1 means ignore dirfd (or use AT_FDCWD), otherwise src is relative to dirfd
srcold unix filename (not a pathname)
dstnew unix filename (not a pathname)
newparentcurdir
newnamenew mac name

◆ setdiroffcnt()

void setdiroffcnt ( struct dir * dir,
struct stat * st,
uint32_t count )
extern

◆ setdirparams()

int setdirparams ( struct vol * vol,
struct path * path,
uint16_t d_bitmap,
char * buf )
extern
Note
assume path == '\0' e.g. it's a directory in canonical form

Variable Documentation

◆ invalid_dircache_entries

q_t* invalid_dircache_entries
extern