diff options
Diffstat (limited to 'bin/pax/tar.c')
-rw-r--r-- | bin/pax/tar.c | 80 |
1 files changed, 39 insertions, 41 deletions
diff --git a/bin/pax/tar.c b/bin/pax/tar.c index b8b4eb3662c..e4005788794 100644 --- a/bin/pax/tar.c +++ b/bin/pax/tar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tar.c,v 1.31 2003/06/26 00:10:18 deraadt Exp $ */ +/* $OpenBSD: tar.c,v 1.32 2004/03/30 16:14:23 millert Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] = "$OpenBSD: tar.c,v 1.31 2003/06/26 00:10:18 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: tar.c,v 1.32 2004/03/30 16:14:23 millert Exp $"; #endif #endif /* not lint */ @@ -58,6 +58,7 @@ static const char rcsid[] = "$OpenBSD: tar.c,v 1.31 2003/06/26 00:10:18 deraadt * Routines for reading, writing and header identify of various versions of tar */ +static size_t expandname(char *, size_t, char **, const char *); static u_long tar_chksm(char *, int); static char *name_split(char *, int); static int ul_oct(u_long, char *, int, int); @@ -70,7 +71,8 @@ static int uqd_oct(u_quad_t, char *, int, int); */ static int tar_nodir; /* do not write dirs under old tar */ -char *gnu_hack_string; /* GNU ././@LongLink hackery */ +char *gnu_name_string; /* GNU ././@LongLink hackery name */ +char *gnu_link_string; /* GNU ././@LongLink hackery link */ /* * tar_endwr() @@ -385,21 +387,19 @@ tar_rd(ARCHD *arcn, char *buf) */ if (tar_id(buf, BLKMULT) < 0) return(-1); + memset(arcn, 0, sizeof(*arcn)); arcn->org_name = arcn->name; arcn->sb.st_nlink = 1; - arcn->pat = NULL; /* * copy out the name and values in the stat buffer */ hd = (HD_TAR *)buf; - if (gnu_hack_string) { - arcn->nlen = strlcpy(arcn->name, gnu_hack_string, - sizeof(arcn->name)); - free(gnu_hack_string); - gnu_hack_string = NULL; - } else { - arcn->nlen = strlcpy(arcn->name, hd->name, sizeof(arcn->name)); + if (hd->linkflag != LONGLINKTYPE && hd->linkflag != LONGNAMETYPE) { + arcn->nlen = expandname(arcn->name, sizeof(arcn->name), + &gnu_name_string, hd->name); + arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), + &gnu_link_string, hd->linkname); } arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) & 0xfff); @@ -427,8 +427,6 @@ tar_rd(ARCHD *arcn, char *buf) * the st_mode so -v printing will look correct. */ arcn->type = PAX_SLK; - arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name)); arcn->sb.st_mode |= S_IFLNK; break; case LNKTYPE: @@ -438,8 +436,6 @@ tar_rd(ARCHD *arcn, char *buf) */ arcn->type = PAX_HLK; arcn->sb.st_nlink = 2; - arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name)); /* * no idea of what type this thing really points at, but @@ -448,19 +444,15 @@ tar_rd(ARCHD *arcn, char *buf) arcn->sb.st_mode |= S_IFREG; break; case LONGLINKTYPE: - arcn->type = PAX_GLL; - /* FALLTHROUGH */ case LONGNAMETYPE: /* * GNU long link/file; we tag these here and let the * pax internals deal with it -- too ugly otherwise. */ - if (hd->linkflag != LONGLINKTYPE) - arcn->type = PAX_GLF; + arcn->type = + hd->linkflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF; arcn->pad = TAR_PAD(arcn->sb.st_size); arcn->skip = arcn->sb.st_size; - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; break; case DIRTYPE: /* @@ -469,8 +461,6 @@ tar_rd(ARCHD *arcn, char *buf) 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: @@ -757,10 +747,9 @@ ustar_rd(ARCHD *arcn, char *buf) */ if (ustar_id(buf, BLKMULT) < 0) return(-1); + memset(arcn, 0, sizeof(*arcn)); arcn->org_name = arcn->name; arcn->sb.st_nlink = 1; - arcn->pat = NULL; - arcn->nlen = 0; hd = (HD_USTAR *)buf; /* @@ -773,14 +762,15 @@ ustar_rd(ARCHD *arcn, char *buf) dest += cnt; *dest++ = '/'; cnt++; - } - if (gnu_hack_string) { - arcn->nlen = strlcpy(dest, gnu_hack_string, - sizeof(arcn->name) - cnt); - free(gnu_hack_string); - gnu_hack_string = NULL; } else { - arcn->nlen = strlcpy(dest, hd->name, sizeof(arcn->name) - cnt); + cnt = 0; + } + + if (hd->typeflag != LONGLINKTYPE && hd->typeflag != LONGNAMETYPE) { + arcn->nlen = expandname(dest, sizeof(arcn->name) - cnt, + &gnu_name_string, hd->name); + arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), + &gnu_link_string, hd->linkname); } /* @@ -813,8 +803,6 @@ ustar_rd(ARCHD *arcn, char *buf) /* * set the defaults, these may be changed depending on the file type */ - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; arcn->pad = 0; arcn->skip = 0; arcn->sb.st_rdev = (dev_t)0; @@ -869,11 +857,6 @@ ustar_rd(ARCHD *arcn, char *buf) arcn->sb.st_mode |= S_IFREG; arcn->sb.st_nlink = 2; } - /* - * copy the link name - */ - arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name)); break; case LONGLINKTYPE: case LONGNAMETYPE: @@ -885,8 +868,6 @@ ustar_rd(ARCHD *arcn, char *buf) hd->typeflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF; arcn->pad = TAR_PAD(arcn->sb.st_size); arcn->skip = arcn->sb.st_size; - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; break; case CONTTYPE: case AREGTYPE: @@ -1135,3 +1116,20 @@ name_split(char *name, int len) */ return(start); } + +static size_t +expandname(char *buf, size_t len, char **gnu_name, const char *name) +{ + size_t nlen; + + if (*gnu_name) { + if ((nlen = strlcpy(buf, *gnu_name, len)) >= len) + nlen = len - 1; + free(*gnu_name); + *gnu_name = NULL; + } else { + if ((nlen = strlcpy(buf, name, len)) >= len) + nlen = len - 1; + } + return(nlen); +} |