]> 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 struct mangled *next;
42 int type;
43 char mangled[NAMSIZ];
44 char *linked_to;
45 char normal[1];
46 };
47
48
49 /* Should use a hash table, etc. . */
50 struct mangled *first_mangle;
51 int mangled_num = 0;
52
53 #if 0 /* Deleted because there is now a better way to do all this */
54
55 char *
56 find_mangled (name)
57 char *name;
58 {
59 struct mangled *munge;
60
61 for(munge=first_mangle;munge;munge=munge->next)
62 if(!strcmp(name,munge->normal))
63 return munge->mangled;
64 return 0;
65 }
66
67
68 #ifdef S_ISLNK
69 void
70 add_symlink_mangle(symlink, linkto, buffer)
71 char *symlink;
72 char *linkto;
73 char *buffer;
74 {
75 struct mangled *munge,*kludge;
76
77 munge=(struct mangled *)ck_malloc(sizeof(struct mangled)+strlen(symlink)+strlen(linkto)+2);
78 if(!first_mangle)
79 first_mangle=munge;
80 else {
81 for(kludge=first_mangle;kludge->next;kludge=kludge->next)
82 ;
83 kludge->next=munge;
84 }
85 munge->type=1;
86 munge->next=0;
87 strcpy(munge->normal,symlink);
88 munge->linked_to=munge->normal+strlen(symlink)+1;
89 strcpy(munge->linked_to,linkto);
90 sprintf(munge->mangled,"@@MaNgLeD.%d",mangled_num++);
91 strncpy(buffer,munge->mangled,NAMSIZ);
92 }
93 #endif
94
95 void
96 add_mangle (name, buffer)
97 char *name;
98 char *buffer;
99 {
100 struct mangled *munge,*kludge;
101
102 munge=(struct mangled *)ck_malloc(sizeof(struct mangled)+strlen(name));
103 if(!first_mangle)
104 first_mangle=munge;
105 else {
106 for(kludge=first_mangle;kludge->next;kludge=kludge->next)
107 ;
108 kludge->next=munge;
109 }
110 munge->next=0;
111 munge->type=0;
112 strcpy(munge->normal,name);
113 sprintf(munge->mangled,"@@MaNgLeD.%d",mangled_num++);
114 strncpy(buffer,munge->mangled,NAMSIZ);
115 }
116
117 void
118 write_mangled()
119 {
120 struct mangled *munge;
121 struct stat hstat;
122 union record *header;
123 char *ptr1,*ptr2;
124 PTR the_buffer;
125 int size;
126 int bufsize;
127
128 if(!first_mangle)
129 return;
130 the_buffer=init_buffer();
131 for(munge=first_mangle,size=0;munge;munge=munge->next) {
132 ptr1=quote_copy_string(munge->normal);
133 if(!ptr1)
134 ptr1=munge->normal;
135 if(munge->type) {
136 add_buffer(the_buffer,"Symlink ",8);
137 add_buffer(the_buffer,ptr1,strlen(ptr1));
138 add_buffer(the_buffer," to ",4);
139
140 if(ptr2=quote_copy_string(munge->linked_to)) {
141 add_buffer(the_buffer,ptr2,strlen(ptr2));
142 free(ptr2);
143 } else
144 add_buffer(the_buffer,munge->linked_to,strlen(munge->linked_to));
145 } else {
146 add_buffer(the_buffer,"Rename ",7);
147 add_buffer(the_buffer,munge->mangled,strlen(munge->mangled));
148 add_buffer(the_buffer," to ",4);
149 add_buffer(the_buffer,ptr1,strlen(ptr1));
150 }
151 add_buffer(the_buffer,"\n",1);
152 if(ptr1!=munge->normal)
153 free(ptr1);
154 }
155
156 bzero(&hstat,sizeof(struct stat));
157 hstat.st_atime=hstat.st_mtime=hstat.st_ctime=time(0);
158 ptr1=get_buffer(the_buffer);
159 hstat.st_size=strlen(ptr1);
160
161 header=start_header("././@MaNgLeD_NaMeS",&hstat);
162 header->header.linkflag=LF_NAMES;
163 finish_header(header);
164 size=hstat.st_size;
165 header=findrec();
166 bufsize = endofrecs()->charptr - header->charptr;
167
168 while(bufsize<size) {
169 bcopy(ptr1,header->charptr,bufsize);
170 ptr1+=bufsize;
171 size-=bufsize;
172 userec(header+(bufsize-1)/RECORDSIZE);
173 header=findrec();
174 bufsize = endofrecs()->charptr - header->charptr;
175 }
176 bcopy(ptr1,header->charptr,size);
177 bzero(header->charptr+size,bufsize-size);
178 userec(header+(size-1)/RECORDSIZE);
179 }
180
181 #endif
182
183 void
184 extract_mangle(head)
185 union record *head;
186 {
187 char *buf;
188 char *fromtape;
189 char *to;
190 char *ptr,*ptrend;
191 char *nam1,*nam1end;
192 int size;
193 int copied;
194
195 size=hstat.st_size;
196 buf=to=ck_malloc(size+1);
197 buf[size]='\0';
198 while(size>0) {
199 fromtape=findrec()->charptr;
200 if(fromtape==0) {
201 msg("Unexpected EOF in mangled names!");
202 return;
203 }
204 copied=endofrecs()->charptr-fromtape;
205 if(copied>size)
206 copied=size;
207 bcopy(fromtape,to,copied);
208 to+=copied;
209 size-=copied;
210 userec((union record *)(fromtape+copied-1));
211 }
212 for(ptr=buf;*ptr;ptr=ptrend) {
213 ptrend=index(ptr,'\n');
214 *ptrend++='\0';
215
216 if(!strncmp(ptr,"Rename ",7)) {
217 nam1=ptr+7;
218 nam1end=index(nam1,' ');
219 while(strncmp(nam1end," to ",4)) {
220 nam1end++;
221 nam1end=index(nam1end,' ');
222 }
223 *nam1end='\0';
224 if(ptrend[-2]=='/')
225 ptrend[-2]='\0';
226 un_quote_string(nam1end+4);
227 if(rename(nam1,nam1end+4))
228 msg_perror("Can't rename %s to %s",nam1,nam1end+4);
229 else if(f_verbose)
230 msg("Renamed %s to %s",nam1,nam1end+4);
231 }
232 #ifdef S_ISLNK
233 else if(!strncmp(ptr,"Symlink ",8)) {
234 nam1=ptr+8;
235 nam1end=index(nam1,' ');
236 while(strncmp(nam1end," to ",4)) {
237 nam1end++;
238 nam1end=index(nam1end,' ');
239 }
240 un_quote_string(nam1);
241 un_quote_string(nam1end+4);
242 if(symlink(nam1,nam1end+4) && (unlink(nam1end+4) || symlink(nam1,nam1end+4)))
243 msg_perror("Can't symlink %s to %s",nam1,nam1end+4);
244 else if(f_verbose)
245 msg("Symlinkd %s to %s",nam1,nam1end+4);
246 }
247 #endif
248 else
249 msg("Unknown demangling command %s",ptr);
250 }
251 }
This page took 0.044133 seconds and 5 git commands to generate.