PERFORCE change 48313 for review

Peter Wemm peter at FreeBSD.org
Sat Mar 6 19:20:28 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=48313

Change 48313 by peter at peter_daintree on 2004/03/06 19:20:21

	IFC @48310

Affected files ...

.. //depot/projects/hammer/bin/dd/Makefile#5 integrate
.. //depot/projects/hammer/bin/dd/dd.h#4 integrate
.. //depot/projects/hammer/gnu/lib/csu/Makefile#6 integrate
.. //depot/projects/hammer/lib/libarchive/archive.h#2 integrate
.. //depot/projects/hammer/lib/libarchive/archive_read.3#2 integrate
.. //depot/projects/hammer/lib/libarchive/archive_read_support_format_cpio.c#2 integrate
.. //depot/projects/hammer/lib/libarchive/archive_write_set_format_pax.c#2 integrate
.. //depot/projects/hammer/lib/libarchive/archive_write_set_format_shar.c#2 integrate
.. //depot/projects/hammer/lib/libarchive/archive_write_set_format_ustar.c#2 integrate
.. //depot/projects/hammer/lib/libc/stdlib/getopt.3#4 integrate
.. //depot/projects/hammer/lib/libc/stdlib/getopt.c#2 integrate
.. //depot/projects/hammer/lib/libc/stdlib/getopt_long.3#5 integrate
.. //depot/projects/hammer/lib/libc/stdlib/getopt_long.c#6 integrate
.. //depot/projects/hammer/share/man/man4/polling.4#6 integrate
.. //depot/projects/hammer/share/man/man9/Makefile#28 integrate
.. //depot/projects/hammer/share/man/man9/contigmalloc.9#1 branch
.. //depot/projects/hammer/share/man/man9/malloc.9#9 integrate
.. //depot/projects/hammer/sys/compat/ndis/kern_ndis.c#8 integrate
.. //depot/projects/hammer/sys/conf/kmod.mk#19 integrate
.. //depot/projects/hammer/sys/dev/if_ndis/if_ndis.c#8 integrate
.. //depot/projects/hammer/sys/dev/if_ndis/if_ndis_pccard.c#1 branch
.. //depot/projects/hammer/sys/dev/if_ndis/if_ndis_pci.c#1 branch
.. //depot/projects/hammer/sys/dev/if_ndis/if_ndisvar.h#6 integrate
.. //depot/projects/hammer/sys/dev/sound/isa/ad1816.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/isa/ess.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/isa/sb16.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/isa/sb8.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/als4000.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/au88x0.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/aureal.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/cmi.c#7 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/cs4281.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/csapcm.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/ds1.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/emu10k1.c#7 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/es137x.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/fm801.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/ich.c#10 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/maestro.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/maestro3.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/neomagic.c#3 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/solo.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/t4dwave.c#6 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/via8233.c#7 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/via82c686.c#7 integrate
.. //depot/projects/hammer/sys/dev/sound/pci/vibes.c#5 integrate
.. //depot/projects/hammer/sys/dev/sound/pcm/sound.h#8 integrate
.. //depot/projects/hammer/sys/i386/conf/NOTES#34 integrate
.. //depot/projects/hammer/sys/kern/kern_fork.c#28 integrate
.. //depot/projects/hammer/sys/kern/vfs_bio.c#27 integrate
.. //depot/projects/hammer/sys/kern/vfs_subr.c#33 integrate
.. //depot/projects/hammer/sys/modules/if_ndis/Makefile#2 integrate
.. //depot/projects/hammer/sys/modules/ndis/Makefile#5 integrate
.. //depot/projects/hammer/usr.bin/Makefile#25 integrate
.. //depot/projects/hammer/usr.bin/logins/Makefile#1 branch
.. //depot/projects/hammer/usr.bin/logins/logins.1#1 branch
.. //depot/projects/hammer/usr.bin/logins/logins.c#1 branch
.. //depot/projects/hammer/usr.bin/mail/lex.c#3 integrate
.. //depot/projects/hammer/usr.sbin/mergemaster/mergemaster.sh#8 integrate

Differences ...

==== //depot/projects/hammer/bin/dd/Makefile#5 (text+ko) ====

@@ -1,5 +1,5 @@
 #	@(#)Makefile	8.1 (Berkeley) 5/31/93
-# $FreeBSD: src/bin/dd/Makefile,v 1.14 2004/03/05 19:35:51 phk Exp $
+# $FreeBSD: src/bin/dd/Makefile,v 1.16 2004/03/06 06:54:58 ache Exp $
 
 PROG=	dd
 SRCS=	args.c conv.c conv_tab.c dd.c misc.c position.c
