#ifndef _WEBDAV_H_INCLUDE #define _WEBDAV_H_INCLUDE /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * The NEXTSTEP Software License Agreement specifies the terms * and conditions for redistribution. * * @(#)webdav.h 8.4 (Berkeley) 1/21/94 */ #include #include #include #include #include #include #include /* Webdav file operation constants */ #define WEBDAV_LOOKUP 1 #define WEBDAV_CREATE 2 #define WEBDAV_OPEN 3 #define WEBDAV_CLOSE 4 #define WEBDAV_GETATTR 5 #define WEBDAV_SETATTR 6 #define WEBDAV_READ 7 #define WEBDAV_WRITE 8 #define WEBDAV_FSYNC 9 #define WEBDAV_REMOVE 10 #define WEBDAV_RENAME 11 #define WEBDAV_MKDIR 12 #define WEBDAV_RMDIR 13 #define WEBDAV_READDIR 14 #define WEBDAV_STATFS 15 #define WEBDAV_UNMOUNT 16 #define WEBDAV_INVALCACHES 17 /* for the future */ #define WEBDAV_LINK 18 #define WEBDAV_SYMLINK 19 #define WEBDAV_READLINK 20 #define WEBDAV_MKNOD 21 #define WEBDAV_GETATTRLIST 22 #define WEBDAV_SETATTRLIST 23 #define WEBDAV_EXCHANGE 24 #define WEBDAV_READDIRATTR 25 #define WEBDAV_SEARCHFS 26 #define WEBDAV_COPYFILE 27 /* Webdav file type constants */ #define WEBDAV_FILE_TYPE 1 #define WEBDAV_DIR_TYPE 2 /* Shared (kernel & processs) WebDAV structures */ typedef int webdav_filehandle_t; typedef int webdav_filetype_t; /* Shared (kernel & process) WebDAV defninitions */ // ееее passed in from process #define WEBDAV_ROOTFILEID 3 // ееее passed in from process #define WEBDAV_DIR_SIZE 2048 /* * object_ref is the reference used to find a file system object in userland. * Lookup returns it. The rest of the operations which act upon a file system * object use it. */ typedef int object_ref; struct webdav_args { char *pa_mntfromname; /* mntfromname */ int pa_version; /* argument struct version */ int pa_socket_namelen; /* Socket to server name length */ struct sockaddr *pa_socket_name; /* Socket to server name */ char *pa_vol_name; /* volume name */ u_int32_t pa_flags; /* flag bits for mount */ object_ref pa_root_obj_ref; /* root object_ref */ ino_t pa_root_fileid; /* root fileid */ off_t pa_dir_size; /* size of directories */ time_t pa_lookup_timeout; /* max number of seconds before a lookup is required */ /* pathconf values: >=0 to return value; -1 if not supported */ int pa_link_max; /* maximum value of a file's link count */ int pa_name_max; /* The maximum number of bytes in a file name (does not include null at end) */ int pa_path_max; /* The maximum number of bytes in a relative pathname (does not include null at end) */ int pa_pipe_buf; /* The maximum number of bytes that can be written atomically to a pipe (usually PIPE_BUF if supported) */ int pa_chown_restricted; /* Return _POSIX_CHOWN_RESTRICTED if appropriate privileges are required for the chown(2) */ int pa_no_trunc; /* Return _POSIX_NO_TRUNC if file names longer than KERN_NAME_MAX are truncated */ /* end of webdav_args version 1 */ }; /* Defines for webdav_args pa_flags field */ #define WEBDAV_SUPPRESSALLUI 0x00000001 /* SuppressAllUI flag */ struct webdav_cred { uid_t pcr_uid; /* From ucred */ short pcr_ngroups; /* From ucred */ gid_t pcr_groups[NGROUPS]; /* From ucred */ }; /* WEBDAV_LOOKUP */ struct webdav_request_lookup { struct webdav_cred pcr; /* user and groups */ object_ref dir; /* directory to search */ size_t name_length; /* length of name */ char name[]; /* filename to find */ }; struct webdav_reply_lookup { object_ref obj_ref; /* object_ref of object corresponding to name */ ino_t obj_fileid; /* object's file ID number */ webdav_filetype_t obj_type; /* WEBDAV_FILE_TYPE or WEBDAV_DIR_TYPE */ struct timespec obj_atime; /* time of last access */ struct timespec obj_mtime; /* time of last data modification */ struct timespec obj_ctime; /* time of last file status change */ off_t obj_filesize; /* filesize of object */ }; /* WEBDAV_CREATE */ struct webdav_request_create { struct webdav_cred pcr; /* user and groups */ object_ref dir; /* The object_ref for the directory in which the file is to be created */ mode_t mode; /* file type and initial file access permissions for the file */ size_t name_length; /* length of name */ char name[]; /* The name that is to be associated with the created file */ }; struct webdav_reply_create { object_ref obj_ref; /* object_ref of file corresponding to name */ ino_t obj_fileid; /* file's file ID number */ }; /* WEBDAV_MKDIR */ struct webdav_request_mkdir { struct webdav_cred pcr; /* user and groups */ object_ref dir; /* The object_ref for the directory in which the file is to be created */ mode_t mode; /* file type and initial file access permissions for the file */ size_t name_length; /* length of name */ char name[]; /* The name that is to be associated with the created file */ }; struct webdav_reply_mkdir { object_ref obj_ref; /* object_ref of directory corresponding to name */ ino_t obj_fileid; /* directory's file ID number */ }; /* WEBDAV_OPEN */ struct webdav_request_open { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of object */ webdav_filetype_t obj_type; /* WEBDAV_FILE_TYPE or WEBDAV_DIR_TYPE */ int flags; /* file access flags (O_RDONLY, O_WRONLY, etc.) */ int ref; /* the reference to the webdav object that the cache object should be associated with */ }; struct webdav_reply_open { pid_t pid; /* process ID of file system daemon (for matching to ref's pid) */ }; /* WEBDAV_CLOSE */ struct webdav_request_close { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of object */ }; struct webdav_reply_close { }; /* WEBDAV_GETATTR */ struct webdav_request_getattr { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of object */ }; struct webdav_reply_getattr { struct stat obj_attr; /* attributes for the object */ }; /* WEBDAV_SETATTR XXX not needed at this time */ struct webdav_request_setattr { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of object */ struct stat new_obj_attr; /* new attributes of the object */ }; struct webdav_reply_setattr { }; /* WEBDAV_READ */ struct webdav_request_read { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of file object */ off_t offset; /* position within the file object at which the read is to begin */ size_t count; /* number of bytes of data to be read (limited to WEBDAV_MAX_IO_BUFFER_SIZE (8000-bytes)) */ }; struct webdav_reply_read { }; /* WEBDAV_WRITE XXX not needed at this time */ struct webdav_request_write { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of file object */ off_t offset; /* position within the file object at which the write is to begin */ size_t count; /* number of bytes of data to be written (limited to WEBDAV_MAX_IO_BUFFER_SIZE (8000-bytes)) */ char data[]; /* data to be written to the file object */ }; struct webdav_reply_write { size_t count; /* number of bytes of data written to the file */ }; /* WEBDAV_FSYNC */ struct webdav_request_fsync { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of object */ }; struct webdav_reply_fsync { }; /* WEBDAV_REMOVE */ struct webdav_request_remove { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of entry to remove */ }; struct webdav_reply_remove { }; /* WEBDAV_RMDIR */ struct webdav_request_rmdir { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of directory object to remove */ }; struct webdav_reply_rmdir { }; /* WEBDAV_RENAME */ struct webdav_request_rename { struct webdav_cred pcr; /* user and groups */ object_ref from_dir_ref; /* object_ref for the directory from which the entry is to be renamed */ object_ref from_obj_ref; /* object_ref for the object to be renamed */ object_ref to_dir_ref; /* object_ref for the directory to which the object is to be renamed */ object_ref to_obj_ref; /* object_ref for the object's new location if it exists (may be NULL) */ size_t to_name_length; /* length of to_name */ char to_name[]; /* new name for the object */ }; struct webdav_reply_rename { }; /* WEBDAV_READDIR */ struct webdav_request_readdir { struct webdav_cred pcr; /* user and groups */ object_ref obj_ref; /* object_ref of directory to read */ int cache; /* if TRUE, perform additional caching */ }; struct webdav_reply_readdir { }; /* WEBDAV_STATFS */ struct webdav_request_statfs { struct webdav_cred pcr; /* user and groups */ object_ref root_obj_ref; /* object_ref of the root directory */ }; struct webdav_reply_statfs { struct statfs fs_attr; /* file system information */ /* * (required: f_bsize, f_iosize, f_blocks, f_bfree, * f_bavail, f_files, f_ffree. The kext will either copy * the remaining info from the mount struct, or the cached * statfs struct in the mount struct IS the destination. */ }; /* WEBDAV_UNMOUNT */ struct webdav_request_unmount { struct webdav_cred pcr; /* user and groups */ }; struct webdav_reply_unmount { }; /* WEBDAV_INVALCACHES */ struct webdav_request_invalcaches { struct webdav_cred pcr; /* user and groups */ }; struct webdav_reply_invalcaches { }; union webdav_request { struct webdav_request_lookup lookup; struct webdav_request_create create; struct webdav_request_open open; struct webdav_request_close close; struct webdav_request_getattr getattr; struct webdav_request_setattr setattr; struct webdav_request_read read; struct webdav_request_write write; struct webdav_request_fsync fsync; struct webdav_request_remove remove; struct webdav_request_rmdir rmdir; struct webdav_request_rename rename; struct webdav_request_readdir readdir; struct webdav_request_statfs statfs; struct webdav_request_invalcaches invalcaches; }; union webdav_reply { struct webdav_reply_lookup lookup; struct webdav_reply_create create; struct webdav_reply_open open; struct webdav_reply_close close; struct webdav_reply_getattr getattr; struct webdav_reply_setattr setattr; struct webdav_reply_read read; struct webdav_reply_write write; struct webdav_reply_fsync fsync; struct webdav_reply_remove remove; struct webdav_reply_rmdir rmdir; struct webdav_reply_rename rename; struct webdav_reply_readdir readdir; struct webdav_reply_statfs statfs; struct webdav_reply_invalcaches invalcaches; }; #define UNKNOWNUID ((uid_t)99) #define WEBDAV_IOSIZE (4*1024) /* should be < WEBDAV_MAX_IO_BUFFER_SIZE */ /* * The WEBDAV_CONNECTION_DOWN_MASK bit is set by the code in send_reply() in * activate.c in the int result when the mount_webdav daemon determines it cannot * communicate with the remote WebDAV server. webdav_sendmsg() and webdav_open() in * webdav_vnops.c check that bit to determine if the connection is up or down. */ #define WEBDAV_CONNECTION_DOWN_MASK 0x80000000 /* * WEBDAVIOC_INVALIDATECACHES commmand passed to fsctl(2) causes WebDAV FS to * revalidate cached files with the WebDAV server and to invalidate all * all cached stat data. * example: * result = fsctl(path, WEBDAVIOC_INVALIDATECACHES, NULL, 0); */ #define WEBDAVIOC_INVALIDATECACHES _IO('w', 1) #define WEBDAV_INVALIDATECACHES IOCBASECMD(WEBDAVIOC_INVALIDATECACHES) struct webdavcachefileref { int ref; int fd; }; /* * Sysctl values for WebDAV FS */ /* * If name[0] is WEBDAV_ASSOCIATECACHEFILE_SYSCTL, then * name[1] = a pointer to a struct open_associatecachefile * name[2] = fd of cache file */ #define WEBDAV_ASSOCIATECACHEFILE_SYSCTL 1 #ifdef KERNEL struct webdavmount { vnode_t pm_root; /* Root node */ u_int32_t pm_status; /* status bits for this mounted structure */ struct mount *pm_mountp; /* vfs structure for this filesystem */ char *pm_vol_name; /* volume name */ struct sockaddr *pm_socket_name; /* Socket to server name */ off_t pm_dir_size; /* size of directories */ time_t pm_lookup_timeout; /* number of seconds before a lookup is required */ /* pathconf values: >=0 to return value; -1 if not supported */ int pm_link_max; /* maximum value of a file's link count (1 for file systems that do not support link counts) */ int pm_name_max; /* The maximum number of bytes in a file name (does not include null at end) */ int pm_path_max; /* The maximum number of bytes in a relative pathname (does not include null at end) */ int pm_pipe_buf; /* The maximum number of bytes that can be written atomically to a pipe (usually PIPE_BUF if supported) */ int pm_chown_restricted; /* Return _POSIX_CHOWN_RESTRICTED if appropriate privileges are required for the chown(2); otherwise 0 */ int pm_no_trunc; /* Return _POSIX_NO_TRUNC if file names longer than KERN_NAME_MAX are truncated; otherwise 0 */ }; struct webdavnode { LIST_ENTRY(webdavnode) pt_hash; /* Hash chain. */ struct mount *pt_mountp; /* vfs structure for this filesystem */ vnode_t pt_vnode; /* Pointer to parent vnode */ vnode_t pt_cache_vnode; /* Pointer to cached file vnode */ object_ref pt_obj_ref; /* object_ref from lookup */ ino_t pt_fileid; /* file id */ struct timespec pt_atime; /* time of last access */ struct timespec pt_mtime; /* time of last data modification */ struct timespec pt_ctime; /* time of last file status change */ off_t pt_filesize; /* what we think the filesize is */ time_t pt_timestamp; /* time we created or looked up on the server */ u_int32_t pt_status; /* WEBDAV_DIRTY, etc */ u_int32_t pt_opencount; /* count of opens */ }; struct open_associatecachefile { vnode_t cachevp; pid_t pid; }; /* Defines for webdavnode pt_status field */ #define WEBDAV_DIRTY 0x00000001 /* Indicates webdavnode has data which has not been flushed to cache file */ #define WEBDAV_ACCESSED 0x00000002 /* Indicates file has been accessed - used by webdav_gettr to determine dates */ #define WEBDAV_ONHASHLIST 0x00000004 /* Indicates webdavnode is on the hash chain */ #define WEBDAV_DELETED 0x00000008 /* Indicates that webdav file (which is still referenced) has been deleted */ #define WEBDAV_DIR_NOT_LOADED 0x00000010 /* Indicates that an open directory is empty and needs to be populated from the server */ #define WEBDAV_INIT 0x00000020 /* Indicates that the webdavnode is in the process of being initialized */ #define WEBDAV_WAITINIT 0x00000040 /* Indicates that someone is sleeping (on webdavnode) waiting for initialization to finish */ #define WEBDAV_ISMAPPED 0x00000080 /* Indicates that the file is mapped */ #define WEBDAV_WASMAPPED 0x00000100 /* Indicates that the file is or was mapped */ /* Defines for webdavmount pm_status field */ #define WEBDAV_MOUNT_SUPPORTS_STATFS 0x00000001 /* Indicates that the server supports quata and quota used properties */ #define WEBDAV_MOUNT_STATFS 0x00000002 /* statfs is in progress */ #define WEBDAV_MOUNT_STATFS_WANTED 0x00000004 /* statfs wakeup is wanted */ #define WEBDAV_MOUNT_TIMEO 0x00000008 /* connection to webdav server was lost */ #define WEBDAV_MOUNT_FORCE 0x00000010 /* doing a forced unmount. */ #define WEBDAV_MOUNT_DEAD 0x00000020 /* doing a forced unmount. */ #define WEBDAV_MOUNT_SUPPRESS_ALL_UI 0x00000040 /* suppress UI when connection is lost */ /* Webdav sizes for statfs */ #define WEBDAV_NUM_BLOCKS -1 /* not supported */ #define WEBDAV_FREE_BLOCKS -1 /* not supported */ #define WEBDAV_NUM_FILES 65535 /* Like HFS */ #define WEBDAV_FREE_FILES (WEBDAV_NUM_FILES - 2) /* Used a couple */ /* Webdav status macros */ #define VFSTOWEBDAV(mp) ((struct webdavmount *)(vfs_fsprivate(mp))) #define VTOWEBDAV(vp) ((struct webdavnode *)(vnode_fsnode(vp))) #define WEBDAVTOV(pt) ((pt)->pt_vnode) #define WEBDAVWASMAPPED(vp) (VTOWEBDAV(vp)->pt_status & WEBDAV_WASMAPPED) /* Other defines */ /* The WEBDAV_MAX_IO_BUFFER_SIZE gates how many bytes we * will try to read with a byte range request to the server. * Because sockets are only so big we can't transfer 8192 bytes. * That many bytes won't fit in a buffer so rather than having * webdav_sendmsg wait for all data, it would have to loop. Limiting * at 8000 works (based on emprical study on Darwin). If you are porting * this code to another platform or if the default socket buffer size * changes you may need to change this constan to implement the looping. * None of this would be necessary if Darwin's soreserve actually did reserve * space rather than just enforcing limits */ #define WEBDAV_MAX_IO_BUFFER_SIZE 8000 /* Gates byte read optimization */ /* * In webdav_read and webdav_pagein, webdav_read_bytes is called if the part of * file we need hasn't been downloaded from the server yet. However, since we're * already downloading the file, there's already data in the stream so reading * a range is counterproductive if we'll have downloaded the part we need (in the * stream) by the time webdav_read_bytes returns the data out of band. * Apache's mod_dav buffers 32K in the stream, so that's we'll use. */ #define WEBDAV_WAIT_IF_WITHIN 32768 /* the number of seconds soreceive() should block * before rechecking the server process state */ #define WEBDAV_SO_RCVTIMEO_SECONDS 10 #ifdef DEBUG #define START_MARKER(str) \ { \ log_vnop_start(str); \ } #define RET_ERR(str, error) \ { \ /*if (error)*/ \ log_vnop_error(str, error); \ return(error); \ } extern void log_vnop_start(char *str); extern void log_vnop_error(char *str, int error); #else #define START_MARKER(str) #define RET_ERR(str, error) return(error) #endif extern int( **webdav_vnodeop_p)(); extern void webdav_hashinit(void); extern void webdav_hashdestroy(void); extern void webdav_hashrem(struct webdavnode *); extern void webdav_hashins(struct webdavnode *); extern vnode_t webdav_hashget(struct mount *mp, ino_t fileid); extern void webdav_copy_creds(vfs_context_t context, struct webdav_cred *dest); extern int webdav_sendmsg(int vnop, struct webdavmount *fmp, void *request, size_t requestsize, void *vardata, size_t vardatasize, int *result, void *reply, size_t replysize); extern int webdav_get( struct mount *mp, /* mount point */ vnode_t dvp, /* parent vnode */ int markroot, /* if 1, mark as root vnode */ struct componentname *cnp, /* componentname */ object_ref obj_ref, /* object's object_ref */ ino_t obj_fileid, /* object's file ID number */ enum vtype obj_vtype, /* VREG or VDIR */ struct timespec obj_atime, /* time of last access */ struct timespec obj_mtime, /* time of last data modification */ struct timespec obj_ctime, /* time of last file status change */ off_t obj_filesize, /* object's filesize */ vnode_t *vpp); /* vnode returned here */ extern int webdav_vnop_getattrlist(struct vnop_getattrlist_args *ap); extern int webdav_assign_ref(struct open_associatecachefile *associatecachefile, int *ref); extern void webdav_release_ref(int ref); extern char webdav_name[MFSNAMELEN]; #endif /* KERNEL */ #endif /*ifndef _WEBDAV_H_INCLUDE */