path.c 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 != '/') /* must be the end or a slash */
  49. return -PAL_ERROR_INVAL;
  50. if (offset > head) { /* remove the last token */
  51. while (offset > head && buf[--offset] != '/');
  52. } else {
  53. if (offset) { /* add a slash */
  54. if (offset >= size - 1)
  55. return -PAL_ERROR_TOOLONG;
  56. buf[offset++] = '/';
  57. } /* add a dot-dot */
  58. if (offset >= size - 2)
  59. return -PAL_ERROR_TOOLONG;
  60. buf[offset++] = '.';
  61. buf[offset++] = '.';
  62. head = offset;
  63. }
  64. } else { /* it's a file */
  65. if (offset) { /* add a slash */
  66. if (offset >= size - 1)
  67. return -PAL_ERROR_TOOLONG;
  68. buf[offset++] = '/';
  69. }
  70. if (offset >= size - 1)
  71. return -PAL_ERROR_TOOLONG;
  72. buf[offset++] = '.';
  73. }
  74. continue;
  75. }
  76. }
  77. if (offset || c != '/' || *path == '/') {
  78. if (offset >= size - 1)
  79. return -PAL_ERROR_TOOLONG;
  80. buf[offset++] = c;
  81. }
  82. }
  83. buf[offset] = 0;
  84. return offset;
  85. }