@@ -8,6 +8,7 @@
 
 .include <bsd.prog.mk>
 
+CLEANFILES+= a.out
 #
 # Test the character conversion functions.  We have to be explicit about
 # which LC_LANG we use because the definition of upper and lower case
@@ -19,7 +20,7 @@
     swab lcase ucase
 	@echo testing conv=${conv}
 	@./a.out | \
-	  /usr/bin/env -i LC_CTYPE=ASCII ./dd conv=${conv} 2>/dev/null | \
-	  /usr/bin/env -i LC_CTYPE=ASCII hexdump -C | \
+	  /usr/bin/env -i LC_CTYPE=en_US.US-ASCII ./dd conv=${conv} 2>/dev/null | \
+	  /usr/bin/env -i LC_CTYPE=en_US.US-ASCII hexdump -C | \
 	  diff -IFreeBSD - ${.CURDIR}/ref.${conv}
 .endfor

==== //depot/projects/hammer/bin/dd/dd.h#4 (text+ko) ====

@@ -35,7 +35,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)dd.h	8.3 (Berkeley) 4/2/94
- * $FreeBSD: src/bin/dd/dd.h,v 1.19 2004/03/05 19:35:51 phk Exp $
+ * $FreeBSD: src/bin/dd/dd.h,v 1.20 2004/03/06 08:21:32 bde Exp $
  */
 
 /* Input/output stream state. */
@@ -55,10 +55,9 @@
 #define	ISTRUNC		0x20		/* valid to ftruncate() */
 	u_int		flags;
 
-	const char 	*name;		/* name */
+	const char	*name;		/* name */
 	int		fd;		/* file descriptor */
 	off_t		offset;		/* # of blocks to skip */
-
 } IO;
 
 typedef struct {
@@ -69,7 +68,7 @@
 	uintmax_t	trunc;		/* # of truncated records */
 	uintmax_t	swab;		/* # of odd-length swab blocks */
 	uintmax_t	bytes;		/* # of bytes written */
-	double		start; 			/* start time of dd */
+	double		start;		/* start time of dd */
 } STAT;
 
 /* Flags (in ddflags). */
@@ -87,17 +86,17 @@
 #define	C_NOTRUNC	0x00800
 #define	C_OBS		0x01000
 #define	C_OF		0x02000
-#define	C_SEEK		0x04000
-#define	C_SKIP		0x08000
-#define	C_SWAB		0x10000
-#define	C_SYNC		0x20000
-#define	C_UCASE		0x40000
-#define	C_UNBLOCK	0x80000
-#define	C_OSYNC		0x100000
-#define	C_SPARSE	0x200000
-#define C_PAREVEN	0x400000
-#define C_PARODD	0x800000
-#define C_PARSET	0x1000000
-#define C_PARNONE	0x2000000
+#define	C_OSYNC		0x04000
+#define	C_PAREVEN	0x08000
+#define	C_PARNONE	0x100000
+#define	C_PARODD	0x200000
+#define	C_PARSET	0x400000
+#define	C_SEEK		0x800000
+#define	C_SKIP		0x1000000
+#define	C_SPARSE	0x2000000
+#define	C_SWAB		0x4000000
+#define	C_SYNC		0x8000000
+#define	C_UCASE		0x10000000
+#define	C_UNBLOCK	0x20000000
 
-#define C_PARITY	(C_PAREVEN|C_PARODD|C_PARSET|C_PARNONE)
+#define	C_PARITY	(C_PAREVEN | C_PARODD | C_PARNONE | C_PARSET)

==== //depot/projects/hammer/gnu/lib/csu/Makefile#6 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/gnu/lib/csu/Makefile,v 1.20 2003/07/13 02:41:48 kan Exp $
+# $FreeBSD: src/gnu/lib/csu/Makefile,v 1.21 2004/03/06 07:34:51 ru Exp $
 
 GCCDIR=	${.CURDIR}/../../../contrib/gcc
 CCDIR=	${.CURDIR}/../../usr.bin/cc
@@ -17,7 +17,7 @@
 CFLAGS+=	-I${GCCDIR}/config -I${GCCDIR} -I. \
 		-I${CCDIR}/cc_tools
 CRTS_CFLAGS=	-DCRTSTUFFS_O -DSHARED ${PICFLAG}
-MKDEPCMD=	CC="${CC}" MKDEP_CPP_OPTS="-M -DCRT_BEGIN" mkdep
+MKDEP=		-DCRT_BEGIN
 
 .if ${MACHINE_ARCH} == "ia64"
 BEGINSRC=	crtbegin.asm

