diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-03-02 14:41:09 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-03-02 14:41:09 +0300 |
commit | e03f5f73381e352469a116d84480427227c04027 (patch) | |
tree | 02bffe58a078fc35290478879889dfeb06944569 /winsup/cygwin/shortcut.c | |
parent | d08d72adff5eb5e2c810494043c7104cd9b3aa6c (diff) |
* dir.cc (readdir): Fix shortcut==symlink condition.
* environ.cc: Add extern decl for `allow_winsymlinks'.
(struct parse_thing): Add entry for `[no]winsymlinks'.
* path.cc (symlink): Change to be able to create both,
symlink==shortcut and symlink==systemfile, dependent of
the setting of `allow_winsymlinks'.
* security.cc (cygwin_logon_user): Add debug output.
* shortcut.c: Add defines from path.h.
(has_exec_chars): Copy from path.h.
(check_shortcut): Check for executable file condition if not a
shortcut.
Diffstat (limited to 'winsup/cygwin/shortcut.c')
-rw-r--r-- | winsup/cygwin/shortcut.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/winsup/cygwin/shortcut.c b/winsup/cygwin/shortcut.c index 5f632f01c..6851f1274 100644 --- a/winsup/cygwin/shortcut.c +++ b/winsup/cygwin/shortcut.c @@ -18,8 +18,24 @@ details. */ #include <errno.h> #include "shortcut.h" +/* TODO: + Currently duplicated from path.h. Later rearrangement of path.h + to allow including from plain C would be better. */ /* This is needed to avoid including path.h which is a pure C++ header. */ -#define PATH_SYMLINK MOUNT_SYMLINK +#define PATH_SYMLINK MOUNT_SYMLINK +#define PATH_EXEC MOUNT_EXEC +#define PATH_CYGWIN_EXEC MOUNT_CYGWIN_EXEC +#define PATH_ALL_EXEC PATH_CYGWIN_EXEC | PATH_EXEC + +/* TODO: Ditto. */ +static BOOL +has_exec_chars (const char *buf, int len) +{ + return len >= 2 && + ((buf[0] == '#' && buf[1] == '!') || + (buf[0] == ':' && buf[1] == '\n') || + (buf[0] == 'M' && buf[1] == 'Z')); +} char shortcut_header[SHORTCUT_HDR_SIZE]; BOOL shortcut_initalized = FALSE; @@ -57,9 +73,11 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, IPersistFile *ppf = NULL; WCHAR wc_path[MAX_PATH]; char full_path[MAX_PATH]; + char file_header[SHORTCUT_HDR_SIZE]; WIN32_FIND_DATA wfd; DWORD len = 0; int res = 0; + DWORD got = 0; /* Initialize COM library. */ CoInitialize (NULL); @@ -78,24 +96,22 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, hres = ppf->lpVtbl->Load (ppf, wc_path, STGM_READ); if (FAILED (hres)) goto close_it; + /* Read the files header information. This is used to check for a + Cygwin or U/WIN shortcut or later to check for executable files. */ + if (! ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0)) + { + *error = EIO; + goto close_it; + } /* Try the description (containing a POSIX path) first. */ if (fileattr & FILE_ATTRIBUTE_READONLY) { - /* An additional check is needed to prove if it's a shortcut - really created by Cygwin or U/WIN. */ - char file_header[SHORTCUT_HDR_SIZE]; - DWORD got; - - if (! ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0)) - { - *error = EIO; - goto close_it; - } + /* Check header if the shortcut is really created by Cygwin or U/WIN. */ if (got == SHORTCUT_HDR_SIZE && !cmp_shortcut_header (file_header)) { hres = psl->lpVtbl->GetDescription (psl, contents, MAX_PATH); if (FAILED (hres)) - goto close_it; + goto file_not_symlink; len = strlen (contents); } } @@ -119,15 +135,21 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, /* Set relative path inside of IShellLink interface. */ hres = psl->lpVtbl->SetRelativePath (psl, full_path, 0); if (FAILED (hres)) - goto close_it; + goto file_not_symlink; /* Get the path to the shortcut target. */ hres = psl->lpVtbl->GetPath (psl, contents, MAX_PATH, &wfd, 0); if (FAILED(hres)) - goto close_it; + goto file_not_symlink; } res = strlen (contents); if (res) /* It's a symlink. */ *pflags = PATH_SYMLINK; + goto close_it; + +file_not_symlink: + /* Not a symlink, see if executable. */ + if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (file_header, got)) + *pflags |= PATH_EXEC; close_it: /* Release the pointer to IPersistFile. */ |