From owner-p4-projects@FreeBSD.ORG Sat Mar 6 19:20:28 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 486CE16A4D0; Sat, 6 Mar 2004 19:20:28 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 206C616A4CE for ; Sat, 6 Mar 2004 19:20:28 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0F67043D1F for ; Sat, 6 Mar 2004 19:20:28 -0800 (PST) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i273KRGe035688 for ; Sat, 6 Mar 2004 19:20:27 -0800 (PST) (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i273KRYK035685 for perforce@freebsd.org; Sat, 6 Mar 2004 19:20:27 -0800 (PST) (envelope-from peter@freebsd.org) Date: Sat, 6 Mar 2004 19:20:27 -0800 (PST) Message-Id: <200403070320.i273KRYK035685@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Subject: PERFORCE change 48313 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Mar 2004 03:20:28 -0000 http://perforce.freebsd.org/chv.cgi?CH=48313 Change 48313 by peter@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 +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 -__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 #ifdef DMALLOC #include #endif +#include #include #include +#include #include #include @@ -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 -__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 #include @@ -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 -__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 #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 -__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 #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 -__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 #include #include +#include #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) <<<