From 6276da5abaede4ecc4bdc163f7781a586634c6fe Mon Sep 17 00:00:00 2001 From: Keith Bostic Date: Fri, 18 Jan 1991 02:23:32 -0800 Subject: [PATCH] date and time created 91/01/17 18:23:32 by bostic SCCS-vsn: usr.bin/ar/archive.c 5.1 --- usr/src/usr.bin/ar/archive.c | 133 +++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 usr/src/usr.bin/ar/archive.c diff --git a/usr/src/usr.bin/ar/archive.c b/usr/src/usr.bin/ar/archive.c new file mode 100644 index 0000000000..b446d1a0ac --- /dev/null +++ b/usr/src/usr.bin/ar/archive.c @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Hugh Smith at The University of Guelph. + * + * %sccs.include.redist.c% + */ + +#ifndef lint +static char sccsid[] = "@(#)archive.c 5.1 (Berkeley) %G%"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "archive.h" + +extern char *archive; /* archive name */ + +open_archive(mode) + int mode; +{ + int created, fd, nr; + char buf[SARMAG]; + + created = 0; + if (mode & O_CREAT) { + mode |= O_EXCL; + if ((fd = open(archive, mode, DEFFILEMODE)) >= 0) { + /* POSIX.2 puts create message on stderr. */ + if (!(options & AR_C)) + (void)fprintf(stderr, + "ar: creating archive %s.\n", archive); + created = 1; + goto opened; + } + if (errno != EEXIST) + error(archive); + mode &= ~O_EXCL; + } + if ((fd = open(archive, mode, DEFFILEMODE)) < 0) + error(archive); + + /* + * Attempt to place a lock on the opened file - if we get an + * error then someone is already working on this library. + */ +opened: if (flock(fd, LOCK_EX|LOCK_NB)) + error(archive); + + /* + * If not created, O_RDONLY|O_RDWR indicates that it has to be + * in archive format. + */ + if (!created && + ((mode & O_ACCMODE) == O_RDONLY || (mode & O_ACCMODE) == O_RDWR)) { + if ((nr = read(fd, buf, SARMAG) != SARMAG)) { + if (nr >= 0) + badfmt(); + error(archive); + } else if (bcmp(buf, ARMAG, SARMAG)) + badfmt(); + } else if (write(fd, ARMAG, SARMAG) != SARMAG) + error(archive); + return(fd); +} + +close_archive(fd) + int fd; +{ + (void)flock(fd, LOCK_UN); + (void)close(fd); +} + +/* + * copyfile -- + * Copy size bytes from one file to another - taking care to handle the + * extra byte (for odd size files) when reading archives and tmpfiles + * and writing an extra byte if necessary when adding files to archive. + * + * The padding is really unnecessary, and is almost certainly a remnant + * of early archive formats where the header included binary data which + * a PDP-11 required to start on an even byte boundary. It should have + * been ripped out when the format changed. + */ +copyfile(cfp, size) + CF *cfp; + register off_t size; +{ + register int from, nr, nw, off, to; + char pad, buf[8*1024]; + + if (!size) + return; + + pad = size & 1; + from = cfp->rfd; + to = cfp->wfd; + while (size && + (nr = read(from, buf, MIN(size, sizeof(buf)))) > 0) { + size -= nr; + for (off = 0; off < nr; nr -= off, off += nw) + if ((nw = write(to, buf + off, nr)) < 0) + error(cfp->wname); + } + if (size) { + if (nr == 0) + badfmt(); + error(cfp->rname); + } + + if (pad) { + if (cfp->flags & RPAD && (nr = read(from, buf, 1)) != 1) { + if (nr == 0) + badfmt(); + error(cfp->rname); + } + if (cfp->flags & WPAD) { + pad = '\n'; + if (write(to, &pad, 1) != 1) + error(cfp->wname); + } + } +} -- 2.20.1