- if (!home || g_access(home, W_OK))
- /* Fatal error */
- g_critical("Unable to find a base directory");
-
- /* Build the name of the directory */
- viking_dir = g_build_filename(home, ".viking", NULL);
- if (g_file_test(viking_dir, G_FILE_TEST_EXISTS) == FALSE)
- g_mkdir(viking_dir, 0755);
+
+// Given the absolute current directory and an absolute file name, returns a relative file name.
+// For example, if the current directory is C:\foo\bar and the filename C:\foo\whee\text.txt is given,
+// GetRelativeFilename will return ..\whee\text.txt.
+
+const gchar *file_GetRelativeFilename ( gchar *currentDirectory, gchar *absoluteFilename )
+{
+ gint afMarker = 0, rfMarker = 0;
+ gint cdLen = 0, afLen = 0;
+ gint i = 0;
+ gint levels = 0;
+ static gchar relativeFilename[MAXPATHLEN+1];
+
+ cdLen = strlen(currentDirectory);
+ afLen = strlen(absoluteFilename);
+
+ // make sure the names are not too long or too short
+ if (cdLen > MAXPATHLEN || cdLen < ABSOLUTE_NAME_START+1 ||
+ afLen > MAXPATHLEN || afLen < ABSOLUTE_NAME_START+1) {
+ return NULL;
+ }
+
+ // Handle DOS names that are on different drives:
+ if (currentDirectory[0] != absoluteFilename[0]) {
+ // not on the same drive, so only absolute filename will do
+ strcpy(relativeFilename, absoluteFilename);
+ return relativeFilename;
+ }
+
+ // they are on the same drive, find out how much of the current directory
+ // is in the absolute filename
+ i = ABSOLUTE_NAME_START;
+ while (i < afLen && i < cdLen && currentDirectory[i] == absoluteFilename[i]) {
+ i++;
+ }
+
+ if (i == cdLen && (absoluteFilename[i] == G_DIR_SEPARATOR || absoluteFilename[i-1] == G_DIR_SEPARATOR)) {
+ // the whole current directory name is in the file name,
+ // so we just trim off the current directory name to get the
+ // current file name.
+ if (absoluteFilename[i] == G_DIR_SEPARATOR) {
+ // a directory name might have a trailing slash but a relative
+ // file name should not have a leading one...
+ i++;
+ }
+
+ strcpy(relativeFilename, &absoluteFilename[i]);
+ return relativeFilename;
+ }
+
+ // The file is not in a child directory of the current directory, so we
+ // need to step back the appropriate number of parent directories by
+ // using "..\"s. First find out how many levels deeper we are than the
+ // common directory
+ afMarker = i;
+ levels = 1;
+
+ // count the number of directory levels we have to go up to get to the
+ // common directory
+ while (i < cdLen) {
+ i++;
+ if (currentDirectory[i] == G_DIR_SEPARATOR) {
+ // make sure it's not a trailing slash
+ i++;
+ if (currentDirectory[i] != '\0') {
+ levels++;
+ }
+ }