* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Hugh Smith at The University of Guelph.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)header.c 5.2 (Berkeley) %G%";
typedef struct ar_hdr HDR
;
extern CHDR chdr
; /* converted header */
static char hb
[sizeof(HDR
) + 1]; /* real header */
extern char *archive
; /* archive name */
/* Convert ar header field to an integer. */
#define AR_ATOI(from, to, len, base) { \
to = strtol(buf, (char **)NULL, base); \
* read the archive header for this member
register char *p
, buf
[20];
nr
= read(fd
, hb
, sizeof(HDR
));
hdr
= (struct ar_hdr
*)hb
;
if (strncmp(hdr
->ar_fmag
, ARFMAG
, sizeof(ARFMAG
) - 1))
/* Convert the header into the internal format. */
AR_ATOI(hdr
->ar_date
, chdr
.date
, sizeof(hdr
->ar_date
), DECIMAL
);
AR_ATOI(hdr
->ar_uid
, chdr
.uid
, sizeof(hdr
->ar_uid
), DECIMAL
);
AR_ATOI(hdr
->ar_gid
, chdr
.gid
, sizeof(hdr
->ar_gid
), DECIMAL
);
AR_ATOI(hdr
->ar_mode
, chdr
.mode
, sizeof(hdr
->ar_mode
), OCTAL
);
AR_ATOI(hdr
->ar_size
, chdr
.size
, sizeof(hdr
->ar_size
), DECIMAL
);
/* Leading spaces should never happen. */
if (hdr
->ar_name
[0] == ' ')
* Long name support. Set the "real" size of the file, and the
if (!bcmp(hdr
->ar_name
, AR_EFMT1
, sizeof(AR_EFMT1
) - 1)) {
len
= atoi(hdr
->ar_name
+ sizeof(AR_EFMT1
) - 1);
if (len
<= 0 || len
> MAXNAMLEN
)
nr
= read(fd
, chdr
.name
, len
);
chdr
.size
-= (chdr
.lname
= len
);
bcopy(hdr
->ar_name
, chdr
.name
, sizeof(hdr
->ar_name
));
/* Only strip off trailing spaces. */
for (p
= chdr
.name
+ sizeof(hdr
->ar_name
) - 1; *p
== ' '; --p
);
* Write the archive member header to a file.
* If passed an sb structure, reading a file from disk. Get stat(2)
* information, build a name and construct a header. (Files are named
* by their last component in the archive.) If not, then just write
name
= rname(cfp
->rname
);
(void)fstat(cfp
->rfd
, sb
);
if ((lname
= strlen(name
)) > sizeof(hdr
->ar_name
) ||
(void)sprintf(hb
, HDR1
, AR_EFMT1
, lname
, sb
->st_mtime
,
sb
->st_uid
, sb
->st_gid
, sb
->st_mode
,
sb
->st_size
+ lname
, ARFMAG
);
(void)sprintf(hb
, HDR2
, name
, sb
->st_mtime
, sb
->st_uid
,
sb
->st_gid
, sb
->st_mode
, sb
->st_size
, ARFMAG
);
if (write(cfp
->wfd
, hb
, sizeof(HDR
)) != sizeof(HDR
) ||
lname
&& write(cfp
->wfd
, name
, lname
) != lname
)