sysfsutils-2.1.0-get_link.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. diff -upr sysfsutils-2.1.0-old/lib/sysfs_utils.c sysfsutils-2.1.0/lib/sysfs_utils.c
  2. --- sysfsutils-2.1.0-old/lib/sysfs_utils.c 2006-08-07 07:08:01.000000000 +0200
  3. +++ sysfsutils-2.1.0/lib/sysfs_utils.c 2008-05-13 07:42:50.000000000 +0200
  4. @@ -117,84 +117,104 @@ int sysfs_get_link(const char *path, cha
  5. {
  6. char devdir[SYSFS_PATH_MAX];
  7. char linkpath[SYSFS_PATH_MAX];
  8. - char temp_path[SYSFS_PATH_MAX];
  9. - char *d = NULL, *s = NULL;
  10. - int slashes = 0, count = 0;
  11. + char *d, *s;
  12. + int count;
  13. if (!path || !target || len == 0) {
  14. errno = EINVAL;
  15. return -1;
  16. }
  17. - memset(devdir, 0, SYSFS_PATH_MAX);
  18. - memset(linkpath, 0, SYSFS_PATH_MAX);
  19. - memset(temp_path, 0, SYSFS_PATH_MAX);
  20. - safestrcpy(devdir, path);
  21. -
  22. - if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) {
  23. + count = readlink(path, linkpath, SYSFS_PATH_MAX);
  24. + if (count < 0)
  25. return -1;
  26. - }
  27. - d = linkpath;
  28. + else
  29. + linkpath[count] = '\0';
  30. /*
  31. * Three cases here:
  32. * 1. relative path => format ../..
  33. * 2. absolute path => format /abcd/efgh
  34. * 3. relative path _from_ this dir => format abcd/efgh
  35. */
  36. - switch (*d) {
  37. - case '.':
  38. + if (*linkpath == '/') {
  39. + /* absolute path - copy as is */
  40. + safestrcpymax(target, linkpath, len);
  41. + return 0;
  42. + }
  43. +
  44. + safestrcpy(devdir, path);
  45. + s = strrchr(devdir, '/');
  46. + if (s == NULL)
  47. + s = devdir - 1;
  48. + d = linkpath;
  49. + while (*d == '.') {
  50. + if (*(d+1) == '/') {
  51. /*
  52. * handle the case where link is of type ./abcd/xxx
  53. */
  54. - safestrcpy(temp_path, devdir);
  55. - if (*(d+1) == '/')
  56. - d += 2;
  57. - else if (*(d+1) == '.')
  58. - goto parse_path;
  59. - s = strrchr(temp_path, '/');
  60. - if (s != NULL) {
  61. - *(s+1) = '\0';
  62. - safestrcat(temp_path, d);
  63. - } else {
  64. - safestrcpy(temp_path, d);
  65. - }
  66. - safestrcpymax(target, temp_path, len);
  67. - break;
  68. + d += 2;
  69. + while (*d == '/')
  70. + d++;
  71. + continue;
  72. + } else if (*(d+1) != '.' || *(d+2) != '/')
  73. /*
  74. - * relative path, getting rid of leading "../.."
  75. + * relative path from this directory, starting
  76. + * with a hidden directory
  77. */
  78. -parse_path:
  79. - while (*d == '/' || *d == '.') {
  80. - if (*d == '/')
  81. - slashes++;
  82. - d++;
  83. - }
  84. - d--;
  85. - s = &devdir[strlen(devdir)-1];
  86. - while (s != NULL && count != (slashes+1)) {
  87. + break;
  88. +
  89. + /*
  90. + * relative path, getting rid of leading "../.."; must
  91. + * be careful here since any path component of devdir
  92. + * could be a symlink again
  93. + */
  94. + for (;;) {
  95. + while (s > devdir && *s == '/') {
  96. s--;
  97. - if (*s == '/')
  98. - count++;
  99. + if (*s == '.'
  100. + && (s == devdir || *(s-1) == '/'))
  101. + s--;
  102. }
  103. - safestrcpymax(s, d, (SYSFS_PATH_MAX-strlen(devdir)));
  104. - safestrcpymax(target, devdir, len);
  105. - break;
  106. - case '/':
  107. - /* absolute path - copy as is */
  108. - safestrcpymax(target, linkpath, len);
  109. - break;
  110. - default:
  111. - /* relative path from this directory */
  112. - safestrcpy(temp_path, devdir);
  113. - s = strrchr(temp_path, '/');
  114. - if (s != NULL) {
  115. - *(s+1) = '\0';
  116. - safestrcat(temp_path, linkpath);
  117. - } else {
  118. - safestrcpy(temp_path, linkpath);
  119. + *(s+1) = '\0';
  120. + if (*devdir == '\0' || sysfs_path_is_link(devdir))
  121. + /*
  122. + * condition will be true eventually
  123. + * because we already know that all
  124. + * but the last component of path
  125. + * resolve to a directory
  126. + */
  127. + break;
  128. + if (sysfs_get_link(devdir, devdir, SYSFS_PATH_MAX))
  129. + return -1;
  130. + s = devdir + strlen(devdir) - 1;
  131. + }
  132. + while (s >= devdir) {
  133. + if (*s == '/') {
  134. + if (*(s+1) != '.' || *(s+2) != '.'
  135. + || *(s+3) != '\0') {
  136. + d += 3;
  137. + while (*d == '/')
  138. + d++;
  139. + } else
  140. + s += 2;
  141. + break;
  142. }
  143. - safestrcpymax(target, temp_path, len);
  144. + s--;
  145. + }
  146. + if (s < devdir || *(s+1) == '\0')
  147. + break;
  148. }
  149. +
  150. + /*
  151. + * appending to devdir a slash and the (possibly shortened)
  152. + * relative path to the link source
  153. + */
  154. + s++;
  155. + if (s > devdir && *s == '\0')
  156. + *s++ = '/';
  157. + *s = '\0';
  158. + safestrcpymax(s, d, SYSFS_PATH_MAX-(s-devdir));
  159. + safestrcpymax(target, devdir, len);
  160. return 0;
  161. }