merge with experimental

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-15 00:38:03 +01:00
commit 5978187394
55 changed files with 15144 additions and 55 deletions

144
ChangeLog
View file

@ -1,3 +1,147 @@
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
Import from Gnulib.
* gnulib/fnmatch.c: New file.
* gnulib/fnmatch.h: Likewise.
* gnulib/fnmatch_loop.c: Likewise.
* gnulib/getopt.c: Likewise.
* gnulib/getopt.h: Likewise.
* gnulib/getopt1.c: Likewise.
* gnulib/getopt_int.h: Likewise.
* gnulib/gettext.h: Likewise.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* normal/dyncmd.c (read_command_list): Replace `0' with `NULL'.
* normal/handler.c (read_handler_list): Likewise.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
Misc cleanup.
* kern/command.c (grub_register_command_prio): Use
grub_zalloc() instead of explicitly zeroing data.
* kern/list.c: Include `<grub/mm.h>'.
(grub_named_list_find): Replace `0' with `NULL'.
* normal/autofs.c (struct grub_fs_module_list): Remove ad-hoc type.
(fs_module_list): Change type to `grub_named_list_t'. Update all
users.
* normal/dyncmd.c (read_command_list): Add space between function
call and parenthesis.
* normal/handler.c (read_handler_list): Likewise.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* normal/auth.c (punishment_delay): Moved from here ...
(grub_auth_strcmp): ... to here (inside function).
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/list.h (struct grub_named_list): Remove `const'
qualifier from `name'.
(struct grub_prio_list): Likewise.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* normal/auth.c: Include `<grub/time.h>'.
(grub_auth_strcmp): Replace `strcmp' with `grub_strcmp'.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* normal/auth.c (punishment_delay): New variable.
(grub_auth_strcmp): Rewrite using grub_get_time_ms ().
(grub_auth_check_authentication): Punish failed login attempts with
an incremental (2^N) delay.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* conf/common.rmk (grub_mkisofs_CFLAGS): Prefix include
path with $(srcdir).
2009-11-09 Vladimir Serbinenko <phcoder@gmail.com>
* normal/auth.c (grub_auth_strcmp): Fixed incorrect variable usage.
2009-11-09 Robert Millan <rmh.grub@aybabtu.com>
* util/i386/coreboot/grub-mkrescue.in: New file.
* conf/i386-coreboot.rmk (bin_SCRIPTS, grub_mkrescue_SOURCES): New
variables.
* conf/common.rmk (bin_UTILITIES): Add `grub-mkisofs'.
(grub_mkisofs_SOURCES, grub_mkisofs_CFLAGS): New variables.
* configure.ac: Add header and function checks to satisfy grub-mkisofs
requirements.
* util/mkisofs/defaults.h: New file.
* util/mkisofs/eltorito.c: Likewise.
* util/mkisofs/exclude.h: Likewise.
* util/mkisofs/fnmatch.c: Likewise.
* util/mkisofs/getopt.c: Likewise.
* util/mkisofs/getopt1.c: Likewise.
* util/mkisofs/hash.c: Likewise.
* util/mkisofs/include/fctldefs.h: Likewise.
* util/mkisofs/include/mconfig.h: Likewise.
* util/mkisofs/include/prototyp.h: Likewise.
* util/mkisofs/include/statdefs.h: Likewise.
* util/mkisofs/iso9660.h: Likewise.
* util/mkisofs/joliet.c: Likewise.
* util/mkisofs/match.c: Likewise.
* util/mkisofs/match.h: Likewise.
* util/mkisofs/mkisofs.c: Likewise.
* util/mkisofs/mkisofs.h: Likewise.
* util/mkisofs/multi.c: Likewise.
* util/mkisofs/name.c: Likewise.
* util/mkisofs/rock.c: Likewise.
* util/mkisofs/tree.c: Likewise.
* util/mkisofs/write.c: Likewise.
2009-11-09 Vladimir Serbinenko <phcoder@gmail.com>
* normal/auth.c (grub_auth_strcmp): Fix bug which resulted in function
being insecure.
2009-11-08 Robert Millan <rmh.grub@aybabtu.com>
* util/i386/pc/grub-mkrescue.in: Fix miss-identification as
`grub-mkimage' (and use $0 when possible).
2009-11-08 Robert Millan <rmh.grub@aybabtu.com>
* kern/i386/multiboot_mmap.c (grub_machine_mmap_init): Improve
error message for excessively large memory map.
2009-11-08 Robert Millan <rmh.grub@aybabtu.com>
* autogen.sh: Use `sh gendistlist.sh' to avoid reliing on
executable bit.
2009-11-08 Robert Millan <rmh.grub@aybabtu.com>
* kern/i386/multiboot_mmap.c (grub_machine_mmap_init): Improve error
message for coreboot users.
2009-11-07 Robert Millan <rmh.grub@aybabtu.com>
Fix build with GNU gold.
* conf/i386-pc.rmk (boot_img_LDFLAGS, pxeboot_img_LDFLAGS)
(diskboot_img_LDFLAGS, lnxboot_img_LDFLAGS)
(cdboot_img_LDFLAGS): Prepend `0x' qualifier to hexadecimal
link addresses.
* aclocal.m4: Likewise.
2009-11-04 Felix Zielcke <fzielcke@z-51.de>
* configure.ac (AC_PREREQ): Bump to 2.59d.
* INSTALL: Make it more clear when Autoconf and Ruby are
needed and when to run `./autogen.sh'.
2009-11-03 Samuel Thibault <samuel.thibault@ens-lyon.org>
* util/grub.d/30_os-prober.in: Restore default behavior for unsupported
OSes.
2009-11-02 Samuel Thibault <samuel.thibault@ens-lyon.org> 2009-11-02 Samuel Thibault <samuel.thibault@ens-lyon.org>
* util/grub.d/30_os-prober.in: Add GNU/Hurd support * util/grub.d/30_os-prober.in: Add GNU/Hurd support

17
INSTALL
View file

@ -16,8 +16,12 @@ configuring the GRUB.
* GNU Bison 2.3 or later * GNU Bison 2.3 or later
* GNU binutils 2.9.1.0.23 or later * GNU binutils 2.9.1.0.23 or later
* Other standard GNU/Unix tools * Other standard GNU/Unix tools
If you use a development snapshot or want to hack on GRUB you may
need the following.
* Ruby 1.6 or later * Ruby 1.6 or later
* Autoconf 2.59 or later * Autoconf 2.59d or later
Configuring the GRUB Configuring the GRUB
==================== ====================
@ -48,11 +52,12 @@ Building the GRUB
The simplest way to compile this package is: The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and 1. `cd' to the directory containing the package's source code. If
type `./autogen.sh' and then `./configure' to configure the you don't use a release tarball you have to type `./autogen.sh'.
package for your system. If you're using `csh' on an old version Type `./configure' to configure the package for your system.
of System V, you might need to type `sh ./configure' instead to If you're using `csh' on an old version of System V, you might
prevent `csh' from trying to execute `configure' itself. need to type `sh ./configure' instead to prevent `csh' from trying
to execute `configure' itself.
Running `configure' takes awhile. While running, it prints some Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for. messages telling which features it is checking for.

2
aclocal.m4 vendored
View file

@ -92,7 +92,7 @@ else
AC_MSG_ERROR([${CC-cc} cannot compile C source code]) AC_MSG_ERROR([${CC-cc} cannot compile C source code])
fi fi
grub_cv_prog_objcopy_absolute=yes grub_cv_prog_objcopy_absolute=yes
for link_addr in 2000 8000 7C00; do for link_addr in 0x2000 0x8000 0x7C00; do
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
else else
AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])

2
autogen.sh Normal file → Executable file
View file

@ -10,6 +10,6 @@ for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'` ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`
fi fi
done done
./gendistlist.sh > DISTLIST sh gendistlist.sh > DISTLIST
exit 0 exit 0

View file

@ -28,6 +28,16 @@ ifeq ($(enable_grub_fstest), yes)
bin_UTILITIES += grub-fstest bin_UTILITIES += grub-fstest
endif endif
bin_UTILITIES += grub-mkisofs
grub_mkisofs_SOURCES = util/mkisofs/eltorito.c util/mkisofs/fnmatch.c \
util/mkisofs/getopt1.c util/mkisofs/getopt.c \
util/mkisofs/hash.c util/mkisofs/joliet.c \
util/mkisofs/match.c util/mkisofs/mkisofs.c \
util/mkisofs/multi.c util/mkisofs/name.c \
util/mkisofs/rock.c util/mkisofs/tree.c \
util/mkisofs/write.c
grub_mkisofs_CFLAGS = -I$(srcdir)/util/mkisofs/include -Wno-all -Werror
# For grub-fstest. # For grub-fstest.
util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c \ grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c \

View file

@ -152,6 +152,9 @@ grub_emu_LDFLAGS = $(LIBCURSES)
sbin_SCRIPTS += grub-install sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/i386/pc/grub-install.in grub_install_SOURCES = util/i386/pc/grub-install.in
bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/i386/coreboot/grub-mkrescue.in
# Modules. # Modules.
pkglib_MODULES = linux.mod multiboot.mod \ pkglib_MODULES = linux.mod multiboot.mod \
aout.mod play.mod serial.mod ata.mod \ aout.mod play.mod serial.mod ata.mod \

View file

@ -16,31 +16,31 @@ pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
# For boot.img. # For boot.img.
boot_img_SOURCES = boot/i386/pc/boot.S boot_img_SOURCES = boot/i386/pc/boot.S
boot_img_ASFLAGS = $(COMMON_ASFLAGS) boot_img_ASFLAGS = $(COMMON_ASFLAGS)
boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
boot_img_FORMAT = binary boot_img_FORMAT = binary
# For pxeboot.img # For pxeboot.img
pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS) pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
pxeboot_img_FORMAT = binary pxeboot_img_FORMAT = binary
# For diskboot.img. # For diskboot.img.
diskboot_img_SOURCES = boot/i386/pc/diskboot.S diskboot_img_SOURCES = boot/i386/pc/diskboot.S
diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)8000 diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8000
diskboot_img_FORMAT = binary diskboot_img_FORMAT = binary
# For lnxboot.img. # For lnxboot.img.
lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS) lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)6000 lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x6000
lnxboot_img_FORMAT = binary lnxboot_img_FORMAT = binary
# For cdboot.img. # For cdboot.img.
cdboot_img_SOURCES = boot/i386/pc/cdboot.S cdboot_img_SOURCES = boot/i386/pc/cdboot.S
cdboot_img_ASFLAGS = $(COMMON_ASFLAGS) cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)7C00 cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
cdboot_img_FORMAT = binary cdboot_img_FORMAT = binary
# For kernel.img. # For kernel.img.

View file

@ -32,7 +32,7 @@ dnl type.
AC_INIT([GRUB],[1.97],[bug-grub@gnu.org]) AC_INIT([GRUB],[1.97],[bug-grub@gnu.org])
AC_PREREQ(2.59) AC_PREREQ(2.59d)
AC_CONFIG_SRCDIR([include/grub/dl.h]) AC_CONFIG_SRCDIR([include/grub/dl.h])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
@ -181,6 +181,13 @@ fi
# Check for functions. # Check for functions.
AC_CHECK_FUNCS(posix_memalign memalign asprintf) AC_CHECK_FUNCS(posix_memalign memalign asprintf)
# For grub-mkisofs
AC_HEADER_MAJOR
AC_HEADER_DIRENT
AC_CHECK_FUNCS(memmove sbrk strdup)
AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h)
# #
# Check for target programs. # Check for target programs.
# #

56
gnulib/alloca.h Normal file
View file

@ -0,0 +1,56 @@
/* Memory allocation on the stack.
Copyright (C) 1995, 1999, 2001-2004, 2006-2008 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
means there is a real alloca function. */
#ifndef _GL_ALLOCA_H
#define _GL_ALLOCA_H
/* alloca (N) returns a pointer to N bytes of memory
allocated on the stack, which will last until the function returns.
Use of alloca should be avoided:
- inside arguments of function calls - undefined behaviour,
- in inline functions - the allocation may actually last until the
calling function returns,
- for huge N (say, N >= 65536) - you never know how large (or small)
the stack is, and when the stack cannot fulfill the memory allocation
request, the program just crashes.
*/
#ifndef alloca
# ifdef __GNUC__
# define alloca __builtin_alloca
# elif defined _AIX
# define alloca __alloca
# elif defined _MSC_VER
# include <malloc.h>
# define alloca _alloca
# elif defined __DECC && defined __VMS
# define alloca __ALLOCA
# else
# include <stddef.h>
# ifdef __cplusplus
extern "C"
# endif
void *alloca (size_t);
# endif
#endif
#endif /* _GL_ALLOCA_H */

354
gnulib/fnmatch.c Normal file
View file

@ -0,0 +1,354 @@
/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _LIBC
# include <config.h>
#endif
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#if ! defined __builtin_expect && __GNUC__ < 3
# define __builtin_expect(expr, expected) (expr)
#endif
#include <fnmatch.h>
#include <alloca.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define WIDE_CHAR_SUPPORT \
(HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
&& HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || WIDE_CHAR_SUPPORT
# include <wctype.h>
# include <wchar.h>
#endif
/* We need some of the locale data (the collation sequence information)
but there is no interface to get this information in general. Therefore
we support a correct implementation only in glibc. */
#ifdef _LIBC
# include "../locale/localeinfo.h"
# include "../locale/elem-hash.h"
# include "../locale/coll-lookup.h"
# include <shlib-compat.h>
# define CONCAT(a,b) __CONCAT(a,b)
# define mbsrtowcs __mbsrtowcs
# define fnmatch __fnmatch
extern int fnmatch (const char *pattern, const char *string, int flags);
#endif
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
#define NO_LEADING_PERIOD(flags) \
((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself, and have not detected a bug
in the library. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
# define isblank(c) ((c) == ' ' || (c) == '\t')
# endif
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
# if defined _LIBC || WIDE_CHAR_SUPPORT
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
# else
/* This shouldn't happen but some implementation might still have this
problem. Use a reasonable default value. */
# define CHAR_CLASS_MAX_LENGTH 256
# endif
# ifdef _LIBC
# define IS_CHAR_CLASS(string) __wctype (string)
# else
# define IS_CHAR_CLASS(string) wctype (string)
# endif
# ifdef _LIBC
# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
# else
# define ISWCTYPE(WC, WT) iswctype (WC, WT)
# endif
# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
/* In this case we are implementing the multibyte character handling. */
# define HANDLE_MULTIBYTE 1
# endif
# else
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
# define IS_CHAR_CLASS(string) \
(STREQ (string, "alpha") || STREQ (string, "upper") \
|| STREQ (string, "lower") || STREQ (string, "digit") \
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|| STREQ (string, "space") || STREQ (string, "print") \
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
/* Global variable. */
static int posixly_correct;
# ifndef internal_function
/* Inside GNU libc we mark some function in a special way. In other
environments simply ignore the marking. */
# define internal_function
# endif
/* Note that this evaluates C many times. */
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# define CHAR char
# define UCHAR unsigned char
# define INT int
# define FCT internal_fnmatch
# define EXT ext_match
# define END end_pattern
# define L_(CS) CS
# ifdef _LIBC
# define BTOWC(C) __btowc (C)
# else
# define BTOWC(C) btowc (C)
# endif
# define STRLEN(S) strlen (S)
# define STRCAT(D, S) strcat (D, S)
# ifdef _LIBC
# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
# else
# if HAVE_MEMPCPY
# define MEMPCPY(D, S, N) mempcpy (D, S, N)
# else
# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
# endif
# endif
# define MEMCHR(S, C, N) memchr (S, C, N)
# define STRCOLL(S1, S2) strcoll (S1, S2)
# include "fnmatch_loop.c"
# if HANDLE_MULTIBYTE
# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
# define CHAR wchar_t
# define UCHAR wint_t
# define INT wint_t
# define FCT internal_fnwmatch
# define EXT ext_wmatch
# define END end_wpattern
# define L_(CS) L##CS
# define BTOWC(C) (C)
# ifdef _LIBC
# define STRLEN(S) __wcslen (S)
# define STRCAT(D, S) __wcscat (D, S)
# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
# else
# define STRLEN(S) wcslen (S)
# define STRCAT(D, S) wcscat (D, S)
# if HAVE_WMEMPCPY
# define MEMPCPY(D, S, N) wmempcpy (D, S, N)
# else
# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
# endif
# endif
# define MEMCHR(S, C, N) wmemchr (S, C, N)
# define STRCOLL(S1, S2) wcscoll (S1, S2)
# define WIDE_CHAR_VERSION 1
# undef IS_CHAR_CLASS
/* We have to convert the wide character string in a multibyte string. But
we know that the character class names consist of alphanumeric characters
from the portable character set, and since the wide character encoding
for a member of the portable character set is the same code point as
its single-byte encoding, we can use a simplified method to convert the
string to a multibyte character string. */
static wctype_t
is_char_class (const wchar_t *wcs)
{
char s[CHAR_CLASS_MAX_LENGTH + 1];
char *cp = s;
do
{
/* Test for a printable character from the portable character set. */
# ifdef _LIBC
if (*wcs < 0x20 || *wcs > 0x7e
|| *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
return (wctype_t) 0;
# else
switch (*wcs)
{
case L' ': case L'!': case L'"': case L'#': case L'%':
case L'&': case L'\'': case L'(': case L')': case L'*':
case L'+': case L',': case L'-': case L'.': case L'/':
case L'0': case L'1': case L'2': case L'3': case L'4':
case L'5': case L'6': case L'7': case L'8': case L'9':
case L':': case L';': case L'<': case L'=': case L'>':
case L'?':
case L'A': case L'B': case L'C': case L'D': case L'E':
case L'F': case L'G': case L'H': case L'I': case L'J':
case L'K': case L'L': case L'M': case L'N': case L'O':
case L'P': case L'Q': case L'R': case L'S': case L'T':
case L'U': case L'V': case L'W': case L'X': case L'Y':
case L'Z':
case L'[': case L'\\': case L']': case L'^': case L'_':
case L'a': case L'b': case L'c': case L'd': case L'e':
case L'f': case L'g': case L'h': case L'i': case L'j':
case L'k': case L'l': case L'm': case L'n': case L'o':
case L'p': case L'q': case L'r': case L's': case L't':
case L'u': case L'v': case L'w': case L'x': case L'y':
case L'z': case L'{': case L'|': case L'}': case L'~':
break;
default:
return (wctype_t) 0;
}
# endif
/* Avoid overrunning the buffer. */
if (cp == s + CHAR_CLASS_MAX_LENGTH)
return (wctype_t) 0;
*cp++ = (char) *wcs++;
}
while (*wcs != L'\0');
*cp = '\0';
# ifdef _LIBC
return __wctype (s);
# else
return wctype (s);
# endif
}
# define IS_CHAR_CLASS(string) is_char_class (string)
# include "fnmatch_loop.c"
# endif
int
fnmatch (const char *pattern, const char *string, int flags)
{
# if HANDLE_MULTIBYTE
# define ALLOCA_LIMIT 2000
if (__builtin_expect (MB_CUR_MAX, 1) != 1)
{
mbstate_t ps;
size_t patsize;
size_t strsize;
size_t totsize;
wchar_t *wpattern;
wchar_t *wstring;
int res;
/* Calculate the size needed to convert the strings to
wide characters. */
memset (&ps, '\0', sizeof (ps));
patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
if (__builtin_expect (patsize != 0, 1))
{
assert (mbsinit (&ps));
strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
if (__builtin_expect (strsize != 0, 1))
{
assert (mbsinit (&ps));
totsize = patsize + strsize;
if (__builtin_expect (! (patsize <= totsize
&& totsize <= SIZE_MAX / sizeof (wchar_t)),
0))
{
errno = ENOMEM;
return -1;
}
/* Allocate room for the wide characters. */
if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
else
{
wpattern = malloc (totsize * sizeof (wchar_t));
if (__builtin_expect (! wpattern, 0))
{
errno = ENOMEM;
return -1;
}
}
wstring = wpattern + patsize;
/* Convert the strings into wide characters. */
mbsrtowcs (wpattern, &pattern, patsize, &ps);
assert (mbsinit (&ps));
mbsrtowcs (wstring, &string, strsize, &ps);
res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
flags & FNM_PERIOD, flags);
if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
free (wpattern);
return res;
}
}
}
# endif /* HANDLE_MULTIBYTE */
return internal_fnmatch (pattern, string, string + strlen (string),
flags & FNM_PERIOD, flags);
}
# ifdef _LIBC
# undef fnmatch
versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
strong_alias (__fnmatch, __fnmatch_old)
compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
# endif
libc_hidden_ver (__fnmatch, fnmatch)
# endif
#endif /* _LIBC or not __GNU_LIBRARY__. */

65
gnulib/fnmatch.h Normal file
View file

@ -0,0 +1,65 @@
/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _FNMATCH_H
#define _FNMATCH_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* We #undef these before defining them because some losing systems
(HP-UX A.08.07 for example) define these in <unistd.h>. */
#undef FNM_PATHNAME
#undef FNM_NOESCAPE
#undef FNM_PERIOD
/* Bits set in the FLAGS argument to `fnmatch'. */
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
#endif
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
#define FNM_NOMATCH 1
/* This value is returned if the implementation does not support
`fnmatch'. Since this is not the case here it will never be
returned but the conformance test suites still require the symbol
to be defined. */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS (-1)
#endif
/* Match NAME against the file name pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not. */
extern int fnmatch (const char *__pattern, const char *__name,
int __flags);
#ifdef __cplusplus
}
#endif
#endif /* fnmatch.h */

