1
0

archive_options.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*-
  2. * Copyright (c) 2011 Tim Kientzle
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "archive_platform.h"
  26. __FBSDID("$FreeBSD$");
  27. #include "archive_options_private.h"
  28. static const char *
  29. parse_option(const char **str,
  30. const char **mod, const char **opt, const char **val);
  31. int
  32. _archive_set_option(struct archive *a,
  33. const char *m, const char *o, const char *v,
  34. int magic, const char *fn, option_handler use_option)
  35. {
  36. const char *mp, *op, *vp;
  37. int r;
  38. archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
  39. mp = m != NULL && m[0] != '\0' ? m : NULL;
  40. op = o != NULL && o[0] != '\0' ? o : NULL;
  41. vp = v != NULL && v[0] != '\0' ? v : NULL;
  42. if (op == NULL && vp == NULL)
  43. return (ARCHIVE_OK);
  44. if (op == NULL) {
  45. archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");
  46. return (ARCHIVE_FAILED);
  47. }
  48. r = use_option(a, mp, op, vp);
  49. if (r == ARCHIVE_WARN - 1) {
  50. archive_set_error(a, ARCHIVE_ERRNO_MISC,
  51. "Unknown module name: `%s'", mp);
  52. return (ARCHIVE_FAILED);
  53. }
  54. if (r == ARCHIVE_WARN) {
  55. archive_set_error(a, ARCHIVE_ERRNO_MISC,
  56. "Undefined option: `%s%s%s%s%s%s'",
  57. vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");
  58. return (ARCHIVE_FAILED);
  59. }
  60. return (r);
  61. }
  62. int
  63. _archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
  64. option_handler use_format_option, option_handler use_filter_option)
  65. {
  66. int r1, r2;
  67. if (o == NULL && v == NULL)
  68. return (ARCHIVE_OK);
  69. if (o == NULL)
  70. return (ARCHIVE_FAILED);
  71. r1 = use_format_option(a, m, o, v);
  72. if (r1 == ARCHIVE_FATAL)
  73. return (ARCHIVE_FATAL);
  74. r2 = use_filter_option(a, m, o, v);
  75. if (r2 == ARCHIVE_FATAL)
  76. return (ARCHIVE_FATAL);
  77. if (r2 == ARCHIVE_WARN - 1)
  78. return r1;
  79. return r1 > r2 ? r1 : r2;
  80. }
  81. int
  82. _archive_set_options(struct archive *a, const char *options,
  83. int magic, const char *fn, option_handler use_option)
  84. {
  85. int allok = 1, anyok = 0, ignore_mod_err = 0, r;
  86. char *data;
  87. const char *s, *mod, *opt, *val;
  88. archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
  89. if (options == NULL || options[0] == '\0')
  90. return ARCHIVE_OK;
  91. data = (char *)malloc(strlen(options) + 1);
  92. strcpy(data, options);
  93. s = (const char *)data;
  94. do {
  95. mod = opt = val = NULL;
  96. parse_option(&s, &mod, &opt, &val);
  97. if (mod == NULL && opt != NULL &&
  98. strcmp("__ignore_wrong_module_name__", opt) == 0) {
  99. /* Ignore module name error */
  100. if (val != NULL) {
  101. ignore_mod_err = 1;
  102. anyok = 1;
  103. }
  104. continue;
  105. }
  106. r = use_option(a, mod, opt, val);
  107. if (r == ARCHIVE_FATAL) {
  108. free(data);
  109. return (ARCHIVE_FATAL);
  110. }
  111. if (r == ARCHIVE_FAILED && mod != NULL) {
  112. free(data);
  113. return (ARCHIVE_FAILED);
  114. }
  115. if (r == ARCHIVE_WARN - 1) {
  116. if (ignore_mod_err)
  117. continue;
  118. /* The module name is wrong. */
  119. archive_set_error(a, ARCHIVE_ERRNO_MISC,
  120. "Unknown module name: `%s'", mod);
  121. free(data);
  122. return (ARCHIVE_FAILED);
  123. }
  124. if (r == ARCHIVE_WARN) {
  125. /* The option name is wrong. No-one used this. */
  126. archive_set_error(a, ARCHIVE_ERRNO_MISC,
  127. "Undefined option: `%s%s%s'",
  128. mod?mod:"", mod?":":"", opt);
  129. free(data);
  130. return (ARCHIVE_FAILED);
  131. }
  132. if (r == ARCHIVE_OK)
  133. anyok = 1;
  134. else
  135. allok = 0;
  136. } while (s != NULL);
  137. free(data);
  138. return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
  139. }
  140. static const char *
  141. parse_option(const char **s, const char **m, const char **o, const char **v)
  142. {
  143. const char *end, *mod, *opt, *val;
  144. char *p;
  145. end = NULL;
  146. mod = NULL;
  147. opt = *s;
  148. val = "1";
  149. p = strchr(opt, ',');
  150. if (p != NULL) {
  151. *p = '\0';
  152. end = ((const char *)p) + 1;
  153. }
  154. if (0 == strlen(opt)) {
  155. *s = end;
  156. *m = NULL;
  157. *o = NULL;
  158. *v = NULL;
  159. return end;
  160. }
  161. p = strchr(opt, ':');
  162. if (p != NULL) {
  163. *p = '\0';
  164. mod = opt;
  165. opt = ++p;
  166. }
  167. p = strchr(opt, '=');
  168. if (p != NULL) {
  169. *p = '\0';
  170. val = ++p;
  171. } else if (opt[0] == '!') {
  172. ++opt;
  173. val = NULL;
  174. }
  175. *s = end;
  176. *m = mod;
  177. *o = opt;
  178. *v = val;
  179. return end;
  180. }