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