diff options
Diffstat (limited to 'winsup/utils/path.cc')
-rw-r--r-- | winsup/utils/path.cc | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc deleted file mode 100644 index c72cefc..0000000 --- a/winsup/utils/path.cc +++ /dev/null @@ -1,350 +0,0 @@ -/* path.cc - - Copyright 2001 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -/* The purpose of this file is to hide all the details about accessing - Cygwin's mount table. If the format or location of the mount table - changes, this is the file to change to match it. */ - -#include <windows.h> -#include <stdio.h> -#include <stdlib.h> -#include <cygwin/version.h> -#include <sys/mount.h> -#include <mntent.h> - -/* Used when treating / and \ as equivalent. */ -#define SLASH_P(ch) \ - ({ \ - char __c = (ch); \ - ((__c) == '/' || (__c) == '\\'); \ - }) - - -static struct mnt - { - const char *native; - char *posix; - unsigned flags; - int issys; - } mount_table[255]; - -struct mnt *root_here = NULL; - -static char * -find2 (HKEY rkey, unsigned *flags, char *what) -{ - char *retval = 0; - DWORD retvallen = 0; - DWORD type; - HKEY key; - - if (RegOpenKeyEx (rkey, what, 0, KEY_READ, &key) != ERROR_SUCCESS) - return 0; - - if (RegQueryValueEx (key, "native", 0, &type, 0, &retvallen) - == ERROR_SUCCESS) - { - retval = (char *) malloc (MAX_PATH + 1); - if (RegQueryValueEx (key, "native", 0, &type, (BYTE *) retval, &retvallen) - != ERROR_SUCCESS) - { - free (retval); - retval = 0; - } - } - - retvallen = sizeof (flags); - RegQueryValueEx (key, "flags", 0, &type, (BYTE *)flags, &retvallen); - - RegCloseKey (key); - - return retval; -} - -static LONG -get_cygdrive0 (HKEY key, const char *what, void *val, DWORD len) -{ - LONG status = RegQueryValueEx (key, what, 0, 0, (BYTE *)val, &len); - return status; -} - -static mnt * -get_cygdrive (HKEY key, mnt *m, int issystem) -{ - - if (get_cygdrive0 (key, CYGWIN_INFO_CYGDRIVE_FLAGS, &m->flags, - sizeof (m->flags)) != ERROR_SUCCESS) { - free (m->posix); - return m; - } - get_cygdrive0 (key, CYGWIN_INFO_CYGDRIVE_PREFIX, m->posix, MAX_PATH); - m->native = strdup ("."); - return m + 1; -} - -static void -read_mounts () -{ - DWORD posix_path_size; - int res; - struct mnt *m = mount_table; - DWORD disposition; - char buf[10000]; - - root_here = NULL; - for (mnt *m1 = mount_table; m1->posix; m1++) - { - free (m1->posix); - if (m1->native) - free ((char *) m1->native); - m1->posix = NULL; - } - - /* Loop through subkeys */ - /* FIXME: we would like to not check MAX_MOUNTS but the heap in the - shared area is currently statically allocated so we can't have an - arbitrarily large number of mounts. */ - for (int issystem = 0; issystem <= 1; issystem++) - { - sprintf (buf, "Software\\%s\\%s\\%s", - CYGWIN_INFO_CYGNUS_REGISTRY_NAME, - CYGWIN_INFO_CYGWIN_REGISTRY_NAME, - CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME); - - HKEY key = issystem ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - if (RegCreateKeyEx (key, buf, 0, (LPTSTR) "Cygwin", 0, KEY_READ, - 0, &key, &disposition) != ERROR_SUCCESS) - break; - for (int i = 0; ;i++, m++) - { - m->posix = (char *) malloc (MAX_PATH + 1); - posix_path_size = MAX_PATH; - /* FIXME: if maximum posix_path_size is 256, we're going to - run into problems if we ever try to store a mount point that's - over 256 but is under MAX_PATH. */ - res = RegEnumKeyEx (key, i, m->posix, &posix_path_size, NULL, - NULL, NULL, NULL); - - if (res == ERROR_NO_MORE_ITEMS) - { - m = get_cygdrive (key, m, issystem); - m->posix = NULL; - break; - } - - if (!*m->posix) - goto no_go; - else if (res != ERROR_SUCCESS) - break; - else - { - m->native = find2 (key, &m->flags, m->posix); - m->issys = issystem; - if (!m->native) - goto no_go; - } - continue; - no_go: - free (m->posix); - m->posix = NULL; - m--; - } - RegCloseKey (key); - } -} - -/* Return non-zero if PATH1 is a prefix of PATH2. - Both are assumed to be of the same path style and / vs \ usage. - Neither may be "". - LEN1 = strlen (PATH1). It's passed because often it's already known. - - Examples: - /foo/ is a prefix of /foo <-- may seem odd, but desired - /foo is a prefix of /foo/ - / is a prefix of /foo/bar - / is not a prefix of foo/bar - foo/ is a prefix foo/bar - /foo is not a prefix of /foobar -*/ - -static int -path_prefix_p (const char *path1, const char *path2, int len1) -{ - /* Handle case where PATH1 has trailing '/' and when it doesn't. */ - if (len1 > 0 && SLASH_P (path1[len1 - 1])) - len1--; - - if (len1 == 0) - return SLASH_P (path2[0]) && !SLASH_P (path2[1]); - - if (strncasecmp (path1, path2, len1) != 0) - return 0; - - return SLASH_P (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':'; -} - -static char * -vconcat (const char *s, va_list v) -{ - int len; - char *rv, *arg; - va_list save_v = v; - int unc; - - if (!s) - return 0; - - len = strlen (s); - - unc = SLASH_P (*s) && SLASH_P (s[1]); - - while (1) - { - arg = va_arg (v, char *); - if (arg == 0) - break; - len += strlen (arg); - } - va_end (v); - - rv = (char *) malloc (len + 1); - strcpy (rv, s); - v = save_v; - while (1) - { - arg = va_arg (v, char *); - if (arg == 0) - break; - strcat (rv, arg); - } - va_end (v); - - char *d, *p; - for (p = rv; *p; p++) - if (*p == '\\') - *p = '/'; - - /* concat is only used for urls and files, so we can safely - canonicalize the results */ - for (p = d = rv; *p; p++) - { - *d++ = *p; - /* special case for URLs */ - if (*p == ':' && p[1] == '/' && p[2] == '/' && p > rv + 1) - { - *d++ = *++p; - *d++ = *++p; - } - else if (*p == '/' || *p == '\\') - { - if (p == rv && unc) - p++; - while (p[1] == '/') - p++; - } - } - *d = 0; - - return rv; -} - -static char * -concat (const char *s, ...) -{ - va_list v; - - va_start (v, s); - - return vconcat (s, v); -} - -char * -cygpath (const char *s, ...) -{ - va_list v; - int max_len = -1; - struct mnt *m, *match = NULL; - - if (!mount_table[0].posix) - read_mounts (); - va_start (v, s); - char *path = vconcat (s, v); - if (strncmp (path, "./", 2) == 0) - memmove (path, path + 2, strlen (path + 2) + 1); - if (strncmp (path, "/./", 3) == 0) - memmove (path + 1, path + 3, strlen (path + 3) + 1); - - for (m = mount_table; m->posix ; m++) - { - if (m->flags & MOUNT_CYGDRIVE) - continue; - - int n = strlen (m->posix); - if (n < max_len || !path_prefix_p (m->posix, path, n)) - continue; - max_len = n; - match = m; - } - - char *native; - if (match == NULL) - native = strdup (path); - else if (max_len == (int) strlen (path)) - native = strdup (match->native); - else - native = concat (match->native, "/", path + max_len, NULL); - free (path); - - return native; -} - -static mnt *m = NULL; - -extern "C" FILE * -setmntent (const char *, const char *) -{ - m = mount_table; - if (!m->posix) - read_mounts (); - return NULL; -} - -extern "C" struct mntent * -getmntent (FILE *) -{ - static mntent mnt; - if (!m->posix) - return NULL; - - mnt.mnt_fsname = (char *) m->native; - mnt.mnt_dir = (char *) m->posix; - if (!mnt.mnt_type) - mnt.mnt_type = (char *) malloc (1024); - if (!mnt.mnt_opts) - mnt.mnt_opts = (char *) malloc (1024); - if (!m->issys) - strcpy (mnt.mnt_type, (char *) "user"); - else - strcpy (mnt.mnt_type, (char *) "system"); - if (!(m->flags & MOUNT_BINARY)) - strcpy (mnt.mnt_opts, (char *) "textmode"); - else - strcpy (mnt.mnt_opts, (char *) "binmode"); - if (m->flags & MOUNT_CYGWIN_EXEC) - strcat (mnt.mnt_opts, (char *) ",cygexec"); - else if (m->flags & MOUNT_EXEC) - strcat (mnt.mnt_opts, (char *) ",exec"); - if ((m->flags & MOUNT_CYGDRIVE)) /* cygdrive */ - strcat (mnt.mnt_opts, (char *) ",cygdrive"); - mnt.mnt_freq = 1; - mnt.mnt_passno = 1; - m++; - return &mnt; -} |