+ /*
+ * 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 '.':
+ /*
+ * 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;
+ /*
+ * relative path
+ * getting rid of leading "../.."
+ */
+parse_path:
+ while (*d == '/' || *d == '.') {
+ if (*d == '/')
+ slashes++;
+ d++;
+ }
+ d--;
+ s = &devdir[strlen(devdir)-1];
+ while (s != NULL && count != (slashes+1)) {
+ s--;
+ if (*s == '/')
+ count++;
+ }
+ 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);
+ }
+ safestrcpymax(target, temp_path, len);