aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-05-09 11:20:06 +0100
committerRon Yorston <rmy@pobox.com>2012-05-09 15:00:05 +0100
commitf2459f232790aab0434d1cc6471ea62bc193e636 (patch)
tree876d184a89f20b9e23d24020dbb3f6f01b519768 /win32
parent0c9c04defd7b21aab1f18eaabd2f461b6a425964 (diff)
downloadbusybox-w32-f2459f232790aab0434d1cc6471ea62bc193e636.tar.gz
busybox-w32-f2459f232790aab0434d1cc6471ea62bc193e636.tar.bz2
busybox-w32-f2459f232790aab0434d1cc6471ea62bc193e636.zip
mingw32: make access(2) check file format for executables
Diffstat (limited to 'win32')
-rw-r--r--win32/mingw.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index be08c5bd5..a6c969596 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -225,7 +225,8 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
225 buf->st_uid = 0; 225 buf->st_uid = 0;
226 buf->st_nlink = 1; 226 buf->st_nlink = 1;
227 buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); 227 buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
228 if (len > 4 && !strcmp(file_name+len-4, ".exe")) 228 if (len > 4 && (!strcasecmp(file_name+len-4, ".exe") ||
229 !strcasecmp(file_name+len-4, ".com")))
229 buf->st_mode |= S_IEXEC; 230 buf->st_mode |= S_IEXEC;
230 buf->st_size = fdata.nFileSizeLow | 231 buf->st_size = fdata.nFileSizeLow |
231 (((off64_t)fdata.nFileSizeHigh)<<32); 232 (((off64_t)fdata.nFileSizeHigh)<<32);
@@ -762,3 +763,70 @@ char *strptime(const char *s UNUSED_PARAM, const char *format UNUSED_PARAM, stru
762{ 763{
763 return NULL; 764 return NULL;
764} 765}
766
767#undef access
768int mingw_access(const char *name, int mode)
769{
770 int ret;
771 struct stat s;
772 int fd, n, offset, sig;
773 unsigned char buf[1024];
774
775 /* Windows can only handle test for existence, read or write */
776 if (mode == F_OK || (mode & ~X_OK)) {
777 ret = _access(name, mode & ~X_OK);
778 if (ret < 0 || !(mode & X_OK)) {
779 return ret;
780 }
781 }
782
783 if (!mingw_stat(name, &s) && S_ISREG(s.st_mode)) {
784
785 /* stat marks .exe and .com files as executable */
786 if ((s.st_mode&S_IEXEC)) {
787 return 0;
788 }
789
790 fd = open(name, O_RDONLY);
791 if (fd < 0)
792 return -1;
793 n = read(fd, buf, sizeof(buf)-1);
794 close(fd);
795 if (n < 4) /* at least '#!/x' and not error */
796 return -1;
797
798 /* shell script */
799 if (buf[0] == '#' && buf[1] == '!') {
800 return 0;
801 }
802
803 /*
804 * Poke about in file to see if it's a PE binary. I've just copied
805 * the magic from the file command.
806 */
807 if (buf[0] == 'M' && buf[1] == 'Z') {
808 offset = (buf[0x19] << 8) + buf[0x18];
809 if (offset > 0x3f) {
810 offset = (buf[0x3f] << 24) + (buf[0x3e] << 16) +
811 (buf[0x3d] << 8) + buf[0x3c];
812 if (offset < sizeof(buf)-100) {
813 if (memcmp(buf+offset, "PE\0\0", 4) == 0) {
814 sig = (buf[offset+25] << 8) + buf[offset+24];
815 if (sig == 0x10b || sig == 0x20b) {
816 sig = (buf[offset+23] << 8) + buf[offset+22];
817 if ((sig & 0x2000) != 0) {
818 /* DLL */
819 return -1;
820 }
821 sig = buf[offset+92];
822 return !(sig == 1 || sig == 2 ||
823 sig == 3 || sig == 7);
824 }
825 }
826 }
827 }
828 }
829 }
830
831 return -1;
832}