1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#ifndef _WEBDAVD_H_INCLUDE 25#define _WEBDAVD_H_INCLUDE 26 27/* 28 * DEBUG (which defines the state of DEBUG_ASSERT_PRODUCTION_CODE), 29 * DEBUG_ASSERT_COMPONENT_NAME_STRING, and DEBUG_ASSERT_MESSAGE must be 30 * defined before including AssertMacros.h 31 */ 32/* we want non-quiet asserts to be logged */ 33#define DEBUG_ASSERT_PRODUCTION_CODE 0 34/* and we want them logged as errors */ 35#define WEBDAV_LOG_LEVEL LOG_ERR 36#define DEBUG_ASSERT_COMPONENT_NAME_STRING "webdavfs" 37#define DEBUG_ASSERT_MESSAGE(componentNameString, assertionString, exceptionLabelString, errorString, fileName, lineNumber, errorCode) \ 38 webdav_debug_assert(componentNameString, assertionString, exceptionLabelString, errorString, fileName, lineNumber, errorCode) 39 40#include <AssertMacros.h> 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/syslog.h> 45#include "../webdav_fs.kextproj/webdav_fs.kmodproj/webdav.h" 46#include <errno.h> 47#include <mach/boolean.h> 48#include <unistd.h> 49#include <CoreFoundation/CFURL.h> 50#include <CoreFoundation/CoreFoundation.h> 51#include <CoreServices/CoreServices.h> 52 53/* Global Defines */ 54 55/* 56 * WEBDAV_RLIMIT_NOFILE needs to be large enough for us to have WEBDAV_MAX_OPEN_FILES cache files 57 * open, plus some for the defaults (stdin/out, etc), the sockets opened by threads, 58 * the dup'd file descriptors passed back to the kext, the socket used to 59 * communicate with the kext, and a few extras for libraries we call that might 60 * need a few. The most I've ever seen in use is just under 530, so 1024 is 61 * more than enough. 62 */ 63#define WEBDAV_RLIMIT_NOFILE 1024 64#define WEBDAV_MAX_OPEN_FILES 512 65 66// The default maximum size of a download to allow the file system to cache 67#define WEBDAV_DEFAULT_CACHE_MAX_SIZE 0x02000000 /* 32M */ 68#define WEBDAV_ONE_GIGABYTE 0x40000000 /* 1G */ 69 70/* the number of threads available to handle requests from the kernel file system and downloads */ 71#define WEBDAV_REQUEST_THREADS 5 72 73#define PRIVATE_CERT_UI_COMMAND "/System/Library/Filesystems/webdav.fs/Support/webdav_cert_ui.app/Contents/MacOS/webdav_cert_ui" 74#define PRIVATE_UNMOUNT_COMMAND "/sbin/umount" 75#define PRIVATE_UNMOUNT_FLAGS "-f" 76 77/* the time interval (in seconds) for holding LOCKs on the server. The pulse thread runs at doublew this rate. */ 78#define WEBDAV_PULSE_TIMEOUT "600" /* Default time out = 10 minutes */ 79 80#define APPLEDOUBLEHEADER_LENGTH 82 /* length of AppleDouble header property */ 81 82/* 83 * BODY_BUFFER_SIZE is the initial size of the buffer used to read an 84 * HTTP entity body. The largest bodies are typically the XML data 85 * returned by the PROPFIND method for a large collection (directory). 86 * 64K is large enough to handle directories with 100-150 items. 87 */ 88#define BODY_BUFFER_SIZE 0x10000 /* 64K */ 89 90/* special file ID values */ 91#define WEBDAV_ROOTPARENTFILEID 2 92#define WEBDAV_ROOTFILEID 3 93 94/* sizes passed to the kernel file system */ 95#define WEBDAV_DIR_SIZE 2048 /* the directory size -- a made up value */ 96#define WEBDAV_IOSIZE (4*1024) /* should be < PIPSIZ (8K) */ 97 98#define WEBDAV_WRITESEQ_RSPBUF_LEN 4096 99#define WEBDAV_WRITESEQ_REQUEST_TIMEOUT 30 /* in seconds */ 100#define WEBDAV_MANAGER_STARTUP_TIMEOUT 5 /* in seconds */ 101 102/* Macro to simplify common CFRelease usage */ 103#define CFReleaseNull(obj) do { if(obj != NULL) { CFRelease(obj); obj = NULL; } } while (0) 104 105struct seqwrite_mgr_req; 106 107enum WriteMgrStatus {WR_MGR_VIRGIN=0, WR_MGR_RUNNING, WR_MGR_DONE}; 108struct stream_put_ctx { 109 /* Stream Pair */ 110 CFReadStreamRef rdStreamRef; 111 CFWriteStreamRef wrStreamRef; 112 struct ReadStreamRec* readStreamRec; 113 CFReadStreamRef rspStreamRef; 114 int sockfd[2]; 115 CFTypeRef theResponsePropertyRef; 116 off_t curr_offset; 117 118 // The outgoing request message 119 CFHTTPMessageRef request; 120 121 // *********************** 122 // *** Synchronization *** 123 // *********************** 124 pthread_mutex_t ctx_lock; 125 pthread_cond_t ctx_condvar; /* close thread waits on finalStatusValid */ 126 127 // Sequential write manager stuff 128 CFRunLoopRef mgr_rl; 129 enum WriteMgrStatus mgr_status; 130 uint32_t canAcceptBytesEvents; 131 132 // Request queue for manager thread, and 133 // message port 134 CFMessagePortRef mgrPort; 135 struct seqwrite_mgr_req *req_head, *req_tail; 136 137 // ************************************* 138 // *** Response stream thread fields *** 139 // ************************************* 140 bool finalStatusValid; 141 int finalStatus; 142 143 CFIndex totalRead; 144 UInt8 rspBuf[WEBDAV_WRITESEQ_RSPBUF_LEN]; 145 146 // *************************** 147 // *** Write thread fields *** 148 // *************************** 149 150 // writeStreamOpenEventReceived is set to true when 151 // a kCFStreamEventOpenCompleted event has been received 152 // on the stream 153 bool writeStreamOpenEventReceived; 154 bool rspStreamOpenEventReceived; 155 156 // True if current write is a retry (due to previous EPIPE) 157 uint32_t is_retry; 158}; 159 160// Sequential write manager request 161enum SeqWriteMgrReqType {SEQWRITE_CHUNK, SEQWRITE_CLOSE}; 162struct seqwrite_mgr_req 163{ 164 enum SeqWriteMgrReqType type; 165 166 struct seqwrite_mgr_req *prev, *next; 167 168 // *********************** 169 // *** Synchronization *** 170 // *********************** 171 pthread_mutex_t req_lock; 172 pthread_cond_t req_condvar; 173 174 // state of this request 175 struct webdav_request_writeseq *req; 176 bool request_done; 177 uint32_t is_retry; // true if this request is a retry (due to a previous EPIPE) 178 int error; 179 180 // chunk state 181 CFIndex chunkLen, chunkWritten; 182 183 uint32_t refCount; 184 185 // Where we store data read from the cache before we throw it on the wire. 186 unsigned char *data; 187}; 188 189/* Global functions */ 190extern void webdav_debug_assert(const char *componentNameString, const char *assertionString, 191 const char *exceptionLabelString, const char *errorString, 192 const char *fileName, long lineNumber, uint64_t errorCode); 193extern void webdav_kill(int message); 194 195/* Global variables */ 196extern unsigned int gtimeout_val; /* the pulse_thread runs at double this rate */ 197extern char * gtimeout_string; /* the length of time LOCKs are held on on the server */ 198extern int gWebdavfsDebug; /* TRUE if the WEBDAVFS_DEBUG environment variable is set */ 199extern uid_t gProcessUID; /* the daemon's UID */ 200extern int gSuppressAllUI; /* if TRUE, the mount requested that all UI be supressed */ 201extern int gSecureServerAuth; /* if TRUE, the authentication for server challenges must be sent securely (not clear-text) */ 202 203extern char gWebdavCachePath[MAXPATHLEN + 1]; /* the current path to the cache directory */ 204extern int gSecureConnection; /* if TRUE, the connection is secure */ 205extern CFURLRef gBaseURL; /* the base URL for this mount */ 206extern CFStringRef gBasePath; /* the base path (from gBaseURL) for this mount */ 207extern char gBasePathStr[MAXPATHLEN]; /* gBasePath as a c-string */ 208extern uint32_t gServerIdent; /* identifies some (not all) types of servers we are connected to (i.e. WEBDAV_IDISK_SERVER) */ 209 210/* 211 * filesystem functions 212 */ 213// there should be a filesystem.h and these prototypes should be moved there 214#include "webdav_cache.h" 215 216extern int filesystem_lookup(struct webdav_request_lookup *request_lookup, 217 struct webdav_reply_lookup *reply_lookup); 218 219extern int filesystem_create(struct webdav_request_create *request_create, 220 struct webdav_reply_create *reply_create); 221 222extern int filesystem_open(struct webdav_request_open *request_open, 223 struct webdav_reply_open *reply_open); 224 225extern int filesystem_close(struct webdav_request_close *request_close); 226 227extern int filesystem_getattr(struct webdav_request_getattr *request_getattr, 228 struct webdav_reply_getattr *reply_getattr); 229 230extern int filesystem_read(struct webdav_request_read *request_read, 231 char **a_byte_addr, size_t *a_size); 232 233extern int filesystem_fsync(struct webdav_request_fsync *request_fsync); 234 235extern int filesystem_remove(struct webdav_request_remove *request_remove); 236 237extern int filesystem_rename(struct webdav_request_rename *request_rename); 238 239extern int filesystem_mkdir(struct webdav_request_mkdir *request_mkdir, 240 struct webdav_reply_mkdir *reply_mkdir); 241 242extern int filesystem_rmdir(struct webdav_request_rmdir *request_rmdir); 243 244extern int filesystem_write_seq(struct webdav_request_writeseq *request_sq_wr); 245 246extern int filesystem_readdir(struct webdav_request_readdir *request_readdir); 247 248extern int filesystem_statfs(struct webdav_request_statfs *request_statfs, 249 struct webdav_reply_statfs *reply_statfs); 250 251extern int filesystem_invalidate_caches(struct webdav_request_invalcaches *request_invalcaches); 252 253extern int filesystem_mount(int *a_mount_args); 254 255extern int filesystem_lock(struct node_entry *node); 256 257extern int filesystem_init(int typenum); 258 259#endif /*ifndef _WEBDAVD_H_INCLUDE */ 260