91 memset(&tparts, 0, sizeof(struct tm)); |
92 memset(&tparts, 0, sizeof(struct tm)); |
92 long val; |
93 long val; |
93 char conv[16]; |
94 char conv[16]; |
94 |
95 |
95 // work on the trimmed string |
96 // work on the trimmed string |
96 sstr_t date = sstrtrim(sstr(iso8601str)); |
97 cxstring date = cx_strtrim(cx_str(iso8601str)); |
97 |
98 |
98 sstr_t time = sstrchr(date, 'T'); |
99 cxstring time = cx_strchr(date, 'T'); |
99 if(time.length == 0) { |
100 if(time.length == 0) { |
100 return 0; |
101 return 0; |
101 } |
102 } |
102 date.length = time.ptr - date.ptr; |
103 date.length = time.ptr - date.ptr; |
103 time.ptr++; time.length--; |
104 time.ptr++; time.length--; |
104 |
105 |
105 sstr_t tzinfo; |
106 cxstring tzinfo; |
106 if((tzinfo = sstrchr(time, 'Z')).length > 0 || |
107 if((tzinfo = cx_strchr(time, 'Z')).length > 0 || |
107 (tzinfo = sstrchr(time, '+')).length > 0 || |
108 (tzinfo = cx_strchr(time, '+')).length > 0 || |
108 (tzinfo = sstrchr(time, '-')).length > 0) { |
109 (tzinfo = cx_strchr(time, '-')).length > 0) { |
109 |
110 |
110 time.length = tzinfo.ptr - time.ptr; |
111 time.length = tzinfo.ptr - time.ptr; |
111 } |
112 } |
112 |
113 |
113 // parse date |
114 // parse date |
122 tparts.tm_mday = val % 100; |
123 tparts.tm_mday = val % 100; |
123 tparts.tm_mon = (val % 10000) / 100 - 1; |
124 tparts.tm_mon = (val % 10000) / 100 - 1; |
124 tparts.tm_year = val / 10000 - 1900; |
125 tparts.tm_year = val / 10000 - 1900; |
125 |
126 |
126 // parse time and skip possible fractional seconds |
127 // parse time and skip possible fractional seconds |
127 sstr_t frac; |
128 cxstring frac; |
128 if((frac = sstrchr(time, '.')).length > 0 || |
129 if((frac = cx_strchr(time, '.')).length > 0 || |
129 (frac = sstrchr(time, ',')).length > 0) { |
130 (frac = cx_strchr(time, ',')).length > 0) { |
130 time.length = frac.ptr - time.ptr; |
131 time.length = frac.ptr - time.ptr; |
131 } |
132 } |
132 if((time.length != 6 && time.length != 8) |
133 if((time.length != 6 && time.length != 8) |
133 || extractval(time, conv , ':') != 6) { |
134 || extractval(time, conv , ':') != 6) { |
134 return 0; |
135 return 0; |
333 path = url + len; // empty string |
334 path = url + len; // empty string |
334 } |
335 } |
335 return path; |
336 return path; |
336 } |
337 } |
337 |
338 |
338 char* util_url_decode(DavSession *sn, char *url) { |
339 char* util_url_decode(DavSession *sn, const char *url) { |
339 char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL); |
340 char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL); |
340 char *ret = strdup(unesc); |
341 char *ret = strdup(unesc); |
341 curl_free(unesc); |
342 curl_free(unesc); |
342 return ret; |
343 return ret; |
343 } |
344 } |
344 |
345 |
345 static size_t util_header_callback(char *buffer, size_t size, |
346 static size_t util_header_callback(char *buffer, size_t size, |
346 size_t nitems, void *data) { |
347 size_t nitems, void *data) { |
347 |
348 |
348 sstr_t sbuffer = sstrn(buffer, size*nitems); |
349 cxstring sbuffer = cx_strn(buffer, size*nitems); |
349 |
350 |
350 UcxMap *map = (UcxMap*) data; |
351 CxMap *map = (CxMap*) data; |
351 |
352 |
352 // if we get a status line, clear the map and exit |
353 // if we get a status line, clear the map and exit |
353 if(sstrprefix(sbuffer, S("HTTP/"))) { |
354 if(cx_strprefix(sbuffer, cx_str("HTTP/"))) { |
354 ucx_map_free_content(map, free); |
355 // TODO: use new map destructor ucx_map_free_content(map, free); |
355 ucx_map_clear(map); |
356 cxMapClear(map); |
356 return size*nitems; |
357 return size*nitems; |
357 } |
358 } |
358 |
359 |
359 // if we get the terminating CRLF, just exit |
360 // if we get the terminating CRLF, just exit |
360 if(!sstrcmp(sbuffer, S("\r\n"))) { |
361 if(!cx_strcmp(sbuffer, cx_str("\r\n"))) { |
361 return 2; |
362 return 2; |
362 } |
363 } |
363 |
364 |
364 sstr_t key = sbuffer; |
365 cxstring key = sbuffer; |
365 sstr_t value = sstrchr(sbuffer, ':'); |
366 cxstring value = cx_strchr(sbuffer, ':'); |
366 |
367 |
367 if(value.length == 0) { |
368 if(value.length == 0) { |
368 return 0; // invalid header line |
369 return 0; // invalid header line |
369 } |
370 } |
370 |
371 |
371 key.length = value.ptr - key.ptr; |
372 key.length = value.ptr - key.ptr; |
372 value.ptr++; value.length--; |
373 value.ptr++; value.length--; |
373 |
374 |
374 key = sstrlower(sstrtrim(key)); |
375 cxmutstr key_cp = cx_strdup(cx_strtrim(key)); |
375 value = sstrdup(sstrtrim(value)); |
376 cx_strlower(key_cp); |
|
377 cxmutstr value_cp = cx_strdup(cx_strtrim(value)); |
376 |
378 |
377 ucx_map_sstr_put(map, key, value.ptr); |
379 cxMapPut(map, cx_hash_key(key_cp.ptr, key_cp.length), value_cp.ptr); |
378 |
380 |
379 free(key.ptr); |
381 free(key_cp.ptr); |
380 |
382 |
381 return sbuffer.length; |
383 return sbuffer.length; |
382 } |
384 } |
383 |
385 |
384 int util_path_isrelated(const char *path1, const char *path2) { |
386 int util_path_isrelated(const char *path1, const char *path2) { |
385 scstr_t p1 = scstr(path1); |
387 cxstring p1 = cx_str(path1); |
386 scstr_t p2 = scstr(path2); |
388 cxstring p2 = cx_str(path2); |
387 |
389 |
388 if(IS_PATH_SEPARATOR(p1.ptr[p1.length-1])) { |
390 if(IS_PATH_SEPARATOR(p1.ptr[p1.length-1])) { |
389 p1.length--; |
391 p1.length--; |
390 } |
392 } |
391 if(IS_PATH_SEPARATOR(p2.ptr[p2.length-1])) { |
393 if(IS_PATH_SEPARATOR(p2.ptr[p2.length-1])) { |
451 seg_ptr++; |
454 seg_ptr++; |
452 seg_len--; |
455 seg_len--; |
453 } |
456 } |
454 |
457 |
455 if(seg_len > 0) { |
458 if(seg_len > 0) { |
456 scstr_t seg = scstrn(seg_ptr, seg_len); |
459 cxstring seg = cx_strn(seg_ptr, seg_len); |
457 if(!sstrcmp(seg, SC(".."))) { |
460 if(!cx_strcmp(seg, CX_STR(".."))) { |
458 for(int j=buf->pos;j>=0;j--) { |
461 for(int j=buf.pos;j>=0;j--) { |
459 char t = buf->space[j]; |
462 char t = buf.space[j]; |
460 if(IS_PATH_SEPARATOR(t) || j == 0) { |
463 if(IS_PATH_SEPARATOR(t) || j == 0) { |
461 buf->pos = j; |
464 buf.pos = j; |
462 buf->size = j; |
465 buf.size = j; |
463 buf->space[j] = 0; |
466 buf.space[j] = 0; |
464 add_separator = IS_PATH_SEPARATOR(t) ? 1 : 0; |
467 add_separator = IS_PATH_SEPARATOR(t) ? 1 : 0; |
465 break; |
468 break; |
466 } |
469 } |
467 } |
470 } |
468 } else if(!sstrcmp(seg, SC("."))) { |
471 } else if(!cx_strcmp(seg, CX_STR("."))) { |
469 // ignore |
472 // ignore |
470 } else { |
473 } else { |
471 if(add_separator) { |
474 if(add_separator) { |
472 ucx_buffer_putc(buf, PATH_SEPARATOR); |
475 cxBufferPut(&buf, PATH_SEPARATOR); |
473 } |
476 } |
474 ucx_buffer_write(seg_ptr, 1, seg_len, buf); |
477 cxBufferWrite(seg_ptr, 1, seg_len, &buf); |
475 add_separator = 1; |
478 add_separator = 1; |
476 } |
479 } |
477 } |
480 } |
478 |
481 |
479 seg_start = i; |
482 seg_start = i; |
480 } |
483 } |
481 } |
484 } |
482 |
485 |
483 ucx_buffer_putc(buf, 0); |
486 cxBufferPut(&buf, 0); |
484 |
487 |
485 |
488 return buf.space; |
486 char *space = buf->space; |
|
487 buf->flags = 0; // disable autofree |
|
488 ucx_buffer_free(buf); |
|
489 return space; |
|
490 } |
489 } |
491 |
490 |
492 static char* create_relative_path(const char *abspath, const char *base) { |
491 static char* create_relative_path(const char *abspath, const char *base) { |
493 size_t path_len = strlen(abspath); |
492 size_t path_len = strlen(abspath); |
494 size_t base_len = strlen(base); |
493 size_t base_len = strlen(base); |
521 last_dir = i; |
520 last_dir = i; |
522 } |
521 } |
523 } |
522 } |
524 |
523 |
525 char *ret = NULL; |
524 char *ret = NULL; |
526 UcxBuffer *out = NULL; |
525 CxBuffer out; |
527 if(last_dir+1 < base_len) { |
526 if(last_dir+1 < base_len) { |
528 // base is deeper than the link root, we have to go backwards |
527 // base is deeper than the link root, we have to go backwards |
529 int dircount = 0; |
528 int dircount = 0; |
530 for(int i=last_dir+1;i<base_len;i++) { |
529 for(int i=last_dir+1;i<base_len;i++) { |
531 if(IS_PATH_SEPARATOR(base[i])) { |
530 if(IS_PATH_SEPARATOR(base[i])) { |
532 dircount++; |
531 dircount++; |
533 } |
532 } |
534 } |
533 } |
535 |
534 |
536 out = ucx_buffer_new(NULL, dircount*3+path_len-last_dir, UCX_BUFFER_AUTOEXTEND); |
535 cxBufferInit(&out, NULL, dircount*3+path_len-last_dir, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
537 |
536 |
538 for(int i=0;i<dircount;i++) { |
537 for(int i=0;i<dircount;i++) { |
539 ucx_buffer_puts(out, "../"); |
538 cxBufferPutString(&out, "../"); |
540 } |
539 } |
541 } else { |
540 } else { |
542 out = ucx_buffer_new(NULL, 1024, path_len - last_dir); |
541 cxBufferInit(&out, NULL, path_len - last_dir, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
543 } |
542 } |
544 |
543 |
545 ucx_buffer_puts(out, abspath + last_dir + 1); |
544 cxBufferPutString(&out, abspath + last_dir + 1); |
546 ucx_buffer_putc(out, 0); |
545 cxBufferPut(&out, 0); |
547 out->flags = 0; |
546 |
548 ret = out->space; |
547 return out.space; |
549 ucx_buffer_free(out); |
|
550 |
|
551 return ret; |
|
552 } |
548 } |
553 |
549 |
554 #ifdef _WIN32 |
550 #ifdef _WIN32 |
555 char* util_create_relative_path(const char *abspath, const char *base) { |
551 char* util_create_relative_path(const char *abspath, const char *base) { |
556 char *abspath_converted = strdup(abspath); |
552 char *abspath_converted = strdup(abspath); |
579 return create_relative_path(abspath, base); |
575 return create_relative_path(abspath, base); |
580 } |
576 } |
581 #endif |
577 #endif |
582 |
578 |
583 |
579 |
584 void util_capture_header(CURL *handle, UcxMap* map) { |
580 void util_capture_header(CURL *handle, CxMap* map) { |
585 if(map) { |
581 if(map) { |
586 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); |
582 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback); |
587 curl_easy_setopt(handle, CURLOPT_HEADERDATA, map); |
583 curl_easy_setopt(handle, CURLOPT_HEADERDATA, map); |
588 } else { |
584 } else { |
589 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, NULL); |
585 curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, NULL); |
590 curl_easy_setopt(handle, CURLOPT_HEADERDATA, NULL); |
586 curl_easy_setopt(handle, CURLOPT_HEADERDATA, NULL); |
591 } |
587 } |
592 } |
588 } |
593 |
589 |
594 char* util_resource_name(char *url) { |
590 const char* util_resource_name(const char *url) { |
595 sstr_t urlstr = sstr(url); |
591 cxstring urlstr = cx_str(url); |
596 if(urlstr.ptr[urlstr.length-1] == '/') { |
592 if(urlstr.ptr[urlstr.length-1] == '/') { |
597 urlstr.length--; |
593 urlstr.length--; |
598 } |
594 } |
599 sstr_t resname = sstrrchr(urlstr, '/'); |
595 cxstring resname = cx_strrchr(urlstr, '/'); |
600 if(resname.length > 1) { |
596 if(resname.length > 1) { |
601 return resname.ptr+1; |
597 return resname.ptr+1; |
602 } else { |
598 } else { |
603 return url; |
599 return url; |
604 } |
600 } |
630 if(path.length == 0 || path.ptr[0] != '/') { |
626 if(path.length == 0 || path.ptr[0] != '/') { |
631 add_separator = 1; |
627 add_separator = 1; |
632 } |
628 } |
633 } |
629 } |
634 |
630 |
635 sstr_t url; |
631 cxmutstr url; |
636 if(add_separator) { |
632 if(add_separator) { |
637 url = sstrcat(3, base, sstr("/"), path); |
633 url = cx_strcat(3, base, CX_STR("/"), path); |
638 } else { |
634 } else { |
639 url = sstrcat(2, base, path); |
635 url = cx_strcat(2, base, path); |
640 } |
636 } |
641 |
637 |
642 return url.ptr; |
638 return url.ptr; |
643 } |
639 } |
644 |
640 |
645 char* util_get_url(DavSession *sn, const char *href) { |
641 char* util_get_url(DavSession *sn, const char *href) { |
646 scstr_t base = scstr(sn->base_url); |
642 cxstring base = cx_str(sn->base_url); |
647 scstr_t href_str = scstr(href); |
643 cxstring href_str = cx_str(href); |
648 |
644 |
649 char *base_path = util_url_path(sn->base_url); |
645 const char *base_path = util_url_path(sn->base_url); |
650 base.length -= strlen(base_path); |
646 base.length -= strlen(base_path); |
651 |
647 |
652 sstr_t url = sstrcat(2, base, href_str); |
648 cxmutstr url = cx_strcat(2, base, href_str); |
653 return url.ptr; |
649 return url.ptr; |
654 } |
650 } |
655 |
651 |
656 void util_set_url(DavSession *sn, const char *href) { |
652 void util_set_url(DavSession *sn, const char *href) { |
657 char *url = util_get_url(sn, href); |
653 char *url = util_get_url(sn, href); |
658 curl_easy_setopt(sn->handle, CURLOPT_URL, url); |
654 curl_easy_setopt(sn->handle, CURLOPT_URL, url); |
659 free(url); |
655 free(url); |
660 } |
656 } |
661 |
657 |
662 char* util_path_to_url(DavSession *sn, char *path) { |
658 char* util_path_to_url(DavSession *sn, const char *path) { |
663 char *space = malloc(256); |
659 CxBuffer url; |
664 UcxBuffer *url = ucx_buffer_new(space, 256, UCX_BUFFER_AUTOEXTEND); |
660 cxBufferInit(&url, NULL, 256, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
665 |
661 |
666 // add base url |
662 // add base url |
667 ucx_buffer_write(sn->base_url, 1, strlen(sn->base_url), url); |
663 cxBufferWrite(sn->base_url, 1, strlen(sn->base_url), &url); |
668 // remove trailing slash |
664 // remove trailing slash |
669 ucx_buffer_seek(url, -1, SEEK_CUR); |
665 cxBufferSeek(&url, -1, SEEK_CUR); |
670 |
666 |
671 sstr_t p = sstr(path); |
667 cxstring p = cx_str(path); |
672 ssize_t ntk = 0; |
668 |
673 sstr_t *tks = sstrsplit(p, S("/"), &ntk); |
669 CxStrtokCtx tkctx = cx_strtok(p, CX_STR("/"), INT_MAX); |
674 |
670 cxstring node; |
675 for(int i=0;i<ntk;i++) { |
671 while(cx_strtok_next(&tkctx, &node)) { |
676 sstr_t node = tks[i]; |
|
677 if(node.length > 0) { |
672 if(node.length > 0) { |
678 char *esc = curl_easy_escape(sn->handle, node.ptr, node.length); |
673 char *esc = curl_easy_escape(sn->handle, node.ptr, node.length); |
679 ucx_buffer_putc(url, '/'); |
674 cxBufferPut(&url, '/'); |
680 ucx_buffer_write(esc, 1, strlen(esc), url); |
675 cxBufferWrite(esc, 1, strlen(esc), &url); |
681 curl_free(esc); |
676 curl_free(esc); |
682 } |
677 } |
683 free(node.ptr); |
678 } |
684 } |
679 |
685 free(tks); |
|
686 if(path[p.length-1] == '/') { |
680 if(path[p.length-1] == '/') { |
687 ucx_buffer_putc(url, '/'); |
681 cxBufferPut(&url, '/'); |
688 } |
682 } |
689 ucx_buffer_putc(url, 0); |
683 cxBufferPut(&url, 0); |
690 |
684 |
691 space = url->space; |
685 return url.space; |
692 ucx_buffer_free(url); |
|
693 |
|
694 return space; |
|
695 } |
686 } |
696 |
687 |
697 char* util_parent_path(const char *path) { |
688 char* util_parent_path(const char *path) { |
698 char *name = util_resource_name((char*)path); |
689 const char *name = util_resource_name(path); |
699 size_t namelen = strlen(name); |
690 size_t namelen = strlen(name); |
700 size_t pathlen = strlen(path); |
691 size_t pathlen = strlen(path); |
701 size_t parentlen = pathlen - namelen; |
692 size_t parentlen = pathlen - namelen; |
702 char *parent = malloc(parentlen + 1); |
693 char *parent = malloc(parentlen + 1); |
703 memcpy(parent, path, parentlen); |
694 memcpy(parent, path, parentlen); |
950 } |
941 } |
951 |
942 |
952 return out; |
943 return out; |
953 } |
944 } |
954 |
945 |
955 char* util_encrypt_str(DavSession *sn, char *str, char *key) { |
946 char* util_encrypt_str(DavSession *sn, const char *str, const char *key) { |
956 DavKey *k = dav_context_get_key(sn->context, key); |
947 DavKey *k = dav_context_get_key(sn->context, key); |
957 if(!k) { |
948 if(!k) { |
958 sn->error = DAV_ERROR; |
949 sn->error = DAV_ERROR; |
959 sstr_t err = ucx_sprintf("Key %s not found", key); |
950 cxmutstr err = cx_asprintf("Key %s not found", key); |
960 dav_session_set_errstr(sn, err.ptr); |
951 dav_session_set_errstr(sn, err.ptr); |
961 free(err.ptr); |
952 free(err.ptr); |
962 return NULL; |
953 return NULL; |
963 } |
954 } |
964 |
955 |
965 return util_encrypt_str_k(sn, str, k); |
956 return util_encrypt_str_k(sn, str, k); |
966 } |
957 } |
967 |
958 |
968 char* util_encrypt_str_k(DavSession *sn, char *str, DavKey *key) { |
959 char* util_encrypt_str_k(DavSession *sn, const char *str, DavKey *key) { |
969 char *enc_str = aes_encrypt(str, strlen(str), key); |
960 char *enc_str = aes_encrypt(str, strlen(str), key); |
970 char *ret_str = dav_session_strdup(sn, enc_str); |
961 char *ret_str = dav_session_strdup(sn, enc_str); |
971 free(enc_str); |
962 free(enc_str); |
972 return ret_str; |
963 return ret_str; |
973 } |
964 } |
974 |
965 |
975 char* util_decrypt_str(DavSession *sn, char *str, char *key) { |
966 char* util_decrypt_str(DavSession *sn, const char *str, const char *key) { |
976 DavKey *k = dav_context_get_key(sn->context, key); |
967 DavKey *k = dav_context_get_key(sn->context, key); |
977 if(!k) { |
968 if(!k) { |
978 sn->error = DAV_ERROR; |
969 sn->error = DAV_ERROR; |
979 sstr_t err = ucx_sprintf("Key %s not found", key); |
970 cxmutstr err = cx_asprintf("Key %s not found", key); |
980 dav_session_set_errstr(sn, err.ptr); |
971 dav_session_set_errstr(sn, err.ptr); |
981 free(err.ptr); |
972 free(err.ptr); |
982 return NULL; |
973 return NULL; |
983 } |
974 } |
984 |
975 |
985 return util_decrypt_str_k(sn, str, k); |
976 return util_decrypt_str_k(sn, str, k); |
986 } |
977 } |
987 |
978 |
988 char* util_decrypt_str_k(DavSession *sn, char *str, DavKey *key) { |
979 char* util_decrypt_str_k(DavSession *sn, const char *str, DavKey *key) { |
989 size_t len = 0; |
980 size_t len = 0; |
990 char *dec_str = aes_decrypt(str, &len, key); |
981 char *dec_str = aes_decrypt(str, &len, key); |
991 char *ret_str = dav_session_strdup(sn, dec_str); |
982 char *ret_str = dav_session_strdup(sn, dec_str); |
992 free(dec_str); |
983 free(dec_str); |
993 return ret_str; |
984 return ret_str; |
1058 str.ptr = NULL; |
1051 str.ptr = NULL; |
1059 str.length = 0; |
1052 str.length = 0; |
1060 return str; |
1053 return str; |
1061 } |
1054 } |
1062 } |
1055 } |
1063 |
1056 */ |
1064 sstr_t util_readline(FILE *stream) { |
1057 |
1065 UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); |
1058 cxmutstr util_readline(FILE *stream) { |
|
1059 CxBuffer buf; |
|
1060 cxBufferInit(&buf, NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1066 |
1061 |
1067 int c; |
1062 int c; |
1068 while((c = fgetc(stream)) != EOF) { |
1063 while((c = fgetc(stream)) != EOF) { |
1069 if(c == '\n') { |
1064 if(c == '\n') { |
1070 break; |
1065 break; |
1071 } |
1066 } |
1072 ucx_buffer_putc(buf, c); |
1067 cxBufferPut(&buf, c); |
1073 } |
1068 } |
1074 |
1069 |
1075 sstr_t str = sstrdup(sstrtrim(sstrn(buf->space, buf->size))); |
1070 cxmutstr str = cx_strdup(cx_strtrim(cx_strn(buf.space, buf.size))); |
1076 ucx_buffer_free(buf); |
1071 cxBufferDestroy(&buf); |
1077 return str; |
1072 return str; |
1078 } |
1073 } |
1079 |
1074 |
1080 char* util_password_input(char *prompt) { |
1075 char* util_password_input(char *prompt) { |
1081 fprintf(stderr, "%s", prompt); |
1076 fprintf(stderr, "%s", prompt); |
1095 } |
1090 } |
1096 |
1091 |
1097 #endif |
1092 #endif |
1098 |
1093 |
1099 // read password input |
1094 // read password input |
1100 UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); |
1095 CxBuffer buf; |
|
1096 cxBufferInit(&buf, NULL, 128, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1101 int c = 0; |
1097 int c = 0; |
1102 while((c = getpasswordchar()) != EOF) { |
1098 while((c = getpasswordchar()) != EOF) { |
1103 if(c == '\n' || c == '\r') { |
1099 if(c == '\n' || c == '\r') { |
1104 break; |
1100 break; |
1105 } |
1101 } |
1106 ucx_buffer_putc(buf, c); |
1102 cxBufferPut(&buf, c); |
1107 } |
1103 } |
1108 ucx_buffer_putc(buf, 0); |
1104 cxBufferPut(&buf, 0); |
1109 fflush(stdin); |
1105 fflush(stdin); |
1110 |
1106 |
1111 #ifndef _WIN32 |
1107 #ifndef _WIN32 |
1112 // restore terminal settings |
1108 // restore terminal settings |
1113 if (isatty(fileno(stdin)) && tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { |
1109 if (isatty(fileno(stdin)) && tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { |
1114 perror("tcsetattr"); |
1110 perror("tcsetattr"); |
1115 } |
1111 } |
1116 #endif |
1112 #endif |
1117 |
1113 |
1118 char *str = buf->space; |
1114 return buf.space; |
1119 free(buf); // only free the UcxBuffer struct |
1115 } |
1120 return str; |
1116 |
1121 } |
1117 int util_exec_command(char *command, CxBuffer *outbuf) { |
1122 |
|
1123 int util_exec_command(char *command, UcxBuffer *outbuf) { |
|
1124 #ifdef _WIN32 |
1118 #ifdef _WIN32 |
1125 fprintf(stderr, "util_exec_command unsupported\n"); |
1119 fprintf(stderr, "util_exec_command unsupported\n"); |
1126 return 1; |
1120 return 1; |
1127 #else |
1121 #else |
1128 |
1122 |
1171 #endif |
1165 #endif |
1172 } |
1166 } |
1173 |
1167 |
1174 char* util_hexstr(const unsigned char *data, size_t len) { |
1168 char* util_hexstr(const unsigned char *data, size_t len) { |
1175 size_t buflen = 2*len + 4; |
1169 size_t buflen = 2*len + 4; |
1176 UcxBuffer *buf = ucx_buffer_new(malloc(buflen), buflen + 1, 0); |
1170 CxBuffer buf; |
|
1171 cxBufferInit(&buf, NULL, buflen + 1, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); |
1177 for(int i=0;i<len;i++) { |
1172 for(int i=0;i<len;i++) { |
1178 ucx_bprintf(buf, "%02x", data[i]); |
1173 cx_bprintf(&buf, "%02x", data[i]); |
1179 } |
1174 } |
1180 ucx_buffer_putc(buf, 0); |
1175 cxBufferPut(&buf, 0); |
1181 char *str = buf->space; |
1176 return buf.space; |
1182 ucx_buffer_free(buf); |
|
1183 return str; |
|
1184 } |
1177 } |
1185 |
1178 |
1186 void util_remove_trailing_pathseparator(char *path) { |
1179 void util_remove_trailing_pathseparator(char *path) { |
1187 size_t len = strlen(path); |
1180 size_t len = strlen(path); |
1188 if(len < 2) { |
1181 if(len < 2) { |