(print_total_written): Use a format compatible with
[debian/tar] / src / mangle.c
1 /* Encode long filenames for GNU tar.
2    Copyright 1988, 1992, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2, or (at your option) any later
7    version.
8
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
12    Public License for more details.
13
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #include "system.h"
19 #include "common.h"
20
21 struct mangled
22   {
23     struct mangled *next;
24     int type;
25     char mangled[NAME_FIELD_SIZE];
26     char *linked_to;
27     char normal[1];
28   };
29
30 /*---------------------------------------------------------------------.
31 | Extract a GNUTYPE_NAMES record contents.  It seems that such are not |
32 | produced anymore by GNU tar, but we leave the reading code around    |
33 | nevertheless, for salvaging old tapes.                               |
34 `---------------------------------------------------------------------*/
35
36 void
37 extract_mangle (void)
38 {
39   off_t size = current_stat.st_size;
40   char *buffer = xmalloc ((size_t) (size + 1));
41   char *copy = buffer;
42   char *cursor = buffer;
43
44   if (size != (size_t) size || size == (size_t) -1)
45     FATAL_ERROR ((0, 0, _("Memory exhausted")));
46
47   buffer[size] = '\0';
48
49   while (size > 0)
50     {
51       union block *block = find_next_block ();
52       size_t available;
53
54       if (!block)
55         {
56           ERROR ((0, 0, _("Unexpected EOF in mangled names")));
57           return;
58         }
59       available = available_space_after (block);
60       if (available > size)
61         available = size;
62       memcpy (copy, block->buffer, available);
63       copy += available;
64       size -= available;
65       set_next_block_after ((union block *) (block->buffer + available - 1));
66     }
67
68   while (*cursor)
69     {
70       char *next_cursor;
71       char *name;
72       char *name_end;
73
74       next_cursor = strchr (cursor, '\n');
75       *next_cursor++ = '\0';
76
77       if (!strncmp (cursor, "Rename ", 7))
78         {
79
80           name = cursor + 7;
81           name_end = strchr (name, ' ');
82           while (strncmp (name_end, " to ", 4))
83             {
84               name_end++;
85               name_end = strchr (name_end, ' ');
86             }
87           *name_end = '\0';
88           if (next_cursor[-2] == '/')
89             next_cursor[-2] = '\0';
90           unquote_string (name_end + 4);
91           if (rename (name, name_end + 4))
92             ERROR ((0, errno, _("Cannot rename %s to %s"), name, name_end + 4));
93           else if (verbose_option)
94             WARN ((0, 0, _("Renamed %s to %s"), name, name_end + 4));
95         }
96 #ifdef HAVE_SYMLINK
97       else if (!strncmp (cursor, "Symlink ", 8))
98         {
99           name = cursor + 8;
100           name_end = strchr (name, ' ');
101           while (strncmp (name_end, " to ", 4))
102             {
103               name_end++;
104               name_end = strchr (name_end, ' ');
105             }
106           *name_end = '\0';
107           unquote_string (name);
108           unquote_string (name_end + 4);
109           if (symlink (name, name_end + 4)
110               && (unlink (name_end + 4) || symlink (name, name_end + 4)))
111             ERROR ((0, errno, _("Cannot symlink %s to %s"),
112                     name, name_end + 4));
113           else if (verbose_option)
114             WARN ((0, 0, _("Symlinked %s to %s"), name, name_end + 4));
115         }
116 #endif
117       else
118         ERROR ((0, 0, _("Unknown demangling command %s"), cursor));
119
120       cursor = next_cursor;
121     }
122 }