123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- diff -upr sysfsutils-2.1.0-old/lib/sysfs_utils.c sysfsutils-2.1.0/lib/sysfs_utils.c
- --- sysfsutils-2.1.0-old/lib/sysfs_utils.c 2006-08-07 07:08:01.000000000 +0200
- +++ sysfsutils-2.1.0/lib/sysfs_utils.c 2008-05-13 07:42:50.000000000 +0200
- @@ -117,84 +117,104 @@ int sysfs_get_link(const char *path, cha
- {
- char devdir[SYSFS_PATH_MAX];
- char linkpath[SYSFS_PATH_MAX];
- - char temp_path[SYSFS_PATH_MAX];
- - char *d = NULL, *s = NULL;
- - int slashes = 0, count = 0;
- + char *d, *s;
- + int count;
-
- if (!path || !target || len == 0) {
- errno = EINVAL;
- return -1;
- }
-
- - memset(devdir, 0, SYSFS_PATH_MAX);
- - memset(linkpath, 0, SYSFS_PATH_MAX);
- - memset(temp_path, 0, SYSFS_PATH_MAX);
- - safestrcpy(devdir, path);
- -
- - if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) {
- + count = readlink(path, linkpath, SYSFS_PATH_MAX);
- + if (count < 0)
- return -1;
- - }
- - d = linkpath;
- + else
- + linkpath[count] = '\0';
- /*
- * Three cases here:
- * 1. relative path => format ../..
- * 2. absolute path => format /abcd/efgh
- * 3. relative path _from_ this dir => format abcd/efgh
- */
- - switch (*d) {
- - case '.':
- + if (*linkpath == '/') {
- + /* absolute path - copy as is */
- + safestrcpymax(target, linkpath, len);
- + return 0;
- + }
- +
- + safestrcpy(devdir, path);
- + s = strrchr(devdir, '/');
- + if (s == NULL)
- + s = devdir - 1;
- + d = linkpath;
- + while (*d == '.') {
- + if (*(d+1) == '/') {
- /*
- * handle the case where link is of type ./abcd/xxx
- */
- - safestrcpy(temp_path, devdir);
- - if (*(d+1) == '/')
- - d += 2;
- - else if (*(d+1) == '.')
- - goto parse_path;
- - s = strrchr(temp_path, '/');
- - if (s != NULL) {
- - *(s+1) = '\0';
- - safestrcat(temp_path, d);
- - } else {
- - safestrcpy(temp_path, d);
- - }
- - safestrcpymax(target, temp_path, len);
- - break;
- + d += 2;
- + while (*d == '/')
- + d++;
- + continue;
- + } else if (*(d+1) != '.' || *(d+2) != '/')
- /*
- - * relative path, getting rid of leading "../.."
- + * relative path from this directory, starting
- + * with a hidden directory
- */
- -parse_path:
- - while (*d == '/' || *d == '.') {
- - if (*d == '/')
- - slashes++;
- - d++;
- - }
- - d--;
- - s = &devdir[strlen(devdir)-1];
- - while (s != NULL && count != (slashes+1)) {
- + break;
- +
- + /*
- + * relative path, getting rid of leading "../.."; must
- + * be careful here since any path component of devdir
- + * could be a symlink again
- + */
- + for (;;) {
- + while (s > devdir && *s == '/') {
- s--;
- - if (*s == '/')
- - count++;
- + if (*s == '.'
- + && (s == devdir || *(s-1) == '/'))
- + s--;
- }
- - safestrcpymax(s, d, (SYSFS_PATH_MAX-strlen(devdir)));
- - safestrcpymax(target, devdir, len);
- - break;
- - case '/':
- - /* absolute path - copy as is */
- - safestrcpymax(target, linkpath, len);
- - break;
- - default:
- - /* relative path from this directory */
- - safestrcpy(temp_path, devdir);
- - s = strrchr(temp_path, '/');
- - if (s != NULL) {
- - *(s+1) = '\0';
- - safestrcat(temp_path, linkpath);
- - } else {
- - safestrcpy(temp_path, linkpath);
- + *(s+1) = '\0';
- + if (*devdir == '\0' || sysfs_path_is_link(devdir))
- + /*
- + * condition will be true eventually
- + * because we already know that all
- + * but the last component of path
- + * resolve to a directory
- + */
- + break;
- + if (sysfs_get_link(devdir, devdir, SYSFS_PATH_MAX))
- + return -1;
- + s = devdir + strlen(devdir) - 1;
- + }
- + while (s >= devdir) {
- + if (*s == '/') {
- + if (*(s+1) != '.' || *(s+2) != '.'
- + || *(s+3) != '\0') {
- + d += 3;
- + while (*d == '/')
- + d++;
- + } else
- + s += 2;
- + break;
- }
- - safestrcpymax(target, temp_path, len);
- + s--;
- + }
- + if (s < devdir || *(s+1) == '\0')
- + break;
- }
- +
- + /*
- + * appending to devdir a slash and the (possibly shortened)
- + * relative path to the link source
- + */
- + s++;
- + if (s > devdir && *s == '\0')
- + *s++ = '/';
- + *s = '\0';
- + safestrcpymax(s, d, SYSFS_PATH_MAX-(s-devdir));
- + safestrcpymax(target, devdir, len);
- return 0;
- }
-
|