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); |