annotate msdos/is_exec.c @ 36150:46e59561af4c

Display Vars node renamed Display Custom. Include info there about customizing cursor appearance. Clean up aggressive scrolling. Clarify horizontal scrolling discussion. Fix index entries for line number mode.
author Richard M. Stallman <rms@gnu.org>
date Sat, 17 Feb 2001 16:45:37 +0000
parents 354e0c45cedf
children 695cf19ef79e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25856
Dave Love <fx@gnu.org>
parents:
diff changeset
1 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
Dave Love <fx@gnu.org>
parents:
diff changeset
2 /* IS_EXEC.C
Dave Love <fx@gnu.org>
parents:
diff changeset
3 *
Dave Love <fx@gnu.org>
parents:
diff changeset
4 * Given a filename or a file handle, and the extension of the file,
Dave Love <fx@gnu.org>
parents:
diff changeset
5 * determine if the file is executable.
Dave Love <fx@gnu.org>
parents:
diff changeset
6 * First, the file extension is checked in case it uniquely identifies
Dave Love <fx@gnu.org>
parents:
diff changeset
7 * the file as either an executable or not. Failing this, the first
Dave Love <fx@gnu.org>
parents:
diff changeset
8 * two bytes of the file are tested for known signatures of executable
Dave Love <fx@gnu.org>
parents:
diff changeset
9 * files.
Dave Love <fx@gnu.org>
parents:
diff changeset
10 *
Dave Love <fx@gnu.org>
parents:
diff changeset
11 * Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il>
Dave Love <fx@gnu.org>
parents:
diff changeset
12 *
Dave Love <fx@gnu.org>
parents:
diff changeset
13 * This software may be used freely so long as this copyright notice is
Dave Love <fx@gnu.org>
parents:
diff changeset
14 * left intact. There is no warranty on this software.
Dave Love <fx@gnu.org>
parents:
diff changeset
15 *
Dave Love <fx@gnu.org>
parents:
diff changeset
16 */
Dave Love <fx@gnu.org>
parents:
diff changeset
17
Dave Love <fx@gnu.org>
parents:
diff changeset
18 #include <libc/stubs.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
19 #include <stdio.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
20 #include <string.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
21 #include <ctype.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
22 #include <errno.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
23 #include <dpmi.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
24 #include <go32.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
25 #include <io.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
26 #include <libc/farptrgs.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
27 #include <libc/dosio.h>
Dave Love <fx@gnu.org>
parents:
diff changeset
28
Dave Love <fx@gnu.org>
parents:
diff changeset
29 extern unsigned short _djstat_flags;
Dave Love <fx@gnu.org>
parents:
diff changeset
30 unsigned short _get_magic(const char *, int);
Dave Love <fx@gnu.org>
parents:
diff changeset
31 int _is_executable(const char *, int, const char *);
Dave Love <fx@gnu.org>
parents:
diff changeset
32
Dave Love <fx@gnu.org>
parents:
diff changeset
33 /*
Dave Love <fx@gnu.org>
parents:
diff changeset
34 * Read a MAGIC NUMBER from a given file. These are the first
Dave Love <fx@gnu.org>
parents:
diff changeset
35 * two bytes of the file, if we look at them as an unsigned short. */
Dave Love <fx@gnu.org>
parents:
diff changeset
36
Dave Love <fx@gnu.org>
parents:
diff changeset
37 #define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */
Dave Love <fx@gnu.org>
parents:
diff changeset
38 #define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */
Dave Love <fx@gnu.org>
parents:
diff changeset
39
Dave Love <fx@gnu.org>
parents:
diff changeset
40 unsigned short
Dave Love <fx@gnu.org>
parents:
diff changeset
41 _get_magic(const char *s, int fh)
Dave Love <fx@gnu.org>
parents:
diff changeset
42 {
Dave Love <fx@gnu.org>
parents:
diff changeset
43 __dpmi_regs regs;
Dave Love <fx@gnu.org>
parents:
diff changeset
44 unsigned short retval;
Dave Love <fx@gnu.org>
parents:
diff changeset
45 unsigned short fpos_high = 0, fpos_low = 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
46 int read_fail = 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
47
Dave Love <fx@gnu.org>
parents:
diff changeset
48 /* If given a pathname, open the file. */
Dave Love <fx@gnu.org>
parents:
diff changeset
49 if (s)
Dave Love <fx@gnu.org>
parents:
diff changeset
50 {
Dave Love <fx@gnu.org>
parents:
diff changeset
51 int handle;
Dave Love <fx@gnu.org>
parents:
diff changeset
52 if((handle = _open(s,0)) == -1)
Dave Love <fx@gnu.org>
parents:
diff changeset
53 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
54 regs.x.bx = handle;
Dave Love <fx@gnu.org>
parents:
diff changeset
55 }
Dave Love <fx@gnu.org>
parents:
diff changeset
56 /* Else file already open. Remember its current file position
Dave Love <fx@gnu.org>
parents:
diff changeset
57 and move to beginning of file. */
Dave Love <fx@gnu.org>
parents:
diff changeset
58 else
Dave Love <fx@gnu.org>
parents:
diff changeset
59 {
Dave Love <fx@gnu.org>
parents:
diff changeset
60 regs.x.ax = 0x4201; /* set pointer from current position */
Dave Love <fx@gnu.org>
parents:
diff changeset
61 regs.x.bx = fh;
Dave Love <fx@gnu.org>
parents:
diff changeset
62 regs.x.cx = regs.x.dx = 0; /* move 0 bytes (i.e., stay put) */
Dave Love <fx@gnu.org>
parents:
diff changeset
63 __dpmi_int(0x21, &regs);
Dave Love <fx@gnu.org>
parents:
diff changeset
64 if (regs.x.flags & 1)
Dave Love <fx@gnu.org>
parents:
diff changeset
65 {
Dave Love <fx@gnu.org>
parents:
diff changeset
66 errno = __doserr_to_errno(regs.x.ax);
Dave Love <fx@gnu.org>
parents:
diff changeset
67 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
68 }
Dave Love <fx@gnu.org>
parents:
diff changeset
69 fpos_high = regs.x.dx; /* got current position */
Dave Love <fx@gnu.org>
parents:
diff changeset
70 fpos_low = regs.x.ax;
Dave Love <fx@gnu.org>
parents:
diff changeset
71
Dave Love <fx@gnu.org>
parents:
diff changeset
72 regs.x.ax = 0x4200; /* set pointer from the beginning of file */
Dave Love <fx@gnu.org>
parents:
diff changeset
73 regs.x.cx = regs.x.dx = 0; /* move to beginning of file */
Dave Love <fx@gnu.org>
parents:
diff changeset
74 __dpmi_int(0x21, &regs);
Dave Love <fx@gnu.org>
parents:
diff changeset
75 if (regs.x.flags & 1)
Dave Love <fx@gnu.org>
parents:
diff changeset
76 {
Dave Love <fx@gnu.org>
parents:
diff changeset
77 errno = __doserr_to_errno(regs.x.ax);
Dave Love <fx@gnu.org>
parents:
diff changeset
78 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
79 }
Dave Love <fx@gnu.org>
parents:
diff changeset
80 }
Dave Love <fx@gnu.org>
parents:
diff changeset
81 regs.x.ds = __tb_segment;
Dave Love <fx@gnu.org>
parents:
diff changeset
82 regs.x.dx = __tb_offset;
Dave Love <fx@gnu.org>
parents:
diff changeset
83
Dave Love <fx@gnu.org>
parents:
diff changeset
84 /* Read 2 bytes from the file. */
Dave Love <fx@gnu.org>
parents:
diff changeset
85 regs.x.ax = 0x3f00;
Dave Love <fx@gnu.org>
parents:
diff changeset
86 regs.x.cx = 2;
Dave Love <fx@gnu.org>
parents:
diff changeset
87 __dpmi_int(0x21, &regs);
Dave Love <fx@gnu.org>
parents:
diff changeset
88
Dave Love <fx@gnu.org>
parents:
diff changeset
89 /* We can either (1) succeed, (2) read less than 2 bytes,
Dave Love <fx@gnu.org>
parents:
diff changeset
90 or (3) fail to read at all. */
Dave Love <fx@gnu.org>
parents:
diff changeset
91 if (regs.x.ax != 2)
Dave Love <fx@gnu.org>
parents:
diff changeset
92 read_fail = (regs.x.flags & 1) ? regs.x.ax : -1;
Dave Love <fx@gnu.org>
parents:
diff changeset
93
Dave Love <fx@gnu.org>
parents:
diff changeset
94 /* If called with filename, close the file. */
Dave Love <fx@gnu.org>
parents:
diff changeset
95 if (s)
Dave Love <fx@gnu.org>
parents:
diff changeset
96 {
Dave Love <fx@gnu.org>
parents:
diff changeset
97 regs.x.ax = 0x3e00;
Dave Love <fx@gnu.org>
parents:
diff changeset
98 __dpmi_int(0x21, &regs);
Dave Love <fx@gnu.org>
parents:
diff changeset
99 if (regs.x.flags & 1)
Dave Love <fx@gnu.org>
parents:
diff changeset
100 errno = __doserr_to_errno(regs.x.ax);
Dave Love <fx@gnu.org>
parents:
diff changeset
101 }
Dave Love <fx@gnu.org>
parents:
diff changeset
102 /* Else leave file pointer where we found it. */
Dave Love <fx@gnu.org>
parents:
diff changeset
103 else
Dave Love <fx@gnu.org>
parents:
diff changeset
104 {
Dave Love <fx@gnu.org>
parents:
diff changeset
105 regs.x.ax = 0x4200; /* set pointer from the beginning of file */
Dave Love <fx@gnu.org>
parents:
diff changeset
106 regs.x.bx = fh;
Dave Love <fx@gnu.org>
parents:
diff changeset
107 regs.x.cx = fpos_high;
Dave Love <fx@gnu.org>
parents:
diff changeset
108 regs.x.dx = fpos_low;
Dave Love <fx@gnu.org>
parents:
diff changeset
109 __dpmi_int(0x21, &regs);
Dave Love <fx@gnu.org>
parents:
diff changeset
110 if (regs.x.flags & 1)
Dave Love <fx@gnu.org>
parents:
diff changeset
111 {
Dave Love <fx@gnu.org>
parents:
diff changeset
112 errno = __doserr_to_errno(regs.x.ax);
Dave Love <fx@gnu.org>
parents:
diff changeset
113 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
114 }
Dave Love <fx@gnu.org>
parents:
diff changeset
115 }
Dave Love <fx@gnu.org>
parents:
diff changeset
116
Dave Love <fx@gnu.org>
parents:
diff changeset
117 if (read_fail == 0)
Dave Love <fx@gnu.org>
parents:
diff changeset
118 retval = _farpeekw(_dos_ds, __tb);
Dave Love <fx@gnu.org>
parents:
diff changeset
119 else
Dave Love <fx@gnu.org>
parents:
diff changeset
120 {
Dave Love <fx@gnu.org>
parents:
diff changeset
121 /* The file couldn't be read: assume non-executable. If the file
Dave Love <fx@gnu.org>
parents:
diff changeset
122 *is* executable, but was passed as a file-handle, and the user
Dave Love <fx@gnu.org>
parents:
diff changeset
123 opened it in write-only mode, they lose... */
Dave Love <fx@gnu.org>
parents:
diff changeset
124 retval = 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
125 if (read_fail != -1)
Dave Love <fx@gnu.org>
parents:
diff changeset
126 errno = __doserr_to_errno(read_fail);
Dave Love <fx@gnu.org>
parents:
diff changeset
127 }
Dave Love <fx@gnu.org>
parents:
diff changeset
128
Dave Love <fx@gnu.org>
parents:
diff changeset
129 return retval;
Dave Love <fx@gnu.org>
parents:
diff changeset
130 }
Dave Love <fx@gnu.org>
parents:
diff changeset
131
Dave Love <fx@gnu.org>
parents:
diff changeset
132 /* A list of extensions which designate executable files. These
Dave Love <fx@gnu.org>
parents:
diff changeset
133 are NOT tested for the magic number. */
Dave Love <fx@gnu.org>
parents:
diff changeset
134 static char executables[] = "|EXE|COM|BAT|BTM|DLL|VXD|";
Dave Love <fx@gnu.org>
parents:
diff changeset
135
Dave Love <fx@gnu.org>
parents:
diff changeset
136 /* A list of extensions which belong to files known to NEVER be
Dave Love <fx@gnu.org>
parents:
diff changeset
137 executables. These exist to minimize read()'ing files while
Dave Love <fx@gnu.org>
parents:
diff changeset
138 detecting executables by magic number. You are welcome to
Dave Love <fx@gnu.org>
parents:
diff changeset
139 add to this list, but remember: only extensions which could
Dave Love <fx@gnu.org>
parents:
diff changeset
140 NEVER be present in executables should go here. */
Dave Love <fx@gnu.org>
parents:
diff changeset
141 static char non_executables[] = "\
Dave Love <fx@gnu.org>
parents:
diff changeset
142 |A|A01|A02|A03|A04|A05|ADL|ARC|ARJ|ASC|ASM|AUX|AWK\
Dave Love <fx@gnu.org>
parents:
diff changeset
143 |BAS|BIB|BGI|BMP\
Dave Love <fx@gnu.org>
parents:
diff changeset
144 |C|CC|CFG|CGZ|CH3|CHR|CI|CLP|CMF|CPI|CPP|CXX\
Dave Love <fx@gnu.org>
parents:
diff changeset
145 |DAT|DBF|DIZ|DOC|DVI\
Dave Love <fx@gnu.org>
parents:
diff changeset
146 |E|EL|ELC\
Dave Love <fx@gnu.org>
parents:
diff changeset
147 |F77|FN3\
Dave Love <fx@gnu.org>
parents:
diff changeset
148 |GIF|GZ\
Dave Love <fx@gnu.org>
parents:
diff changeset
149 |H|HLP|HPP|HXX\
Dave Love <fx@gnu.org>
parents:
diff changeset
150 |ICO|IN|INC|INF|INI\
Dave Love <fx@gnu.org>
parents:
diff changeset
151 |JPG\
Dave Love <fx@gnu.org>
parents:
diff changeset
152 |L|LEX|LF|LIB|LOG|LST|LZH\
Dave Love <fx@gnu.org>
parents:
diff changeset
153 |M|MAK|MAP|MF|MID|MPG\
Dave Love <fx@gnu.org>
parents:
diff changeset
154 |O|OBJ\
Dave Love <fx@gnu.org>
parents:
diff changeset
155 |PAK|PAS|PBM|PCD|PCX|PDS|PIC|PIF|PN3|PRJ|PS\
Dave Love <fx@gnu.org>
parents:
diff changeset
156 |RAS|RGB|RLE\
Dave Love <fx@gnu.org>
parents:
diff changeset
157 |S|SND|SY3\
Dave Love <fx@gnu.org>
parents:
diff changeset
158 |TAR|TAZ|TEX|TGA|TGZ|TIF|TXH|TXI|TXT\
Dave Love <fx@gnu.org>
parents:
diff changeset
159 |VOC\
Dave Love <fx@gnu.org>
parents:
diff changeset
160 |WAV|WK1|WK3|WKB|WQ1|WQ3|WQ4|WQ5|WQ6|WQ!\
Dave Love <fx@gnu.org>
parents:
diff changeset
161 |XBM\
Dave Love <fx@gnu.org>
parents:
diff changeset
162 |Y\
Dave Love <fx@gnu.org>
parents:
diff changeset
163 |ZIP|ZOO|";
Dave Love <fx@gnu.org>
parents:
diff changeset
164
Dave Love <fx@gnu.org>
parents:
diff changeset
165 int
Dave Love <fx@gnu.org>
parents:
diff changeset
166 _is_executable(const char *filename, int fhandle, const char *extension)
Dave Love <fx@gnu.org>
parents:
diff changeset
167 {
Dave Love <fx@gnu.org>
parents:
diff changeset
168 if (!extension && filename)
Dave Love <fx@gnu.org>
parents:
diff changeset
169 {
Dave Love <fx@gnu.org>
parents:
diff changeset
170 const char *cp, *ep=0;
Dave Love <fx@gnu.org>
parents:
diff changeset
171 for (cp=filename; *cp; cp++)
Dave Love <fx@gnu.org>
parents:
diff changeset
172 {
Dave Love <fx@gnu.org>
parents:
diff changeset
173 if (*cp == '.')
Dave Love <fx@gnu.org>
parents:
diff changeset
174 ep = cp;
Dave Love <fx@gnu.org>
parents:
diff changeset
175 if (*cp == '/' || *cp == '\\' || *cp == ':')
Dave Love <fx@gnu.org>
parents:
diff changeset
176 ep = 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
177 }
Dave Love <fx@gnu.org>
parents:
diff changeset
178 extension = ep;
Dave Love <fx@gnu.org>
parents:
diff changeset
179 }
Dave Love <fx@gnu.org>
parents:
diff changeset
180 if ((_djstat_flags & _STAT_EXEC_EXT) == 0
Dave Love <fx@gnu.org>
parents:
diff changeset
181 && extension
Dave Love <fx@gnu.org>
parents:
diff changeset
182 && *extension
Dave Love <fx@gnu.org>
parents:
diff changeset
183 && strlen(extension) <= ((extension[0]=='.') ? 4 : 3))
Dave Love <fx@gnu.org>
parents:
diff changeset
184 {
Dave Love <fx@gnu.org>
parents:
diff changeset
185 /* Search the list of extensions in executables[]. */
Dave Love <fx@gnu.org>
parents:
diff changeset
186 char tmp_buf[6], *tp = tmp_buf;
Dave Love <fx@gnu.org>
parents:
diff changeset
187
Dave Love <fx@gnu.org>
parents:
diff changeset
188 *tp++ = '|';
Dave Love <fx@gnu.org>
parents:
diff changeset
189 if (*extension == '.')
Dave Love <fx@gnu.org>
parents:
diff changeset
190 extension++;
Dave Love <fx@gnu.org>
parents:
diff changeset
191 while (*extension)
Dave Love <fx@gnu.org>
parents:
diff changeset
192 *tp++ = toupper (*extension++);
Dave Love <fx@gnu.org>
parents:
diff changeset
193 *tp++ = '|';
Dave Love <fx@gnu.org>
parents:
diff changeset
194 *tp = '\0';
Dave Love <fx@gnu.org>
parents:
diff changeset
195 if (strstr(non_executables, tmp_buf))
Dave Love <fx@gnu.org>
parents:
diff changeset
196 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
197 else if (strstr(executables, tmp_buf))
Dave Love <fx@gnu.org>
parents:
diff changeset
198 return 1;
Dave Love <fx@gnu.org>
parents:
diff changeset
199 }
Dave Love <fx@gnu.org>
parents:
diff changeset
200
Dave Love <fx@gnu.org>
parents:
diff changeset
201 /* No extension, or extension doesn't define execute
Dave Love <fx@gnu.org>
parents:
diff changeset
202 bits unambiguously. We are in for some dirty work.
Dave Love <fx@gnu.org>
parents:
diff changeset
203 Read the first two bytes of the file and see if they
Dave Love <fx@gnu.org>
parents:
diff changeset
204 are any of the known magic numbers which designate
Dave Love <fx@gnu.org>
parents:
diff changeset
205 executable files.
Dave Love <fx@gnu.org>
parents:
diff changeset
206 Unix-like shells, which have executable shell scripts
Dave Love <fx@gnu.org>
parents:
diff changeset
207 without extensions and DON'T have "#!" as their FIRST
Dave Love <fx@gnu.org>
parents:
diff changeset
208 TWO CHARACTERS, lose here. Sorry, folks. */
Dave Love <fx@gnu.org>
parents:
diff changeset
209 if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 )
Dave Love <fx@gnu.org>
parents:
diff changeset
210 {
Dave Love <fx@gnu.org>
parents:
diff changeset
211 switch (_get_magic(filename, fhandle))
Dave Love <fx@gnu.org>
parents:
diff changeset
212 {
Dave Love <fx@gnu.org>
parents:
diff changeset
213 case 0x5a4d: /* "MZ" */
Dave Love <fx@gnu.org>
parents:
diff changeset
214 case 0x010b:
Dave Love <fx@gnu.org>
parents:
diff changeset
215 case 0x014c:
Dave Love <fx@gnu.org>
parents:
diff changeset
216 case 0x2123: /* "#!" */
Dave Love <fx@gnu.org>
parents:
diff changeset
217 return 1;
Dave Love <fx@gnu.org>
parents:
diff changeset
218 }
Dave Love <fx@gnu.org>
parents:
diff changeset
219 }
Dave Love <fx@gnu.org>
parents:
diff changeset
220
Dave Love <fx@gnu.org>
parents:
diff changeset
221 return 0;
Dave Love <fx@gnu.org>
parents:
diff changeset
222 }