libidav/utils.c

changeset 576
62cc92445234
parent 575
f746f601c35c
child 578
bb1e60fada74
equal deleted inserted replaced
575:f746f601c35c 576:62cc92445234
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);

mercurial