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