Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2001-03-02 14:41:09 +0300
committerCorinna Vinschen <corinna@vinschen.de>2001-03-02 14:41:09 +0300
commite03f5f73381e352469a116d84480427227c04027 (patch)
tree02bffe58a078fc35290478879889dfeb06944569 /winsup/cygwin/shortcut.c
parentd08d72adff5eb5e2c810494043c7104cd9b3aa6c (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.c50
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. */