==== //depot/projects/hammer/lib/libarchive/archive.h#2 (text+ko) ====

@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive.h,v 1.1 2004/02/09 23:22:53 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive.h,v 1.3 2004/03/06 01:06:49 kientzle Exp $
  */
 
 #ifndef ARCHIVE_H_INCLUDED
@@ -107,15 +107,6 @@
 struct archive	*archive_read_new(void);
 
 /*
- * XXX Kill this function.  The client callback is now responsible for
- * read blocking. XXX
- */
-/*
-  int		 archive_read_set_bytes_per_block(struct archive *,
-		     int bytes_per_blk);
-*/
-
-/*
  * The archive_read_support_XXX calls enable auto-detect for this
  * archive handle.  They also link in the necessary support code.
  * For example, if you don't want bzlib linked in, don't invoke
@@ -190,6 +181,7 @@
 #define	ARCHIVE_EXTRACT_PERM	(2) /* Default: restore perm only for reg file*/
 #define	ARCHIVE_EXTRACT_TIME	(4) /* Default: mod time not restored */
 #define	ARCHIVE_EXTRACT_NO_OVERWRITE (8) /* Default: Replace files on disk */
+#define	ARCHIVE_EXTRACT_UNLINK	(16) /* Default: don't unlink existing files */
 
 int		 archive_read_extract(struct archive *, struct archive_entry *,
 		     int flags);

==== //depot/projects/hammer/lib/libarchive/archive_read.3#2 (text+ko) ====

@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.1 2004/02/09 23:22:53 kientzle Exp $
+.\" $FreeBSD: src/lib/libarchive/archive_read.3,v 1.2 2004/03/06 01:05:32 kientzle Exp $
 .\"
 .Dd October 1, 2003
 .Dt archive_read 3
@@ -178,6 +178,11 @@
 .It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
 Existing files on disk will not be overwritten.
 By default, existing files are unlinked before the new entry is written.
+.It Cm ARCHIVE_EXTRACT_UNLINK
+Existing files on disk will be unlinked and recreated from scratch.
+By default, existing files are truncated and rewritten, but
+the file is not recreated.
+In particular, the default behavior does not break existing hard links.
 .El
 .It Fn archive_read_finish
 Complete the archive, invoke the close callback, and release

==== //depot/projects/hammer/lib/libarchive/archive_read_support_format_cpio.c#2 (text+ko) ====

@@ -25,13 +25,17 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_cpio.c,v 1.1 2004/02/09 23:22:54 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_cpio.c,v 1.3 2004/03/07 00:57:43 kientzle Exp $");
+
+#include <sys/stat.h>
 
 #ifdef DMALLOC
 #include <dmalloc.h>
 #endif
+#include <err.h>
 #include <errno.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -53,19 +57,43 @@
 	char	c_filesize[11];
 };
 
+struct links_entry {
+        struct links_entry      *next;
+        struct links_entry      *previous;
+        int                      links;
+        dev_t                    dev;
+        ino_t                    ino;
+        char                    *name;
+};
+
+#define CPIO_MAGIC   0x13141516
+struct cpio {
+	int magic;
+	struct links_entry	*links_head;
+};
+
 static int64_t	atol8(const char *, unsigned);
 static int	archive_read_format_cpio_bid(struct archive *);
+static int	archive_read_format_cpio_cleanup(struct archive *);
 static int	archive_read_format_cpio_read_header(struct archive *,
 		    struct archive_entry *);
+static void	record_hardlink(struct cpio *cpio, struct archive_entry *entry,
+		    const struct stat *st);
 
 int
 archive_read_support_format_cpio(struct archive *a)
 {
+	struct cpio *cpio;
+
+	cpio = malloc(sizeof(*cpio));
+	memset(cpio, 0, sizeof(*cpio));
+	cpio->magic = CPIO_MAGIC;
+
 	return (__archive_read_register_format(a,
-	    NULL,
+	    cpio,
 	    archive_read_format_cpio_bid,
 	    archive_read_format_cpio_read_header,
-	    NULL));
+	    archive_read_format_cpio_cleanup));
 }
 
 
