Mercurial > emacs
view msdos/is_exec.c @ 31383:860d7ac182e3
(vc-rcs-show-log-entry): New function.
(vc-rcs-checkin, vc-rcs-checkout): Don't set all properties.
(vc-rcs-register): If there is no RCS subdir, ask the
user whether to create one.
(vc-rcs-state-heuristic): Use
file-ownership-preserved-p.
(vc-rcs-checkout): Remove the error-handling for missing-rcs.
(vc-rcs-state-heuristic): Don't use file-writable-p.
(vc-rcs-print-log): Insert in the current buffer.
(vc-rcs-diff): Insert in the current buffer and remove unused arg
CMP.
(vc-rcs-workfile-unchanged-p): Use vc-do-command
instead of vc-simple-command.
(vc-rcs-fetch-master-state): Removed check for unlocked-changes to
avoid doing a diff when opening a file.
(vc-rcs-state): Added check for unlocked-changes.
(vc-rcs-header): Escape Id.
(vc-rcs-workfile-unchanged-p): Remove optional arg VERSION.
(vc-rcs-state): Call vc-workfile-unchanged-p, not the RCS-specific
version.
(vc-rcs-state-heuristic): Use file-writable-p instead
of comparing userids.
(vc-rcs-fetch-master-state): Handle the case where rcs is missing.
Simplify the logic by eliminating unreachable code.
(vc-rcs-diff): Only pass `2' to vc-do-command if necessary and
just do a recursive call if we need to retry.
(vc-rcs-checkout): Handle the case where rcs is missing by making
the buffer read-write if requested and re-signalling the error.
(vc-rcs-find-most-recent-rev): New function. The code
derives from the old vc-parse-buffer but uses the revision number
rather than the date (much easier to compare robustly).
(vc-rcs-fetch-master-state): Use `with-temp-buffer'. Adapt to the
new vc-parse-buffer (and vc-rcs-find-most-recent-rev). Find the
locking-user more directly. Check strict locking and set
checkout-model appropriately.
(vc-rcs-parse-locks): Remove.
(vc-rcs-latest-on-branch-p): Use with-temp-buffer and adapt to the
new vc-parse-buffer (and vc-rcs-find-most-recent-rev).
(vc-rcs-system-release): Use with-current-buffer and
vc-parse-buffer.
(vc-rcs-register, vc-rcs-checkout): Use with-current-buffer.
Merge in code
from vc-rcs-hooks.el. Don't require 'vc anymore.
(vc-rcs-responsible-p): Use expand-file-name instead of concat and
file-directory-p instead of file-exists-p.
(vc-rcs-exists): Remove.
(vc-rcs-header): New var.
Update Copyright.
(vc-rcs-rename-file): New function.
(vc-rcs-diff): Remove unused `backend' variable.
(vc-rcs-clear-headers): New function; code moved here
from vc-clear-headers in vc.el.
(tail): Provide vc-rcs and remove vc-rcs-logentry-check.
(vc-rcs-register): Parse command output to find master
file name and workfile version.
(vc-rcs-checkout): Removed call to vc-file-clear-masterprops.
Require vc and vc-rcs-hooks.
(vc-rcs-trunk-p, vc-rcs-branch-part): Move to vc-rcs-hooks.
(vc-rcs-backend-release-p): Remove (use vc-rcs-release-p).
(vc-release-greater-or-equal-p): Move from vc.
(vc-rcs-trunk-p, vc-rcs-branch-p, vc-rcs-branch-part,
vc-rcs-minor-part, vc-rcs-previous-version): Remove duplicates.
(vc-rcs-checkout): Add a missing `new-version' argument in the
call to vc-rcs-latest-on-branch-p. Hopefully that was the right
one.
(vc-rcs-steal-lock): Renamed from `vc-rcs-steal'.
Updated everything to use `vc-checkout-model'.
(vc-rcs-backend-release-p): function added. other
stuff updated to reference this function instead of the old
`vc-backend-release-p'.
(vc-rcs-logentry-check): Function added.
(vc-rcs-checkin, vc-rcs-previous-version)
(vc-rcs-checkout): Name space cleaned up. No more revision number
crunching function names that are not prefixed with vc-rcs.
(vc-rcs-checkout-model): Function added. References to
`vc-checkout-model' replaced.
(vc-rcs-admin): Added the query-only option as
required by the vc.el file.
(vc-rcs-exists): Function added.
(vc-*-checkout):
Use with-temp-file instead of /bin/sh. Merged from mainline
(vc-rcs-latest-on-branch-p): Moved to vc-rcs-hooks.el.
(vc-rcs-latest-on-branch-p, vc-rcs-trunk-p)
(vc-rcs-branch-p, vc-rcs-branch-part, vc-rcs-minor-part)
(vc-rcs-previous-version): Functions added.
(vc-rcs-diff): Function added.
(vc-rcs-checkout) Bug (typo) found and fixed.
(vc-rcs-register-switches) Variable `vc-rcs-register-switches' added.
Require vc when compiling.
(vc-rcs-print-log, vc-rcs-assign-name, vc-rcs-merge)
(vc-rcs-check-headers, vc-rcs-steal, vc-rcs-uncheck, vc-rcs-revert)
(vc-rcs-checkin): New functions (code from vc.el).
(vc-rcs-previous-version, vc-rcs-system-release, vc-rcs-checkout):
Doc fix.
(vc-rcs-release): Deleted. (Duplicated vc-rcs-system-release).
(vc-rcs-trunk-p, vc-rcs-branch-p, vc-rcs-branch-part)
(vc-rcs-minor-part, vc-rcs-previous-version, vc-rcs-release)
(vc-rcs-release-p, vc-rcs-admin, vc-rcs-checkout): New functions
from vc.el.
(vc-rcs-system-release):
Renamed from vc-rcs-backend-release.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Mon, 04 Sep 2000 19:47:43 +0000 |
parents | 354e0c45cedf |
children | 695cf19ef79e |
line wrap: on
line source
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ /* IS_EXEC.C * * Given a filename or a file handle, and the extension of the file, * determine if the file is executable. * First, the file extension is checked in case it uniquely identifies * the file as either an executable or not. Failing this, the first * two bytes of the file are tested for known signatures of executable * files. * * Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il> * * This software may be used freely so long as this copyright notice is * left intact. There is no warranty on this software. * */ #include <libc/stubs.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <dpmi.h> #include <go32.h> #include <io.h> #include <libc/farptrgs.h> #include <libc/dosio.h> extern unsigned short _djstat_flags; unsigned short _get_magic(const char *, int); int _is_executable(const char *, int, const char *); /* * Read a MAGIC NUMBER from a given file. These are the first * two bytes of the file, if we look at them as an unsigned short. */ #define _STAT_EXEC_EXT 2 /* get execute bits from file extension? */ #define _STAT_EXEC_MAGIC 4 /* get execute bits from magic signature? */ unsigned short _get_magic(const char *s, int fh) { __dpmi_regs regs; unsigned short retval; unsigned short fpos_high = 0, fpos_low = 0; int read_fail = 0; /* If given a pathname, open the file. */ if (s) { int handle; if((handle = _open(s,0)) == -1) return 0; regs.x.bx = handle; } /* Else file already open. Remember its current file position and move to beginning of file. */ else { regs.x.ax = 0x4201; /* set pointer from current position */ regs.x.bx = fh; regs.x.cx = regs.x.dx = 0; /* move 0 bytes (i.e., stay put) */ __dpmi_int(0x21, ®s); if (regs.x.flags & 1) { errno = __doserr_to_errno(regs.x.ax); return 0; } fpos_high = regs.x.dx; /* got current position */ fpos_low = regs.x.ax; regs.x.ax = 0x4200; /* set pointer from the beginning of file */ regs.x.cx = regs.x.dx = 0; /* move to beginning of file */ __dpmi_int(0x21, ®s); if (regs.x.flags & 1) { errno = __doserr_to_errno(regs.x.ax); return 0; } } regs.x.ds = __tb_segment; regs.x.dx = __tb_offset; /* Read 2 bytes from the file. */ regs.x.ax = 0x3f00; regs.x.cx = 2; __dpmi_int(0x21, ®s); /* We can either (1) succeed, (2) read less than 2 bytes, or (3) fail to read at all. */ if (regs.x.ax != 2) read_fail = (regs.x.flags & 1) ? regs.x.ax : -1; /* If called with filename, close the file. */ if (s) { regs.x.ax = 0x3e00; __dpmi_int(0x21, ®s); if (regs.x.flags & 1) errno = __doserr_to_errno(regs.x.ax); } /* Else leave file pointer where we found it. */ else { regs.x.ax = 0x4200; /* set pointer from the beginning of file */ regs.x.bx = fh; regs.x.cx = fpos_high; regs.x.dx = fpos_low; __dpmi_int(0x21, ®s); if (regs.x.flags & 1) { errno = __doserr_to_errno(regs.x.ax); return 0; } } if (read_fail == 0) retval = _farpeekw(_dos_ds, __tb); else { /* The file couldn't be read: assume non-executable. If the file *is* executable, but was passed as a file-handle, and the user opened it in write-only mode, they lose... */ retval = 0; if (read_fail != -1) errno = __doserr_to_errno(read_fail); } return retval; } /* A list of extensions which designate executable files. These are NOT tested for the magic number. */ static char executables[] = "|EXE|COM|BAT|BTM|DLL|VXD|"; /* A list of extensions which belong to files known to NEVER be executables. These exist to minimize read()'ing files while detecting executables by magic number. You are welcome to add to this list, but remember: only extensions which could NEVER be present in executables should go here. */ static char non_executables[] = "\ |A|A01|A02|A03|A04|A05|ADL|ARC|ARJ|ASC|ASM|AUX|AWK\ |BAS|BIB|BGI|BMP\ |C|CC|CFG|CGZ|CH3|CHR|CI|CLP|CMF|CPI|CPP|CXX\ |DAT|DBF|DIZ|DOC|DVI\ |E|EL|ELC\ |F77|FN3\ |GIF|GZ\ |H|HLP|HPP|HXX\ |ICO|IN|INC|INF|INI\ |JPG\ |L|LEX|LF|LIB|LOG|LST|LZH\ |M|MAK|MAP|MF|MID|MPG\ |O|OBJ\ |PAK|PAS|PBM|PCD|PCX|PDS|PIC|PIF|PN3|PRJ|PS\ |RAS|RGB|RLE\ |S|SND|SY3\ |TAR|TAZ|TEX|TGA|TGZ|TIF|TXH|TXI|TXT\ |VOC\ |WAV|WK1|WK3|WKB|WQ1|WQ3|WQ4|WQ5|WQ6|WQ!\ |XBM\ |Y\ |ZIP|ZOO|"; int _is_executable(const char *filename, int fhandle, const char *extension) { if (!extension && filename) { const char *cp, *ep=0; for (cp=filename; *cp; cp++) { if (*cp == '.') ep = cp; if (*cp == '/' || *cp == '\\' || *cp == ':') ep = 0; } extension = ep; } if ((_djstat_flags & _STAT_EXEC_EXT) == 0 && extension && *extension && strlen(extension) <= ((extension[0]=='.') ? 4 : 3)) { /* Search the list of extensions in executables[]. */ char tmp_buf[6], *tp = tmp_buf; *tp++ = '|'; if (*extension == '.') extension++; while (*extension) *tp++ = toupper (*extension++); *tp++ = '|'; *tp = '\0'; if (strstr(non_executables, tmp_buf)) return 0; else if (strstr(executables, tmp_buf)) return 1; } /* No extension, or extension doesn't define execute bits unambiguously. We are in for some dirty work. Read the first two bytes of the file and see if they are any of the known magic numbers which designate executable files. Unix-like shells, which have executable shell scripts without extensions and DON'T have "#!" as their FIRST TWO CHARACTERS, lose here. Sorry, folks. */ if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 ) { switch (_get_magic(filename, fhandle)) { case 0x5a4d: /* "MZ" */ case 0x010b: case 0x014c: case 0x2123: /* "#!" */ return 1; } } return 0; }