path.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 OSCAR lab, 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 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 General Public License for more details.
  13. You should have received a copy of the GNU 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. continue;
  51. if (offset > head) { /* remove the last token */
  52. while (offset > head && buf[--offset] != '/');
  53. } else {
  54. if (offset) { /* add a slash */
  55. if (offset >= size - 1)
  56. return -PAL_ERROR_TOOLONG;
  57. buf[offset++] = '/';
  58. } /* add a dot-dot */
  59. if (offset >= size - 2)
  60. return -PAL_ERROR_TOOLONG;
  61. buf[offset++] = '.';
  62. buf[offset++] = '.';
  63. head = offset;
  64. }
  65. } else { /* it's a file */
  66. if (offset) { /* add a slash */
  67. if (offset >= size - 1)
  68. return -PAL_ERROR_TOOLONG;
  69. buf[offset++] = '/';
  70. }
  71. if (offset >= size - 1)
  72. return -PAL_ERROR_TOOLONG;
  73. buf[offset++] = '.';
  74. }
  75. continue;
  76. }
  77. }
  78. if (offset || c != '/' || *path == '/') {
  79. if (offset >= size - 1)
  80. return -PAL_ERROR_TOOLONG;
  81. buf[offset++] = c;
  82. }
  83. }
  84. buf[offset] = 0;
  85. return offset;
  86. }
  87. int get_base_name (const char * path, char * buf, int size)
  88. {
  89. const char * p = path;
  90. for (; *p ; p++) {
  91. if (*p == '/')
  92. continue;
  93. if (*p == '.') {
  94. if (*(p + 1) == '/' || !*(p + 1)) {
  95. p++;
  96. continue;
  97. }
  98. if (*(p + 1) == '.') {
  99. if (*(p + 2) == '/' || !*(p + 2)) {
  100. p += 2;
  101. continue;
  102. }
  103. return -PAL_ERROR_INVAL;
  104. }
  105. }
  106. const char * e = p + 1;
  107. for (; *e && *e != '/' ; e++);
  108. if (*e) {
  109. p = e - 1;
  110. continue;
  111. }
  112. if (e - p > size - 1)
  113. return -PAL_ERROR_TOOLONG;
  114. int offset = 0;
  115. for (; p < e ; p++, offset++)
  116. buf[offset] = *p;
  117. buf[offset] = 0;
  118. return offset;
  119. }
  120. return 0;
  121. }