@@ -98,6 +126,7 @@
     struct archive_entry *entry)
 {
 	struct stat st;
+	struct cpio *cpio;
 	size_t bytes;
 	const struct cpio_header *header;
 	const void *h;
@@ -105,6 +134,9 @@
 
 	a->archive_format = ARCHIVE_FORMAT_CPIO;
 	a->archive_format_name = "POSIX octet-oriented cpio";
+	cpio = *(a->pformat_data);
+	if (cpio->magic != CPIO_MAGIC)
+		errx(1, "CPIO data lost? This can't happen.\n");
 
 	/* Read fixed-size portion of header. */
 	bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_header));
@@ -112,7 +144,7 @@
 	    return (ARCHIVE_FATAL);
 	(a->compression_read_consume)(a, sizeof(struct cpio_header));
 
-	/* Parse out octal fields into struct stat */
+	/* Parse out octal fields into struct stat. */
 	memset(&st, 0, sizeof(st));
 	header = h;
 
@@ -128,7 +160,7 @@
 
 	/*
 	 * Note: entry_bytes_remaining is at least 64 bits and
-	 * therefore gauranteed to be big enough for a 33-bite file
+	 * therefore gauranteed to be big enough for a 33-bit file
 	 * size.  struct stat.st_size may only be 32 bits, so
 	 * assigning there first could lose information.
 	 */
@@ -145,9 +177,21 @@
 	if (bytes < namelength)
 	    return (ARCHIVE_FATAL);
 	(a->compression_read_consume)(a, namelength);
-	archive_strncpy(&a->entry_name, h, bytes);
+	archive_strncpy(&a->entry_name, h, namelength);
 	archive_entry_set_pathname(entry, a->entry_name.s);
 
+	/* If this is a symlink, read the link contents. */
+	if (S_ISLNK(st.st_mode)) {
+		bytes = (a->compression_read_ahead)(a, &h,
+		    a->entry_bytes_remaining);
+		if (bytes < a->entry_bytes_remaining)
+			return (ARCHIVE_FATAL);
+		(a->compression_read_consume)(a, a->entry_bytes_remaining);
+		archive_strncpy(&a->entry_linkname, h, a->entry_bytes_remaining);
+		archive_entry_set_symlink(entry, a->entry_linkname.s);
+		a->entry_bytes_remaining = 0;
+	}
+
 	/* Compare name to "TRAILER!!!" to test for end-of-archive. */
 	if (namelength == 11 && strcmp(h,"TRAILER!!!")==0) {
 	    /* TODO: Store file location of start of block. */
@@ -155,11 +199,36 @@
 	    return (ARCHIVE_EOF);
 	}
 
+	/* Detect and record hardlinks to previously-extracted entries. */
+	record_hardlink(cpio, entry, &st);
+
 	return (ARCHIVE_OK);
 }
 
+static int
+archive_read_format_cpio_cleanup(struct archive *a)
+{
+	struct cpio *cpio;
+
+	cpio = *(a->pformat_data);
+        /* Free inode->name map */
+        while (cpio->links_head != NULL) {
+                struct links_entry *lp = cpio->links_head->next;
+
+                if (cpio->links_head->name)
+                        free(cpio->links_head->name);
+                free(cpio->links_head);
+                cpio->links_head = lp;
+        }
 
-/* Note that this implementation does not (and should not!) obey
+	free(cpio);
+	*(a->pformat_data) = NULL;
+	return (ARCHIVE_OK);
+}
+
+
+/*
+ * Note that this implementation does not (and should not!) obey
  * locale settings; you cannot simply substitute strtol here, since
  * it does obey locale.
  */
@@ -185,3 +254,43 @@
 	}
 	return (l);
 }
+
+static void
+record_hardlink(struct cpio *cpio, struct archive_entry *entry,
+    const struct stat *st)
+{
+        struct links_entry      *le;
+
+        /*
+         * First look in the list of multiply-linked files.  If we've
+         * already dumped it, convert this entry to a hard link entry.
+         */
+        for (le = cpio->links_head; le; le = le->next) {
+                if (le->dev == st->st_dev && le->ino == st->st_ino) {
+                        archive_entry_set_hardlink(entry, le->name);
+
+                        if (--le->links <= 0) {
+                                if (le->previous != NULL)
+                                        le->previous->next = le->next;
+                                if (le->next != NULL)
+                                        le->next->previous = le->previous;
+                                if (cpio->links_head == le)
+                                        cpio->links_head = le->next;
+                                free(le);
+                        }
+
+                        return;
+                }
+        }
+
+        le = malloc(sizeof(struct links_entry));
+        if (cpio->links_head != NULL)
+                cpio->links_head->previous = le;
+        le->next = cpio->links_head;
+        le->previous = NULL;
+        cpio->links_head = le;
+        le->dev = st->st_dev;
+        le->ino = st->st_ino;
+        le->links = st->st_nlink - 1;
+        le->name = strdup(archive_entry_pathname(entry));
+}

