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