1210
gnulib/fnmatch_loop.c Normal file

File diff suppressed because it is too large Load diff

1186
gnulib/getopt.c Normal file

File diff suppressed because it is too large Load diff

225
gnulib/getopt.h Normal file
View file

@ -0,0 +1,225 @@
/* Declarations for getopt.
Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_H
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
/* Standalone applications should #define __GETOPT_PREFIX to an
identifier that prefixes the external functions and variables
defined in this header. When this happens, include the
headers that might declare getopt so that they will not cause
confusion if included after this file. Then systematically rename
identifiers so that they do not collide with the system functions
and variables. Renaming avoids problems with some compilers and
linkers. */
#if defined __GETOPT_PREFIX && !defined __need_getopt
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>
# undef __need_getopt
# undef getopt
# undef getopt_long
# undef getopt_long_only
# undef optarg
# undef opterr
# undef optind
# undef optopt
# define __GETOPT_CONCAT(x, y) x ## y
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
# define getopt __GETOPT_ID (getopt)
# define getopt_long __GETOPT_ID (getopt_long)
# define getopt_long_only __GETOPT_ID (getopt_long_only)
# define optarg __GETOPT_ID (optarg)
# define opterr __GETOPT_ID (opterr)
# define optind __GETOPT_ID (optind)
# define optopt __GETOPT_ID (optopt)
#endif
/* Standalone applications get correct prototypes for getopt_long and
getopt_long_only; they declare "char **argv". libc uses prototypes
with "char *const *argv" that are incorrect because getopt_long and
getopt_long_only can permute argv; this is required for backward
compatibility (e.g., for LSB 2.0.1).
This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
but it caused redefinition warnings if both unistd.h and getopt.h were
included, since unistd.h includes getopt.h having previously defined
__need_getopt.
The only place where __getopt_argv_const is used is in definitions
of getopt_long and getopt_long_only below, but these are visible
only if __need_getopt is not defined, so it is quite safe to rewrite
the conditional as follows:
*/
#if !defined __need_getopt
# if defined __GETOPT_PREFIX
# define __getopt_argv_const /* empty */
# else
# define __getopt_argv_const const
# endif
#endif
/* If __GNU_LIBRARY__ is not already defined, either we are being used
standalone, or this is the first header included in the source file.
If we are being used with glibc, we need to include <features.h>, but
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
not defined, include <ctype.h>, which will pull in <features.h> for us
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#endif
#ifndef __THROW
# ifndef __GNUC_PREREQ
# define __GNUC_PREREQ(maj, min) (0)
# endif
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# else
# define __THROW
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
const char *name;
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `-', then non-option arguments are treated as
arguments to the option '\1'. This behavior is specific to the GNU
`getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in
the environment, then do not permute arguments. */
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
__THROW;
#ifndef __need_getopt
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind)
__THROW;
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind)
__THROW;
#endif
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */

170
gnulib/getopt1.c Normal file
View file

@ -0,0 +1,170 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef _LIBC
# include <getopt.h>
#else
# include <config.h>
# include "getopt.h"
#endif
#include "getopt_int.h"
#include <stdio.h>
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, (char **) argv, options, long_options,
opt_index, 0, 0);
}
int
_getopt_long_r (int argc, char **argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
0, 0, d);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (int argc, char *__getopt_argv_const *argv,
const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, (char **) argv, options, long_options,
opt_index, 1, 0);
}
int
_getopt_long_only_r (int argc, char **argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r (argc, argv, options, long_options, opt_index,
1, 0, d);
}
#ifdef TEST
#include <stdio.h>
int
main (int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

130
gnulib/getopt_int.h Normal file
View file

@ -0,0 +1,130 @@
/* Internal declarations for getopt.
Copyright (C) 1989-1994,1996-1999,2001,2003,2004
Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GETOPT_INT_H
#define _GETOPT_INT_H 1
extern int _getopt_internal (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only, int __posixly_correct);
/* Reentrant versions which can handle parsing multiple argument
vectors at the same time. */
/* Data type for reentrant functions. */
struct _getopt_data
{
/* These have exactly the same meaning as the corresponding global
variables, except that they are used for the reentrant
versions of getopt. */
int optind;
int opterr;
int optopt;
char *optarg;
/* Internal members. */
/* True if the internal members have been initialized. */
int __initialized;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
char *__nextchar;
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters, or by calling getopt.
PERMUTE is the default. We permute the contents of ARGV as we
scan, so that eventually all the non-options are at the end.
This allows options to be given in any order, even with programs
that were not written to expect this.
RETURN_IN_ORDER is an option available to programs that were
written to expect options and other ARGV-elements in any order
and that care about the ordering of the two. We describe each
non-option ARGV-element as if it were the argument of an option
with character code 1. Using `-' as the first character of the
list of option characters selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} __ordering;
/* If the POSIXLY_CORRECT environment variable is set
or getopt was called. */
int __posixly_correct;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first
of them; `last_nonopt' is the index after the last of them. */
int __first_nonopt;
int __last_nonopt;
#if defined _LIBC && defined USE_NONOPTION_FLAGS
int __nonoption_flags_max_len;
int __nonoption_flags_len;
# endif
};
/* The initializer is necessary to set OPTIND and OPTERR to their
default values and to clear the initialization flag. */
#define _GETOPT_DATA_INITIALIZER { 1, 1 }
extern int _getopt_internal_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only, int __posixly_correct,
struct _getopt_data *__data);
extern int _getopt_long_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
struct _getopt_data *__data);
extern int _getopt_long_only_r (int ___argc, char **___argv,
const char *__shortopts,
const struct option *__longopts,
int *__longind,
struct _getopt_data *__data);
#endif /* getopt_int.h */

270
gnulib/gettext.h Normal file
View file

@ -0,0 +1,270 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
#if ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dcgettext(Domainname, Msgid, Category) \
((void) (Category), dgettext (Domainname, Msgid))
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 \
? ((void) (Msgid2), (const char *) (Msgid1)) \
: ((void) (Msgid1), (const char *) (Msgid2)))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) \
((void) (Domainname), (const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) \
((void) (Domainname), (const char *) (Codeset))
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

View file

@ -0,0 +1 @@
#include <grub/i386/pc/boot.h>

View file

@ -0,0 +1,28 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER
#define GRUB_INIT_I386_LINUXBIOS_HEADER 1
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_stop_floppy) (void);
#endif