==== //depot/projects/hammer/lib/libarchive/archive_write_set_format_pax.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.1 2004/02/09 23:22:54 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_pax.c,v 1.2 2004/03/06 05:44:13 kientzle Exp $");
 
 #include <sys/stat.h>
 #include <errno.h>
@@ -458,6 +458,31 @@
 		    st_main->st_nlink);
 	}
 
+	/* Only regular files have data. */
+	if (!S_ISREG(archive_entry_mode(entry_main)))
+		archive_entry_set_size(entry_main, 0);
+
+	/*
+	 * Pax-restricted does not store data for hardlinks, in order
+	 * to improve compatibility with ustar.
+	 */
+	if (a->archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE &&
+	    archive_entry_hardlink(entry_main) != NULL)
+		archive_entry_set_size(entry_main, 0);
+
+	/*
+	 * XXX Full pax interchange format does permit a hardlink
+	 * entry to have data associated with it.  I'm not supporting
+	 * that here because the client expects me to tell them whether
+	 * or not this format expects data for hardlinks.  If I
+	 * don't check here, then every pax archive will end up with
+	 * duplicated data for hardlinks.  Someday, there may be
+	 * need to select this behavior, in which case the following
+	 * will need to be revisited. XXX
+	 */
+	if (archive_entry_hardlink(entry_main) != NULL)
+		archive_entry_set_size(entry_main, 0);
+
 	/* Format 'ustar' header for main entry. */
 	/* We don't care if this returns an error. */
 	__archive_write_format_header_ustar(a, ustarbuff, entry_main);
@@ -528,13 +553,13 @@
 	if (ret != ARCHIVE_OK)
 		ret = (r < 512) ? ARCHIVE_FATAL : ARCHIVE_OK;
 
-	/* Only regular files have data.  Note that pax, unlike ustar,
-	 * does permit a hardlink to have data associated with it. */
-	if (!S_ISREG(archive_entry_mode(entry_main)))
-		pax->entry_bytes_remaining = 0;
-	else
-		pax->entry_bytes_remaining = archive_entry_size(entry_main);
-
+	/*
+	 * Inform the client of the on-disk size we're using, so
+	 * they can avoid unnecessarily writing a body for something
+	 * that we're just going to ignore.
+	 */
+	archive_entry_set_size(entry_original, archive_entry_size(entry_main));
+	pax->entry_bytes_remaining = archive_entry_size(entry_main);
 	pax->entry_padding = 0x1ff & (- pax->entry_bytes_remaining);
 	archive_entry_free(entry_main);
 

==== //depot/projects/hammer/lib/libarchive/archive_write_set_format_shar.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_shar.c,v 1.1 2004/02/09 23:22:54 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_shar.c,v 1.2 2004/03/06 05:44:13 kientzle Exp $");
 
 #include <sys/stat.h>
 #ifdef DMALLOC
@@ -56,6 +56,7 @@
 	int			 end_of_line;
 	struct archive_entry	*entry;
 	int			 has_data;
+	char			*last_dir;
 	char			 outbuff[1024];
 	size_t			 outbytes;
 	size_t			 outpos;
@@ -130,6 +131,7 @@
 {
 	const char *linkname;
 	const char *name;
+	char *p, *pp;
 	struct shar *shar;
 	const struct stat *st;
 
@@ -140,28 +142,74 @@
 		shar->wrote_header = 1;
 	}
 
-	/* Save the entry for the closing */
+	/* Save the entry for the closing. */
 	if (shar->entry)
 		archive_entry_free(shar->entry);
 	shar->entry = archive_entry_clone(entry);
 	name = archive_entry_pathname(entry);
 	st = archive_entry_stat(entry);
 
