2012-03-12 3 views
2

Я хотел бы знать, как абсолютный путь символической ссылки может быть преобразован в относительный на основе заданного каталога (включая связанный файл) на языке c на linux (Ubuntu) ОПЕРАЦИОННЫЕ СИСТЕМЫ.Как преобразовать абсолютный путь в относительный в c linux

Я думал о поиске подстроки относительного пути, но что, если он уже существует выше в иерархии папки?

Вот более конкретное описание того, что я хочу сделать: Относительный путь:

folder/folder1/folder2 

Absolut путь:

/home/giorgos/Desktop/folder/folder1/folder2/a.pdf 

изменен

/home/giorgos/Desktop/myfolder/folder1/folder2/a.pdf 

Очевидно, что я не могу «просто найдите и замените« папку/», рассмотрите этот случай:

/home/giorgos/Desktop/folder/folder/folder/folder1/folder2/a.pdf 

Это можно искать как вперед и назад, и если заменить это все еще дает неправильный вывод Только если я знал, что относительный путь, который я мог бы поиск абсолюта назад и заменить его, то результат будет правильным:

/home/giorgos/Desktop/folder/myfolder/folder/folder1/folder2/a.pdf 
+1

по отношению к чему? Текущий каталог? –

+0

Да, относительная директория текущего каталога, я постараюсь быть более конкретным –

+1

Я не знаю никакого общего, предварительно написанного кода, который сделает это; каков контекст этой проблемы? Возможно, будет хорошее решение, которое не обязательно будет идти по этому маршруту. – sarnold

ответ

1

Мне было бы очень сложно принять решение, если бы я писал этот инструмент, что абсолютные символические ссылки должны иметь одинаковое значение при перемещении в другое место в файловой системе - пользователю нужен очень конкретный файл. И относительные символические ссылки должны иметь одинаковое значение при перемещении где-то еще в файловой системе - пользователь хотел, чтобы ссылки работали независимо от того, где было внедрено дерево каталогов.

Но если бы два типа ссылок были перемешаны, тогда вам нужно было бы еще поработать - вот где я предполагаю, что вы сейчас. (Программы Unix часто не то, что прощающие о угадывании намерения пользователя, если вы просто readlink(2) и symlink(2) именно то, что говорит, что файловая система, ваша программа никогда не будете удивительно.)

rsync(1) может иметь некоторый исходный код, который можно использовать - - или, по крайней мере, учиться. Параметр командной строки --safe-links вызывает rsync: ignore Абсолютные символические ссылки и относительные символические ссылки, которые указывают за пределами деревьев, было дано указание скопировать. Это не канонические пути к относительным, как вы пожелаете, но может предоставить достаточный код для обнаружения, какие ссылки указывают за пределами рассматриваемого дерева каталогов.

Немного связанных; системный вызов symlinkat(2) для Linux может облегчить вам создание ваших символических ссылок.(Семейство системных вызовов ...at() - это что-то вроде предоставления процесса с несколькими «текущими рабочими каталогами», не заставляя вас делать все звонки fchdir(2).)

+0

Спасибо, я посмотрю. На самом деле на данный момент меня не интересуют символические ссылки за пределами дерева каталогов –

3

Преобразование путь к относительному является предметом первой видеть, сколько атомов базы распределяются между двумя путями, а затем вставив ../ перемещаться в обратном направлении вверх по дереву Прежде чем перейти вниз правильную ветку. IE, идущий от: /foo/bar/some/path до /foo/other/path, вы сначала увидите, что они делят/foo, чтобы перейти вверх к этой точке, вам нужно 3 ../, повернув относительный путь в /foo/../../../other/path. Существует пример boost :: filesystem для C++ here, за исключением C++ & boost :: filesystem то же самое можно сделать в C.

+0

Все еще, если пути похожи на/foo/bar/one/foo и вы собираетесь foo/bar/one/foo/onemore, тогда вы остановитесь при первом встречном foo. Я прав? –

+0

Нет, продолжайте. В приведенном выше примере, если вы собираетесь перейти от первого ко второму, вы увидите, что все первое является общим со вторым, поэтому результат просто «onemore». Атомы не обязательно должны быть уникальными во всем дереве каталогов, это сама ветвь, которая является UID для пути. – Ylisar

0

Вначале я не считал следующую важную информацию, но с помощью функции я обнаружил абсолютный путь к оригинальным и скопированным каталогам.

Таким образом, я мог бы, наконец, получить папку оригинала «относительный путь» (путь, начиная с исходной папки), изменить корень узла дерева дерева в скопированную папку, а затем получить абсолютный путь скопированной папки и добавить скопированный «относительный путь», и все!

realpath(directory,absolutePath); 

Это то, что мой код выглядит следующим образом:

readlink(A[i].str, oldLink, NAMESIZE);//A is the struct I keep the paths to directory entries 
k=0; 
j=strlen(absolutPath); 
while(oldLink[j]!='\0') 
{ 
    fixLink[k]=oldLink[j]; 
    j++; 
    k++; 
} 
strcpy(tmpLink,newAbsolutPath); 
strcat(tmpLink,fixLink); 
symlink (tmpLink,tmpPath);//tmpPath is the name of the link, tmp link is the absolute path to the actual file 
//tmpPath is built almost the same way 

До сих пор она работает без каких-либо ошибок