View file

@ -0,0 +1 @@
#include <grub/cpu/loader.h>

View file

@ -0,0 +1 @@
#include <grub/i386/pc/serial.h>

View file

@ -0,0 +1 @@
#include <grub/i386/pc/time.h>

View file

@ -68,7 +68,7 @@ extern void* grub_assert_fail (void);
struct grub_named_list struct grub_named_list
{ {
struct grub_named_list *next; struct grub_named_list *next;
const char *name; char *name;
}; };
typedef struct grub_named_list *grub_named_list_t; typedef struct grub_named_list *grub_named_list_t;
@ -91,7 +91,7 @@ void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
struct grub_prio_list struct grub_prio_list
{ {
struct grub_prio_list *next; struct grub_prio_list *next;
const char *name; char *name;
int prio; int prio;
}; };
typedef struct grub_prio_list *grub_prio_list_t; typedef struct grub_prio_list *grub_prio_list_t;

View file

@ -31,7 +31,7 @@ grub_register_command_prio (const char *name,
{ {
grub_command_t cmd; grub_command_t cmd;
cmd = (grub_command_t) grub_malloc (sizeof (*cmd)); cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
if (! cmd) if (! cmd)
return 0; return 0;
@ -42,7 +42,6 @@ grub_register_command_prio (const char *name,
cmd->flags = GRUB_COMMAND_FLAG_BOTH; cmd->flags = GRUB_COMMAND_FLAG_BOTH;
cmd->prio = prio; cmd->prio = prio;
cmd->data = 0;
grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list), grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
GRUB_AS_PRIO_LIST (cmd)); GRUB_AS_PRIO_LIST (cmd));

View file

@ -1,6 +1,6 @@
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -40,7 +40,7 @@ void
grub_machine_mmap_init () grub_machine_mmap_init ()
{ {
if (! startup_multiboot_info) if (! startup_multiboot_info)
grub_fatal ("Must be loaded using Multiboot specification (is this an old version of coreboot?)"); grub_fatal ("Unable to find Multiboot Information (is CONFIG_MULTIBOOT disabled in coreboot?)");
/* Move MBI to a safe place. */ /* Move MBI to a safe place. */
grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info)); grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info));
@ -51,7 +51,8 @@ grub_machine_mmap_init ()
/* Move the memory map to a safe place. */ /* Move the memory map to a safe place. */
if (kern_multiboot_info.mmap_length > sizeof (mmap_entries)) if (kern_multiboot_info.mmap_length > sizeof (mmap_entries))
{ {
grub_printf ("WARNING: Memory map size exceeds limit; it will be truncated\n"); grub_printf ("WARNING: Memory map size exceeds limit (0x%x > 0x%x); it will be truncated\n",
kern_multiboot_info.mmap_length, sizeof (mmap_entries));
kern_multiboot_info.mmap_length = sizeof (mmap_entries); kern_multiboot_info.mmap_length = sizeof (mmap_entries);
} }
grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length); grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);

View file

@ -19,6 +19,7 @@
#include <grub/list.h> #include <grub/list.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/mm.h>
void void
grub_list_push (grub_list_t *head, grub_list_t item) grub_list_push (grub_list_t *head, grub_list_t item)
@ -81,7 +82,7 @@ grub_list_insert (grub_list_t *head, grub_list_t item,
void * void *
grub_named_list_find (grub_named_list_t head, const char *name) grub_named_list_find (grub_named_list_t head, const char *name)
{ {
grub_named_list_t result = 0; grub_named_list_t result = NULL;
auto int list_find (grub_named_list_t item); auto int list_find (grub_named_list_t item);
int list_find (grub_named_list_t item) int list_find (grub_named_list_t item)

View file

@ -22,6 +22,7 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/env.h> #include <grub/env.h>
#include <grub/normal.h> #include <grub/normal.h>
#include <grub/time.h>
struct grub_auth_user struct grub_auth_user
{ {
@ -35,17 +36,19 @@ struct grub_auth_user
struct grub_auth_user *users = NULL; struct grub_auth_user *users = NULL;
int int
grub_auth_strcmp (const char *user_input, const char *template) grub_auth_strcmp (const char *s1, const char *s2)
{ {
int ok = 1; int ret;
const char *ptr1, *ptr2; grub_uint64_t end;
for (ptr1 = user_input, ptr2 = template; *ptr1; ptr1++)
if (*ptr1 == (ptr2 ? *ptr2 : ptr1[1]) && ok && ptr2 != NULL)
ptr2++;
else
ok = 0;
return !ok; end = grub_get_time_ms () + 100;
ret = grub_strcmp (s1, s2);
/* This prevents an attacker from deriving information about the
password from the time it took to execute this function. */
while (grub_get_time_ms () < end);
return ret;
} }
static int static int
@ -208,6 +211,7 @@ grub_auth_check_authentication (const char *userlist)
char login[1024]; char login[1024];
struct grub_auth_user *cur = NULL; struct grub_auth_user *cur = NULL;
grub_err_t err; grub_err_t err;
static unsigned long punishment_delay = 1;
auto int hook (grub_list_t item); auto int hook (grub_list_t item);
int hook (grub_list_t item) int hook (grub_list_t item)
@ -228,11 +232,14 @@ grub_auth_check_authentication (const char *userlist)
grub_memset (login, 0, sizeof (login)); grub_memset (login, 0, sizeof (login));
if (is_authenticated (userlist)) if (is_authenticated (userlist))
return GRUB_ERR_NONE; {
punishment_delay = 1;
return GRUB_ERR_NONE;
}
if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1, if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1,
0, 0, 0)) 0, 0, 0))
return GRUB_ACCESS_DENIED; goto access_denied;
grub_list_iterate (GRUB_AS_LIST (users), hook); grub_list_iterate (GRUB_AS_LIST (users), hook);
@ -242,15 +249,25 @@ grub_auth_check_authentication (const char *userlist)
/* No users present at all. */ /* No users present at all. */
if (!cur) if (!cur)
return GRUB_ACCESS_DENIED; goto access_denied;
/* Display any of available authentication schemes. */ /* Display any of available authentication schemes. */
err = cur->callback (login, 0); err = cur->callback (login, 0);
return GRUB_ACCESS_DENIED; goto access_denied;
} }
err = cur->callback (login, cur->arg); err = cur->callback (login, cur->arg);
if (is_authenticated (userlist)) if (is_authenticated (userlist))
return GRUB_ERR_NONE; {
punishment_delay = 1;
return GRUB_ERR_NONE;
}
access_denied:
grub_sleep (punishment_delay);
if (punishment_delay < GRUB_ULONG_MAX / 2)
punishment_delay *= 2;
return GRUB_ACCESS_DENIED; return GRUB_ACCESS_DENIED;
} }

View file

