path.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * path.c
  17. *
  18. * This file contains functions to read app config (manifest) file and create
  19. * a tree to lookup / access config values.
  20. */
  21. #include <api.h>
  22. #include <pal_error.h>
  23. int get_norm_path (const char * path, char * buf, int offset, int size)
  24. {
  25. int head = offset;
  26. char c, c1;
  27. const char * p = path;
  28. while (head) { /* find the real head, not interrupted by dot-dot */
  29. if (head > 1 && buf[head - 1] == '.' && buf[head - 2] == '.')
  30. break;
  31. head--;
  32. }
  33. for (c = '/' ; c ; c = c1, p++) {
  34. c1 = *p;
  35. if (c == '/') { /* find a slash, or the beginning of the path */
  36. if (c1 == 0) /* no more path */
  37. break;
  38. if (c1 == '/') /* consequential slashes */
  39. continue;
  40. if (c1 == '.') { /* find a dot, can be dot-dot or a file */
  41. c1 = *(++p);
  42. if (c1 == 0) /* no more path */
  43. break;
  44. if (c1 == '/') /* a dot, skip it */
  45. continue;
  46. if (c1 == '.') { /* must be dot-dot */
  47. c1 = *(++p);
  48. if (c1 != 0 && c1 != '/') { /* Paths can start with a dot
  49. * dot: ..xyz is ok */
  50. if (offset >= size - 2)
  51. return -PAL_ERROR_TOOLONG;
  52. buf[offset++] = '.';
  53. buf[offset++] = '.';
  54. continue;
  55. }
  56. if (offset > head) { /* remove the last token */
  57. while (offset > head && buf[--offset] != '/');
  58. } else {
  59. if (offset) { /* add a slash */
  60. if (offset >= size - 1)
  61. return -PAL_ERROR_TOOLONG;
  62. buf[offset++] = '/';
  63. } /* add a dot-dot */
  64. if (offset >= size - 2)
  65. return -PAL_ERROR_TOOLONG;
  66. buf[offset++] = '.';
  67. buf[offset++] = '.';
  68. head = offset;
  69. }
  70. } else { /* it's a file */
  71. if (offset) { /* add a slash */
  72. if (offset >= size - 1)
  73. return -PAL_ERROR_TOOLONG;
  74. buf[offset++] = '/';
  75. }
  76. if (offset >= size - 1)
  77. return -PAL_ERROR_TOOLONG;
  78. buf[offset++] = '.';
  79. }
  80. continue;
  81. }
  82. }
  83. if (offset || c != '/' || *path == '/') {
  84. if (offset >= size - 1)
  85. return -PAL_ERROR_TOOLONG;
  86. buf[offset++] = c;
  87. }
  88. }
  89. buf[offset] = 0;
  90. return offset;
  91. }
  92. int get_base_name (const char * path, char * buf, int size)
  93. {
  94. const char * p = path;
  95. for (; *p ; p++) {
  96. if (*p == '/')
  97. continue;
  98. if (*p == '.') {
  99. if (*(p + 1) == '/' || !*(p + 1)) {
  100. p++;
  101. continue;
  102. }
  103. if (*(p + 1) == '.') {
  104. if (*(p + 2) == '/' || !*(p + 2)) {
  105. p += 2;
  106. continue;
  107. }
  108. }
  109. }
  110. const char * e = p + 1;
  111. for (; *e && *e != '/' ; e++);
  112. if (*e) {
  113. p = e - 1;
  114. continue;
  115. }
  116. if (e - p > size - 1)
  117. return -PAL_ERROR_TOOLONG;
  118. int offset = 0;
  119. for (; p < e ; p++, offset++)
  120. buf[offset] = *p;
  121. buf[offset] = 0;
  122. return offset;
  123. }
  124. return 0;
  125. }