X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fmangle.c;h=fe37f6466c00643ca472726a579d191bd5024f51;hb=409bddf38c61520400e74332b02cc1cc9f8379ce;hp=55a8973426ca82f01d0c09ffabaab6c1bdadc2b3;hpb=38d3d0399047f688ae0872a6054a4ad9e9dcdeaf;p=chaz%2Ftar diff --git a/src/mangle.c b/src/mangle.c index 55a8973..fe37f64 100644 --- a/src/mangle.c +++ b/src/mangle.c @@ -1,251 +1,121 @@ -/* mangle.c -- encode long filenames - Copyright (C) 1988, 1992 Free Software Foundation - -This file is part of GNU Tar. - -GNU Tar is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Tar is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Tar; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include -#include -time_t time(); - -#include "tar.h" -#include "port.h" - -void add_buffer(); -extern PTR ck_malloc(); -void finish_header(); -extern PTR init_buffer(); -extern char *quote_copy_string(); -extern char *get_buffer(); -char *un_quote_string(); - -extern union record *start_header(); - -extern struct stat hstat; /* Stat struct corresponding */ - -struct mangled { - struct mangled *next; - int type; - char mangled[NAMSIZ]; - char *linked_to; - char normal[1]; -}; - - -/* Should use a hash table, etc. . */ -struct mangled *first_mangle; -int mangled_num = 0; - -#if 0 /* Deleted because there is now a better way to do all this */ - -char * -find_mangled (name) -char *name; -{ - struct mangled *munge; - - for(munge=first_mangle;munge;munge=munge->next) - if(!strcmp(name,munge->normal)) - return munge->mangled; - return 0; -} - - -#ifdef S_ISLNK +/* Encode long filenames for GNU tar. + Copyright 1988, 92, 94, 96, 97, 99, 2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include +#include "common.h" +#include + +struct mangled + { + struct mangled *next; + int type; + char mangled[NAME_FIELD_SIZE]; + char *linked_to; + char normal[1]; + }; + +/* Extract a GNUTYPE_NAMES record contents. It seems that such are + not produced anymore by GNU tar, but we leave the reading code + around nevertheless, for salvaging old tapes. */ void -add_symlink_mangle(symlink, linkto, buffer) -char *symlink; -char *linkto; -char *buffer; +extract_mangle (void) { - struct mangled *munge,*kludge; - - munge=(struct mangled *)ck_malloc(sizeof(struct mangled)+strlen(symlink)+strlen(linkto)+2); - if(!first_mangle) - first_mangle=munge; - else { - for(kludge=first_mangle;kludge->next;kludge=kludge->next) - ; - kludge->next=munge; - } - munge->type=1; - munge->next=0; - strcpy(munge->normal,symlink); - munge->linked_to=munge->normal+strlen(symlink)+1; - strcpy(munge->linked_to,linkto); - sprintf(munge->mangled,"@@MaNgLeD.%d",mangled_num++); - strncpy(buffer,munge->mangled,NAMSIZ); -} -#endif + off_t size = current_stat_info.stat.st_size; + char *buffer = xmalloc ((size_t) (size + 1)); + char *copy = buffer; + char *cursor = buffer; -void -add_mangle (name, buffer) -char *name; -char *buffer; -{ - struct mangled *munge,*kludge; + if (size != (size_t) size || size == (size_t) -1) + xalloc_die (); - munge=(struct mangled *)ck_malloc(sizeof(struct mangled)+strlen(name)); - if(!first_mangle) - first_mangle=munge; - else { - for(kludge=first_mangle;kludge->next;kludge=kludge->next) - ; - kludge->next=munge; - } - munge->next=0; - munge->type=0; - strcpy(munge->normal,name); - sprintf(munge->mangled,"@@MaNgLeD.%d",mangled_num++); - strncpy(buffer,munge->mangled,NAMSIZ); -} + buffer[size] = '\0'; -void -write_mangled() -{ - struct mangled *munge; - struct stat hstat; - union record *header; - char *ptr1,*ptr2; - PTR the_buffer; - int size; - int bufsize; + while (size > 0) + { + union block *block = find_next_block (); + size_t available; - if(!first_mangle) - return; - the_buffer=init_buffer(); - for(munge=first_mangle,size=0;munge;munge=munge->next) { - ptr1=quote_copy_string(munge->normal); - if(!ptr1) - ptr1=munge->normal; - if(munge->type) { - add_buffer(the_buffer,"Symlink ",8); - add_buffer(the_buffer,ptr1,strlen(ptr1)); - add_buffer(the_buffer," to ",4); - - if(ptr2=quote_copy_string(munge->linked_to)) { - add_buffer(the_buffer,ptr2,strlen(ptr2)); - free(ptr2); - } else - add_buffer(the_buffer,munge->linked_to,strlen(munge->linked_to)); - } else { - add_buffer(the_buffer,"Rename ",7); - add_buffer(the_buffer,munge->mangled,strlen(munge->mangled)); - add_buffer(the_buffer," to ",4); - add_buffer(the_buffer,ptr1,strlen(ptr1)); - } - add_buffer(the_buffer,"\n",1); - if(ptr1!=munge->normal) - free(ptr1); + if (!block) + { + ERROR ((0, 0, _("Unexpected EOF in mangled names"))); + return; } - - bzero(&hstat,sizeof(struct stat)); - hstat.st_atime=hstat.st_mtime=hstat.st_ctime=time(0); - ptr1=get_buffer(the_buffer); - hstat.st_size=strlen(ptr1); - - header=start_header("././@MaNgLeD_NaMeS",&hstat); - header->header.linkflag=LF_NAMES; - finish_header(header); - size=hstat.st_size; - header=findrec(); - bufsize = endofrecs()->charptr - header->charptr; - - while(bufsizecharptr,bufsize); - ptr1+=bufsize; - size-=bufsize; - userec(header+(bufsize-1)/RECORDSIZE); - header=findrec(); - bufsize = endofrecs()->charptr - header->charptr; + available = available_space_after (block); + if (available > size) + available = size; + memcpy (copy, block->buffer, available); + copy += available; + size -= available; + set_next_block_after ((union block *) (block->buffer + available - 1)); + } + + while (*cursor) + { + char *next_cursor; + char *name; + char *name_end; + + next_cursor = strchr (cursor, '\n'); + *next_cursor++ = '\0'; + + if (!strncmp (cursor, "Rename ", 7)) + { + + name = cursor + 7; + name_end = strchr (name, ' '); + while (strncmp (name_end, " to ", 4)) + { + name_end++; + name_end = strchr (name_end, ' '); + } + *name_end = '\0'; + if (next_cursor[-2] == '/') + next_cursor[-2] = '\0'; + unquote_string (name_end + 4); + if (rename (name, name_end + 4)) + ERROR ((0, errno, _("%s: Cannot rename to %s"), + quotearg_colon (name), quote_n (1, name_end + 4))); + else if (verbose_option) + WARN ((0, 0, _("Renamed %s to %s"), name, name_end + 4)); } - bcopy(ptr1,header->charptr,size); - bzero(header->charptr+size,bufsize-size); - userec(header+(size-1)/RECORDSIZE); -} - -#endif - -void -extract_mangle(head) -union record *head; -{ - char *buf; - char *fromtape; - char *to; - char *ptr,*ptrend; - char *nam1,*nam1end; - int size; - int copied; - - size=hstat.st_size; - buf=to=ck_malloc(size+1); - buf[size]='\0'; - while(size>0) { - fromtape=findrec()->charptr; - if(fromtape==0) { - msg("Unexpected EOF in mangled names!"); - return; - } - copied=endofrecs()->charptr-fromtape; - if(copied>size) - copied=size; - bcopy(fromtape,to,copied); - to+=copied; - size-=copied; - userec((union record *)(fromtape+copied-1)); +#ifdef HAVE_SYMLINK + else if (!strncmp (cursor, "Symlink ", 8)) + { + name = cursor + 8; + name_end = strchr (name, ' '); + while (strncmp (name_end, " to ", 4)) + { + name_end++; + name_end = strchr (name_end, ' '); + } + *name_end = '\0'; + unquote_string (name); + unquote_string (name_end + 4); + if (symlink (name, name_end + 4) + && (unlink (name_end + 4) || symlink (name, name_end + 4))) + ERROR ((0, errno, _("%s: Cannot symlink to %s"), + quotearg_colon (name), quote_n (1, name_end + 4))); + else if (verbose_option) + WARN ((0, 0, _("Symlinked %s to %s"), name, name_end + 4)); } - for(ptr=buf;*ptr;ptr=ptrend) { - ptrend=index(ptr,'\n'); - *ptrend++='\0'; - - if(!strncmp(ptr,"Rename ",7)) { - nam1=ptr+7; - nam1end=index(nam1,' '); - while(strncmp(nam1end," to ",4)) { - nam1end++; - nam1end=index(nam1end,' '); - } - *nam1end='\0'; - if(ptrend[-2]=='/') - ptrend[-2]='\0'; - un_quote_string(nam1end+4); - if(rename(nam1,nam1end+4)) - msg_perror("Can't rename %s to %s",nam1,nam1end+4); - else if(f_verbose) - msg("Renamed %s to %s",nam1,nam1end+4); - } -#ifdef S_ISLNK - else if(!strncmp(ptr,"Symlink ",8)) { - nam1=ptr+8; - nam1end=index(nam1,' '); - while(strncmp(nam1end," to ",4)) { - nam1end++; - nam1end=index(nam1end,' '); - } - un_quote_string(nam1); - un_quote_string(nam1end+4); - if(symlink(nam1,nam1end+4) && (unlink(nam1end+4) || symlink(nam1,nam1end+4))) - msg_perror("Can't symlink %s to %s",nam1,nam1end+4); - else if(f_verbose) - msg("Symlinkd %s to %s",nam1,nam1end+4); - } #endif - else - msg("Unknown demangling command %s",ptr); - } + else + ERROR ((0, 0, _("Unknown demangling command %s"), cursor)); + + cursor = next_cursor; + } }