1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2018 Olaf Wintermann. All rights reserved. |
4 * Copyright 2019 Olaf Wintermann. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
453 buf->flags = 0; // disable autofree |
453 buf->flags = 0; // disable autofree |
454 ucx_buffer_free(buf); |
454 ucx_buffer_free(buf); |
455 return space; |
455 return space; |
456 } |
456 } |
457 |
457 |
|
458 char* util_create_relative_path(const char *abspath, const char *base) { |
|
459 size_t path_len = strlen(abspath); |
|
460 size_t base_len = strlen(base); |
|
461 |
|
462 if(abspath[path_len-1] == '/') { |
|
463 path_len--; |
|
464 } |
|
465 if(base[base_len-1] == '/') { |
|
466 base_len--; |
|
467 } |
|
468 // get base parent |
|
469 for(int i=base_len-1;i>=0;i--) { |
|
470 if(base[i] == '/') { |
|
471 base_len = i+1; |
|
472 break; |
|
473 } |
|
474 } |
|
475 |
|
476 size_t max = path_len > base_len ? base_len : path_len; |
|
477 |
|
478 // get prefix of abspath and base |
|
479 // this dir is the root of the link |
|
480 size_t i; |
|
481 size_t last_dir = 0; |
|
482 for(i=0;i<max;i++) { |
|
483 char c = abspath[i]; |
|
484 if(c != base[i]) { |
|
485 break; |
|
486 } else if(c == '/') { |
|
487 last_dir = i; |
|
488 } |
|
489 } |
|
490 |
|
491 char *ret = NULL; |
|
492 UcxBuffer *out = NULL; |
|
493 if(last_dir+1 < base_len) { |
|
494 // base is deeper than the link root, we have to go backwards |
|
495 int dircount = 0; |
|
496 for(int i=last_dir+1;i<base_len;i++) { |
|
497 if(base[i] == '/') { |
|
498 dircount++; |
|
499 } |
|
500 } |
|
501 |
|
502 out = ucx_buffer_new(NULL, dircount*3+path_len-last_dir, UCX_BUFFER_AUTOEXTEND); |
|
503 |
|
504 for(int i=0;i<dircount;i++) { |
|
505 ucx_buffer_puts(out, "../"); |
|
506 } |
|
507 } else { |
|
508 out = ucx_buffer_new(NULL, 1024, path_len - last_dir); |
|
509 } |
|
510 |
|
511 ucx_buffer_puts(out, abspath + last_dir + 1); |
|
512 ucx_buffer_putc(out, 0); |
|
513 out->flags = 0; |
|
514 ret = out->space; |
|
515 ucx_buffer_free(out); |
|
516 |
|
517 return ret; |
|
518 } |
|
519 |
458 |
520 |
459 void util_capture_header(CURL *handle, UcxMap* map) { |
521 void util_capture_header(CURL *handle, UcxMap* map) { |
460 if(map) { |
522 if(map) { |
461 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); |
523 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); |
462 curl_easy_setopt(handle, CURLOPT_HEADERDATA, map); |
524 curl_easy_setopt(handle, CURLOPT_HEADERDATA, map); |