@ -25,22 +25,15 @@
#include <grub/normal.h> #include <grub/normal.h>
/* This is used to store the names of filesystem modules for auto-loading. */ /* This is used to store the names of filesystem modules for auto-loading. */
struct grub_fs_module_list static grub_named_list_t fs_module_list;
{
char *name;
struct grub_fs_module_list *next;
};
typedef struct grub_fs_module_list *grub_fs_module_list_t;
static grub_fs_module_list_t fs_module_list = 0;
/* The auto-loading hook for filesystems. */ /* The auto-loading hook for filesystems. */
static int static int
autoload_fs_module (void) autoload_fs_module (void)
{ {
grub_fs_module_list_t p; grub_named_list_t p;
while ((p = fs_module_list) != 0) while ((p = fs_module_list) != NULL)
{ {
if (! grub_dl_get (p->name) && grub_dl_load (p->name)) if (! grub_dl_get (p->name) && grub_dl_load (p->name))
return 1; return 1;
@ -84,7 +77,7 @@ read_fs_list (void)
char *buf; char *buf;
char *p; char *p;
char *q; char *q;
grub_fs_module_list_t fs_mod; grub_named_list_t fs_mod;
buf = grub_file_getline (file); buf = grub_file_getline (file);
if (! buf) if (! buf)

View file

@ -83,8 +83,8 @@ read_command_list (void)
file = grub_file_open (filename); file = grub_file_open (filename);
if (file) if (file)
{ {
char *buf = 0; char *buf = NULL;
for (;; grub_free(buf)) for (;; grub_free (buf))
{ {
char *p, *name, *modname; char *p, *name, *modname;
grub_command_t cmd; grub_command_t cmd;

View file

@ -181,8 +181,8 @@ read_handler_list (void)
file = grub_file_open (filename); file = grub_file_open (filename);
if (file) if (file)
{ {
char *buf = 0; char *buf = NULL;
for (;; grub_free(buf)) for (;; grub_free (buf))
{ {
char *p; char *p;

View file

@ -158,7 +158,7 @@ EOF
} }
EOF EOF
;; ;;
hurd|*) hurd)
cat << EOF cat << EOF
menuentry "${LONGNAME} (on ${DEVICE})" { menuentry "${LONGNAME} (on ${DEVICE})" {
EOF EOF
@ -182,5 +182,8 @@ EOF
} }
EOF EOF
;; ;;
*)
echo " ${LONGNAME} is not yet supported by grub-mkconfig." >&2
;;
esac esac
done done

View file

@ -0,0 +1,148 @@
#! /bin/sh -e
# Make GRUB rescue image
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
transform="@program_transform_name@"
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
libdir=@libdir@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_TARNAME=@PACKAGE_TARNAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
target_cpu=@target_cpu@
platform=@platform@
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}`
grub_mkisofs=${bindir}/`echo grub-mkisofs | sed ${transform}`
# Usage: usage
# Print the usage.
usage () {
cat <<EOF
Usage: $0 [OPTION] output_image
Make GRUB rescue image.
-h, --help print this message and exit
-v, --version print the version information and exit
--modules=MODULES pre-load specified modules MODULES
--overlay=DIR overlay directory DIR in the memdisk image
(may be specified multiple times)
--pkglibdir=DIR use images from directory DIR instead of ${pkglibdir}
--grub-mkimage=FILE use FILE as grub-mkimage
--grub-mkisofs=FILE use FILE as grub-mkisofs
$0 generates a bootable rescue image.
Report bugs to <bug-grub@gnu.org>.
EOF
}
input_dir=${pkglibdir}
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
-v | --version)
echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
exit 0 ;;
--modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;;
--overlay=*)
overlay=${overlay}${overlay:+ }`echo "$option" | sed 's/--overlay=//'` ;;
--pkglibdir=*)
input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;;
--grub-mkimage=*)
grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;;
--grub-mkisofs=*)
grub_mkisofs=`echo "$option" | sed 's/--grub-mkisofs=//'` ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
exit 1
;;
*)
if test "x$output_image" != x; then
echo "Unrecognized option \`$option'" 1>&2
usage
exit 1
fi
output_image="${option}" ;;
esac
done
if test "x$output_image" = x; then
usage
exit 1
fi
memdisk_dir=`mktemp -d`
iso9660_dir=`mktemp -d`
mkdir -p ${memdisk_dir}/boot/grub ${iso9660_dir}/boot/grub
for file in ${input_dir}/*.mod ${input_dir}/efiemu??.o \
${input_dir}/command.lst ${input_dir}/moddep.lst ${input_dir}/fs.lst \
${input_dir}/handler.lst ${input_dir}/parttool.lst; do
if test -f "$file"; then
cp -f "$file" ${iso9660_dir}/boot/grub/
fi
done
# obtain date-based UUID
iso_uuid=$(date +%Y-%m-%d-%H-%M-%S-00)
# first-stage grub.cfg
cat << EOF >> ${memdisk_dir}/boot/grub/grub.cfg
search --fs-uuid --set ${iso_uuid}
set prefix=(\${root})/boot/grub
source /boot/grub/grub.cfg
EOF
# build memdisk
memdisk_img=`mktemp`
tar -C ${memdisk_dir} -cf ${memdisk_img} boot
rm -rf ${memdisk_dir}
# build core.img
mkdir -p ${iso9660_dir}/boot/grub
${grub_mkimage} -d ${input_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \
at_keyboard memdisk tar ata search iso9660 configfile sh
rm -f ${memdisk_img}
for d in ${overlay}; do
echo "Overlaying $d"
cp -dpR "${d}"/* "${iso9660_dir}"/
done
# second-stage grub.cfg
modules="`cat ${input_dir}/partmap.lst` ${modules}"
for i in ${modules} ; do
echo "insmod $i"
done > ${iso9660_dir}/boot/grub/grub.cfg
# build iso image
${grub_mkisofs} \
--modification-date=$(echo ${iso_uuid} | sed -e s/-//g) \
-o ${output_image} -r -J ${iso9660_dir}
exit 0

View file

@ -36,7 +36,7 @@ grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: grub-mkrescue [OPTION] output_image Usage: $0 [OPTION] output_image
Make GRUB rescue image. Make GRUB rescue image.
-h, --help print this message and exit -h, --help print this message and exit
@ -50,7 +50,7 @@ Make GRUB rescue image.
--emulation=TYPE select El Torito boot emulation type floppy --emulation=TYPE select El Torito boot emulation type floppy
or none (default) (cdrom only) or none (default) (cdrom only)
grub-mkimage generates a bootable rescue image of the specified type. $0 generates a bootable rescue image of the specified type.
Report bugs to <bug-grub@gnu.org>. Report bugs to <bug-grub@gnu.org>.
EOF EOF
@ -67,7 +67,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;

54
util/mkisofs/defaults.h Normal file
View file

@ -0,0 +1,54 @@
/*
* Header file defaults.h - assorted default values for character strings in
* the volume descriptor.
*
* $Id: defaults.h,v 1.8 1999/03/02 03:41:25 eric Exp $
*/
#define PREPARER_DEFAULT NULL
#define PUBLISHER_DEFAULT NULL
#ifndef APPID_DEFAULT
#define APPID_DEFAULT "MKISOFS ISO 9660 FILESYSTEM BUILDER"
#endif
#define COPYRIGHT_DEFAULT NULL
#define BIBLIO_DEFAULT NULL
#define ABSTRACT_DEFAULT NULL
#define VOLSET_ID_DEFAULT NULL
#define VOLUME_ID_DEFAULT "CDROM"
#define BOOT_CATALOG_DEFAULT "boot.catalog"
#define BOOT_IMAGE_DEFAULT NULL
#ifdef __QNX__
#define SYSTEM_ID_DEFAULT "QNX"
#endif
#ifdef __osf__
#define SYSTEM_ID_DEFAULT "OSF"
#endif
#ifdef __sun
#ifdef __SVR4
#define SYSTEM_ID_DEFAULT "Solaris"
#else
#define SYSTEM_ID_DEFAULT "SunOS"
#endif
#endif
#ifdef __hpux
#define SYSTEM_ID_DEFAULT "HP-UX"
#endif
#ifdef __sgi
#define SYSTEM_ID_DEFAULT "SGI"
#endif
#ifdef _AIX
#define SYSTEM_ID_DEFAULT "AIX"
#endif
#ifdef _WIN
#define SYSTEM_ID_DEFAULT "Win32"
#endif /* _WIN */
#ifndef SYSTEM_ID_DEFAULT
#define SYSTEM_ID_DEFAULT "LINUX"
#endif

290
util/mkisofs/eltorito.c Normal file
View file

@ -0,0 +1,290 @@
/*
* Program eltorito.c - Handle El Torito specific extensions to iso9660.
*
Written by Michael Fulbright <msf@redhat.com> (1996).
Copyright 1996 RedHat Software, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static char rcsid[] ="$Id: eltorito.c,v 1.13 1999/03/02 03:41:25 eric Exp $";
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include "config.h"
#include "mkisofs.h"
#include "iso9660.h"
/* used by Win32 for opening binary file - not used by Unix */
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#undef MIN
#define MIN(a, b) (((a) < (b))? (a): (b))
static struct eltorito_validation_entry valid_desc;
static struct eltorito_defaultboot_entry default_desc;
static struct eltorito_boot_descriptor gboot_desc;
static int tvd_write __PR((FILE * outfile));
/*
* Check for presence of boot catalog. If it does not exist then make it
*/
void FDECL1(init_boot_catalog, const char *, path)
{
int bcat;
char * bootpath; /* filename of boot catalog */
char * buf;
struct stat statbuf;
bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
strcpy(bootpath, path);
if (bootpath[strlen(bootpath)-1] != '/')
{
strcat(bootpath,"/");
}
strcat(bootpath, boot_catalog);
/*
* check for the file existing
*/
#ifdef DEBUG_TORITO
fprintf(stderr,"Looking for boot catalog file %s\n",bootpath);
#endif
if (!stat_filter(bootpath, &statbuf))
{
/*
* make sure its big enough to hold what we want
*/
if (statbuf.st_size == 2048)
{
/*
* printf("Boot catalog exists, so we do nothing\n");
*/
free(bootpath);
return;
}
else
{
fprintf(stderr, "A boot catalog exists and appears corrupted.\n");
fprintf(stderr, "Please check the following file: %s.\n",bootpath);
fprintf(stderr, "This file must be removed before a bootable CD can be done.\n");
free(bootpath);
exit(1);
}
}
/*
* file does not exist, so we create it
* make it one CD sector long
*/
bcat = open(bootpath, O_WRONLY | O_CREAT | O_BINARY, S_IROTH | S_IRGRP | S_IRWXU );
if (bcat == -1)
{
fprintf(stderr, "Error creating boot catalog, exiting...\n");
perror("");
exit(1);
}
buf = (char *) e_malloc( 2048 );
write(bcat, buf, 2048);
close(bcat);
free(bootpath);
} /* init_boot_catalog(... */
void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
{
int bootcat;
int checksum;
unsigned char * checksum_ptr;
struct directory_entry * de;
struct directory_entry * de2;
unsigned int i;
int nsectors;
memset(boot_desc, 0, sizeof(*boot_desc));
boot_desc->id[0] = 0;
memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
boot_desc->version[0] = 1;
memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));
/*
* search from root of iso fs to find boot catalog
*/
de2 = search_tree_file(root, boot_catalog);
if (!de2)
{
fprintf(stderr,"Uh oh, I cant find the boot catalog!\n");
exit(1);
}
set_731(boot_desc->bootcat_ptr,
(unsigned int) get_733(de2->isorec.extent));
/*
* now adjust boot catalog
* lets find boot image first
*/
de=search_tree_file(root, boot_image);
if (!de)
{
fprintf(stderr,"Uh oh, I cant find the boot image!\n");
exit(1);
}
/*
* we have the boot image, so write boot catalog information
* Next we write out the primary descriptor for the disc
*/
memset(&valid_desc, 0, sizeof(valid_desc));
valid_desc.headerid[0] = 1;
valid_desc.arch[0] = EL_TORITO_ARCH_x86;
/*
* we'll shove start of publisher id into id field, may get truncated
* but who really reads this stuff!
*/
if (publisher)
memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher)));
valid_desc.key1[0] = 0x55;
valid_desc.key2[0] = 0xAA;
/*
* compute the checksum
*/
checksum=0;
checksum_ptr = (unsigned char *) &valid_desc;
for (i=0; i<sizeof(valid_desc); i+=2)
{
/*
* skip adding in ckecksum word, since we dont have it yet!
*/
if (i == 28)
{
continue;
}
checksum += (unsigned int)checksum_ptr[i];
checksum += ((unsigned int)checksum_ptr[i+1])*256;
}
/*
* now find out the real checksum
*/
checksum = -checksum;
set_721(valid_desc.cksum, (unsigned int) checksum);
/*
* now make the initial/default entry for boot catalog
*/
memset(&default_desc, 0, sizeof(default_desc));
default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
/*
* use default BIOS loadpnt
*/
set_721(default_desc.loadseg, 0);
default_desc.arch[0] = EL_TORITO_ARCH_x86;
/*
* figure out size of boot image in sectors, for now hard code to
* assume 512 bytes/sector on a bootable floppy
*/
nsectors = ((de->size + 511) & ~(511))/512;
fprintf(stderr, "\nSize of boot image is %d sectors -> ", nsectors);
/*
* choose size of emulated floppy based on boot image size
*/
if (nsectors == 2880 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
fprintf(stderr, "Emulating a 1.44 meg floppy\n");
}
else if (nsectors == 5760 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
fprintf(stderr,"Emulating a 2.88 meg floppy\n");
}
else if (nsectors == 2400 )
{
default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
fprintf(stderr,"Emulating a 1.2 meg floppy\n");
}
else
{
fprintf(stderr,"\nError - boot image is not the an allowable size.\n");
exit(1);
}
/*
* FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!!
*/
nsectors = 1;
set_721(default_desc.nsect, (unsigned int) nsectors );
#ifdef DEBUG_TORITO
fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent));
#endif
set_731(default_desc.bootoff,
(unsigned int) get_733(de->isorec.extent));
/*
* now write it to disk
*/
bootcat = open(de2->whole_name, O_RDWR | O_BINARY);
if (bootcat == -1)
{
fprintf(stderr,"Error opening boot catalog for update.\n");
perror("");
exit(1);
}
/*
* write out
*/
write(bootcat, &valid_desc, 32);
write(bootcat, &default_desc, 32);
close(bootcat);
} /* get_torito_desc(... */
/*
* Function to write the EVD for the disc.
*/
static int FDECL1(tvd_write, FILE *, outfile)
{
/*
* Next we write out the boot volume descriptor for the disc
*/
get_torito_desc(&gboot_desc);
xfwrite(&gboot_desc, 1, 2048, outfile);
last_extent_written ++;
return 0;
}
struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write};

10
util/mkisofs/exclude.h Normal file
View file

@ -0,0 +1,10 @@
/*
* 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de:
* added 'exclude' option (-x) to specify pathnames NOT to be included in
* CD image.
*
* $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $
*/
void exclude __PR((char * fn));
int is_excluded __PR((char * fn));

230
util/mkisofs/fnmatch.c Normal file
View file

@ -0,0 +1,230 @@
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
static char rcsid[] ="$Id: fnmatch.c,v 1.4 1999/03/02 03:41:25 eric Exp $";
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include <fnmatch.h>
#ifndef __STDC__
#define const
#endif
#ifndef FNM_FILE_NAME
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#endif
#ifndef FNM_LEADING_DIR
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#endif
#ifndef FNM_CASEFOLD
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
#include <ctype.h>
#if defined (STDC_HEADERS) || !defined (isascii)
#define ISASCII(c) 1
#else
#define ISASCII(c) isascii(c)
#endif
#define ISUPPER(c) (ISASCII (c) && isupper (c))
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
extern int errno;
#endif
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
{
register const char *p = pattern, *n = string;
register char c;
/* Note that this evalutes C many times. */
#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
while ((c = *p++) != '\0')
{
c = FOLD ((unsigned char)c);
switch (c)
{
case '?':
if (*n == '\0')
return FNM_NOMATCH;
else if ((flags & FNM_FILE_NAME) && *n == '/')
return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
return FNM_NOMATCH;
break;
case '\\':
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
c = FOLD ((unsigned char )c);
}
if (FOLD ((unsigned char )*n) != c)
return FNM_NOMATCH;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
if (((flags & FNM_FILE_NAME) && *n == '/') ||
(c == '?' && *n == '\0'))
return FNM_NOMATCH;
if (c == '\0')
return 0;
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
c1 = FOLD ((unsigned char )c1);
for (--p; *n != '\0'; ++n)
if ((c == '[' || FOLD ((unsigned char )*n) == c1) &&
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
return 0;
return FNM_NOMATCH;
}
case '[':
{
/* Nonzero if the sense of the character class is inverted. */
register int not;
if (*n == '\0')
return FNM_NOMATCH;
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
return FNM_NOMATCH;
not = (*p == '!' || *p == '^');
if (not)
++p;
c = *p++;
for (;;)
{
register char cstart = c, cend = c;
if (!(flags & FNM_NOESCAPE) && c == '\\')
cstart = cend = *p++;
cstart = cend = FOLD ((unsigned char)cstart);
if (c == '\0')
/* [ (unterminated) loses. */
return FNM_NOMATCH;
c = *p++;
c = FOLD ((unsigned char)c);
if ((flags & FNM_FILE_NAME) && c == '/')
/* [/] can never match. */
return FNM_NOMATCH;
if (c == '-' && *p != ']')
{
cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
cend = FOLD ((unsigned char)cend);
c = *p++;
}
if (FOLD ((unsigned char)*n) >= cstart && FOLD ((unsigned char)*n) <= cend)
goto matched;
if (c == ']')
break;
}
if (!not)
return FNM_NOMATCH;
break;
matched:;
/* Skip the rest of the [...] that already matched. */
while (c != ']')
{
if (c == '\0')
/* [... (unterminated) loses. */
return FNM_NOMATCH;
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
if (not)
return FNM_NOMATCH;
}
break;
default:
if (c != FOLD ((unsigned char)*n))
return FNM_NOMATCH;
}
++n;
}
if (*n == '\0')
return 0;
if ((flags & FNM_LEADING_DIR) && *n == '/')
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
return FNM_NOMATCH;
}
#endif /* _LIBC or not __GNU_LIBRARY__. */

762
util/mkisofs/getopt.c Normal file
View file

@ -0,0 +1,762 @@
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 2009
Free Software Foundation, Inc.
This file is part of the libiberty library. This library is free
software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option)
any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, if you link this library with files
compiled with a GNU compiler to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#ifndef __STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
#include <assert.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
/* Many versions of the Linux C library include older, broken versions
of these routines, which will break the linker's command-line
parsing. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#include <stdlib.h>
#endif /* GNU C library. */
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "getopt.h"
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* XXX 1003.2 says this must be 1 before any call. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own getopt implementation. */
int optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
#include <string.h>
#define my_index strchr
#else
/* Avoid depending on library functions or files
whose names are inconsistent. */
char *getenv ();
static char *
my_index (str, chr)
const char *str;
int chr;
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
#ifndef __STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
static void
exchange (argv)
char **argv;
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Initialize the internal data when the first call is made. */
static const char *
_getopt_initialize (optstring)
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = optind = 1;
nextchar = NULL;
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (getenv ("POSIXLY_CORRECT") != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
{
optarg = NULL;
if (optind == 0)
optstring = _getopt_initialize (optstring);
if (argc == 0)
return EOF;
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
optind++;
last_nonopt = optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
assert (nameend > nextchar);
if (nameend == strlen (p->name) + nextchar)
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, "%s: option `%s' is ambiguous\n",
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
optind++;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (opterr)
{
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
"%s: option `--%s' doesn't allow an argument\n",
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
"%s: option `%c%s' doesn't allow an argument\n",
argv[0], argv[optind - 1][0], pfound->name);
}
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (opterr)
fprintf (stderr, "%s: option `%s' requires an argument\n",
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, "%s: unrecognized option `--%s'\n",
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
optind++;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
if (temp == NULL || c == ':')
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
}
optopt = c;
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
optarg = nextchar;
optind++;
}
else
optarg = NULL;
nextchar = NULL;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr, "%s: option requires an argument -- %c\n",
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = NULL;
}
}
return c;
}
}
int
getopt (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
if (c == EOF)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

190
util/mkisofs/getopt1.c Normal file
View file

@ -0,0 +1,190 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because it found this file in $srcdir). */
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include "getopt.h"
#ifndef __STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
/* Many versions of the Linux C library include older, broken versions
of these routines, which will break the linker's command-line
parsing. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || defined (__linux__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#else
char *getenv ();
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == EOF)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

227
util/mkisofs/hash.c Normal file
View file

@ -0,0 +1,227 @@
/*
* File hash.c - generate hash tables for iso9660 filesystem.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static char rcsid[] ="$Id: hash.c,v 1.4 1997/12/06 21:05:04 eric Exp $";
#include <stdlib.h>
#include "config.h"
#include "mkisofs.h"
#define NR_HASH 1024
#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH)
static struct file_hash * hash_table[NR_HASH] = {0,};
void FDECL1(add_hash, struct directory_entry *, spnt){
struct file_hash * s_hash;
unsigned int hash_number;
if(spnt->size == 0 || spnt->starting_block == 0)
if(spnt->size != 0 || spnt->starting_block != 0) {
fprintf(stderr,"Non zero-length file assigned zero extent.\n");
exit(1);
};
if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return;
hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode);
#if 0
if (verbose > 1) fprintf(stderr,"%s ",spnt->name);
#endif
s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
s_hash->next = hash_table[hash_number];
s_hash->inode = spnt->inode;
s_hash->dev = spnt->dev;
s_hash->starting_block = spnt->starting_block;
s_hash->size = spnt->size;
hash_table[hash_number] = s_hash;
}
struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){
unsigned int hash_number;
struct file_hash * spnt;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
spnt = hash_table[hash_number];
while(spnt){
if(spnt->inode == inode && spnt->dev == dev) return spnt;
spnt = spnt->next;
};
return NULL;
}
static struct file_hash * directory_hash_table[NR_HASH] = {0,};
void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){
struct file_hash * s_hash;
unsigned int hash_number;
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
s_hash->next = directory_hash_table[hash_number];
s_hash->inode = inode;
s_hash->dev = dev;
directory_hash_table[hash_number] = s_hash;
}
struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){
unsigned int hash_number;
struct file_hash * spnt;
hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
spnt = directory_hash_table[hash_number];
while(spnt){
if(spnt->inode == inode && spnt->dev == dev) return spnt;
spnt = spnt->next;
};
return NULL;
}
struct name_hash
{
struct name_hash * next;
struct directory_entry * de;
};
#define NR_NAME_HASH 128
static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
/*
* Find the hash bucket for this name.
*/
static unsigned int FDECL1(name_hash, const char *, name)
{
unsigned int hash = 0;
const char * p;
p = name;
while (*p)
{
/*
* Don't hash the iso9660 version number. This way
* we can detect duplicates in cases where we have
* directories (i.e. foo) and non-directories
* (i.e. foo;1).
*/
if( *p == ';' )
{
break;
}
hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
}
return hash % NR_NAME_HASH;
}
void FDECL1(add_file_hash, struct directory_entry *, de){
struct name_hash * new;
int hash;
new = (struct name_hash *) e_malloc(sizeof(struct name_hash));
new->de = de;
new->next = NULL;
hash = name_hash(de->isorec.name);
/* Now insert into the hash table */
new->next = name_hash_table[hash];
name_hash_table[hash] = new;
}
struct directory_entry * FDECL1(find_file_hash, char *, name)
{
struct name_hash * nh;
char * p1;
char * p2;
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
{
p1 = name;
p2 = nh->de->isorec.name;
/*
* Look for end of string, or a mismatch.
*/
while(1==1)
{
if( (*p1 == '\0' || *p1 == ';')
|| (*p2 == '\0' || *p2 == ';')
|| (*p1 != *p2) )
{
break;
}
p1++;
p2++;
}
/*
* If we are at the end of both strings, then
* we have a match.
*/
if( (*p1 == '\0' || *p1 == ';')
&& (*p2 == '\0' || *p2 == ';') )
{
return nh->de;
}
}
return NULL;
}
int FDECL1(delete_file_hash, struct directory_entry *, de){
struct name_hash * nh, *prev;
int hash;
prev = NULL;
hash = name_hash(de->isorec.name);
for(nh = name_hash_table[hash]; nh; nh = nh->next) {
if(nh->de == de) break;
prev = nh;
}
if(!nh) return 1;
if(!prev)
name_hash_table[hash] = nh->next;
else
prev->next = nh->next;
free(nh);
return 0;
}
void flush_file_hash(){
struct name_hash * nh, *nh1;
int i;
for(i=0; i<NR_NAME_HASH; i++) {
nh = name_hash_table[i];
while(nh) {
nh1 = nh->next;
free(nh);
nh = nh1;
}
name_hash_table[i] = NULL;
}
}

