1 /*
2    WebDAV Properties manipulation
3    Copyright (C) 1999-2004, Joe Orton <joe@manyfish.co.uk>
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14 
15    You should have received a copy of the GNU Library General Public
16    License along with this library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18    MA 02111-1307, USA
19 
20 */
21 
22 #ifndef NE_PROPS_H
23 #define NE_PROPS_H
24 
25 #include "ne_request.h"
26 #include "ne_207.h"
27 
28 BEGIN_NEON_DECLS
29 
30 /* There are two interfaces for fetching properties. The first is
31  * 'ne_simple_propfind', which is relatively simple, and easy to use,
32  * but only lets you fetch FLAT properties, i.e. properties which are
33  * just a string of bytes.  The complex interface is 'ne_propfind_*',
34  * which is complicated, and hard to use, but lets you parse
35  * structured properties, i.e.  properties which have XML content.  */
36 
37 /* The 'ne_simple_propfind' interface. ***
38  *
39  * ne_simple_propfind allows you to fetch a set of properties for a
40  * single resource, or a tree of resources.  You set the operation
41  * going by passing these arguments:
42  *
43  *  - the session which should be used.
44  *  - the URI and the depth of the operation (0, 1, infinite)
45  *  - the names of the properties which you want to fetch
46  *  - a results callback, and the userdata for the callback.
47  *
48  * For each resource found, the results callback is called, passing
49  * you two things along with the userdata you passed in originally:
50  *
51  *   - the URI of the resource (const char *href)
52  *   - the properties results set (const ne_prop_result_set *results)
53  * */
54 
55 /* The name of a WebDAV property. 'nspace' may be NULL. */
56 typedef struct {
57     const char *nspace, *name;
58 } ne_propname;
59 
60 typedef struct ne_prop_result_set_s ne_prop_result_set;
61 
62 /* Get the value of a given property. Will return NULL if there was an
63  * error fetching this property on this resource.  Call
64  * ne_propset_result to get the response-status if so.  */
65 const char *ne_propset_value(const ne_prop_result_set *set,
66 			      const ne_propname *propname);
67 
68 /* Returns the status structure for fetching the given property on
69  * this resource. This function will return NULL if the server did not
70  * return the property (which is a server error). */
71 const ne_status *ne_propset_status(const ne_prop_result_set *set,
72 				      const ne_propname *propname);
73 
74 /* Returns the private pointer for the given propset. */
75 void *ne_propset_private(const ne_prop_result_set *set);
76 
77 /* Return language string of property (may be NULL). */
78 const char *ne_propset_lang(const ne_prop_result_set *set,
79 			     const ne_propname *pname);
80 
81 /* ne_propset_iterate iterates over a properties result set,
82  * calling the callback for each property in the set. userdata is
83  * passed as the first argument to the callback. value may be NULL,
84  * indicating an error occurred fetching this property: look at
85  * status for the error in that case.
86  *
87  * If the iterator returns non-zero, ne_propset_iterate will return
88  * immediately with that value.
89  */
90 typedef int (*ne_propset_iterator)(void *userdata,
91 				    const ne_propname *pname,
92 				    const char *value,
93 				    const ne_status *status);
94 
95 /* Iterate over all the properties in 'set', calling 'iterator'
96  * for each, passing 'userdata' as the first argument to callback.
97  *
98  * Returns:
99  *   whatever value iterator returns.
100  */
101 int ne_propset_iterate(const ne_prop_result_set *set,
102 			ne_propset_iterator iterator, void *userdata);
103 
104 /* Callback for handling the results of fetching properties for a
105  * single resource (named by 'href').  The results are stored in the
106  * result set 'results': use ne_propset_* to examine this object.  */
107 typedef void (*ne_props_result)(void *userdata, const char *href,
108 				 const ne_prop_result_set *results);
109 
110 /* Fetch properties for a resource (if depth == NE_DEPTH_ZERO),
111  * or a tree of resources (if depth == NE_DEPTH_ONE or _INFINITE).
112  *
113  * Names of the properties required must be given in 'props',
114  * or if props is NULL, *all* properties are fetched.
115  *
116  * 'results' is called for each resource in the response, userdata is
117  * passed as the first argument to the callback. It is important to
118  * note that the callback is called as the response is read off the
119  * socket, so don't do anything silly in it (e.g. sleep(100), or call
120  * any functions which use this session).
121  *
122  * Note that if 'depth' is NE_DEPTH_INFINITY, some servers may refuse
123  * the request.
124  *
125  * Returns NE_*.  */
126 int ne_simple_propfind(ne_session *sess, const char *path, int depth,
127 			const ne_propname *props,
128 			ne_props_result results, void *userdata);
129 
130 /* The properties of a resource can be manipulated using ne_proppatch.
131  * A single proppatch request may include any number of individual
132  * "set" and "remove" operations, and is defined to have
133  * "all-or-nothing" semantics, so either all the operations succeed,
134  * or none do. */
135 
136 /* A proppatch operation may either set a property to have a new
137  * value, in which case 'type' must be ne_propset, and 'value' must be
138  * non-NULL; or it can remove a property; in which case 'type' must be
139  * ne_propremove, and 'value' is ignored.  In both cases, 'name' must
140  * be set to the name of the property to alter. */
141 enum ne_proppatch_optype {
142     ne_propset,
143     ne_propremove
144 };
145 typedef struct {
146     const ne_propname *name;
147     enum ne_proppatch_optype type;
148     const char *value;
149 } ne_proppatch_operation;
150 
151 /* Execute a set of property operations 'ops' on 'path'. 'ops' is an
152  * array terminated by an operation with a NULL 'name' field. Returns
153  * NE_*. */
154 int ne_proppatch(ne_session *sess, const char *path,
155 		 const ne_proppatch_operation *ops);
156 
157 /* Retrieve property names for the resources at 'path'.  'results'
158  * callback is called for each resource.  Use 'ne_propset_iterate' on
159  * the passed results object to retrieve the list of property names.
160  * */
161 int ne_propnames(ne_session *sess, const char *path, int depth,
162 		 ne_props_result results, void *userdata);
163 
164 /* The complex, you-do-all-the-work, property fetch interface:
165  */
166 
167 struct ne_propfind_handler_s;
168 typedef struct ne_propfind_handler_s ne_propfind_handler;
169 
170 /* Retrieve the 'private' pointer for the current propset for the
171  * given handler, as returned by the ne_props_create_complex callback
172  * installed using 'ne_propfind_set_private'.  If this callback was
173  * not registered, this function will return NULL.  */
174 void *ne_propfind_current_private(ne_propfind_handler *handler);
175 
176 /* Create a PROPFIND handler, for the given resource or set of
177  * resources.
178  *
179  * Depth must be one of NE_DEPTH_*. */
180 ne_propfind_handler *
181 ne_propfind_create(ne_session *sess, const char *path, int depth);
182 
183 /* Return the XML parser for the given handler (only need if you want
184  * to handle complex properties). */
185 ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler);
186 
187 /* This interface reserves the state integer range 'x' where 0 < x
188  * and x < NE_PROPS_STATE_TOP. */
189 #define NE_PROPS_STATE_TOP (NE_207_STATE_TOP + 100)
190 
191 /* Return the request object for the given handler.  You MUST NOT use
192  * ne_set_request_body_* on this request object.  (this call is only
193  * needed if for instance, you want to add extra headers to the
194  * PROPFIND request).  The result of using the request pointer after
195  * ne_propfind_destroy(handler) has been called is undefined. */
196 ne_request *ne_propfind_get_request(ne_propfind_handler *handler);
197 
198 /* A "complex property" has a value which is structured XML. To handle
199  * complex properties, you must set up and register an XML handler
200  * which will understand the elements which make up such properties.
201  * The handler must be registered with the parser returned by
202  * 'ne_propfind_get_parser'.
203  *
204  * To store the parsed value of the property, a 'private' structure is
205  * allocated in each propset (i.e. one per resource). When parsing the
206  * property value elements, for each new resource encountered in the
207  * response, the 'creator' callback is called to retrieve a 'private'
208  * structure for this resource.
209  *
210  * Whilst in XML element callbacks you will have registered to handle
211  * complex properties, you can use the 'ne_propfind_current_private'
212  * call to retrieve the pointer to this private structure.
213  *
214  * To retrieve this 'private' structure from the propset in the
215  * results callback, simply call 'ne_propset_private'.
216  * */
217 typedef void *(*ne_props_create_complex)(void *userdata,
218 					 const char *href);
219 
220 void ne_propfind_set_private(ne_propfind_handler *handler,
221 			     ne_props_create_complex creator,
222 			     void *userdata);
223 
224 /* Fetch all properties.
225  *
226  * Returns NE_*. */
227 int ne_propfind_allprop(ne_propfind_handler *handler,
228 			ne_props_result result, void *userdata);
229 
230 /* Fetch all properties with names listed in array 'names', which is
231  * terminated by a property with a NULL name field.  For each resource
232  * encountered, the result callback will be invoked, passing in
233  * 'userdata' as the first argument.
234  *
235  * Returns NE_*. */
236 int ne_propfind_named(ne_propfind_handler *handler,
237 		      const ne_propname *names,
238 		      ne_props_result result, void *userdata);
239 
240 /* Destroy a propfind handler after use. */
241 void ne_propfind_destroy(ne_propfind_handler *handler);
242 
243 END_NEON_DECLS
244 
245 #endif /* NE_PROPS_H */
246