filepath_util.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define APR_WANT_STRFUNC
  17. #define APR_WANT_MEMFUNC
  18. #include "fspr_want.h"
  19. #include "fspr_errno.h"
  20. #include "fspr_pools.h"
  21. #include "fspr_strings.h"
  22. #include "fspr_tables.h"
  23. #include "fspr_private.h"
  24. fspr_status_t fspr_filepath_list_split_impl(fspr_array_header_t **pathelts,
  25. const char *liststr,
  26. char separator,
  27. fspr_pool_t *p)
  28. {
  29. char *path, *part, *ptr;
  30. char separator_string[2] = { '\0', '\0' };
  31. fspr_array_header_t *elts;
  32. int nelts;
  33. separator_string[0] = separator;
  34. /* Count the number of path elements. We know there'll be at least
  35. one even if path is an empty string. */
  36. path = fspr_pstrdup(p, liststr);
  37. for (nelts = 0, ptr = path; ptr != NULL; ++nelts)
  38. {
  39. ptr = strchr(ptr, separator);
  40. if (ptr)
  41. ++ptr;
  42. }
  43. /* Split the path into the array. */
  44. elts = fspr_array_make(p, nelts, sizeof(char*));
  45. while ((part = fspr_strtok(path, separator_string, &ptr)) != NULL)
  46. {
  47. if (*part == '\0') /* Ignore empty path components. */
  48. continue;
  49. *(char**)fspr_array_push(elts) = part;
  50. path = NULL; /* For the next call to fspr_strtok */
  51. }
  52. *pathelts = elts;
  53. return APR_SUCCESS;
  54. }
  55. fspr_status_t fspr_filepath_list_merge_impl(char **liststr,
  56. fspr_array_header_t *pathelts,
  57. char separator,
  58. fspr_pool_t *p)
  59. {
  60. fspr_size_t path_size = 0;
  61. char *path;
  62. int i;
  63. /* This test isn't 100% certain, but it'll catch at least some
  64. invalid uses... */
  65. if (pathelts->elt_size != sizeof(char*))
  66. return APR_EINVAL;
  67. /* Calculate the size of the merged path */
  68. for (i = 0; i < pathelts->nelts; ++i)
  69. path_size += strlen(((char**)pathelts->elts)[i]);
  70. if (path_size == 0)
  71. {
  72. *liststr = NULL;
  73. return APR_SUCCESS;
  74. }
  75. if (i > 0) /* Add space for the separators */
  76. path_size += (i - 1);
  77. /* Merge the path components */
  78. path = *liststr = fspr_palloc(p, path_size + 1);
  79. for (i = 0; i < pathelts->nelts; ++i)
  80. {
  81. /* ### Hmmmm. Calling strlen twice on the same string. Yuck.
  82. But is is better than reallocation in fspr_pstrcat? */
  83. const char *part = ((char**)pathelts->elts)[i];
  84. fspr_size_t part_size = strlen(part);
  85. if (part_size == 0) /* Ignore empty path components. */
  86. continue;
  87. if (i > 0)
  88. *path++ = separator;
  89. memcpy(path, part, part_size);
  90. path += part_size;
  91. }
  92. *path = '\0';
  93. return APR_SUCCESS;
  94. }