+\f
+/* Writing routines. */
+
+/* Write the EOT block(s). Zero at least two blocks, through the end
+ of the record. Old tar, as previous versions of GNU tar, writes
+ garbage after two zeroed blocks. */
+void
+write_eot (void)
+{
+ union block *pointer = find_next_block ();
+ memset (pointer->buffer, 0, BLOCKSIZE);
+ set_next_block_after (pointer);
+ pointer = find_next_block ();
+ memset (pointer->buffer, 0, available_space_after (pointer));
+ set_next_block_after (pointer);
+}
+
+/* Write a "private" header */
+union block *
+start_private_header (const char *name, size_t size)
+{
+ time_t t;
+ union block *header = find_next_block ();
+
+ memset (header->buffer, 0, sizeof (union block));
+
+ tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE);
+ OFF_TO_CHARS (size, header->header.size);
+
+ time (&t);
+ TIME_TO_CHARS (t, header->header.mtime);
+ MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
+ UID_TO_CHARS (getuid (), header->header.uid);
+ GID_TO_CHARS (getgid (), header->header.gid);
+ MAJOR_TO_CHARS (0, header->header.devmajor);
+ MINOR_TO_CHARS (0, header->header.devminor);
+ strncpy (header->header.magic, TMAGIC, TMAGLEN);
+ strncpy (header->header.version, TVERSION, TVERSLEN);
+ return header;
+}
+
+/* Create a new header and store there at most NAME_FIELD_SIZE bytes of
+ the file name */
+
+static union block *
+write_short_name (struct tar_stat_info *st)
+{
+ union block *header = find_next_block ();
+ memset (header->buffer, 0, sizeof (union block));
+ tar_name_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);
+ return header;
+}
+
+#define FILL(field,byte) do { \
+ memset(field, byte, sizeof(field)-1); \
+ (field)[sizeof(field)-1] = 0; \
+} while (0)
+
+/* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. */
+static void
+write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
+{
+ size_t size = strlen (p) + 1;
+ size_t bufsize;
+ union block *header;
+ char *tmpname;
+
+ header = start_private_header ("././@LongLink", size);
+ FILL(header->header.mtime, '0');
+ FILL(header->header.mode, '0');
+ FILL(header->header.uid, '0');
+ FILL(header->header.gid, '0');
+ FILL(header->header.devmajor, 0);
+ FILL(header->header.devminor, 0);
+ uid_to_uname (0, &tmpname);
+ UNAME_TO_CHARS (tmpname, header->header.uname);
+ free (tmpname);
+ gid_to_gname (0, &tmpname);
+ GNAME_TO_CHARS (tmpname, header->header.gname);
+ free (tmpname);
+
+ strcpy (header->header.magic, OLDGNU_MAGIC);
+ header->header.typeflag = type;
+ finish_header (st, header, -1);
+
+ header = find_next_block ();
+
+ bufsize = available_space_after (header);
+
+ while (bufsize < size)
+ {
+ memcpy (header->buffer, p, bufsize);
+ p += bufsize;
+ size -= bufsize;
+ set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
+ header = find_next_block ();
+ bufsize = available_space_after (header);