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 _WEBDAV_PARSE_H_INCLUDE
25#define _WEBDAV_PARSE_H_INCLUDE
26
27#include <sys/types.h>
28#include <sys/dirent.h> // for __DARWIN_MAXNAMELEN
29
30/* Types */
31
32typedef struct
33{
34	int context;
35	char *locktoken;
36	Boolean start; /*For characters callback to work only after start tag and no end tag*/
37} webdav_parse_lock_struct_t;
38
39struct webdav_parse_cachevalidators_struct
40{
41	time_t last_modified;
42	char *entity_tag;
43	void* data;
44	Boolean start; /*For characters callback to work only after start tag and no end tag*/
45};
46
47struct webdav_quotas
48{
49	int			use_bytes_values;		/* if TRUE, use quota_available_bytes and quota_used_bytes */
50	uint64_t	quota_available_bytes;	/* DAV:quota-available-bytes property value */
51	uint64_t	quota_used_bytes;		/* DAV:quota-used-bytes property value */
52	uint64_t	quota;					/* deprecated DAV:quota property value */
53	uint64_t	quotaused;				/* deprecated DAV:quotaused property value */
54	void* data;
55	Boolean start; /*For characters callback to work only after start tag and no end tag*/
56};
57
58/* This needs to be big enough for a pathname where every character comes to us
59 * in URI Escaped Encoding. That means that each character could expand to
60 * 3 characters (i.e., ' ' = '%20').
61 */
62#define WEBDAV_MAX_URI_LEN ((MAXPATHLEN * 3) + 1)
63
64/* This structure must be exactly like "struct dirent", defined in sys/dirent.h,
65   except that d_name is long enough to hold the entire URI and the URI length
66   is stored in d_name_URI_length. */
67struct large_dirent
68{
69	webdav_ino_t d_ino;							/* file number of entry */
70	u_int16_t d_reclen;							/* sizeof(struct dirent) */
71	u_int8_t d_type;							/* file type, see below */
72	u_int8_t d_namlen;							/* length of string in d_name */
73	char d_name[WEBDAV_MAX_URI_LEN];			/* name must be no longer than this */
74	u_int32_t d_name_URI_length;				/* the length of the URI stored in
75												 * d_name until it is shortened
76												 * to a file name */
77};
78
79// XXX Dependency on __DARWIN_64_BIT_INO_T
80// struct dirent is in flux right now because __DARWIN_64_BIT_INO_T is set to 1 for user space,
81// but set to zero for kernel space.
82// So user space sees dirent as:
83//
84// struct dirent {
85// __uint64_t  d_ino;      /* file number of entry */
86// __uint64_t  d_seekoff;  /* seek offset (optional, used by servers) */
87// __uint16_t  d_reclen;   /* length of this record */
88// __uint16_t  d_namlen;   /* length of string in d_name */
89// __uint8_t   d_type;     /* file type, see below */
90// char      d_name[__DARWIN_MAXPATHLEN]; /* entry name (up to MAXPATHLEN bytes) */
91// };
92//
93// But kernel space sees dirent like this:
94//
95// struct dirent {
96//	ino_t d_ino;			/* file number of entry */
97//	__uint16_t d_reclen;		/* length of this record */
98//	__uint8_t  d_type; 		/* file type, see below */
99//	__uint8_t  d_namlen;		/* length of string in d_name */
100//	char d_name[__DARWIN_MAXNAMLEN + 1];	/* name must be no longer than this */
101// };
102//
103// So until kernel and user space sees the same dirent, we need to use our
104// own type since we pass a struct dirent from user to kernel space when we
105// process readdir vnop.
106//
107// Once __DARWIN_64_BIT_INO_T is set to 1 for both user and kernel space, we
108// can get rid of webdav_dirent and just use dirent exclusively.
109//
110struct webdav_dirent {
111		webdav_ino_t d_ino;			/* file number of entry */
112		__uint16_t d_reclen;		/* length of this record */
113		__uint8_t  d_type; 		/* file type, see below */
114		__uint8_t  d_namlen;		/* length of string in d_name */
115		char d_name[__DARWIN_MAXNAMLEN + 1];	/* name must be no longer than this */
116};
117
118typedef struct webdav_parse_opendir_element_tag
119{
120	struct large_dirent dir_data;
121	struct timespec stattime;
122	struct timespec createtime;
123	u_quad_t statsize;
124	int appledoubleheadervalid;	/* TRUE if appledoubleheader field is valid */
125	int seen_href;	/* TRUE if we've seen the <D:href> entity for this element (otherwise this is a place holder) */
126	int seen_response_end; /* TRUE if we've seen <d:/response> for this element */
127	char appledoubleheader[APPLEDOUBLEHEADER_LENGTH];
128	struct webdav_parse_opendir_element_tag *next;
129} webdav_parse_opendir_element_t;
130
131typedef struct
132{
133	int error;
134	int id;
135	void *data_ptr;
136	Boolean start; /*For characters callback to work only after start tag and no end tag*/
137	webdav_parse_opendir_element_t *head;
138	webdav_parse_opendir_element_t *tail;
139} webdav_parse_opendir_struct_t;
140
141typedef struct
142{
143	CFIndex size;
144	UInt8 name[WEBDAV_MAX_URI_LEN];
145} webdav_parse_opendir_text_t;
146
147typedef struct
148{
149	int id;
150	void *data_ptr;
151} webdav_parse_opendir_return_t;
152
153/* Parsing Multistatus replies for LOCK & DELETE */
154
155#define WEBDAV_MULTISTATUS_INVALID_STATUS 999
156typedef struct
157{
158	CFIndex size;
159	UInt8 name[WEBDAV_MAX_URI_LEN];
160} webdav_parse_multistatus_text_t;
161
162typedef struct
163{
164	int id;
165	void *data_ptr;
166	Boolean start; /*For characters callback to work only after start tag and no end tag*/
167} webdav_parse_multistatus_return_t;
168
169typedef struct webdav_parse_multistatus_element_tag
170{
171	UInt32 statusCode;
172	UInt8  name_len;		/* length of string in name */
173	UInt8 name[WEBDAV_MAX_URI_LEN];
174
175	/* some bookkeeping fields, only used during parsing */
176	int seen_href;	/* TRUE if we've seen the <D:href> entity for this element (otherwise this is a place holder) */
177	int seen_response_end; /* TRUE if we've seen <d:/response> for this element */
178
179	struct webdav_parse_multistatus_element_tag *next;
180} webdav_parse_multistatus_element_t;
181
182typedef struct
183{
184	int error;
185	int id;
186	void *data_ptr;
187	webdav_parse_multistatus_element_t *head;
188	webdav_parse_multistatus_element_t *tail;
189	Boolean start;
190} webdav_parse_multistatus_list_t;
191
192/* Functions */
193extern int parse_stat(const UInt8 *xmlp, CFIndex xmlp_len, struct webdav_stat_attr *statbuf);
194extern int parse_statfs(const UInt8 *xmlp, CFIndex xmlp_len, struct statfs *statfsbuf);
195extern int parse_lock(const UInt8 *xmlp, CFIndex xmlp_len, char **locktoken);
196extern int parse_opendir(
197	UInt8 *xmlp,					/* -> xml data returned by PROPFIND with depth of 1 */
198	CFIndex xmlp_len,				/* -> length of xml data */
199	CFURLRef urlRef,				/* -> the CFURL to the parent directory (may be a relative CFURL) */
200	uid_t uid,						/* -> uid of the user making the request */
201	struct node_entry *parent_node);/* -> pointer to the parent directory's node_entry */
202extern int parse_file_count(const UInt8 *xmlp, CFIndex xmlp_len, int *file_count);
203extern int parse_cachevalidators(const UInt8 *xmlp, CFIndex xmlp_len, time_t *last_modified, char **entity_tag);
204extern webdav_parse_multistatus_list_t *parse_multi_status(	UInt8 *xmlp, CFIndex xmlp_len);
205/* Definitions */
206
207#define WEBDAV_OPENDIR_ELEMENT 1	/* Make it not 0 (for null) but small enough to not be a ptr */
208#define WEBDAV_OPENDIR_ELEMENT_LENGTH 2
209#define WEBDAV_OPENDIR_ELEMENT_MODDATE 3
210#define WEBDAV_OPENDIR_ELEMENT_CREATEDATE 4
211#define WEBDAV_OPENDIR_TEXT 5
212#define WEBDAV_OPENDIR_APPLEDOUBLEHEADER 6
213#define WEBDAV_OPENDIR_ELEMENT_RESPONSE 7
214#define WEBDAV_OPENDIR_IGNORE 8		/* Same Rules Apply */
215
216#define WEBDAV_MULTISTATUS_ELEMENT 1
217#define WEBDAV_MULTISTATUS_STATUS 2
218#define WEBDAV_MULTISTATUS_TEXT 3
219#define WEBDAV_MULTISTATUS_RESPONSE 4
220#define WEBDAV_MULTISTATUS_IGNORE 8
221
222#define WEBDAV_STAT_IGNORE 1
223#define WEBDAV_STAT_LENGTH 2
224#define WEBDAV_STAT_MODDATE 3
225#define WEBDAV_STAT_CREATEDATE 4
226
227#define WEBDAV_STATFS_IGNORE 1
228#define WEBDAV_STATFS_QUOTA_AVAILABLE_BYTES 2
229#define WEBDAV_STATFS_QUOTA_USED_BYTES 3
230/*
231 * WEBDAV_STATFS_QUOTA and WEBDAV_STATFS_QUOTAUSED correspond to
232 * the deprecated "quota" and "quotaused" properties in the "DAV:" namespace.
233 */
234#define WEBDAV_STATFS_QUOTA 4
235#define WEBDAV_STATFS_QUOTAUSED 5
236
237#define WEBDAV_LOCK_CONTINUE 1
238#define WEBDAV_LOCK_TOKEN 1
239#define WEBDAV_LOCK_HREF 2
240
241#define WEBDAV_CACHEVALIDATORS_IGNORE 1
242#define WEBDAV_CACHEVALIDATORS_MODDATE 2
243#define WEBDAV_CACHEVALIDATORS_ETAG 3
244
245#endif
246