View file

@ -0,0 +1,57 @@
/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */
/*
* Generic header for users of open(), creat() and chmod()
*
* Copyright (c) 1996 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _FCTLDEFS_H
#define _FCTLDEFS_H
#ifndef _MCONFIG_H
#include <mconfig.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else /* HAVE_FCNTL_H */
# include <sys/file.h>
#endif /* HAVE_FCNTL_H */
/*
* Do not define more than O_RDONLY / O_WRONLY / O_RDWR
* The values may differ.
*/
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#ifndef O_WRONLY
#define O_WRONLY 1
#endif
#ifndef O_RDWR
#define O_RDWR 2
#endif
#endif /* _FCTLDEFS_H */

View file

@ -0,0 +1,253 @@
/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */
/*
* definitions for machine configuration
*
* Copyright (c) 1995 J. Schilling
*
* This file must be included before any other file.
* Use only cpp instructions.
*
* NOTE: SING: (Schily Is Not Gnu)
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _MCONFIG_H
#define _MCONFIG_H
#include <config.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(unix) || defined(__unix) || defined(__unix__)
# define IS_UNIX
#endif
#ifdef __MSDOS__
# define IS_MSDOS
#endif
#if defined(tos) || defined(__tos)
# define IS_TOS
#endif
#ifdef THINK_C
# define IS_MAC
#endif
#if defined(sun) || defined(__sun) || defined(__sun__)
# define IS_SUN
#endif
#if defined(__CYGWIN32__)
# define IS_GCC_WIN32
#endif
/*--------------------------------------------------------------------------*/
/*
* Some magic that cannot (yet) be figured out with autoconf.
*/
#ifdef sparc
# ifndef HAVE_LDSTUB
# define HAVE_LDSTUB
# endif
# ifndef HAVE_SCANSTACK
# define HAVE_SCANSTACK
# endif
#endif
#if defined(__i386_) || defined(i386)
# ifndef HAVE_XCHG
# define HAVE_XCHG
# endif
# ifndef HAVE_SCANSTACK
# define HAVE_SCANSTACK
# endif
#endif
#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \
|| defined(SVR4)
# ifndef __SVR4
# define __SVR4
# endif
#endif
#ifdef __SVR4
# ifndef SVR4
# define SVR4
# endif
#endif
/*
* SunOS 4.x / SunOS 5.x
*/
#if defined(IS_SUN)
# define HAVE_GETAV0
#endif
/*
* AIX
*/
#if defined(_IBMR2) || defined(_AIX)
# define IS_UNIX /* ??? really ??? */
#endif
/*
* Silicon Graphics (must be before SVR4)
*/
#if defined(sgi) || defined(__sgi)
# define __NOT_SVR4__ /* Not a real SVR4 implementation */
#endif
/*
* Data General
*/
#if defined(__DGUX__)
#ifdef XXXXXXX
# undef HAVE_MTGET_DSREG
# undef HAVE_MTGET_RESID
# undef HAVE_MTGET_FILENO
# undef HAVE_MTGET_BLKNO
#endif
# define mt_type mt_model
# define mt_dsreg mt_status1
# define mt_erreg mt_status2
/*
* DGUX hides its flock as dg_flock.
*/
# define HAVE_FLOCK
# define flock dg_flock
/*
* Use the BSD style wait on DGUX to get the resource usages of child
* processes.
*/
# define _BSD_WAIT_FLAVOR
#endif
/*
* Apple Rhapsody
*/
#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody
# define HAVE_OSDEF /* prevent later definitions to overwrite current */
#endif
/*
* NextStep
*/
#if defined(__NeXT__) && !defined(HAVE_OSDEF)
#define NO_PRINT_OVR
#undef HAVE_USG_STDIO /*
* NeXT Step 3.x uses __flsbuf(unsigned char , FILE *)
* instead of __flsbuf(int, FILE *)
*/
#endif
/*
* NextStep 3.x has a broken linker that does not allow us to override
* these functions.
*/
#ifndef __OPRINTF__
#ifdef NO_PRINT_OVR
# define printf Xprintf
# define fprintf Xfprintf
# define sprintf Xsprintf
#endif
#endif /* __OPRINTF__ */
/*--------------------------------------------------------------------------*/
/*
* If there is no flock defined by the system, use emulation
* through fcntl record locking.
*/
#ifndef HAVE_FLOCK
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* don't block when locking */
#define LOCK_UN 8 /* unlock */
#endif
#include <prototyp.h>
/*
* gcc 2.x generally implements the long long type.
*/
#ifdef __GNUC__
# if __GNUC__ > 1
# ifndef HAVE_LONGLONG
# define HAVE_LONGLONG
# endif
# endif
#endif
/*
* Convert to GNU name
*/
#ifdef HAVE_STDC_HEADERS
# ifndef STDC_HEADERS
# define STDC_HEADERS
# endif
#endif
/*
* Convert to SCHILY name
*/
#ifdef STDC_HEADERS
# ifndef HAVE_STDC_HEADERS
# define HAVE_STDC_HEADERS
# endif
#endif
#ifdef IS_UNIX
# define PATH_DELIM '/'
# define PATH_DELIM_STR "/"
# define far
# define near
#endif
#ifdef IS_GCC_WIN32
# define PATH_DELIM '/'
# define PATH_DELIM_STR "/"
# define far
# define near
#endif
#ifdef IS_MSDOS
# define PATH_DELIM '\\'
# define PATH_DELIM_STR "\\"
#endif
#ifdef IS_TOS
# define PATH_DELIM '\\'
# define PATH_DELIM_STR "\\"
# define far
# define near
#endif
#ifdef IS_MAC
# define PATH_DELIM ':'
# define PATH_DELIM_STR ":"
# define far
# define near
#endif
#ifdef __cplusplus
}
#endif
#endif /* _MCONFIG_H */

View file

@ -0,0 +1,74 @@
/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */
/*
* Definitions for dealing with ANSI / KR C-Compilers
*
* Copyright (c) 1995 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _PROTOTYP_H
#define _PROTOTYP_H
#ifndef PROTOTYPES
/*
* If this has already been defined,
* someone else knows better than us...
*/
# ifdef __STDC__
# if __STDC__ /* ANSI C */
# define PROTOTYPES
# endif
# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */
# define PROTOTYPES
# endif
# endif
#endif /* PROTOTYPES */
/*
* If we have prototypes, we should have stdlib.h string.h stdarg.h
*/
#ifdef PROTOTYPES
#if !(defined(SABER) && defined(sun))
# ifndef HAVE_STDARG_H
# define HAVE_STDARG_H
# endif
#endif
# ifndef HAVE_STDLIB_H
# define HAVE_STDLIB_H
# endif
# ifndef HAVE_STRING_H
# define HAVE_STRING_H
# endif
# ifndef HAVE_STDC_HEADERS
# define HAVE_STDC_HEADERS
# endif
# ifndef STDC_HEADERS
# define STDC_HEADERS /* GNU name */
# endif
#endif
#ifdef NO_PROTOTYPES /* Force not to use prototypes */
# undef PROTOTYPES
#endif
#ifdef PROTOTYPES
# define __PR(a) a
#else
# define __PR(a) ()
#endif
#endif /* _PROTOTYP_H */

View file

@ -0,0 +1,139 @@
/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */
/*
* Definitions for stat() file mode
*
* Copyright (c) 1998 J. Schilling
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _STATDEFS_H
#define _STATDEFS_H
#ifndef _MCONFIG_H
#include <mconfig.h>
#endif
#ifdef STAT_MACROS_BROKEN
#undef S_ISFIFO /* Named pipe */
#undef S_ISCHR /* Character special */
#undef S_ISMPC /* UNUSED multiplexed c */
#undef S_ISDIR /* Directory */
#undef S_ISNAM /* Named file (XENIX) */
#undef S_ISBLK /* Block special */
#undef S_ISMPB /* UNUSED multiplexed b */
#undef S_ISREG /* Regular file */
#undef S_ISCNT /* Contiguous file */
#undef S_ISLNK /* Symbolic link */
#undef S_ISSHAD /* Solaris shadow inode */
#undef S_ISSOCK /* UNIX domain socket */
#undef S_ISDOOR /* Solaris DOOR */
#endif
#ifndef S_ISFIFO /* Named pipe */
# ifdef S_IFIFO
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
# else
# define S_ISFIFO(m) (0)
# endif
#endif
#ifndef S_ISCHR /* Character special */
# ifdef S_IFCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
# else
# define S_ISCHR(m) (0)
# endif
#endif
#ifndef S_ISMPC /* UNUSED multiplexed c */
# ifdef S_IFMPC
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
# else
# define S_ISMPC(m) (0)
# endif
#endif
#ifndef S_ISDIR /* Directory */
# ifdef S_IFDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# else
# define S_ISDIR(m) (0)
# endif
#endif
#ifndef S_ISNAM /* Named file (XENIX) */
# ifdef S_IFNAM
# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
# else
# define S_ISNAM(m) (0)
# endif
#endif
#ifndef S_ISBLK /* Block special */
# ifdef S_IFBLK
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
# else
# define S_ISBLK(m) (0)
# endif
#endif
#ifndef S_ISMPB /* UNUSED multiplexed b */
# ifdef S_IFMPB
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
# else
# define S_ISMPB(m) (0)
# endif
#endif
#ifndef S_ISREG /* Regular file */
# ifdef S_IFREG
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
# else
# define S_ISREG(m) (0)
# endif
#endif
#ifndef S_ISCNT /* Contiguous file */
# ifdef S_IFCNT
# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT)
# else
# define S_ISCNT(m) (0)
# endif
#endif
#ifndef S_ISLNK /* Symbolic link */
# ifdef S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
# else
# define S_ISLNK(m) (0)
# endif
#endif
#ifndef S_ISSHAD /* Solaris shadow inode */
# ifdef S_IFSHAD
# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD)
# else
# define S_ISSHAD(m) (0)
# endif
#endif
#ifndef S_ISSOCK /* UNIX domain socket */
# ifdef S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
# else
# define S_ISSOCK(m) (0)
# endif
#endif
#ifndef S_ISDOOR /* Solaris DOOR */
# ifdef S_IFDOOR
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
# else
# define S_ISDOOR(m) (0)
# endif
#endif
#endif /* _STATDEFS_H */

