summaryrefslogtreecommitdiffstats
path: root/bin/pax/tar.c
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2001-05-08 06:19:06 +0000
committerkris <kris@FreeBSD.org>2001-05-08 06:19:06 +0000
commit6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4 (patch)
tree63ec355a438835dcc12c39eb54e9e286c4f71426 /bin/pax/tar.c
parent7ecc59e45de1a67ed22b32856a18f28bb30d36e6 (diff)
downloadFreeBSD-src-6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4.zip
FreeBSD-src-6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4.tar.gz
Sync up with OpenBSD. Too many changes to note, but the major features
are: * Implement cpio compatibility mode when pax is invoked as cpio * Extend tar compatibility mode to cover many of the GNU tar single-letter options (bzip2 mode, aka -y/-j is not present in OpenBSD). When invoked as tar, pax is now full-featured enough for use by the ports collection to extract distfiles and create packages. * Many bug fixes to the operation of pax and the tar compatibility modes * Code fixes for things like correct string buffer termination. I tried to preserve existing FreeBSD fixes to this utility; please let me know if I have inadvertently spammed something.
Diffstat (limited to 'bin/pax/tar.c')
-rw-r--r--bin/pax/tar.c78
1 files changed, 51 insertions, 27 deletions
diff --git a/bin/pax/tar.c b/bin/pax/tar.c
index c6d5b89..541b450 100644
--- a/bin/pax/tar.c
+++ b/bin/pax/tar.c
@@ -162,7 +162,7 @@ tar_trail(buf, in_resync, cnt)
* ul_oct()
* convert an unsigned long to an octal string. many oddball field
* termination characters are used by the various versions of tar in the
- * different fields. term selects which kind to use. str is BLANK padded
+ * different fields. term selects which kind to use. str is '0' padded
* at the front to len. we are unable to use only one format as many old
* tar readers are very cranky about this.
* Return:
@@ -215,7 +215,7 @@ ul_oct(val, str, len, term)
}
while (pt >= str)
- *pt-- = ' ';
+ *pt-- = '0';
if (val != (u_long)0)
return(-1);
return(0);
@@ -226,7 +226,7 @@ ul_oct(val, str, len, term)
* uqd_oct()
* convert an u_quad_t to an octal string. one of many oddball field
* termination characters are used by the various versions of tar in the
- * different fields. term selects which kind to use. str is BLANK padded
+ * different fields. term selects which kind to use. str is '0' padded
* at the front to len. we are unable to use only one format as many old
* tar readers are very cranky about this.
* Return:
@@ -279,7 +279,7 @@ uqd_oct(val, str, len, term)
}
while (pt >= str)
- *pt-- = ' ';
+ *pt-- = '0';
if (val != (u_quad_t)0)
return(-1);
return(0);
@@ -453,13 +453,17 @@ tar_rd(arcn, buf)
* copy out the name and values in the stat buffer
*/
hd = (HD_TAR *)buf;
- arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(hd->name));
+ arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(arcn->name) - 1);
arcn->name[arcn->nlen] = '\0';
arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
0xfff);
arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
- arcn->sb.st_size = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT);
+#ifdef NET2_STAT
+ arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
+#else
+ arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
+#endif
arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
@@ -478,7 +482,7 @@ tar_rd(arcn, buf)
*/
arcn->type = PAX_SLK;
arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
- sizeof(hd->linkname));
+ sizeof(arcn->ln_name) - 1);
arcn->ln_name[arcn->ln_nlen] = '\0';
arcn->sb.st_mode |= S_IFLNK;
break;
@@ -490,7 +494,7 @@ tar_rd(arcn, buf)
arcn->type = PAX_HLK;
arcn->sb.st_nlink = 2;
arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
- sizeof(hd->linkname));
+ sizeof(arcn->ln_name) - 1);
arcn->ln_name[arcn->ln_nlen] = '\0';
/*
@@ -499,6 +503,16 @@ tar_rd(arcn, buf)
*/
arcn->sb.st_mode |= S_IFREG;
break;
+ case DIRTYPE:
+ /*
+ * It is a directory, set the mode for -v printing
+ */
+ arcn->type = PAX_DIR;
+ arcn->sb.st_mode |= S_IFDIR;
+ arcn->sb.st_nlink = 2;
+ arcn->ln_name[0] = '\0';
+ arcn->ln_nlen = 0;
+ break;
case AREGTYPE:
case REGTYPE:
default:
@@ -607,7 +621,7 @@ tar_wr(arcn)
len = arcn->nlen;
if (arcn->type == PAX_DIR)
++len;
- if (len > sizeof(hd->name)) {
+ if (len >= sizeof(hd->name)) {
paxwarn(1, "File name too long for tar %s", arcn->name);
return(1);
}
@@ -621,7 +635,8 @@ tar_wr(arcn)
* a header)
*/
hd = (HD_TAR *)hdblk;
- zf_strncpy(hd->name, arcn->name, sizeof(hd->name));
+ l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1);
+ hd->name[sizeof(hd->name) - 1] = '\0';
arcn->pad = 0;
if (arcn->type == PAX_DIR) {
@@ -640,7 +655,8 @@ tar_wr(arcn)
* no data follows this file, so no pad
*/
hd->linkflag = SYMTYPE;
- zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname));
+ l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
+ hd->linkname[sizeof(hd->linkname) - 1] = '\0';
if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
goto out;
} else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
@@ -648,7 +664,8 @@ tar_wr(arcn)
* no data follows this file, so no pad
*/
hd->linkflag = LNKTYPE;
- zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname));
+ l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
+ hd->linkname[sizeof(hd->linkname) - 1] = '\0';
if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
goto out;
} else {
@@ -685,7 +702,7 @@ tar_wr(arcn)
* to be written
*/
if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
- sizeof(hd->chksum), 2))
+ sizeof(hd->chksum), 3))
goto out;
if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0)
return(-1);
@@ -818,6 +835,7 @@ ustar_rd(arcn, buf)
arcn->org_name = arcn->name;
arcn->sb.st_nlink = 1;
arcn->pat = NULL;
+ arcn->nlen = 0;
hd = (HD_USTAR *)buf;
/*
@@ -826,12 +844,12 @@ ustar_rd(arcn, buf)
*/
dest = arcn->name;
if (*(hd->prefix) != '\0') {
- cnt = l_strncpy(arcn->name, hd->prefix, sizeof(hd->prefix));
- dest = arcn->name + arcn->nlen;
+ cnt = l_strncpy(dest, hd->prefix, sizeof(arcn->name) - 2);
+ dest += cnt;
*dest++ = '/';
+ cnt++;
}
- arcn->nlen = l_strncpy(dest, hd->name, sizeof(hd->name));
- arcn->nlen += cnt;
+ arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(arcn->name) - cnt);
arcn->name[arcn->nlen] = '\0';
/*
@@ -840,7 +858,11 @@ ustar_rd(arcn, buf)
*/
arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
0xfff);
- arcn->sb.st_size = (size_t)asc_ul(hd->size, sizeof(hd->size), OCT);
+#ifdef NET2_STAT
+ arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
+#else
+ arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
+#endif
arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
@@ -920,7 +942,7 @@ ustar_rd(arcn, buf)
* copy the link name
*/
arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
- sizeof(hd->linkname));
+ sizeof(arcn->ln_name) - 1);
arcn->ln_name[arcn->ln_nlen] = '\0';
break;
case CONTTYPE:
@@ -1002,7 +1024,7 @@ ustar_wr(arcn)
* occur, we remove the / and copy the first part to the prefix
*/
*pt = '\0';
- zf_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix));
+ l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix) - 1);
*pt++ = '/';
} else
memset(hd->prefix, 0, sizeof(hd->prefix));
@@ -1011,7 +1033,8 @@ ustar_wr(arcn)
* copy the name part. this may be the whole path or the part after
* the prefix
*/
- zf_strncpy(hd->name, pt, sizeof(hd->name));
+ l_strncpy(hd->name, pt, sizeof(hd->name) - 1);
+ hd->name[sizeof(hd->name) - 1] = '\0';
/*
* set the fields in the header that are type dependent
@@ -1054,7 +1077,8 @@ ustar_wr(arcn)
hd->typeflag = SYMTYPE;
else
hd->typeflag = LNKTYPE;
- zf_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname));
+ l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
+ hd->linkname[sizeof(hd->linkname) - 1] = '\0';
memset(hd->devmajor, 0, sizeof(hd->devmajor));
memset(hd->devminor, 0, sizeof(hd->devminor));
if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
@@ -1087,8 +1111,8 @@ ustar_wr(arcn)
break;
}
- zf_strncpy(hd->magic, TMAGIC, TMAGLEN);
- zf_strncpy(hd->version, TVERSION, TVERSLEN);
+ l_strncpy(hd->magic, TMAGIC, TMAGLEN);
+ l_strncpy(hd->version, TVERSION, TVERSLEN);
/*
* set the remaining fields. Some versions want all 16 bits of mode
@@ -1099,8 +1123,8 @@ ustar_wr(arcn)
ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
goto out;
- zf_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
- zf_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
+ l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
+ l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
/*
* calculate and store the checksum write the header to the archive
@@ -1154,7 +1178,7 @@ name_split(name, len)
* check to see if the file name is small enough to fit in the name
* field. if so just return a pointer to the name.
*/
- if (len <= TNMSZ)
+ if (len < TNMSZ)
return(name);
if (len > (TPFSZ + TNMSZ))
return(NULL);
OpenPOWER on IntegriCloud