libidav/utils.c

changeset 611
a7c48e0dca88
parent 609
dc3d70848c7c
child 624
27985062cd2c
equal deleted inserted replaced
610:aa3baf1dd81b 611:a7c48e0dca88
39 #include <curl/curl.h> 39 #include <curl/curl.h>
40 40
41 #ifdef _WIN32 41 #ifdef _WIN32
42 #include <conio.h> 42 #include <conio.h>
43 #define getpasswordchar() getch() 43 #define getpasswordchar() getch()
44 #define IS_PATH_SEPARATOR(c) (c == '/' || c == '\\')
45 #define PATH_SEPARATOR '\\'
44 #else 46 #else
45 #include <termios.h> 47 #include <termios.h>
46 #define getpasswordchar() getchar() 48 #define getpasswordchar() getchar()
49 #define IS_PATH_SEPARATOR(c) (c == '/')
50 #define PATH_SEPARATOR '/'
47 #endif 51 #endif
48 52
49 #include "webdav.h" 53 #include "webdav.h"
50 #include "utils.h" 54 #include "utils.h"
51 #include "crypto.h" 55 #include "crypto.h"
375 379
376 int util_path_isrelated(const char *path1, const char *path2) { 380 int util_path_isrelated(const char *path1, const char *path2) {
377 scstr_t p1 = scstr(path1); 381 scstr_t p1 = scstr(path1);
378 scstr_t p2 = scstr(path2); 382 scstr_t p2 = scstr(path2);
379 383
380 if(p1.ptr[p1.length-1] == '/') { 384 if(IS_PATH_SEPARATOR(p1.ptr[p1.length-1])) {
381 p1.length--; 385 p1.length--;
382 } 386 }
383 if(p2.ptr[p2.length-1] == '/') { 387 if(IS_PATH_SEPARATOR(p2.ptr[p2.length-1])) {
384 p2.length--; 388 p2.length--;
385 } 389 }
386 390
387 if(p2.length < p1.length) { 391 if(p2.length < p1.length) {
388 return 0; 392 return 0;
391 if(!sstrcmp(p1, p2)) { 395 if(!sstrcmp(p1, p2)) {
392 return 1; 396 return 1;
393 } 397 }
394 398
395 if(sstrprefix(p2, p1)) { 399 if(sstrprefix(p2, p1)) {
396 if(p2.ptr[p1.length] == '/') { 400 if(IS_PATH_SEPARATOR(p2.ptr[p1.length])) {
397 return 1; 401 return 1;
398 } 402 }
399 } 403 }
400 404
401 return 0; 405 return 0;
402 } 406 }
407
408 #ifdef _WIN32
409 int util_path_isabsolut(const char *path) {
410 if(strlen(path) < 3) {
411 return 0;
412 }
413
414 // check if first char is A-Z or a-z
415 char c = path[0];
416 if(!((c >= 65 && c <= 90) || (c >= 97 && c <= 122))) {
417 return 0;
418 }
419
420 if(path[1] == ':' && path[2] == '\\') {
421 return 1;
422 }
423 return 0;
424 }
425 #else
426 int util_path_isabsolut(const char *path) {
427 return path[0] == '/';
428 }
429 #endif
403 430
404 char* util_path_normalize(const char *path) { 431 char* util_path_normalize(const char *path) {
405 size_t len = strlen(path); 432 size_t len = strlen(path);
406 UcxBuffer *buf = ucx_buffer_new(NULL, len+1, UCX_BUFFER_AUTOEXTEND); 433 UcxBuffer *buf = ucx_buffer_new(NULL, len+1, UCX_BUFFER_AUTOEXTEND);
407 434
411 438
412 int add_separator = 0; 439 int add_separator = 0;
413 int seg_start = 0; 440 int seg_start = 0;
414 for(int i=0;i<=len;i++) { 441 for(int i=0;i<=len;i++) {
415 char c = path[i]; 442 char c = path[i];
416 if(c == '/' || c == '\0') { 443 if(IS_PATH_SEPARATOR(c) || c == '\0') {
417 const char *seg_ptr = path+seg_start; 444 const char *seg_ptr = path+seg_start;
418 int seg_len = i - seg_start; 445 int seg_len = i - seg_start;
419 if(seg_ptr[0] == '/') { 446 if(IS_PATH_SEPARATOR(seg_ptr[0])) {
420 seg_ptr++; 447 seg_ptr++;
421 seg_len--; 448 seg_len--;
422 } 449 }
423 450
424 if(seg_len > 0) { 451 if(seg_len > 0) {
425 scstr_t seg = scstrn(seg_ptr, seg_len); 452 scstr_t seg = scstrn(seg_ptr, seg_len);
426 if(!sstrcmp(seg, SC(".."))) { 453 if(!sstrcmp(seg, SC(".."))) {
427 for(int j=buf->pos;j>=0;j--) { 454 for(int j=buf->pos;j>=0;j--) {
428 char t = buf->space[j]; 455 char t = buf->space[j];
429 if(t == '/' || j == 0) { 456 if(IS_PATH_SEPARATOR(t) || j == 0) {
430 buf->pos = j; 457 buf->pos = j;
431 buf->size = j; 458 buf->size = j;
432 buf->space[j] = 0; 459 buf->space[j] = 0;
433 add_separator = t == '/' ? 1 : 0; 460 add_separator = IS_PATH_SEPARATOR(t) ? 1 : 0;
434 break; 461 break;
435 } 462 }
436 } 463 }
437 } else if(!sstrcmp(seg, SC("."))) { 464 } else if(!sstrcmp(seg, SC("."))) {
438 // ignore 465 // ignore
439 } else { 466 } else {
440 if(add_separator) { 467 if(add_separator) {
441 ucx_buffer_putc(buf, '/'); 468 ucx_buffer_putc(buf, PATH_SEPARATOR);
442 } 469 }
443 ucx_buffer_write(seg_ptr, 1, seg_len, buf); 470 ucx_buffer_write(seg_ptr, 1, seg_len, buf);
444 add_separator = 1; 471 add_separator = 1;
445 } 472 }
446 } 473 }
456 buf->flags = 0; // disable autofree 483 buf->flags = 0; // disable autofree
457 ucx_buffer_free(buf); 484 ucx_buffer_free(buf);
458 return space; 485 return space;
459 } 486 }
460 487
461 char* util_create_relative_path(const char *abspath, const char *base) { 488 static char* create_relative_path(const char *abspath, const char *base) {
462 size_t path_len = strlen(abspath); 489 size_t path_len = strlen(abspath);
463 size_t base_len = strlen(base); 490 size_t base_len = strlen(base);
464 491
465 if(abspath[path_len-1] == '/') { 492 if(IS_PATH_SEPARATOR(abspath[path_len-1])) {
466 path_len--; 493 path_len--;
467 } 494 }
468 if(base[base_len-1] == '/') { 495 if(IS_PATH_SEPARATOR(base[base_len-1])) {
469 base_len--; 496 base_len--;
470 } 497 }
471 // get base parent 498 // get base parent
472 for(int i=base_len-1;i>=0;i--) { 499 for(int i=base_len-1;i>=0;i--) {
473 if(base[i] == '/') { 500 if(IS_PATH_SEPARATOR(base[i])) {
474 base_len = i+1; 501 base_len = i+1;
475 break; 502 break;
476 } 503 }
477 } 504 }
478 505
484 size_t last_dir = 0; 511 size_t last_dir = 0;
485 for(i=0;i<max;i++) { 512 for(i=0;i<max;i++) {
486 char c = abspath[i]; 513 char c = abspath[i];
487 if(c != base[i]) { 514 if(c != base[i]) {
488 break; 515 break;
489 } else if(c == '/') { 516 } else if(IS_PATH_SEPARATOR(c)) {
490 last_dir = i; 517 last_dir = i;
491 } 518 }
492 } 519 }
493 520
494 char *ret = NULL; 521 char *ret = NULL;
495 UcxBuffer *out = NULL; 522 UcxBuffer *out = NULL;
496 if(last_dir+1 < base_len) { 523 if(last_dir+1 < base_len) {
497 // base is deeper than the link root, we have to go backwards 524 // base is deeper than the link root, we have to go backwards
498 int dircount = 0; 525 int dircount = 0;
499 for(int i=last_dir+1;i<base_len;i++) { 526 for(int i=last_dir+1;i<base_len;i++) {
500 if(base[i] == '/') { 527 if(IS_PATH_SEPARATOR(base[i])) {
501 dircount++; 528 dircount++;
502 } 529 }
503 } 530 }
504 531
505 out = ucx_buffer_new(NULL, dircount*3+path_len-last_dir, UCX_BUFFER_AUTOEXTEND); 532 out = ucx_buffer_new(NULL, dircount*3+path_len-last_dir, UCX_BUFFER_AUTOEXTEND);
517 ret = out->space; 544 ret = out->space;
518 ucx_buffer_free(out); 545 ucx_buffer_free(out);
519 546
520 return ret; 547 return ret;
521 } 548 }
549
550 #ifdef _WIN32
551 char* util_create_relative_path(const char *abspath, const char *base) {
552 char *abspath_converted = strdup(abspath);
553 char *base_converted = strdup(base);
554 size_t abs_len = strlen(abspath_converted);
555 size_t base_len = strlen(base_converted);
556
557 for(int i=0;i<abs_len;i++) {
558 if(abspath_converted[i] == '\\') {
559 abspath_converted[i] = '/';
560 }
561 }
562 for(int i=0;i<base_len;i++) {
563 if(base_converted[i] == '\\') {
564 base_converted[i] = '/';
565 }
566 }
567
568 char *ret = create_relative_path(abspath_converted, base_converted);
569 free(abspath_converted);
570 free(base_converted);
571 return ret;
572 }
573 #else
574 char* util_create_relative_path(const char *abspath, const char *base) {
575 return create_relative_path(abspath, base);
576 }
577 #endif
522 578
523 579
524 void util_capture_header(CURL *handle, UcxMap* map) { 580 void util_capture_header(CURL *handle, UcxMap* map) {
525 if(map) { 581 if(map) {
526 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); 582 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback);

mercurial