158
util/mkisofs/iso9660.h Normal file
View file

@ -0,0 +1,158 @@
/*
* Header file iso9660.h - assorted structure definitions and typecasts.
* specific to iso9660 filesystem.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* $Id: iso9660.h,v 1.2 1997/05/17 15:46:44 eric Exp $
*/
#ifndef _ISOFS_FS_H
#define _ISOFS_FS_H
/*
* The isofs filesystem constants/structures
*/
/* This part borrowed from the bsd386 isofs */
#define ISODCL(from, to) (to - from + 1)
struct iso_volume_descriptor {
char type[ISODCL(1,1)]; /* 711 */
char id[ISODCL(2,6)];
char version[ISODCL(7,7)];
char data[ISODCL(8,2048)];
};
/* volume descriptor types */
#define ISO_VD_PRIMARY 1
#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */
#define ISO_VD_END 255
#define ISO_STANDARD_ID "CD001"
#define EL_TORITO_ID "EL TORITO SPECIFICATION"
#define EL_TORITO_ARCH_x86 0
#define EL_TORITO_ARCH_PPC 1
#define EL_TORITO_ARCH_MAC 2
#define EL_TORITO_BOOTABLE 0x88
#define EL_TORITO_MEDIA_NOEMUL 0
#define EL_TORITO_MEDIA_12FLOP 1
#define EL_TORITO_MEDIA_144FLOP 2
#define EL_TORITO_MEDIA_288FLOP 3
#define EL_TORITO_MEDIA_HD 4
struct iso_primary_descriptor {
char type [ISODCL ( 1, 1)]; /* 711 */
char id [ISODCL ( 2, 6)];
char version [ISODCL ( 7, 7)]; /* 711 */
char unused1 [ISODCL ( 8, 8)];
char system_id [ISODCL ( 9, 40)]; /* achars */
char volume_id [ISODCL ( 41, 72)]; /* dchars */
char unused2 [ISODCL ( 73, 80)];
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
char escape_sequences [ISODCL ( 89, 120)];
char volume_set_size [ISODCL (121, 124)]; /* 723 */
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
char logical_block_size [ISODCL (129, 132)]; /* 723 */
char path_table_size [ISODCL (133, 140)]; /* 733 */
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
char volume_set_id [ISODCL (191, 318)]; /* dchars */
char publisher_id [ISODCL (319, 446)]; /* achars */
char preparer_id [ISODCL (447, 574)]; /* achars */
char application_id [ISODCL (575, 702)]; /* achars */
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
char file_structure_version [ISODCL (882, 882)]; /* 711 */
char unused4 [ISODCL (883, 883)];
char application_data [ISODCL (884, 1395)];
char unused5 [ISODCL (1396, 2048)];
};
/* El Torito Boot Record Volume Descriptor */
struct eltorito_boot_descriptor {
char id [ISODCL ( 1, 1)]; /* 711 */
char id2 [ISODCL ( 2, 6)];
char version [ISODCL ( 7, 7)]; /* 711 */
char system_id [ISODCL ( 8, 39)];
char unused2 [ISODCL ( 40, 71)];
char bootcat_ptr [ISODCL ( 72 , 75)];
char unused5 [ISODCL ( 76, 2048)];
};
/* Validation entry for El Torito */
struct eltorito_validation_entry {
char headerid [ISODCL ( 1, 1)]; /* 711 */
char arch [ISODCL ( 2, 2)];
char pad1 [ISODCL ( 3, 4)]; /* 711 */
char id [ISODCL ( 5, 28)];
char cksum [ISODCL ( 29, 30)];
char key1 [ISODCL ( 31, 31)];
char key2 [ISODCL ( 32, 32)];
};
/* El Torito initial/default entry in boot catalog */
struct eltorito_defaultboot_entry {
char boot_id [ISODCL ( 1, 1)]; /* 711 */
char boot_media [ISODCL ( 2, 2)];
char loadseg [ISODCL ( 3, 4)]; /* 711 */
char arch [ISODCL ( 5, 5)];
char pad1 [ISODCL ( 6, 6)];
char nsect [ISODCL ( 7, 8)];
char bootoff [ISODCL ( 9, 12)];
char pad2 [ISODCL ( 13, 32)];
};
/* We use this to help us look up the parent inode numbers. */
struct iso_path_table{
unsigned char name_len[2]; /* 721 */
char extent[4]; /* 731 */
char parent[2]; /* 721 */
char name[1];
};
struct iso_directory_record {
unsigned char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
char extent [ISODCL (3, 10)]; /* 733 */
char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
char name [34]; /* Not really, but we need something here */
};
#endif

1022
util/mkisofs/joliet.c Normal file

File diff suppressed because it is too large Load diff

147
util/mkisofs/match.c Normal file
View file

@ -0,0 +1,147 @@
/*
* 27-Mar-96: Jan-Piet Mens <jpm@mens.de>
* added 'match' option (-m) to specify regular expressions NOT to be included
* in the CD image.
*/
static char rcsid[] ="$Id: match.c,v 1.3 1999/03/02 03:41:25 eric Exp $";
#include "config.h"
#include <prototyp.h>
#include <stdio.h>
#ifndef VMS
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#endif
#include <string.h>
#include "match.h"
#define MAXMATCH 1000
static char *mat[MAXMATCH];
void add_match(fn)
char * fn;
{
register int i;
for (i=0; mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return;
}
mat[i] = (char *) malloc(strlen(fn)+1);
if (! mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return;
}
strcpy(mat[i],fn);
}
int matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; mat[i] && i<MAXMATCH; i++) {
if (fnmatch(mat[i], fn, FNM_FILE_NAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
/* ISO9660/RR hide */
static char *i_mat[MAXMATCH];
void i_add_match(fn)
char * fn;
{
register int i;
for (i=0; i_mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return;
}
i_mat[i] = (char *) malloc(strlen(fn)+1);
if (! i_mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return;
}
strcpy(i_mat[i],fn);
}
int i_matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; i_mat[i] && i<MAXMATCH; i++) {
if (fnmatch(i_mat[i], fn, FNM_FILE_NAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
int i_ishidden()
{
return (i_mat[0] != NULL);
}
/* Joliet hide */
static char *j_mat[MAXMATCH];
void j_add_match(fn)
char * fn;
{
register int i;
for (i=0; j_mat[i] && i<MAXMATCH; i++);
if (i == MAXMATCH) {
fprintf(stderr,"Can't exclude RE '%s' - too many entries in table\n",fn);
return;
}
j_mat[i] = (char *) malloc(strlen(fn)+1);
if (! j_mat[i]) {
fprintf(stderr,"Can't allocate memory for excluded filename\n");
return;
}
strcpy(j_mat[i],fn);
}
int j_matches(fn)
char * fn;
{
/* very dumb search method ... */
register int i;
for (i=0; j_mat[i] && i<MAXMATCH; i++) {
if (fnmatch(j_mat[i], fn, FNM_FILE_NAME) != FNM_NOMATCH) {
return 1; /* found -> excluded filenmae */
}
}
return 0; /* not found -> not excluded */
}
int j_ishidden()
{
return (j_mat[0] != NULL);
}

22
util/mkisofs/match.h Normal file
View file

@ -0,0 +1,22 @@
/*
* 27th March 1996. Added by Jan-Piet Mens for matching regular expressions
* in paths.
*
*/
/*
* $Id: match.h,v 1.2 1999/03/02 03:41:25 eric Exp $
*/
#include "fnmatch.h"
void add_match __PR((char *fn));
int matches __PR((char *fn));
void i_add_match __PR((char *fn));
int i_matches __PR((char *fn));
int i_ishidden __PR((void));
void j_add_match __PR((char *fn));
int j_matches __PR((char *fn));
int j_ishidden __PR((void));

1387
util/mkisofs/mkisofs.c Normal file

File diff suppressed because it is too large Load diff

480
util/mkisofs/mkisofs.h Normal file
View file

@ -0,0 +1,480 @@
/*
* Header file mkisofs.h - assorted structure definitions and typecasts.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
Copyright (C) 2009 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $
*/
#include <stdio.h>
#include <prototyp.h>
/* This symbol is used to indicate that we do not have things like
symlinks, devices, and so forth available. Just files and dirs */
#ifdef VMS
#define NON_UNIXFS
#endif
#ifdef DJGPP
#define NON_UNIXFS
#endif
#ifdef VMS
#include <sys/dir.h>
#define dirent direct
#endif
#ifdef _WIN32
#define NON_UNIXFS
#endif /* _WIN32 */
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(HAVE_DIRENT_H)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined(HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif
# if defined(HAVE_NDIR_H)
# include <ndir.h>
# endif
#endif
#if defined(HAVE_STRING_H)
#include <string.h>
#else
#if defined(HAVE_STRINGS_H)
#include <strings.h>
#endif
#endif
#ifdef ultrix
extern char *strdup();
#endif
#ifdef __STDC__
#define DECL(NAME,ARGS) NAME ARGS
#define FDECL1(NAME,TYPE0, ARG0) \
NAME(TYPE0 ARG0)
#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \
NAME(TYPE0 ARG0, TYPE1 ARG1)
#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2)
#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3)
#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4)
#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5)
#else
#define DECL(NAME,ARGS) NAME()
#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0;
#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1;
#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2;
#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3;
#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4;
#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5;
#define const
#endif
#ifdef __SVR4
#include <stdlib.h>
#else
extern int optind;
extern char *optarg;
/* extern int getopt (int __argc, char **__argv, char *__optstring); */
#endif
#include "iso9660.h"
#include "defaults.h"
struct directory_entry{
struct directory_entry * next;
struct directory_entry * jnext;
struct iso_directory_record isorec;
unsigned int starting_block;
unsigned int size;
unsigned short priority;
unsigned char jreclen; /* Joliet record len */
char * name;
char * table;
char * whole_name;
struct directory * filedir;
struct directory_entry * parent_rec;
unsigned int de_flags;
ino_t inode; /* Used in the hash table */
dev_t dev; /* Used in the hash table */
unsigned char * rr_attributes;
unsigned int rr_attr_size;
unsigned int total_rr_attr_size;
unsigned int got_rr_name;
};
struct file_hash{
struct file_hash * next;
ino_t inode; /* Used in the hash table */
dev_t dev; /* Used in the hash table */
unsigned int starting_block;
unsigned int size;
};
/*
* This structure is used to control the output of fragments to the cdrom
* image. Everything that will be written to the output image will eventually
* go through this structure. There are two pieces - first is the sizing where
* we establish extent numbers for everything, and the second is when we actually
* generate the contents and write it to the output image.
*
* This makes it trivial to extend mkisofs to write special things in the image.
* All you need to do is hook an additional structure in the list, and the rest
* works like magic.
*
* The three passes each do the following:
*
* The 'size' pass determines the size of each component and assigns the extent number
* for that component.
*
* The 'generate' pass will adjust the contents and pointers as required now that extent
* numbers are assigned. In some cases, the contents of the record are also generated.
*
* The 'write' pass actually writes the data to the disc.
*/
struct output_fragment
{
struct output_fragment * of_next;
#ifdef __STDC__
int (*of_size)(int);
int (*of_generate)(void);
int (*of_write)(FILE *);
#else
int (*of_size)();
int (*of_generate)();
int (*of_write)();
#endif
};
extern struct output_fragment * out_list;
extern struct output_fragment * out_tail;
extern struct output_fragment padblock_desc;
extern struct output_fragment voldesc_desc;
extern struct output_fragment joliet_desc;
extern struct output_fragment torito_desc;
extern struct output_fragment end_vol;
extern struct output_fragment pathtable_desc;
extern struct output_fragment jpathtable_desc;
extern struct output_fragment dirtree_desc;
extern struct output_fragment dirtree_clean;
extern struct output_fragment jdirtree_desc;
extern struct output_fragment extension_desc;
extern struct output_fragment files_desc;
/*
* This structure describes one complete directory. It has pointers
* to other directories in the overall tree so that it is clear where
* this directory lives in the tree, and it also must contain pointers
* to the contents of the directory. Note that subdirectories of this
* directory exist twice in this stucture. Once in the subdir chain,
* and again in the contents chain.
*/
struct directory{
struct directory * next; /* Next directory at same level as this one */
struct directory * subdir; /* First subdirectory in this directory */
struct directory * parent;
struct directory_entry * contents;
struct directory_entry * jcontents;
struct directory_entry * self;
char * whole_name; /* Entire path */
char * de_name; /* Entire path */
unsigned int ce_bytes; /* Number of bytes of CE entries reqd for this dir */
unsigned int depth;
unsigned int size;
unsigned int extent;
unsigned int jsize;
unsigned int jextent;
unsigned short path_index;
unsigned short jpath_index;
unsigned short dir_flags;
unsigned short dir_nlink;
};
struct deferred{
struct deferred * next;
unsigned int starting_block;
char * name;
struct directory * filedir;
unsigned int flags;
};
extern int goof;
extern struct directory * root;
extern struct directory * reloc_dir;
extern unsigned int next_extent;
extern unsigned int last_extent;
extern unsigned int last_extent_written;
extern unsigned int session_start;
extern unsigned int path_table_size;
extern unsigned int path_table[4];
extern unsigned int path_blocks;
extern char * path_table_l;
extern char * path_table_m;
extern unsigned int jpath_table_size;
extern unsigned int jpath_table[4];
extern unsigned int jpath_blocks;
extern char * jpath_table_l;
extern char * jpath_table_m;
extern struct iso_directory_record root_record;
extern struct iso_directory_record jroot_record;
extern int use_eltorito;
extern int use_RockRidge;
extern int use_Joliet;
extern int rationalize;
extern int follow_links;
extern int verbose;
extern int all_files;
extern int generate_tables;
extern int print_size;
extern int split_output;
extern int omit_period;
extern int omit_version_number;
extern int transparent_compression;
extern unsigned int RR_relocation_depth;
extern int full_iso9660_filenames;
extern int split_SL_component;
extern int split_SL_field;
/* tree.c */
extern int DECL(stat_filter, (char *, struct stat *));
extern int DECL(lstat_filter, (char *, struct stat *));
extern int DECL(sort_tree,(struct directory *));
extern struct directory *
DECL(find_or_create_directory,(struct directory *, const char *,
struct directory_entry * self, int));
extern void DECL (finish_cl_pl_entries, (void));
extern int DECL(scan_directory_tree,(struct directory * this_dir,
char * path,
struct directory_entry * self));
extern int DECL(insert_file_entry,(struct directory *, char *,
char *));
extern void DECL(generate_iso9660_directories,(struct directory *, FILE*));
extern void DECL(dump_tree,(struct directory * node));
extern struct directory_entry * DECL(search_tree_file, (struct
directory * node,char * filename));
extern void DECL(update_nlink_field,(struct directory * node));
extern void DECL (init_fstatbuf, (void));
extern struct stat root_statbuf;
/* eltorito.c */
extern void DECL(init_boot_catalog, (const char * path ));
extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path ));
/* write.c */
extern int DECL(get_733,(char *));
extern int DECL(isonum_733,(unsigned char *));
extern void DECL(set_723,(char *, unsigned int));
extern void DECL(set_731,(char *, unsigned int));
extern void DECL(set_721,(char *, unsigned int));
extern void DECL(set_733,(char *, unsigned int));
extern int DECL(sort_directory,(struct directory_entry **));
extern void DECL(generate_one_directory,(struct directory *, FILE*));
extern void DECL(memcpy_max, (char *, char *, int));
extern int DECL(oneblock_size, (int starting_extent));
extern struct iso_primary_descriptor vol_desc;
extern void DECL(xfwrite, (void * buffer, int count, int size, FILE * file));
extern void DECL(set_732, (char * pnt, unsigned int i));
extern void DECL(set_722, (char * pnt, unsigned int i));
extern void DECL(outputlist_insert, (struct output_fragment * frag));
/*
* Set by user command-line to override default date values
*/
extern char *creation_date;
extern char *modification_date;
extern char *expiration_date;
extern char *effective_date;
/* multi.c */
extern FILE * in_image;
extern struct iso_directory_record *
DECL(merge_isofs,(char * path));
extern int DECL(free_mdinfo, (struct directory_entry **, int len));
extern struct directory_entry **
DECL(read_merging_directory,(struct iso_directory_record *, int*));
extern void
DECL(merge_remaining_entries, (struct directory *,
struct directory_entry **, int));
extern int
DECL(merge_previous_session, (struct directory *,
struct iso_directory_record *));
extern int DECL(get_session_start, (int *));
/* joliet.c */
int DECL(joliet_sort_tree, (struct directory * node));
/* match.c */
extern int DECL(matches, (char *));
extern void DECL(add_match, (char *));
/* files.c */
struct dirent * DECL(readdir_add_files, (char **, char *, DIR *));
/* */
extern int DECL(iso9660_file_length,(const char* name,
struct directory_entry * sresult, int flag));
extern int DECL(iso9660_date,(char *, time_t));
extern void DECL(add_hash,(struct directory_entry *));
extern struct file_hash * DECL(find_hash,(dev_t, ino_t));
extern void DECL(add_directory_hash,(dev_t, ino_t));
extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t));
extern void DECL (flush_file_hash, (void));
extern int DECL(delete_file_hash,(struct directory_entry *));
extern struct directory_entry * DECL(find_file_hash,(char *));
extern void DECL(add_file_hash,(struct directory_entry *));
extern int DECL(generate_rock_ridge_attributes,(char *, char *,
struct directory_entry *,
struct stat *, struct stat *,
int deep_flag));
extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor,
char * source, int * size));
extern int DECL(check_prev_session, (struct directory_entry **, int len,
struct directory_entry *,
struct stat *,
struct stat *,
struct directory_entry **));
#ifdef USE_SCG
/* scsi.c */
#ifdef __STDC__
extern int readsecs(int startsecno, void *buffer, int sectorcount);
extern int scsidev_open(char *path);
#else
extern int readsecs();
extern int scsidev_open();
#endif
#endif
extern char * extension_record;
extern int extension_record_extent;
extern int n_data_extents;
/* These are a few goodies that can be specified on the command line, and are
filled into the root record */
extern char * preparer;
extern char * publisher;
extern char * copyright;
extern char * biblio;
extern char * abstract;
extern char * appid;
extern char * volset_id;
extern char * system_id;
extern char * volume_id;
extern char * boot_catalog;
extern char * boot_image;
extern int volume_set_size;
extern int volume_sequence_number;
extern void * DECL(e_malloc,(size_t));
#define SECTOR_SIZE (2048)
#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
#define NEED_RE 1
#define NEED_PL 2
#define NEED_CL 4
#define NEED_CE 8
#define NEED_SP 16
#define PREV_SESS_DEV (sizeof(dev_t) >= 4 ? 0x7ffffffd : 0x7ffd)
#define TABLE_INODE (sizeof(ino_t) >= 4 ? 0x7ffffffe : 0x7ffe)
#define UNCACHED_INODE (sizeof(ino_t) >= 4 ? 0x7fffffff : 0x7fff)
#define UNCACHED_DEVICE (sizeof(dev_t) >= 4 ? 0x7fffffff : 0x7fff)
#ifdef VMS
#define STAT_INODE(X) (X.st_ino[0])
#define PATH_SEPARATOR ']'
#define SPATH_SEPARATOR ""
#else
#define STAT_INODE(X) (X.st_ino)
#define PATH_SEPARATOR '/'
#define SPATH_SEPARATOR "/"
#endif
/*
* When using multi-session, indicates that we can reuse the
* TRANS.TBL information for this directory entry. If this flag
* is set for all entries in a directory, it means we can just
* reuse the TRANS.TBL and not generate a new one.
*/
#define SAFE_TO_REUSE_TABLE_ENTRY 0x01
#define DIR_HAS_DOT 0x02
#define DIR_HAS_DOTDOT 0x04
#define INHIBIT_JOLIET_ENTRY 0x08
#define INHIBIT_RR_ENTRY 0x10
#define RELOCATED_DIRECTORY 0x20
#define INHIBIT_ISO9660_ENTRY 0x40
/*
* Volume sequence number to use in all of the iso directory records.
*/
#define DEF_VSN 1
/*
* Make sure we have a definition for this. If not, take a very conservative
* guess. From what I can tell SunOS is the only one with this trouble.
*/
#ifndef NAME_MAX
#ifdef FILENAME_MAX
#define NAME_MAX FILENAME_MAX
#else
#define NAME_MAX 128
#endif
#endif