+	/* Handle some preparatory issues. */
+	switch(st->st_mode & S_IFMT) {
+	case S_IFREG:
+		/* Only regular files have non-zero size. */
+		break;
+	case S_IFDIR:
+	case S_IFIFO:
+	case S_IFCHR:
+	case S_IFBLK:
+		/* All other file types have zero size in the archive. */
+		archive_entry_set_size(entry, 0);
+		break;
+	default:
+		archive_entry_set_size(entry, 0);
+		if (archive_entry_hardlink(entry) == NULL &&
+		    archive_entry_symlink(entry) == NULL) {
+			archive_set_error(a, -1,
+			    "shar format cannot archive this");
+			return (ARCHIVE_WARN);
+		}
+	}
+
+	/* Stock preparation for all file types. */
+	shar_printf(a, "echo x %s\n", name);
+
+	if (!S_ISDIR(st->st_mode)) {
+		/* Try to create the dir. */
+		p = strdup(name);
+		pp = strrchr(p, '/');
+		if (pp != NULL)
+			*pp = '\0';
+
+		if (shar->last_dir == NULL) {
+			shar_printf(a, "mkdir -p %s > /dev/null 2>&1\n", p);
+			shar->last_dir = p;
+		} else if (strcmp(p, shar->last_dir) == 0) {
+			/* We've already created this exact dir. */
+			free(p);
+		} else if (strlen(p) < strlen(shar->last_dir) &&
+		    strncmp(p, shar->last_dir, strlen(p)) == 0) {
+			/* We've already created a subdir. */
+			free(p);
+		} else {
+			shar_printf(a, "mkdir -p %s > /dev/null 2>&1\n", p);
+			free(shar->last_dir);
+			shar->last_dir = p;
+		}
+	}
+
+	/* Handle file-type specific issues. */
 	shar->has_data = 0;
