Annotation of src/usr.bin/rdist/isexec.c, Revision 1.8
1.8 ! deraadt 1: /* $OpenBSD: isexec.c,v 1.7 2003/06/03 02:56:14 millert Exp $ */
1.3 deraadt 2:
1.1 dm 3: /*
4: * Copyright (c) 1983 Regents of the University of California.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.7 millert 15: * 3. Neither the name of the University nor the names of its contributors
1.1 dm 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
1.6 millert 31:
32: #include "defs.h"
1.1 dm 33:
1.6 millert 34: static int _isexec(int);
1.1 dm 35:
36: #if EXE_TYPE == EXE_AOUT
37: /*
38: * BSD style A.OUT
39: */
40: #include <a.out.h>
41:
1.6 millert 42: static int
43: _isexec(int fd)
1.1 dm 44: {
45: struct exec ehdr;
46:
47: if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
48: !N_BADMAG(ehdr))
49: return(TRUE);
50: else
51: return(FALSE);
52: }
53: #endif /* EXE_AOUT */
54:
55:
56: #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF
57: /*
58: * Elf
59: */
1.5 millert 60: #include <elf_abi.h>
1.1 dm 61: #define ISELF(h) (h.e_type == ET_EXEC)
62: #endif /* EXE_ELF_AND_COFF || EXE_ELF */
63:
64: #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF
65:
66: /*
67: * COFF
68: */
69: #if defined(FILEHDR_H)
70: #include FILEHDR_H
71: #endif /* FILEHDR_H */
72:
73: #if !defined(ISCOFF)
74:
75: /*
76: * Stupid AIX
77: */
78: #if defined(U802WRMAGIC) && defined(U802ROMAGIC) && defined(U802TOCMAGIC)
79: #define ISCOFF(x) (((x)==U802WRMAGIC) || ((x)==U802TOCMAGIC) || \
80: ((x)==U802TOCMAGIC))
81: #endif /* U802... */
82: /*
83: * Stupid Umax4.3
84: */
85: #if defined(NS32GMAGIC) || defined(NS32SMAGIC)
86: #define ISCOFF(x) (((x)==NS32GMAGIC) || ((x)==NS32SMAGIC))
87: #endif /* NS32 ... */
88:
89: #endif /* ISCOFF */
90:
91: #endif /* EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF */
92:
93: #if EXE_TYPE == EXE_ELF_AND_COFF
94: /*
95: * ELF and COFF
96: */
97: typedef union {
98: struct filehdr coffhdr;
99: Elf32_Ehdr elfhdr;
100: } hdr_t;
101: #endif /* EXE_TYPE == EXE_ELF_AND_COFF */
102:
103: #if EXE_TYPE == EXE_ELF
104: /*
105: * Elf
106: */
107: typedef Elf32_Ehdr hdr_t;
108: #endif /* EXE_TYPE == EXE_ELF */
109:
110: #if EXE_TYPE == EXE_COFF
111: /*
112: * COFF
113: */
114:
115: #if defined(FILEHDR_H)
116: #include FILEHDR_H
117: #endif /* FILEHDR_H */
118:
119: typedef struct filehdr hdr_t;
120: #endif /* EXE_TYPE == EXE_COFF */
121:
122: #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF || EXE_TYPE == EXE_COFF
123: /*
124: * System V style COFF and System V R4 style ELF
125: */
1.6 millert 126: static int
127: _isexec(int fd)
1.1 dm 128: {
129: hdr_t hdr;
130:
131: if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)) {
132: #if EXE_TYPE == EXE_ELF_AND_COFF
133: if (ISELF(hdr.elfhdr) || ISCOFF(hdr.coffhdr.f_magic))
134: return(TRUE);
135: #endif
136: #if EXE_TYPE == EXE_ELF
137: if (ISELF(hdr))
138: return(TRUE);
139: #endif
140: #if EXE_TYPE == EXE_COFF
141: if (ISCOFF(hdr.f_magic))
142: return(TRUE);
143: #endif
144: }
145:
146: return(FALSE);
147: }
148: #endif /* EXE_ELF_AND_COFF */
149:
150:
151: #if EXE_TYPE == EXE_MACHO
152: /*
153: * Mach-O format
154: */
155:
156: #if defined(NEXTSTEP) && NEXTSTEP >= 3
157: # include <mach-o/loader.h>
158: #else
159: # include <sys/loader.h>
160: #endif /* NEXTSTEP */
161:
162: #ifndef MH_CIGAM
163: #define MH_CIGAM 0xcefaedfe
164: #endif
165: #ifndef FAT_MAGIC
166: #define FAT_MAGIC 0xcafebabe
167: #endif
168: #ifndef FAT_CIGAM
169: #define FAT_CIGAM 0xbebafeca
170: #endif
171:
1.6 millert 172: static int
173: _isexec(int fd)
1.1 dm 174: {
175: struct mach_header ehdr;
176:
177: if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
178: (ehdr.magic == MH_MAGIC || ehdr.magic == MH_CIGAM ||
179: ehdr.magic == FAT_MAGIC || ehdr.magic == FAT_CIGAM))
180: return(TRUE);
181: else
182: return(FALSE);
183: }
184: #endif /* EXE_COFF */
185:
186:
187: #if EXE_TYPE == EXE_HPEXEC
188: /*
189: * HP 9000 executable format
190: */
191:
192: #ifdef hp9000s300
193:
194: #include <a.out.h>
195: #define header exec
196: #define ISEXEC(a) ((a.file_type)==EXEC_MAGIC || (a.file_type)==SHARE_MAGIC || \
197: (a.file_type)==DEMAND_MAGIC)
198:
199: #else /* ! hp9000s300 */
200:
201: #define ISEXEC(a) ((a)==EXEC_MAGIC || (a)==SHARE_MAGIC || (a)==DEMAND_MAGIC)
202: #include <filehdr.h>
203:
204: #endif /* hp9000s300 */
205:
1.6 millert 206: static int
207: _isexec(int fd)
1.1 dm 208: {
209: struct header ehdr;
210:
211: if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
212: ISEXEC(ehdr.a_magic))
213: return(TRUE);
214: else
215: return(FALSE);
216: }
217: #endif /* EXE_HPEXEC */
218:
219:
220: #if !defined(EXE_TYPE)
221: /*
222: * Fake _isexec() call for unknown executable formats.
223: */
1.6 millert 224: static int
225: _isexec(int fd)
1.1 dm 226: {
227: return(FALSE);
228: }
229: #endif /* !defined(EXE_TYPE) */
230:
231: /*
232: * Determine whether 'file' is an executable or not.
233: */
1.6 millert 234: int
235: isexec(char *file, struct stat *statp)
1.1 dm 236: {
237: int fd, r;
238:
239: /*
240: * Must be a regular file that has some executable mode bit on
241: */
242: if (!S_ISREG(statp->st_mode) ||
243: !(statp->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
244: return(FALSE);
245:
246: if ((fd = open(file, O_RDONLY, 0)) < 0)
247: return(FALSE);
248: r = _isexec(fd);
249: (void) close(fd);
250:
251: return(r);
252: }
253: