You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "system.h"
void
mode_to_oct (mode_t v, char *p, size_t s)
{
- to_oct ((uintmax_t) v, (uintmax_t) 0, p, s, "mode_t");
+ /* In the common case where the internal and external mode bits are the same,
+ propagate all unknown bits to the external mode.
+ This matches historical practice.
+ Otherwise, just copy the bits we know about. */
+ uintmax_t u =
+ ((S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
+ && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
+ && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
+ && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC)
+ ? v
+ : ((v & S_ISUID ? TSUID : 0)
+ | (v & S_ISGID ? TSGID : 0)
+ | (v & S_ISVTX ? TSVTX : 0)
+ | (v & S_IRUSR ? TUREAD : 0)
+ | (v & S_IWUSR ? TUWRITE : 0)
+ | (v & S_IXUSR ? TUEXEC : 0)
+ | (v & S_IRGRP ? TGREAD : 0)
+ | (v & S_IWGRP ? TGWRITE : 0)
+ | (v & S_IXGRP ? TGEXEC : 0)
+ | (v & S_IROTH ? TOREAD : 0)
+ | (v & S_IWOTH ? TOWRITE : 0)
+ | (v & S_IXOTH ? TOEXEC : 0)));
+ to_oct (u, (uintmax_t) 0, p, s, "mode_t");
}
void
off_to_oct (off_t v, char *p, size_t s)
if (group_option != (gid_t) -1)
st->st_gid = group_option;
if (mode_option)
- st->st_mode = ((st->st_mode & S_IFMT)
+ st->st_mode = ((st->st_mode & ~MODE_ALL)
| mode_adjust (st->st_mode, mode_option));
/* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
acceptor for Paul's test. */
if (archive_format == V7_FORMAT)
- MODE_TO_OCT (st->st_mode & 07777, header->header.mode);
+ MODE_TO_OCT (st->st_mode & MODE_ALL, header->header.mode);
else
MODE_TO_OCT (st->st_mode, header->header.mode);
/* Fill in the checksum field. It's formatted differently from the
other fields: it has [6] digits, a null, then a space -- rather than
digits, then a null. We use to_oct.
- The final space is already there, from checksumming,
- and to_oct doesn't modify it.
+ The final space is already there, from
+ checksumming, and to_oct doesn't modify it.
This is a fast way to do:
init_sparsearray ();
clear_buffer (buffer);
- while (count = read (file, buffer, sizeof buffer), count != 0)
+ while (count = safe_read (file, buffer, sizeof buffer), count != 0)
{
/* Realloc the scratch area as necessary. FIXME: should reallocate
only at beginning of a new instance of non-zero data. */
break;
}
- if (lseek (file, sparsearray[sparse_index++].offset, 0) < 0)
+ if (lseek (file, sparsearray[sparse_index++].offset, SEEK_SET) < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
ERROR ((0, errno, _("lseek error at byte %s in file %s"),
#if 0
if (amount_read)
{
- count = read (file, start->buffer + amount_read,
- BLOCKSIZE - amount_read);
+ count = safe_read (file, start->buffer + amount_read,
+ BLOCKSIZE - amount_read);
bufsize -= BLOCKSIZE - amount_read;
amount_read = 0;
set_next_block_after (start);
#endif
/* Store the data. */
- count = read (file, start->buffer, BLOCKSIZE);
+ count = safe_read (file, start->buffer, BLOCKSIZE);
if (count < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
char buffer[BLOCKSIZE];
clear_buffer (buffer);
- count = read (file, buffer, bufsize);
+ count = safe_read (file, buffer, bufsize);
memcpy (start->buffer, buffer, BLOCKSIZE);
}
collect_and_sort_names ();
while (p = name_from_list (), p)
- dump_file (p, (dev_t) -1, 1);
+ if (!excluded_pathname (excluded, p))
+ dump_file (p, (dev_t) -1, 1);
blank_name_list ();
while (p = name_from_list (), p)
else
{
while (p = name_next (1), p)
- dump_file (p, (dev_t) -1, 1);
+ if (!excluded_pathname (excluded, p))
+ dump_file (p, (dev_t) -1, 1);
}
write_eot ();
if (current_stat.st_nlink > 1
&& (S_ISREG (current_stat.st_mode)
-#ifdef S_ISCTG
|| S_ISCTG (current_stat.st_mode)
-#endif
-#ifdef S_ISCHR
|| S_ISCHR (current_stat.st_mode)
-#endif
-#ifdef S_ISBLK
|| S_ISBLK (current_stat.st_mode)
-#endif
-#ifdef S_ISFIFO
- || S_ISFIFO (current_stat.st_mode)
-#endif
- ))
+ || S_ISFIFO (current_stat.st_mode)))
{
struct link *lp;
/* This is not a link to a previously dumped file, so dump it. */
if (S_ISREG (current_stat.st_mode)
-#ifdef S_ISCTG
- || S_ISCTG (current_stat.st_mode)
-#endif
- )
+ || S_ISCTG (current_stat.st_mode))
{
int f; /* file descriptor */
size_t bufsize;
files when archive is meant for /dev/null. */
if (dev_null_output
- || (sizeleft == 0 && 0444 == (0444 & current_stat.st_mode)))
+ || (sizeleft == 0
+ && MODE_R == (MODE_R & current_stat.st_mode)))
f = -1;
else
{
return;
}
}
-#ifdef S_ISCTG
+
/* Mark contiguous files, if we support them. */
if (archive_format != V7_FORMAT && S_ISCTG (current_stat.st_mode))
header->header.typeflag = CONTTYPE;
-#endif
+
isextended = header->oldgnu_header.isextended;
save_typeflag = header->header.typeflag;
finish_header (header);
}
if (save_typeflag == GNUTYPE_SPARSE)
{
- if (finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
+ if (f < 0
+ || finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
goto padit;
}
else
if (f < 0)
count = bufsize;
else
- count = read (f, start->buffer, bufsize);
+ count = safe_read (f, start->buffer, bufsize);
if (count < 0)
{
char buf[UINTMAX_STRSIZE_BOUND];
return;
}
-#ifdef S_ISLNK
+#ifdef HAVE_READLINK
else if (S_ISLNK (current_stat.st_mode))
{
int size;
}
return;
}
-#endif /* S_ISLNK */
+#endif
else if (S_ISDIR (current_stat.st_mode))
{
while (entry = readdir (directory), entry)
{
- /* Skip `.' and `..'. */
+ /* Skip `.', `..', and excluded file names. */
- if (is_dot_or_dotdot (entry->d_name))
+ if (is_dot_or_dotdot (entry->d_name)
+ || excluded_filename (excluded, entry->d_name))
continue;
if ((int) NAMLEN (entry) + len >= buflen)
#endif
}
strcpy (namebuf + len, entry->d_name);
- if (exclude_option && check_exclude (namebuf))
- continue;
dump_file (namebuf, our_device, 0);
}
return;
}
-#ifdef S_ISCHR
else if (S_ISCHR (current_stat.st_mode))
type = CHRTYPE;
-#endif
-
-#ifdef S_ISBLK
else if (S_ISBLK (current_stat.st_mode))
type = BLKTYPE;
-#endif
-
- /* Avoid screwy apollo lossage where S_IFIFO == S_IFSOCK. */
-
-#if (_ISP__M68K == 0) && (_ISP__A88K == 0) && defined(S_ISFIFO)
- else if (S_ISFIFO (current_stat.st_mode))
+ else if (S_ISFIFO (current_stat.st_mode)
+ || S_ISSOCK (current_stat.st_mode))
type = FIFOTYPE;
-#endif
-
-#ifdef S_ISSOCK
- else if (S_ISSOCK (current_stat.st_mode))
- type = FIFOTYPE;
-#endif
-
else
goto unknown;
header->header.typeflag = type;
-#if defined(S_IFBLK) || defined(S_IFCHR)
if (type != FIFOTYPE)
{
MAJOR_TO_OCT (major (current_stat.st_rdev), header->header.devmajor);
MINOR_TO_OCT (minor (current_stat.st_rdev), header->header.devminor);
}
-#endif
finish_header (header);
if (remove_files_option)