-	if ((linkname = archive_entry_hardlink(entry)) != NULL) {
-		shar_printf(a, "echo x %s\n", name);
+	if ((linkname = archive_entry_hardlink(entry)) != NULL)
 		shar_printf(a, "ln -f %s %s\n", linkname, name);
-	} else if ((linkname = archive_entry_symlink(entry)) != NULL) {
-		shar_printf(a, "echo x %s\n", name);
+	else if ((linkname = archive_entry_symlink(entry)) != NULL)
 		shar_printf(a, "ln -fs %s %s\n", linkname, name);
-	} else {
+	else {
 		switch(st->st_mode & S_IFMT) {
 		case S_IFREG:
-			shar_printf(a, "echo x %s\n", name);
-			if (archive_entry_size(entry) == 0) {
+			if (archive_entry_size(entry) == 0)
 				shar_printf(a, "touch %s\n", name);
-				shar->has_data = 0;
-			} else {
+			else {
 				if (shar->dump) {
 					shar_printf(a,
 					    "uudecode -o %s << 'SHAR_END'\n",
@@ -180,36 +228,35 @@
 			}
 			break;
 		case S_IFDIR:
-			shar_printf(a, "echo x %s\n", name);
 			shar_printf(a, "mkdir -p %s > /dev/null 2>&1\n", name);
+			/* Record that we just created this directory. */
+			if (shar->last_dir != NULL)
+				free(shar->last_dir);
+
+			shar->last_dir = strdup(name);
+			/* Trim a trailing '/'. */
+			pp = strrchr(shar->last_dir, '/');
+			if (pp != NULL && pp[1] == '\0')
+				*pp = '\0';
 			/*
 			 * TODO: Put dir name/mode on a list to be fixed
 			 * up at end of archive.
 			 */
 			break;
 		case S_IFIFO:
-			shar_printf(a, "echo x %s\n", name);
 			shar_printf(a, "mkfifo %s\n", name);
 			break;
 		case S_IFCHR:
-			shar_printf(a, "echo x %s\n", name);
 			shar_printf(a, "mknod %s c %d %d\n", name,
 			    archive_entry_devmajor(entry),
 			    archive_entry_devminor(entry));
 			break;
 		case S_IFBLK:
-			shar_printf(a, "echo x %s\n", name);
 			shar_printf(a, "mknod %s b %d %d\n", name,
 			    archive_entry_devmajor(entry),
 			    archive_entry_devminor(entry));
 			break;
-		case S_IFSOCK:
-			archive_set_error(a, -1,
-			    "shar format cannot archive socket");
-			return (ARCHIVE_WARN);
 		default:
-			archive_set_error(a, -1,
-			    "shar format cannot archive this");
 			return (ARCHIVE_WARN);
 		}
 	}
@@ -395,8 +442,10 @@
 		 * uncompressed data within gzip/bzip2 streams.
 		 */
 	}
-	if (shar->entry)
+	if (shar->entry != NULL)
 		archive_entry_free(shar->entry);
+	if (shar->last_dir != NULL)
+		free(shar->last_dir);
 	free(shar);
 	a->format_data = NULL;
 	return (ARCHIVE_OK);

==== //depot/projects/hammer/lib/libarchive/archive_write_set_format_ustar.c#2 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.1 2004/02/09 23:22:54 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.2 2004/03/06 05:44:13 kientzle Exp $");
 
 #include <sys/stat.h>
 #ifdef DMALLOC
@@ -125,6 +125,13 @@
 
 	ustar = a->format_data;
 	ustar->written = 1;
+
+	/* Only regular files (not hardlinks) have data. */
+	if (archive_entry_hardlink(entry) != NULL ||
+	    archive_entry_symlink(entry) != NULL ||
+	    !S_ISREG(archive_entry_mode(entry)))
+		archive_entry_set_size(entry, 0);
+
 	ret = __archive_write_format_header_ustar(a, buff, entry);
 	if (ret != ARCHIVE_OK)
 		return (ret);
@@ -132,14 +139,7 @@
 	if (ret < 512)
 		return (ARCHIVE_FATAL);
 
-	/* Only regular files (not hardlinks) have data. */
-	if (archive_entry_hardlink(entry) != NULL ||
-	    archive_entry_symlink(entry) != NULL ||
-	    !S_ISREG(archive_entry_mode(entry)))
-		ustar->entry_bytes_remaining = 0;
-	else
-		ustar->entry_bytes_remaining = archive_entry_size(entry);
-
+	ustar->entry_bytes_remaining = archive_entry_size(entry);
 	ustar->entry_padding = 0x1ff & (- ustar->entry_bytes_remaining);
 	return (ARCHIVE_OK);
 }

==== //depot/projects/hammer/lib/libc/stdlib/getopt.3#4 (text+ko) ====

@@ -1,3 +1,5 @@
+.\"	$NetBSD: getopt.3,v 1.31 2003/09/23 10:26:54 wiz Exp $
+.\"
 .\" Copyright (c) 1988, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -30,7 +32,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getopt.3	8.5 (Berkeley) 4/27/95
-.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.22 2003/09/10 19:24:33 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdlib/getopt.3,v 1.23 2004/03/06 17:09:10 ache Exp $
 .\"
 .Dd April 27, 1995
 .Dt GETOPT 3
@@ -48,7 +50,7 @@
 .Vt extern int   opterr ;
 .Vt extern int   optreset ;
 .Ft int
-.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Fn getopt "int argc" "char * const argv[]" "const char *optstring"
 .Sh DESCRIPTION
 The
 .Fn getopt
@@ -97,7 +99,7 @@
 option character returned by
 .Fn getopt .
 .Pp
-The variable
+The variables
 .Va opterr
 and
 .Va optind
@@ -122,12 +124,7 @@
 .Pp
 The
 .Fn getopt
-function
-returns \-1
-when the argument list is exhausted, or
-.Ql ?\&
-if a non-recognized
-option is encountered.
+function returns \-1 when the argument list is exhausted.
 The interpretation of options in the argument list may be cancelled
 by the option
 .Ql --
@@ -138,21 +135,75 @@
 argument),
 .Fn getopt
 returns \-1.
+.Sh RETURN VALUES
+The
+.Fn getopt
+function returns the next known option character in
+.Fa optstring .
+If
+.Fn getopt
+encounters a character not found in
+.Fa optstring
+or if it detects a missing option argument,
+it returns
+.Ql \&?
+(question mark).
+If
+.Fa optstring
+has a leading
+.Ql \&:
+then a missing option argument causes
+.Ql \&:
+to be returned instead of
+.Ql \&? .
+In either case, the variable
+.Va optopt
+is set to the character that caused the error.
+The
+.Fn getopt
+function returns \-1 when the argument list is exhausted.
+.Sh EXAMPLES
+.Bd -literal -compact
+extern char *optarg;
+extern int optind;
+int bflag, ch, fd;
+
+bflag = 0;
+while ((ch = getopt(argc, argv, "bf:")) != -1) {
+	switch (ch) {
+	case 'b':
+		bflag = 1;
+		break;
+	case 'f':
+		if ((fd = open(optarg, O_RDONLY, 0)) \*[Lt] 0) {
+			(void)fprintf(stderr,
+			    "myname: %s: %s\en", optarg, strerror(errno));
+			exit(1);
+		}
+		break;
+	case '?':
+	default:
+		usage();
+	}
+}
+argc -= optind;
+argv += optind;
+.Ed
 .Sh DIAGNOSTICS
 If the
 .Fn getopt
 function encounters a character not found in the string
-.Va optstring
+.Fa optstring
 or detects
 a missing option argument it writes an error message to the
 .Dv stderr
 and returns
-.Ql ?\& .
+.Ql \&? .
 Setting
 .Va opterr
 to a zero will disable these error messages.
 If
-.Va optstring
+.Fa optstring
 has a leading
 .Ql \&:
 then a missing option argument causes a
@@ -161,9 +212,12 @@
 .Pp
 Option arguments are allowed to begin with
 .Dq Li \- ;
-this is reasonable but
-reduces the amount of error checking possible.
-.Sh EXTENSIONS
+this is reasonable but reduces the amount of error checking possible.
+.Sh SEE ALSO
+.Xr getopt 1 ,
+.Xr getopt_long 3 ,
+.Xr getsubopt 3
+.Sh STANDARDS
 The
 .Va optreset
 variable was added to make it possible to call the
@@ -172,27 +226,6 @@
 This is an extension to the
 .St -p1003.2
 specification.
-.Sh EXAMPLES
-.Bd -literal -compact
-int bflag, ch, fd;
-
-bflag = 0;
-while ((ch = getopt(argc, argv, "bf:")) != -1)
-	switch (ch) {
-	case 'b':
-		bflag = 1;
-		break;
-	case 'f':
-		if ((fd = open(optarg, O_RDONLY, 0)) < 0)
-			err(1, "%s", optarg);
-		break;
-	case '?':
-	default:
-		usage();
-	}
-argc -= optind;
-argv += optind;
-.Ed
 .Sh HISTORY
 The
 .Fn getopt
@@ -226,10 +259,20 @@
 This practice is wrong, and should not be used in any current development.
 It is provided for backward compatibility
 .Em only .
+Care should be taken not to use
+.Ql \&-
+as the first character in
+.Fa optstring
+to avoid a semantic conflict with
+.Tn GNU
+.Fn getopt ,
+which assigns different meaning to an
+.Fa optstring
+that begins with a
+.Ql \&- .
 By default, a single dash causes
 .Fn getopt
 to return \-1.
-This is, we believe, compatible with System V.
 .Pp
 It is also possible to handle digits as option letters.
 This allows
@@ -240,9 +283,10 @@
 This practice is wrong, and should not be used in any current development.
 It is provided for backward compatibility
 .Em only .
-The following code fragment works in most (but not all) cases.
+The following code fragment works in most cases.
 .Bd -literal -offset indent
-int length;
+int ch;
+long length;
 char *p, *ep;
 
 while ((ch = getopt(argc, argv, "0123456789")) != -1)
@@ -250,16 +294,17 @@
 	case '0': case '1': case '2': case '3': case '4':
 	case '5': case '6': case '7': case '8': case '9':
 		p = argv[optind - 1];
-		if (p[0] == '-' && p[1] == ch && !p[2])
-			length = strtol(++p, &ep, 10);
-		else if (argv[optind] && argv[optind][1] == ch) {
+		if (p[0] == '-' \*[Am]\*[Am] p[1] == ch \*[Am]\*[Am] !p[2]) {
+			length = ch - '0';
+			ep = "";
+		} else if (argv[optind] \*[Am]\*[Am] argv[optind][1] == ch) {
 			length = strtol((p = argv[optind] + 1),
-			    &ep, 10);
+			    \*[Am]ep, 10);
 			optind++;
 			optreset = 1;
 		} else
 			usage();
-		if (*ep != '\0')
+		if (*ep != '\e0')
 			errx(EX_USAGE, "illegal number -- %s", p);
 		break;
 	}

