]> Dogcows Code - chaz/tar/blob - src/mangle.c
*** empty log message ***
[chaz/tar] / src / mangle.c
1 /* mangle.c -- encode long filenames
2 Copyright (C) 1988, 1992 Free Software Foundation
3
4 This file is part of GNU Tar.
5
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <time.h>
23 time_t time ();
24
25 #include "tar.h"
26 #include "port.h"
27
28 void add_buffer ();
29 extern PTR ck_malloc ();
30 void finish_header ();
31 extern PTR init_buffer ();
32 extern char *quote_copy_string ();
33 extern char *get_buffer ();
34 char *un_quote_string ();
35
36 extern union record *start_header ();
37
38 extern struct stat hstat; /* Stat struct corresponding */
39
40 struct mangled
41 {
42 struct mangled *next;
43 int type;
44 char mangled[NAMSIZ];
45 char *linked_to;
46 char normal[1];
47 };
48
49
50 /* Should use a hash table, etc. . */
51 struct mangled *first_mangle;
52 int mangled_num = 0;
53
54 #if 0 /* Deleted because there is now a better way to do all this */
55
56 char *
57 find_mangled (name)
58 char *name;
59 {
60 struct mangled *munge;
61
62 for (munge = first_mangle; munge; munge = munge->next)
63 if (!strcmp (name, munge->normal))
64 return munge->mangled;
65 return 0;
66 }
67
68
69 #ifdef S_ISLNK
70 void
71 add_symlink_mangle (symlink, linkto, buffer)
72 char *symlink;
73 char *linkto;
74 char *buffer;
75 {
76 struct mangled *munge, *kludge;
77
78 munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (symlink) + strlen (linkto) + 2);
79 if (!first_mangle)
80 first_mangle = munge;
81 else
82 {
83 for (kludge = first_mangle; kludge->next; kludge = kludge->next)
84 ;
85 kludge->next = munge;
86 }
87 munge->type = 1;
88 munge->next = 0;
89 strcpy (munge->normal, symlink);
90 munge->linked_to = munge->normal + strlen (symlink) + 1;
91 strcpy (munge->linked_to, linkto);
92 sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
93 strncpy (buffer, munge->mangled, NAMSIZ);
94 }
95
96 #endif
97
98 void
99 add_mangle (name, buffer)
100 char *name;
101 char *buffer;
102 {
103 struct mangled *munge, *kludge;
104
105 munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (name));
106 if (!first_mangle)
107 first_mangle = munge;
108 else
109 {
110 for (kludge = first_mangle; kludge->next; kludge = kludge->next)
111 ;
112 kludge->next = munge;
113 }
114 munge->next = 0;
115 munge->type = 0;
116 strcpy (munge->normal, name);
117 sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
118 strncpy (buffer, munge->mangled, NAMSIZ);
119 }
120
121 void
122 write_mangled ()
123 {
124 struct mangled *munge;
125 struct stat hstat;
126 union record *header;
127 char *ptr1, *ptr2;
128 PTR the_buffer;
129 int size;
130 int bufsize;
131
132 if (!first_mangle)
133 return;
134 the_buffer = init_buffer ();
135 for (munge = first_mangle, size = 0; munge; munge = munge->next)
136 {
137 ptr1 = quote_copy_string (munge->normal);
138 if (!ptr1)
139 ptr1 = munge->normal;
140 if (munge->type)
141 {
142 add_buffer (the_buffer, "Symlink ", 8);
143 add_buffer (the_buffer, ptr1, strlen (ptr1));
144 add_buffer (the_buffer, " to ", 4);
145
146 if (ptr2 = quote_copy_string (munge->linked_to))
147 {
148 add_buffer (the_buffer, ptr2, strlen (ptr2));
149 free (ptr2);
150 }
151 else
152 add_buffer (the_buffer, munge->linked_to, strlen (munge->linked_to));
153 }
154 else
155 {
156 add_buffer (the_buffer, "Rename ", 7);
157 add_buffer (the_buffer, munge->mangled, strlen (munge->mangled));
158 add_buffer (the_buffer, " to ", 4);
159 add_buffer (the_buffer, ptr1, strlen (ptr1));
160 }
161 add_buffer (the_buffer, "\n", 1);
162 if (ptr1 != munge->normal)
163 free (ptr1);
164 }
165
166 bzero (&hstat, sizeof (struct stat));
167 hstat.st_atime = hstat.st_mtime = hstat.st_ctime = time (0);
168 ptr1 = get_buffer (the_buffer);
169 hstat.st_size = strlen (ptr1);
170
171 header = start_header ("././@MaNgLeD_NaMeS", &hstat);
172 header->header.linkflag = LF_NAMES;
173 finish_header (header);
174 size = hstat.st_size;
175 header = findrec ();
176 bufsize = endofrecs ()->charptr - header->charptr;
177
178 while (bufsize < size)
179 {
180 bcopy (ptr1, header->charptr, bufsize);
181 ptr1 += bufsize;
182 size -= bufsize;
183 userec (header + (bufsize - 1) / RECORDSIZE);
184 header = findrec ();
185 bufsize = endofrecs ()->charptr - header->charptr;
186 }
187 bcopy (ptr1, header->charptr, size);
188 bzero (header->charptr + size, bufsize - size);
189 userec (header + (size - 1) / RECORDSIZE);
190 }
191
192 #endif
193
194 void
195 extract_mangle (head)
196 union record *head;
197 {
198 char *buf;
199 char *fromtape;
200 char *to;
201 char *ptr, *ptrend;
202 char *nam1, *nam1end;
203 int size;
204 int copied;
205
206 size = hstat.st_size;
207 buf = to = ck_malloc (size + 1);
208 buf[size] = '\0';
209 while (size > 0)
210 {
211 fromtape = findrec ()->charptr;
212 if (fromtape == 0)
213 {
214 msg ("Unexpected EOF in mangled names!");
215 return;
216 }
217 copied = endofrecs ()->charptr - fromtape;
218 if (copied > size)
219 copied = size;
220 bcopy (fromtape, to, copied);
221 to += copied;
222 size -= copied;
223 userec ((union record *) (fromtape + copied - 1));
224 }
225 for (ptr = buf; *ptr; ptr = ptrend)
226 {
227 ptrend = index (ptr, '\n');
228 *ptrend++ = '\0';
229
230 if (!strncmp (ptr, "Rename ", 7))
231 {
232 nam1 = ptr + 7;
233 nam1end = index (nam1, ' ');
234 while (strncmp (nam1end, " to ", 4))
235 {
236 nam1end++;
237 nam1end = index (nam1end, ' ');
238 }
239 *nam1end = '\0';
240 if (ptrend[-2] == '/')
241 ptrend[-2] = '\0';
242 un_quote_string (nam1end + 4);
243 if (rename (nam1, nam1end + 4))
244 msg_perror ("Can't rename %s to %s", nam1, nam1end + 4);
245 else if (f_verbose)
246 msg ("Renamed %s to %s", nam1, nam1end + 4);
247 }
248 #ifdef S_ISLNK
249 else if (!strncmp (ptr, "Symlink ", 8))
250 {
251 nam1 = ptr + 8;
252 nam1end = index (nam1, ' ');
253 while (strncmp (nam1end, " to ", 4))
254 {
255 nam1end++;
256 nam1end = index (nam1end, ' ');
257 }
258 *nam1end = '\0';
259 un_quote_string (nam1);
260 un_quote_string (nam1end + 4);
261 if (symlink (nam1, nam1end + 4) && (unlink (nam1end + 4) || symlink (nam1, nam1end + 4)))
262 msg_perror ("Can't symlink %s to %s", nam1, nam1end + 4);
263 else if (f_verbose)
264 msg ("Symlinkd %s to %s", nam1, nam1end + 4);
265 }
266 #endif
267 else
268 msg ("Unknown demangling command %s", ptr);
269 }
270 }
This page took 0.046464 seconds and 5 git commands to generate.