File: [local] / src / usr.bin / rdist / isexec.c (download)
Revision 1.6, Wed May 14 01:34:35 2003 UTC (21 years, 1 month ago) by millert
Branch: MAIN
Changes since 1.5: +24 -23 lines
o Sync w/ freerdist 0.92 minus the compress option
o KNF and ANSIfy the function headers
Sparse file support is currently a no-op since it didn't work.
Proper sparse file support will be added later.
|
/* $OpenBSD: isexec.c,v 1.6 2003/05/14 01:34:35 millert Exp $ */
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "defs.h"
#ifndef lint
#if 0
static char RCSid[] __attribute__((__unused__)) =
"$From: isexec.c,v 1.2 1999/08/04 15:57:33 christos Exp $";
#else
static char RCSid[] __attribute__((__unused__)) =
"$OpenBSD: isexec.c,v 1.6 2003/05/14 01:34:35 millert Exp $";
#endif
static char sccsid[] __attribute__((__unused__)) =
"@(#)client.c";
static char copyright[] __attribute__((__unused__)) =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
static int _isexec(int);
#if EXE_TYPE == EXE_AOUT
/*
* BSD style A.OUT
*/
#include <a.out.h>
static int
_isexec(int fd)
{
struct exec ehdr;
if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
!N_BADMAG(ehdr))
return(TRUE);
else
return(FALSE);
}
#endif /* EXE_AOUT */
#if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF
/*
* Elf
*/
#include <elf_abi.h>
#define ISELF(h) (h.e_type == ET_EXEC)
#endif /* EXE_ELF_AND_COFF || EXE_ELF */
#if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF
/*
* COFF
*/
#if defined(FILEHDR_H)
#include FILEHDR_H
#endif /* FILEHDR_H */
#if !defined(ISCOFF)
/*
* Stupid AIX
*/
#if defined(U802WRMAGIC) && defined(U802ROMAGIC) && defined(U802TOCMAGIC)
#define ISCOFF(x) (((x)==U802WRMAGIC) || ((x)==U802TOCMAGIC) || \
((x)==U802TOCMAGIC))
#endif /* U802... */
/*
* Stupid Umax4.3
*/
#if defined(NS32GMAGIC) || defined(NS32SMAGIC)
#define ISCOFF(x) (((x)==NS32GMAGIC) || ((x)==NS32SMAGIC))
#endif /* NS32 ... */
#endif /* ISCOFF */
#endif /* EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF */
#if EXE_TYPE == EXE_ELF_AND_COFF
/*
* ELF and COFF
*/
typedef union {
struct filehdr coffhdr;
Elf32_Ehdr elfhdr;
} hdr_t;
#endif /* EXE_TYPE == EXE_ELF_AND_COFF */
#if EXE_TYPE == EXE_ELF
/*
* Elf
*/
typedef Elf32_Ehdr hdr_t;
#endif /* EXE_TYPE == EXE_ELF */
#if EXE_TYPE == EXE_COFF
/*
* COFF
*/
#if defined(FILEHDR_H)
#include FILEHDR_H
#endif /* FILEHDR_H */
typedef struct filehdr hdr_t;
#endif /* EXE_TYPE == EXE_COFF */
#if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF || EXE_TYPE == EXE_COFF
/*
* System V style COFF and System V R4 style ELF
*/
static int
_isexec(int fd)
{
hdr_t hdr;
if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)) {
#if EXE_TYPE == EXE_ELF_AND_COFF
if (ISELF(hdr.elfhdr) || ISCOFF(hdr.coffhdr.f_magic))
return(TRUE);
#endif
#if EXE_TYPE == EXE_ELF
if (ISELF(hdr))
return(TRUE);
#endif
#if EXE_TYPE == EXE_COFF
if (ISCOFF(hdr.f_magic))
return(TRUE);
#endif
}
return(FALSE);
}
#endif /* EXE_ELF_AND_COFF */
#if EXE_TYPE == EXE_MACHO
/*
* Mach-O format
*/
#if defined(NEXTSTEP) && NEXTSTEP >= 3
# include <mach-o/loader.h>
#else
# include <sys/loader.h>
#endif /* NEXTSTEP */
#ifndef MH_CIGAM
#define MH_CIGAM 0xcefaedfe
#endif
#ifndef FAT_MAGIC
#define FAT_MAGIC 0xcafebabe
#endif
#ifndef FAT_CIGAM
#define FAT_CIGAM 0xbebafeca
#endif
static int
_isexec(int fd)
{
struct mach_header ehdr;
if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
(ehdr.magic == MH_MAGIC || ehdr.magic == MH_CIGAM ||
ehdr.magic == FAT_MAGIC || ehdr.magic == FAT_CIGAM))
return(TRUE);
else
return(FALSE);
}
#endif /* EXE_COFF */
#if EXE_TYPE == EXE_HPEXEC
/*
* HP 9000 executable format
*/
#ifdef hp9000s300
#include <a.out.h>
#define header exec
#define ISEXEC(a) ((a.file_type)==EXEC_MAGIC || (a.file_type)==SHARE_MAGIC || \
(a.file_type)==DEMAND_MAGIC)
#else /* ! hp9000s300 */
#define ISEXEC(a) ((a)==EXEC_MAGIC || (a)==SHARE_MAGIC || (a)==DEMAND_MAGIC)
#include <filehdr.h>
#endif /* hp9000s300 */
static int
_isexec(int fd)
{
struct header ehdr;
if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) &&
ISEXEC(ehdr.a_magic))
return(TRUE);
else
return(FALSE);
}
#endif /* EXE_HPEXEC */
#if !defined(EXE_TYPE)
/*
* Fake _isexec() call for unknown executable formats.
*/
static int
_isexec(int fd)
{
return(FALSE);
}
#endif /* !defined(EXE_TYPE) */
/*
* Determine whether 'file' is an executable or not.
*/
int
isexec(char *file, struct stat *statp)
{
int fd, r;
/*
* Must be a regular file that has some executable mode bit on
*/
if (!S_ISREG(statp->st_mode) ||
!(statp->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
return(FALSE);
if ((fd = open(file, O_RDONLY, 0)) < 0)
return(FALSE);
r = _isexec(fd);
(void) close(fd);
return(r);
}