==== //depot/projects/hammer/lib/libc/stdlib/getopt.c#2 (text+ko) ====

@@ -1,3 +1,5 @@
+/*	$NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $	*/
+
 /*
  * Copyright (c) 1987, 1993, 1994
  *	The Regents of the University of California.  All rights reserved.
@@ -35,12 +37,13 @@
 static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.6 2002/03/29 22:43:42 markm Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdlib/getopt.c,v 1.7 2004/03/06 17:05:45 ache Exp $");
 
 #include "namespace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include "un-namespace.h"
 
 #include "libc_private.h"
@@ -62,48 +65,64 @@
 int
 getopt(nargc, nargv, ostr)
 	int nargc;
-	char * const *nargv;
+	char * const nargv[];
 	const char *ostr;
 {
 	static char *place = EMSG;		/* option letter processing */
 	char *oli;				/* option letter list index */
 
-	if (optreset || !*place) {		/* update scanning pointer */
+	if (optreset || *place == 0) {		/* update scanning pointer */
 		optreset = 0;
-		if (optind >= nargc || *(place = nargv[optind]) != '-') {
+		place = nargv[optind];
+		if (optind >= nargc || *place++ != '-') {
+			/* Argument is absent or is not an option */
 			place = EMSG;
 			return (-1);
 		}

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list