diff options
author | kris <kris@FreeBSD.org> | 2001-05-08 06:19:06 +0000 |
---|---|---|
committer | kris <kris@FreeBSD.org> | 2001-05-08 06:19:06 +0000 |
commit | 6f2ea93cf4d39dc17b5fff4bc84a55d6562c8cd4 (patch) | |
tree | 63ec355a438835dcc12c39eb54e9e286c4f71426 /bin/pax/tar.c | |
parent | 7ecc59e45de1a67ed22b32856a18f28bb30d36e6 (diff) | |
download | FreeBSD-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.c | 78 |
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); |