1213
util/mkisofs/multi.c Normal file

File diff suppressed because it is too large Load diff

396
util/mkisofs/name.c Normal file
View file

@ -0,0 +1,396 @@
/*
* File name.c - map full Unix file names to unique 8.3 names that
* would be valid on DOS.
*
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static char rcsid[] ="$Id: name.c,v 1.11 1999/03/02 03:41:26 eric Exp $";
#include "config.h"
#include "mkisofs.h"
#include <ctype.h>
extern int allow_leading_dots;
/*
* Function: iso9660_file_length
*
* Purpose: Map file name to 8.3 format, return length
* of result.
*
* Arguments: name file name we need to map.
* sresult directory entry structure to contain mapped name.
* dirflag flag indicating whether this is a directory or not.
*
* Notes: This procedure probably needs to be rationalized somehow.
* New options to affect the behavior of this function
* would also be nice to have.
*/
int FDECL3(iso9660_file_length,
const char*, name,
struct directory_entry *, sresult,
int, dirflag)
{
char * c;
int chars_after_dot = 0;
int chars_before_dot = 0;
int current_length = 0;
int extra = 0;
int ignore = 0;
char * last_dot;
const char * pnt;
int priority = 32767;
char * result;
int seen_dot = 0;
int seen_semic = 0;
int tildes = 0;
result = sresult->isorec.name;
/*
* For the '.' entry, generate the correct record, and return
* 1 for the length.
*/
if(strcmp(name,".") == 0)
{
if(result)
{
*result = 0;
}
return 1;
}
/*
* For the '..' entry, generate the correct record, and return
* 1 for the length.
*/
if(strcmp(name,"..") == 0)
{
if(result)
{
*result++ = 1;
*result++ = 0;
}
return 1;
}
/*
* Now scan the directory one character at a time, and figure out
* what to do.
*/
pnt = name;
/*
* Find the '.' that we intend to use for the extension. Usually this
* is the last dot, but if we have . followed by nothing or a ~, we
* would consider this to be unsatisfactory, and we keep searching.
*/
last_dot = strrchr (pnt,'.');
if( (last_dot != NULL)
&& ( (last_dot[1] == '~')
|| (last_dot[1] == '\0')) )
{
c = last_dot;
*c = '\0';
last_dot = strrchr (pnt,'.');
*c = '.';
}
while(*pnt)
{
#ifdef VMS
if( strcmp(pnt,".DIR;1") == 0 )
{
break;
}
#endif
/*
* This character indicates a Unix style of backup file
* generated by some editors. Lower the priority of
* the file.
*/
if(*pnt == '#')
{
priority = 1;
pnt++;
continue;
}
/*
* This character indicates a Unix style of backup file
* generated by some editors. Lower the priority of
* the file.
*/
if(*pnt == '~')
{
priority = 1;
tildes++;
pnt++;
continue;
}
/*
* This might come up if we had some joker already try and put
* iso9660 version numbers into the file names. This would be
* a silly thing to do on a Unix box, but we check for it
* anyways. If we see this, then we don't have to add our
* own version number at the end.
* UNLESS the ';' is part of the filename and no version
* number is following. [VK]
*/
if(*pnt == ';')
{
/* [VK] */
if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9'))
{
pnt++;
ignore++;
continue;
}
}
/*
* If we have a name with multiple '.' characters, we ignore everything
* after we have gotten the extension.
*/
if(ignore)
{
pnt++;
continue;
}
/*
* Spin past any iso9660 version number we might have.
*/
if(seen_semic)
{
if(*pnt >= '0' && *pnt <= '9')
{
*result++ = *pnt;
}
extra++;
pnt++;
continue;
}
/*
* If we have full names, the names we generate will not
* work on a DOS machine, since they are not guaranteed
* to be 8.3. Nonetheless, in many cases this is a useful
* option. We still only allow one '.' character in the
* name, however.
*/
if(full_iso9660_filenames)
{
/* Here we allow a more relaxed syntax. */
if(*pnt == '.')
{
if (seen_dot)
{
ignore++;
continue;
}
seen_dot++;
}
if(current_length < 30)
{
if( *pnt < 0 )
{
*result++ = '_';
}
else
{
*result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt);
}
}
}
else
{
/*
* Dos style filenames. We really restrict the
* names here.
*/
/* It would be nice to have .tar.gz transform to .tgz,
* .ps.gz to .psz, ...
*/
if(*pnt == '.')
{
if (!chars_before_dot && !allow_leading_dots)
{
/* DOS can't read files with dot first */
chars_before_dot++;
if (result)
{
*result++ = '_'; /* Substitute underscore */
}
}
else if( pnt != last_dot )
{
/*
* If this isn't the dot that we use for the extension,
* then change the character into a '_' instead.
*/
if(chars_before_dot < 8)
{
chars_before_dot++;
if(result)
{
*result++ = '_';
}
}
}
else
{
if (seen_dot)
{
ignore++; continue;
}
if(result)
{
*result++ = '.';
}
seen_dot++;
}
}
else
{
if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot)
|| (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) )
{
if(result)
{
switch (*pnt)
{
default:
if( *pnt < 0 )
{
*result++ = '_';
}
else
{
*result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt;
}
break;
/*
* Descriptions of DOS's 'Parse Filename'
* (function 29H) describes V1 and V2.0+
* separator and terminator characters.
* These characters in a DOS name make
* the file visible but un-manipulable
* (all useful operations error off.
*/
/* separators */
case '+':
case '=':
case '%': /* not legal DOS filename */
case ':':
case ';': /* already handled */
case '.': /* already handled */
case ',': /* already handled */
case '\t':
case ' ':
/* V1 only separators */
case '/':
case '"':
case '[':
case ']':
/* terminators */
case '>':
case '<':
case '|':
/* Hmm - what to do here? Skip?
* Win95 looks like it substitutes '_'
*/
*result++ = '_';
break;
} /* switch (*pnt) */
} /* if (result) */
} /* if (chars_{after,before}_dot) ... */
} /* else *pnt == '.' */
} /* else DOS file names */
current_length++;
pnt++;
} /* while (*pnt) */
/*
* OK, that wraps up the scan of the name. Now tidy up a few other
* things.
*/
/*
* Look for emacs style of numbered backups, like foo.c.~3~. If
* we see this, convert the version number into the priority
* number. In case of name conflicts, this is what would end
* up being used as the 'extension'.
*/
if(tildes == 2)
{
int prio1 = 0;
pnt = name;
while (*pnt && *pnt != '~')
{
pnt++;
}
if (*pnt)
{
pnt++;
}
while(*pnt && *pnt != '~')
{
prio1 = 10*prio1 + *pnt - '0';
pnt++;
}
priority = prio1;
}
/*
* If this is not a directory, force a '.' in case we haven't
* seen one, and add a version number if we haven't seen one
* of those either.
*/
if (!dirflag)
{
if (!seen_dot && !omit_period)
{
if (result) *result++ = '.';
extra++;
}
if(!omit_version_number && !seen_semic)
{
if(result)
{
*result++ = ';';
*result++ = '1';
};
extra += 2;
}
}
if(result)
{
*result++ = 0;
}
sresult->priority = priority;
return (chars_before_dot + chars_after_dot + seen_dot + extra);
}

599
util/mkisofs/rock.c Normal file
View file

