Merge tag 'upstream/520.56.06' into main
Upstream version 520.56.06
Andreas Beckmann
1 year, 3 months ago
594 | 594 | } |
595 | 595 | |
596 | 596 | |
597 | ||
598 | /* | |
599 | * nvdircat() - concatenate path elements, inserting a '/' path separator | |
600 | * character between each element. | |
601 | */ | |
602 | ||
603 | char *nvdircat(const char *str, ...) | |
604 | { | |
605 | const char *s; | |
606 | char *result = nvstrdup(""); | |
607 | va_list ap; | |
608 | ||
609 | va_start(ap, str); | |
610 | ||
611 | for (s = str; s; s = va_arg(ap, char *)) { | |
612 | char *oldresult = result; | |
613 | ||
614 | result = nvstrcat(result, s == str ? "" : "/", s, NULL); | |
615 | nvfree(oldresult); | |
616 | } | |
617 | ||
618 | va_end(ap); | |
619 | ||
620 | collapse_multiple_slashes(result); | |
621 | ||
622 | return result; | |
623 | } | |
624 | ||
625 | ||
626 | /* | |
627 | * dirname(3) workalike that abstracts away implementation-specific behavior: | |
628 | * this function always returns a heap-allocated string that can be passed to | |
629 | * free(3), and never modifies the contents of the original string. | |
630 | */ | |
631 | char *nv_dirname(const char *path) | |
632 | { | |
633 | char *last_slash = strrchr(path, '/'); | |
634 | if (last_slash) { | |
635 | return nvstrndup(path, last_slash - path); | |
636 | } else { | |
637 | return nvstrdup("."); | |
638 | } | |
639 | } | |
640 | ||
641 | ||
642 | /* | |
643 | * Simple helper function to write the contents of a NUL-terminated string to | |
644 | * a file. A trailing newline is appended if not already present. | |
645 | * Returns TRUE on success; FALSE if an error occurred. | |
646 | */ | |
647 | int nv_string_to_file(const char *destination, const char *data) | |
648 | { | |
649 | char *dname = nv_dirname(destination); | |
650 | int written, newline_success = TRUE; | |
651 | char *error = NULL; | |
652 | int len, ret; | |
653 | FILE *fp; | |
654 | ||
655 | ret = nv_mkdir_recursive(dname, 0755, &error, NULL); | |
656 | nvfree(dname); | |
657 | nvfree(error); | |
658 | ||
659 | if (!ret) return FALSE; | |
660 | ||
661 | fp = fopen(destination, "w"); | |
662 | if (!fp) return FALSE; | |
663 | ||
664 | len = strlen(data); | |
665 | written = fwrite(data, 1, len, fp); | |
666 | if (data[len-1] != '\n') { | |
667 | if (fwrite("\n", 1, 1, fp) != 1) { | |
668 | newline_success = FALSE; | |
669 | } | |
670 | } | |
671 | ||
672 | if (fclose(fp)) return FALSE; | |
673 | if (chmod(destination, 0644)) return FALSE; | |
674 | ||
675 | return written == len && newline_success; | |
676 | } | |
677 | ||
678 | ||
679 | ||
597 | 680 | /****************************************************************************/ |
598 | 681 | /* string helper functions */ |
599 | 682 | /****************************************************************************/ |
719 | 802 | |
720 | 803 | } |
721 | 804 | |
805 | ||
806 | ||
807 | /* | |
808 | * collapse_multiple_slashes() - remove any/all occurrences of "//" from the | |
809 | * argument string. | |
810 | */ | |
811 | ||
812 | void collapse_multiple_slashes(char *s) | |
813 | { | |
814 | char *p; | |
815 | ||
816 | while ((p = strstr(s, "//")) != NULL) { | |
817 | p++; /* advance to second '/' */ | |
818 | while (*p == '/') { | |
819 | unsigned int i, len; | |
820 | ||
821 | len = strlen(p); | |
822 | for (i = 0; i < len; i++) p[i] = p[i+1]; | |
823 | } | |
824 | } | |
825 | } |
74 | 74 | char *nv_basename(const char *path); |
75 | 75 | int nv_mkdir_recursive(const char *path, const mode_t mode, |
76 | 76 | char **error_str, char **log_str); |
77 | char *nvdircat(const char *str, ...); | |
78 | char *nv_dirname(const char *path); | |
79 | int nv_string_to_file(const char *, const char *); | |
77 | 80 | |
78 | 81 | char *nv_trim_space(char *string); |
79 | 82 | char *nv_trim_char(char *string, char trim); |
80 | 83 | char *nv_trim_char_strict(char *string, char trim); |
81 | 84 | void remove_trailing_slashes(char *string); |
85 | void collapse_multiple_slashes(char *s); | |
82 | 86 | |
83 | 87 | int directory_exists(const char *dir); |
84 | 88 |
42 | 42 | * through 'boolval'. |
43 | 43 | */ |
44 | 44 | |
45 | #define NVGETOPT_IS_BOOLEAN 0x01 | |
45 | #define NVGETOPT_IS_BOOLEAN 0x0001 | |
46 | 46 | |
47 | 47 | |
48 | 48 | /* |
51 | 51 | * through 'strval'. |
52 | 52 | */ |
53 | 53 | |
54 | #define NVGETOPT_STRING_ARGUMENT 0x02 | |
54 | #define NVGETOPT_STRING_ARGUMENT 0x0002 | |
55 | 55 | |
56 | 56 | |
57 | 57 | /* |
60 | 60 | * argument through 'intval'. |
61 | 61 | */ |
62 | 62 | |
63 | #define NVGETOPT_INTEGER_ARGUMENT 0x04 | |
63 | #define NVGETOPT_INTEGER_ARGUMENT 0x0004 | |
64 | 64 | |
65 | 65 | |
66 | 66 | /* |
69 | 69 | * argument through 'doubleval'. |
70 | 70 | */ |
71 | 71 | |
72 | #define NVGETOPT_DOUBLE_ARGUMENT 0x08 | |
72 | #define NVGETOPT_DOUBLE_ARGUMENT 0x0008 | |
73 | 73 | |
74 | 74 | |
75 | 75 | /* helper macro */ |
88 | 88 | * take arguments. |
89 | 89 | */ |
90 | 90 | |
91 | #define NVGETOPT_ALLOW_DISABLE 0x10 | |
91 | #define NVGETOPT_ALLOW_DISABLE 0x0010 | |
92 | 92 | |
93 | 93 | |
94 | 94 | /* |
98 | 98 | * option is returned without an argument. |
99 | 99 | */ |
100 | 100 | |
101 | #define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x20 | |
101 | #define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x0020 | |
102 | 102 | |
103 | 103 | |
104 | 104 | /* |
109 | 109 | * printed. |
110 | 110 | */ |
111 | 111 | |
112 | #define NVGETOPT_HELP_ALWAYS 0x40 | |
113 | ||
112 | #define NVGETOPT_HELP_ALWAYS 0x0040 | |
113 | ||
114 | ||
115 | /* | |
116 | * Indicates that an option is deprecated. The description field of the | |
117 | * NVGetoptOption, if set, may be used to store text explaining why the | |
118 | * option is no longer used. | |
119 | */ | |
120 | ||
121 | #define NVGETOPT_IS_DEPRECATED 0x0080 | |
122 | ||
123 | /* | |
124 | * These flags indicate that a particular boolean or disableable value is no | |
125 | * longer supported. They can be used together with NVGETOPT_DEPRECATED in | |
126 | * order to differentiate between deprecated boolean values or enable/disable | |
127 | * states that will be ignored, and unsupported boolean values or enable/disable | |
128 | * states that are invalid. | |
129 | */ | |
130 | ||
131 | #define NVGETOPT_DISABLE_IS_INVALID 0x0100 | |
132 | #define NVGETOPT_ENABLE_IS_INVALID 0x0200 | |
114 | 133 | |
115 | 134 | typedef struct { |
116 | 135 | const char *name; |