use stdlib.h to declare atof and malloc
[unix-history] / usr / src / usr.bin / ar / archive.c
CommitLineData
6276da5a
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Hugh Smith at The University of Guelph.
7 *
8 * %sccs.include.redist.c%
9 */
10
11#ifndef lint
12static char sccsid[] = "@(#)archive.c 5.1 (Berkeley) %G%";
13#endif /* not lint */
14
15#include <sys/param.h>
16#include <sys/errno.h>
17#include <sys/stat.h>
18#include <fcntl.h>
19#include <unistd.h>
20#include <dirent.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <ar.h>
25#include "archive.h"
26
27extern char *archive; /* archive name */
28
29open_archive(mode)
30 int mode;
31{
32 int created, fd, nr;
33 char buf[SARMAG];
34
35 created = 0;
36 if (mode & O_CREAT) {
37 mode |= O_EXCL;
38 if ((fd = open(archive, mode, DEFFILEMODE)) >= 0) {
39 /* POSIX.2 puts create message on stderr. */
40 if (!(options & AR_C))
41 (void)fprintf(stderr,
42 "ar: creating archive %s.\n", archive);
43 created = 1;
44 goto opened;
45 }
46 if (errno != EEXIST)
47 error(archive);
48 mode &= ~O_EXCL;
49 }
50 if ((fd = open(archive, mode, DEFFILEMODE)) < 0)
51 error(archive);
52
53 /*
54 * Attempt to place a lock on the opened file - if we get an
55 * error then someone is already working on this library.
56 */
57opened: if (flock(fd, LOCK_EX|LOCK_NB))
58 error(archive);
59
60 /*
61 * If not created, O_RDONLY|O_RDWR indicates that it has to be
62 * in archive format.
63 */
64 if (!created &&
65 ((mode & O_ACCMODE) == O_RDONLY || (mode & O_ACCMODE) == O_RDWR)) {
66 if ((nr = read(fd, buf, SARMAG) != SARMAG)) {
67 if (nr >= 0)
68 badfmt();
69 error(archive);
70 } else if (bcmp(buf, ARMAG, SARMAG))
71 badfmt();
72 } else if (write(fd, ARMAG, SARMAG) != SARMAG)
73 error(archive);
74 return(fd);
75}
76
77close_archive(fd)
78 int fd;
79{
80 (void)flock(fd, LOCK_UN);
81 (void)close(fd);
82}
83
84/*
85 * copyfile --
86 * Copy size bytes from one file to another - taking care to handle the
87 * extra byte (for odd size files) when reading archives and tmpfiles
88 * and writing an extra byte if necessary when adding files to archive.
89 *
90 * The padding is really unnecessary, and is almost certainly a remnant
91 * of early archive formats where the header included binary data which
92 * a PDP-11 required to start on an even byte boundary. It should have
93 * been ripped out when the format changed.
94 */
95copyfile(cfp, size)
96 CF *cfp;
97 register off_t size;
98{
99 register int from, nr, nw, off, to;
100 char pad, buf[8*1024];
101
102 if (!size)
103 return;
104
105 pad = size & 1;
106 from = cfp->rfd;
107 to = cfp->wfd;
108 while (size &&
109 (nr = read(from, buf, MIN(size, sizeof(buf)))) > 0) {
110 size -= nr;
111 for (off = 0; off < nr; nr -= off, off += nw)
112 if ((nw = write(to, buf + off, nr)) < 0)
113 error(cfp->wname);
114 }
115 if (size) {
116 if (nr == 0)
117 badfmt();
118 error(cfp->rname);
119 }
120
121 if (pad) {
122 if (cfp->flags & RPAD && (nr = read(from, buf, 1)) != 1) {
123 if (nr == 0)
124 badfmt();
125 error(cfp->rname);
126 }
127 if (cfp->flags & WPAD) {
128 pad = '\n';
129 if (write(to, &pad, 1) != 1)
130 error(cfp->wname);
131 }
132 }
133}