@ -0,0 +1,599 @@
/*
* File rock.c - generate RRIP records for iso9660 filesystems.
Written by Eric Youngdale (1993).
Copyright 1993 Yggdrasil Computing, Incorporated
Copyright (C) 2009 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static char rcsid[] ="$Id: rock.c,v 1.8 1999/03/02 03:41:26 eric Exp $";
#include <stdlib.h>
#include "config.h"
#ifndef VMS
#if defined(MAJOR_IN_SYSMACROS)
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#endif
#if defined(MAJOR_IN_MKDEV)
#include <sys/types.h>
#include <sys/mkdev.h>
#endif
#include "mkisofs.h"
#include "iso9660.h"
#include <string.h>
#ifdef DOESNT_WORK
#ifdef NON_UNIXFS
#define S_ISLNK(m) (0)
#else
#ifndef S_ISLNK
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#endif
#else
#include <statdefs.h>
#endif
#define SU_VERSION 1
#define SL_ROOT 8
#define SL_PARENT 4
#define SL_CURRENT 2
#define SL_CONTINUE 1
#define CE_SIZE 28
#define CL_SIZE 12
#define ER_SIZE 8
#define NM_SIZE 5
#define PL_SIZE 12
#define PN_SIZE 20
#define PX_SIZE 36
#define RE_SIZE 4
#define SL_SIZE 20
#define ZZ_SIZE 15
#ifdef __QNX__
#define TF_SIZE (5 + 4 * 7)
#else
#define TF_SIZE (5 + 3 * 7)
#endif
/* If we need to store this number of bytes, make sure we
do not box ourselves in so that we do not have room for
a CE entry for the continuation record */
#define MAYBE_ADD_CE_ENTRY(BYTES) \
((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0)
/*
* Buffer to build RR attributes
*/
static unsigned char Rock[16384];
static unsigned char symlink_buff[256];
static int ipnt = 0;
static int recstart = 0;
static int currlen = 0;
static int mainrec = 0;
static int reclimit;
static void add_CE_entry __PR((void));
static void add_CE_entry(){
if(recstart)
set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart);
Rock[ipnt++] ='C';
Rock[ipnt++] ='E';
Rock[ipnt++] = CE_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
recstart = ipnt;
currlen = 0;
if(!mainrec) mainrec = ipnt;
reclimit = SECTOR_SIZE - 8; /* Limit to one sector */
}
#ifdef __STDC__
int generate_rock_ridge_attributes (char * whole_name, char * name,
struct directory_entry * s_entry,
struct stat * statbuf,
struct stat * lstatbuf,
int deep_opt)
#else
int generate_rock_ridge_attributes (whole_name, name,
s_entry,
statbuf,
lstatbuf,
deep_opt)
char * whole_name; char * name; struct directory_entry * s_entry;
struct stat * statbuf, *lstatbuf;
int deep_opt;
#endif
{
int flagpos, flagval;
int need_ce;
statbuf = statbuf; /* this shuts up unreferenced compiler warnings */
mainrec = recstart = ipnt = 0;
reclimit = 0xf8;
/* no need to fill in the RR stuff if we won't see the file */
if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
return 0;
/* Obtain the amount of space that is currently used for the directory
record. Assume max for name, since name conflicts may cause us
to rename the file later on */
currlen = sizeof(s_entry->isorec);
/* Identify that we are using the SUSP protocol */
if(deep_opt & NEED_SP){
Rock[ipnt++] ='S';
Rock[ipnt++] ='P';
Rock[ipnt++] = 7;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 0xbe;
Rock[ipnt++] = 0xef;
Rock[ipnt++] = 0;
};
/* First build the posix name field */
Rock[ipnt++] ='R';
Rock[ipnt++] ='R';
Rock[ipnt++] = 5;
Rock[ipnt++] = SU_VERSION;
flagpos = ipnt;
flagval = 0;
Rock[ipnt++] = 0; /* We go back and fix this later */
if(strcmp(name,".") && strcmp(name,"..")){
char * npnt;
int remain, use;
remain = strlen(name);
npnt = name;
while(remain){
use = remain;
need_ce = 0;
/* Can we fit this SUSP and a CE entry? */
if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
use = reclimit - currlen - CE_SIZE - (ipnt - recstart);
need_ce++;
}
/* Only room for 256 per SUSP field */
if(use > 0xf8) use = 0xf8;
/* First build the posix name field */
Rock[ipnt++] ='N';
Rock[ipnt++] ='M';
Rock[ipnt++] = NM_SIZE + use;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = (remain != use ? 1 : 0);
flagval |= (1<<3);
strncpy((char *)&Rock[ipnt], npnt, use);
npnt += use;
ipnt += use;
remain -= use;
if(remain && need_ce) add_CE_entry();
};
};
/*
* Add the posix modes
*/
if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='X';
Rock[ipnt++] = PX_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<0);
set_733((char*)Rock + ipnt, lstatbuf->st_mode);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_nlink);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_uid);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_gid);
ipnt += 8;
/*
* Check for special devices
*/
#ifndef NON_UNIXFS
if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) {
if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='N';
Rock[ipnt++] = PN_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<1);
#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)
set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev ));
ipnt += 8;
set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev));
ipnt += 8;
#else
/*
* If we don't have sysmacros.h, then we have to guess as to how
* best to pick apart the device number for major/minor.
* Note: this may very well be wrong for many systems, so
* it is always best to use the major/minor macros if the
* system supports it.
*/
if(sizeof(dev_t) <= 2) {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8));
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff);
ipnt += 8;
}
else if(sizeof(dev_t) <= 4) {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff);
ipnt += 8;
}
else {
set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16);
ipnt += 8;
set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
ipnt += 8;
}
#endif
};
#endif
/*
* Check for and symbolic links. VMS does not have these.
*/
if (S_ISLNK(lstatbuf->st_mode)){
int lenpos, lenval, j0, j1;
int nchar;
unsigned char * cpnt, *cpnt1;
nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff));
symlink_buff[nchar < 0 ? 0 : nchar] = 0;
nchar = strlen((char *) symlink_buff);
set_733(s_entry->isorec.size, 0);
cpnt = &symlink_buff[0];
flagval |= (1<<2);
if (! split_SL_field)
{
int sl_bytes = 0;
for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++)
{
if (*cpnt1 == '/')
{
sl_bytes += 4;
}
else
{
sl_bytes += 1;
}
}
if (sl_bytes > 250)
{
/*
* the symbolic link won't fit into one SL System Use Field
* print an error message and continue with splited one
*/
fprintf(stderr,"symbolic link ``%s'' to long for one SL System Use Field, splitting", cpnt);
}
if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry();
}
while(nchar){
if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry();
Rock[ipnt++] ='S';
Rock[ipnt++] ='L';
lenpos = ipnt;
Rock[ipnt++] = SL_SIZE;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 0; /* Flags */
lenval = 5;
while(*cpnt){
cpnt1 = (unsigned char *) strchr((char *) cpnt, '/');
if(cpnt1) {
nchar--;
*cpnt1 = 0;
};
/* We treat certain components in a special way. */
if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_PARENT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
nchar -= 2;
} else if(cpnt[0] == '.' && cpnt[1] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_CURRENT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
nchar -= 1;
} else if(cpnt[0] == 0){
if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
Rock[ipnt++] = SL_ROOT;
Rock[ipnt++] = 0; /* length is zero */
lenval += 2;
} else {
/* If we do not have enough room for a component, start
a new continuations segment now */
if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) :
MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt)))
{
add_CE_entry();
if(cpnt1)
{
*cpnt1 = '/';
nchar++;
cpnt1 = NULL; /* A kluge so that we can restart properly */
}
break;
}
j0 = strlen((char *) cpnt);
while(j0) {
j1 = j0;
if(j1 > 0xf8) j1 = 0xf8;
need_ce = 0;
if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart);
need_ce++;
}
Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0);
Rock[ipnt++] = j1;
strncpy((char *) Rock + ipnt, (char *) cpnt, j1);
ipnt += j1;
lenval += j1 + 2;
cpnt += j1;
nchar -= j1; /* Number we processed this time */
j0 -= j1;
if(need_ce) {
add_CE_entry();
if(cpnt1) {
*cpnt1 = '/';
nchar++;
cpnt1 = NULL; /* A kluge so that we can restart properly */
}
break;
}
}
};
if(cpnt1) {
cpnt = cpnt1 + 1;
} else
break;
}
Rock[lenpos] = lenval;
if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */
} /* while nchar */
} /* Is a symbolic link */
/*
* Add in the Rock Ridge TF time field
*/
if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry();
Rock[ipnt++] ='T';
Rock[ipnt++] ='F';
Rock[ipnt++] = TF_SIZE;
Rock[ipnt++] = SU_VERSION;
#ifdef __QNX__
Rock[ipnt++] = 0x0f;
#else
Rock[ipnt++] = 0x0e;
#endif
flagval |= (1<<7);
#ifdef __QNX__
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime);
ipnt += 7;
#endif
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime);
ipnt += 7;
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime);
ipnt += 7;
iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime);
ipnt += 7;
/*
* Add in the Rock Ridge RE time field
*/
if(deep_opt & NEED_RE){
if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry();
Rock[ipnt++] ='R';
Rock[ipnt++] ='E';
Rock[ipnt++] = RE_SIZE;
Rock[ipnt++] = SU_VERSION;
flagval |= (1<<6);
};
/*
* Add in the Rock Ridge PL record, if required.
*/
if(deep_opt & NEED_PL){
if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry();
Rock[ipnt++] ='P';
Rock[ipnt++] ='L';
Rock[ipnt++] = PL_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
flagval |= (1<<5);
};
/*
* Add in the Rock Ridge CL field, if required.
*/
if(deep_opt & NEED_CL){
if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry();
Rock[ipnt++] ='C';
Rock[ipnt++] ='L';
Rock[ipnt++] = CL_SIZE;
Rock[ipnt++] = SU_VERSION;
set_733((char*)Rock + ipnt, 0);
ipnt += 8;
flagval |= (1<<4);
};
#ifndef VMS
/* If transparent compression was requested, fill in the correct
field for this file */
if(transparent_compression &&
S_ISREG(lstatbuf->st_mode) &&
strlen(name) > 3 &&
strcmp(name + strlen(name) - 3,".gZ") == 0){
FILE * zipfile;
char * checkname;
unsigned int file_size;
unsigned char header[8];
int OK_flag;
/* First open file and verify that the correct algorithm was used */
file_size = 0;
OK_flag = 1;
zipfile = fopen(whole_name, "rb");
fread(header, 1, sizeof(header), zipfile);
/* Check some magic numbers from gzip. */
if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0;
/* Make sure file was blocksized. */
if(((header[3] & 0x40) == 0)) OK_flag = 0;
/* OK, now go to the end of the file and get some more info */
if(OK_flag){
int status;
status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END);
if(status == -1) OK_flag = 0;
}
if(OK_flag){
if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header))
OK_flag = 0;
else {
int blocksize;
blocksize = (header[3] << 8) | header[2];
file_size = ((unsigned int)header[7] << 24) |
((unsigned int)header[6] << 16) |
((unsigned int)header[5] << 8) | header[4];
#if 0
fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size);
#endif
if(blocksize != SECTOR_SIZE) OK_flag = 0;
}
}
fclose(zipfile);
checkname = strdup(whole_name);
checkname[strlen(whole_name)-3] = 0;
zipfile = fopen(checkname, "rb");
if(zipfile) {
OK_flag = 0;
fprintf(stderr,"Unable to insert transparent compressed file - name conflict\n");
fclose(zipfile);
}
free(checkname);
if(OK_flag){
if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry();
Rock[ipnt++] ='Z';
Rock[ipnt++] ='Z';
Rock[ipnt++] = ZZ_SIZE;
Rock[ipnt++] = SU_VERSION;
Rock[ipnt++] = 'g'; /* Identify compression technique used */
Rock[ipnt++] = 'z';
Rock[ipnt++] = 3;
set_733((char*)Rock + ipnt, file_size); /* Real file size */
ipnt += 8;
};
}
#endif
/*
* Add in the Rock Ridge CE field, if required. We use this for the
* extension record that is stored in the root directory.
*/
if(deep_opt & NEED_CE) add_CE_entry();
/*
* Done filling in all of the fields. Now copy it back to a buffer for the
* file in question.
*/
/* Now copy this back to the buffer for the file */
Rock[flagpos] = flagval;
/* If there was a CE, fill in the size field */
if(recstart)
set_733((char*)Rock + recstart - 8, ipnt - recstart);
s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt);
s_entry->total_rr_attr_size = ipnt;
s_entry->rr_attr_size = (mainrec ? mainrec : ipnt);
memcpy(s_entry->rr_attributes, Rock, ipnt);
return ipnt;
}
/* Guaranteed to return a single sector with the relevant info */
char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor,
char *, source, int *, size){
int lipnt = 0;
char * pnt;
int len_id, len_des, len_src;
len_id = strlen(id);
len_des = strlen(descriptor);
len_src = strlen(source);
Rock[lipnt++] ='E';
Rock[lipnt++] ='R';
Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src;
Rock[lipnt++] = 1;
Rock[lipnt++] = len_id;
Rock[lipnt++] = len_des;
Rock[lipnt++] = len_src;
Rock[lipnt++] = 1;
memcpy(Rock + lipnt, id, len_id);
lipnt += len_id;
memcpy(Rock + lipnt, descriptor, len_des);
lipnt += len_des;
memcpy(Rock + lipnt, source, len_src);
lipnt += len_src;
if(lipnt > SECTOR_SIZE) {
fprintf(stderr,"Extension record too long\n");
exit(1);
};
pnt = (char *) e_malloc(SECTOR_SIZE);
memset(pnt, 0, SECTOR_SIZE);
memcpy(pnt, Rock, lipnt);
*size = lipnt;
return pnt;
}

1890
util/mkisofs/tree.c Normal file

File diff suppressed because it is too large Load diff

1460
util/mkisofs/write.c Normal file

File diff suppressed because it is too large Load diff