Annotation of XML/testDAV.c, revision 1.2
1.1 daniel 1: /*
2: * testDAV.c : a small tester program for WebDAV operations
3: *
4: * See Copyright for the status of this software.
5: *
6: * Daniel.Veillard@w3.org
7: */
8:
9: #ifdef WIN32
10: #define HAVE_FCNTL_H
11: #include <io.h>
12: #else
13: #include "config.h"
14: #endif
15:
16: #include <stdio.h>
17: #include <string.h>
18:
19: #ifdef HAVE_SYS_TYPES_H
20: #include <sys/types.h>
21: #endif
22: #ifdef HAVE_SYS_STAT_H
23: #include <sys/stat.h>
24: #endif
25: #ifdef HAVE_FCNTL_H
26: #include <fcntl.h>
27: #endif
28: #ifdef HAVE_UNISTD_H
29: #include <unistd.h>
30: #endif
31: #ifdef HAVE_STDLIB_H
32: #include <stdlib.h>
33: #endif
34:
1.2 ! daniel 35: #include "xmlmemory.h"
1.1 daniel 36: #include "nanohttp.h"
37: #include "tree.h"
38: #include "parser.h"
39:
40: static int debug = 0;
41:
42: typedef struct nodeinfo {
43: struct nodeinfo *next;
44: char *name;
45: char *size;
46: char *date;
47: char *content;
48: } nodeinfo, *nodeinfoPtr;
49:
50: char current_protocol[20] = "http";
51: char current_hostname[100] = "localhost";
52: char current_path[1024] = "/";
53: char current_file[1024] = "";
54: int current_port = 80;
55:
56: void scanURL(const char *URL) {
57: const char *cur = URL;
58: char buf[4096];
59: int index = 0;
60: int port = 0;
61:
62: buf[index] = 0;
63: while (*cur != 0) {
64: if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
65: buf[index] = 0;
66: strcpy(current_protocol, buf);
67: index = 0;
68: cur += 3;
69: break;
70: }
71: buf[index++] = *cur++;
72: }
73: if (*cur == 0) return;
74:
75: buf[index] = 0;
76: while (1) {
77: if (cur[0] == ':') {
78: buf[index] = 0;
79: strcpy(current_hostname, buf);
80: index = 0;
81: cur += 1;
82: while ((*cur >= '0') && (*cur <= '9')) {
83: port *= 10;
84: port += *cur - '0';
85: cur++;
86: }
87: if (port != 0) current_port = port;
88: while ((cur[0] != '/') && (*cur != 0))
89: cur++;
90: break;
91: }
92: if ((*cur == '/') || (*cur == 0)) {
93: buf[index] = 0;
94: strcpy(current_hostname, buf);
95: index = 0;
96: break;
97: }
98: buf[index++] = *cur++;
99: }
100: if (*cur == 0) {
101: strcpy(current_path, "/");
102: strcpy(current_file, "");
103: }else {
104: buf[index] = 0;
105: while (*cur != 0) {
106: if ((cur[0] == '#') || (cur[0] == '?'))
107: break;
108: buf[index++] = *cur++;
109: }
110: buf[index] = 0;
111: while ((index > 0) && (buf[index] != '/')) index--;
112: strcpy(current_file, &buf[index + 1]);
113: buf[index + 1] = 0;
114: strcpy(current_path, buf);
115: }
116: }
117:
118: nodeinfoPtr nodeinfoNew() {
1.2 ! daniel 119: nodeinfoPtr ret = xmlMalloc(sizeof(nodeinfo));
1.1 daniel 120: if (ret == NULL) return(NULL);
121: memset(ret, 0, sizeof(nodeinfo));
122: return(ret);
123: }
124: void nodeinfoFree(nodeinfoPtr info) {
125: if (info == NULL) return;
1.2 ! daniel 126: if (info->name) xmlFree(info->name);
! 127: if (info->date) xmlFree(info->date);
! 128: if (info->size) xmlFree(info->date);
! 129: if (info->content) xmlFree(info->content);
1.1 daniel 130: }
131: void nodeinfoListFree(nodeinfoPtr info) {
132: nodeinfoPtr cur = info;
133:
134: while (cur != NULL) {
135: info = info->next;
136: nodeinfoFree(cur);
137: cur = info;
138: }
139: }
140: void nodeinfoPrint(nodeinfoPtr info) {
141: if (info == NULL) return;
142: if (info->date) printf("%s\t", info->date);
143: if (info->name) printf("%s\t", info->name);
144: else printf("???\t");
145: if (info->size) printf("%s\t", info->size);
146: if (info->content) printf("%s\t", info->content);
147: printf("\n");
148: }
149: void nodeinfoListPrint(nodeinfoPtr info) {
150: nodeinfoPtr cur = info;
151:
152: while (cur != NULL) {
153: info = info->next;
154: nodeinfoPrint(cur);
155: cur = info;
156: }
157: }
158: int propfindQuery(const char *URL, char **result) {
159: void *ctxt;
160: char *contentType = "text/xml; charset=\"utf-8\"";
161: char *output;
162: int len;
163: int size = 40000;
164: int returnCode;
165: char *verboseQuery =
166: "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
167: <D:propfind xmlns:D=\"DAV:\">\
168: <D:allprop/>\
169: </D:propfind>";
170:
171:
172: if ((URL == NULL) || (result == NULL)) return(-1);
173:
174: if (URL[strlen(URL) - 1] == '/')
175: ctxt = xmlNanoHTTPMethod(URL, "PROPFIND", NULL,
176: &contentType, "Depth: 1\r\n");
177: else
178: ctxt = xmlNanoHTTPMethod(URL, "PROPFIND", verboseQuery,
179: &contentType, "Depth: 0\r\n");
180: if (ctxt == NULL) {
181: fprintf(stderr, "PROPFIND %s failed\n", URL);
182: return(-1);
183: }
1.2 ! daniel 184:
1.1 daniel 185: returnCode = xmlNanoHTTPReturnCode(ctxt);
186: if ((returnCode >= 300) ||
187: ((contentType != NULL) && (strncmp(contentType, "text/xml", 8)))) {
188: xmlNanoHTTPClose(ctxt);
1.2 ! daniel 189: if (contentType != NULL) xmlFree(contentType);
1.1 daniel 190: return(-1);
191: }
1.2 ! daniel 192: if (contentType != NULL) xmlFree(contentType);
1.1 daniel 193:
1.2 ! daniel 194: output = (char *) xmlMalloc(size + 1);
1.1 daniel 195: if (output == NULL) {
196: fprintf(stderr, "out of memory\n");
197: xmlNanoHTTPClose(ctxt);
198: return(-1);
199: }
200: len = xmlNanoHTTPRead(ctxt, output, size);
201: if (len < 0) {
202: fprintf(stderr, "cannot read PROPFIND %s result\n", URL);
203: xmlNanoHTTPClose(ctxt);
1.2 ! daniel 204: xmlFree(output);
1.1 daniel 205: return(-1);
206: }
207: /* !!!!!!!!! handle returns size > size !!!!!!!!!! */
208: output[len] = 0;
209: xmlNanoHTTPClose(ctxt);
210:
211: *result = output;
212: return(returnCode);
213: }
214:
215: void parsePropfindProp(xmlNodePtr cur, nodeinfoPtr node) {
216: cur = cur->childs;
217:
218: /*
219: * prop ANY
220: */
221: while (cur != NULL) {
222: if (!strcmp((char *) cur->name, "getlastmodified")) {
223: node->date = (char *) xmlNodeGetContent(cur);
224: } else if (!strcmp((char *) cur->name, "getcontenttype")) {
225: node->content = (char *) xmlNodeGetContent(cur);
226: } else if (!strcmp((char *) cur->name, "getcontentlength")) {
227: node->size = (char *) xmlNodeGetContent(cur);
228: }
229: cur = cur->next;
230: }
231: }
232:
233: void parsePropfindPropstat(xmlNodePtr cur, nodeinfoPtr node) {
234: cur = cur->childs;
235:
236: /*
237: * propstat (prop, status, responsedescription?)
238: */
239: while (cur != NULL) {
240: if (!strcmp((char *) cur->name, "prop")) {
241: parsePropfindProp(cur, node);
242: } else if (!strcmp((char *) cur->name, "status")) {
243: } else if (!strcmp((char *) cur->name, "responsedescription")) {
244: }
245: cur = cur->next;
246: }
247: }
248:
249: nodeinfoPtr parsePropfindHref(xmlNodePtr cur) {
250: nodeinfoPtr ret;
251:
252: ret = nodeinfoNew();
253: ret->name = (char *) xmlNodeGetContent(cur);
254: return(ret);
255: }
256:
257: nodeinfoPtr parsePropfindResponse(xmlNodePtr cur) {
258: nodeinfoPtr ret, last, res = NULL;
259:
260: ret = last = NULL;
261: cur = cur->childs;
262:
263: /*
264: * response (href, ((href*, status)|(propstat+)), responsedescription?
265: */
266: while (cur != NULL) {
267: if (!strcmp((char *) cur->name, "href")) {
268: res = parsePropfindHref(cur);
269: if (res != NULL) {
270: if (ret == NULL) ret = last = res;
271: else last->next = res;
272: while (last->next != NULL) last = last->next;
273: }
274: } else if (!strcmp((char *) cur->name, "propstat")) {
275: parsePropfindPropstat(cur, res);
276: } else if (!strcmp((char *) cur->name, "status")) {
277: } else if (!strcmp((char *) cur->name, "responsedescription")) {
278: }
279: cur = cur->next;
280: }
281: return(ret);
282: }
283:
284: nodeinfoPtr parsePropfindAnswer(xmlNodePtr cur) {
285: nodeinfoPtr ret = NULL, last, res;
286:
287: if (!strcmp((char *) cur->name, "multistatus")) {
288: ret = last = NULL;
289: cur = cur->childs;
290: while (cur != NULL) {
291: if (!strcmp((char *) cur->name, "response")) {
292: res = parsePropfindResponse(cur);
293: if (res != NULL) {
294: if (ret == NULL) ret = last = res;
295: else last->next = res;
296: while (last->next != NULL) last = last->next;
297: }
298: }
299: cur = cur->next;
300: }
301: }
302: return(ret);
303: }
304:
305: nodeinfoPtr propfind(char *file) {
306: nodeinfoPtr ret;
307: xmlDocPtr doc;
308: char URL[1024];
309: char *xmlResult = NULL;
310: int result;
311:
312: if ((file != NULL) && (!strncmp(file, "http://", 7))) {
313: scanURL(file);
314: } else if (file != NULL) {
315: strcpy(current_path, file);
316: }
317: if (current_file[0] == 0)
1.2 ! daniel 318: #ifdef HAVE_SNPRINTF
1.1 daniel 319: snprintf(URL, sizeof(URL), "%s://%s:%d%s", current_protocol,
320: current_hostname, current_port, current_path);
1.2 ! daniel 321: #else
! 322: sprintf(URL, "%s://%s:%d%s", current_protocol,
! 323: current_hostname, current_port, current_path);
! 324: #endif
1.1 daniel 325: else
1.2 ! daniel 326: #ifdef HAVE_SNPRINTF
1.1 daniel 327: snprintf(URL, sizeof(URL), "%s://%s:%d%s%s", current_protocol,
328: current_hostname, current_port, current_path, current_file);
1.2 ! daniel 329: #else
! 330: sprintf(URL, "%s://%s:%d%s%s", current_protocol,
! 331: current_hostname, current_port, current_path, current_file);
! 332: #endif
1.1 daniel 333:
334: result = propfindQuery(URL, &xmlResult);
335: if (result == -1) return(NULL);
336: if (xmlResult == NULL) return(NULL);
337:
338: doc = xmlParseMemory(xmlResult, strlen(xmlResult));
339: if (doc == NULL) {
340: fprintf(stdout, "%s\n", xmlResult);
1.2 ! daniel 341: xmlFree(xmlResult);
1.1 daniel 342: return(NULL);
343: }
344:
345: if (debug)
346: fprintf(stdout, "%s\n", xmlResult);
347:
348: ret = parsePropfindAnswer(doc->root);
349: xmlFreeDoc(doc);
1.2 ! daniel 350: xmlFree(xmlResult);
1.1 daniel 351: return(ret);
352: }
353:
354: int cd(char *newpath) {
355: nodeinfoPtr ret;
356:
357: if (newpath == NULL) {
358: strcpy(current_path, "/");
359: strcpy(current_file, "");
360: } /* else if */
361: }
362:
363: int ls(char *newpath) {
364: }
365:
366: int main(int argc, char** argv) {
367: nodeinfoPtr ret;
368: char line[1024], *cur;
369: int i;
370:
371: for (i = 1; i < argc ; i++) {
372: if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
373: debug++;
374: }
375: for (i = 1; i < argc ; i++) {
376: if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
377: continue;
378: ret = propfind(argv[i]);
379: nodeinfoListPrint(ret);
380: }
381: /**************
382: int ret;
383: while (1) {
384: ret = fscanf("%s", line);
385: if (!strncmp(line, "cd", 2)) {
386: cur = &line[2];
387: while ((*cur == ' ') || (*cur == "\t")) cur++;
388: if ((*cur != 0) && (*cur != '\n') && (*cur != '\r')) {
389: cd(cur);
390: } else {
391: cd(NULL);
392: }
393: } else if (!strncmp(line, "ls", 2)) {
394: cur = &line[2];
395: while ((*cur == ' ') || (*cur == "\t")) cur++;
396: if ((*cur != 0) && (*cur != '\n') && (*cur != '\r')) {
397: ls(cur);
398: } else {
399: ls(NULL);
400: }
401: }
402: }
403: **********/
1.2 ! daniel 404: xmlMemoryDump();
1.1 daniel 405: return(0);
406: }
Webmaster