archive_options.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
  38. mp = m != NULL && m[0] != '\0' ? m : NULL;
  39. op = o != NULL && o[0] != '\0' ? o : NULL;
  40. vp = v != NULL && v[0] != '\0' ? v : NULL;
  41. if (op == NULL && vp == NULL)
  42. return (ARCHIVE_OK);
  43. if (op == NULL)
  44. return (ARCHIVE_FAILED);
  45. return use_option(a, mp, op, vp);
  46. }
  47. int
  48. _archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
  49. option_handler use_format_option, option_handler use_filter_option)
  50. {
  51. int r1, r2;
  52. if (o == NULL && v == NULL)
  53. return (ARCHIVE_OK);
  54. if (o == NULL)
  55. return (ARCHIVE_FAILED);
  56. r1 = use_format_option(a, m, o, v);
  57. if (r1 == ARCHIVE_FATAL)
  58. return (ARCHIVE_FATAL);
  59. r2 = use_filter_option(a, m, o, v);
  60. if (r2 == ARCHIVE_FATAL)
  61. return (ARCHIVE_FATAL);
  62. return r1 > r2 ? r1 : r2;
  63. }
  64. int
  65. _archive_set_options(struct archive *a, const char *options,
  66. int magic, const char *fn, option_handler use_option)
  67. {
  68. int allok = 1, anyok = 0, r;
  69. char *data;
  70. const char *s, *mod, *opt, *val;
  71. archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
  72. if (options == NULL || options[0] == '\0')
  73. return ARCHIVE_OK;
  74. data = (char *)malloc(strlen(options) + 1);
  75. strcpy(data, options);
  76. s = (const char *)data;
  77. do {
  78. mod = opt = val = NULL;
  79. parse_option(&s, &mod, &opt, &val);
  80. r = use_option(a, mod, opt, val);
  81. if (r == ARCHIVE_FATAL) {
  82. free(data);
  83. return (ARCHIVE_FATAL);
  84. }
  85. if (r == ARCHIVE_OK)
  86. anyok = 1;
  87. else
  88. allok = 0;
  89. } while (s != NULL);
  90. free(data);
  91. return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
  92. }
  93. static const char *
  94. parse_option(const char **s, const char **m, const char **o, const char **v)
  95. {
  96. const char *end, *mod, *opt, *val;
  97. char *p;
  98. end = NULL;
  99. mod = NULL;
  100. opt = *s;
  101. val = "1";
  102. p = strchr(opt, ',');
  103. if (p != NULL) {
  104. *p = '\0';
  105. end = ((const char *)p) + 1;
  106. }
  107. if (0 == strlen(opt)) {
  108. *s = end;
  109. *m = NULL;
  110. *o = NULL;
  111. *v = NULL;
  112. return end;
  113. }
  114. p = strchr(opt, ':');
  115. if (p != NULL) {
  116. *p = '\0';
  117. mod = opt;
  118. opt = ++p;
  119. }
  120. p = strchr(opt, '=');
  121. if (p != NULL) {
  122. *p = '\0';
  123. val = ++p;
  124. } else if (opt[0] == '!') {
  125. ++opt;
  126. val = NULL;
  127. }
  128. *s = end;
  129. *m = mod;
  130. *o = opt;
  131. *v = val;
  132. return end;
  133. }