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