From: François Pinard Date: Wed, 16 Nov 1994 03:04:54 +0000 (+0000) Subject: Initial revision X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=62ece1146850487dd39f22c557fc05ce297c072e;p=chaz%2Ftar Initial revision --- diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..579a4db --- /dev/null +++ b/NEWS @@ -0,0 +1,85 @@ +Current Version: 1.11. + +User-visible changes since 1.10: + +o Many bug fixes + +o Now uses GNU standard configure, generated by Autoconf. + +o Long options now use `--'; use of `+' is deprecated and support for it + will eventually be removed. + +o New option --null causes filenames read by -T to be null-terminated, + and causes -C to be ignored. + +o New option --remove-files deletes files (but not directories) after + they are added to the archive. + +o New option --ignore-failed-read prevents read-errors from affecting + the exit status. + +o New option --checkpoint prints occasional messages as the tape is + being read or written. + +o New option --show-omitted-dirs prints the names of directories + omitted from the archive. + +o Some tape drives which use a non-standard method of indicating + end-of-tape now work correctly with multi-tape archives. + +o --volno-file: Read the volume number used in prompting the user (but + not in recording volume ID's on the archive) from a file. + +o When using --multi-volume, you can now give multiple -f arguments; + the various tape drives will get used in sequence and then wrap + around to the beginning. + +o Remote archive names no longer have to be in /dev: any file with a + `:' is interpreted as remote. If new option --force-local is given, + then even archive files with a `:' are considered local. + +o New option --atime-preserve restores (if possible) atimes to their + original values after dumping the file. + +o No longer does tar confusingly dump "." when you don't tell it what + to dump. + +o When extracting directories, tar now correctly restores their + modification and access times. + +o Longnames support is redone differently--long name info directly + precedes the long-named file or link in the archive, so you no + longer have to wait for the extract to hit the end of the tape for + long names to work. + +================== + +User-visible changes since 1.09: + +Filename to -G is optional. -C works right. +Names +newer and +newer-mtime work right. + +-g is now +incremental +-G is now +listed-incremental + +Sparse files now work correctly. + ++volume is now called +label. + ++exclude now takes a filename argument, and +exclude-from does what ++exclude used to do. + +Exit status is now correct. + ++totals keeps track of total I/O and prints it when tar exits. + +When using +label with +extract, the label is now a regexp. + +New option +tape-length (-L) does multi-volume handling like BSD dump: +you tell tar how big the tape is and it will prompt at that point +instead of waiting for a write error. + +New backup scripts level-0 and level-1 which might be useful to +people. They use a file "backup-specs" for information, and shouldn't +need local modification. These are what we use to do all our backups +at the FSF. diff --git a/src/mangle.c b/src/mangle.c new file mode 100644 index 0000000..5b1b937 --- /dev/null +++ b/src/mangle.c @@ -0,0 +1,247 @@ +/* mangle.c -- encode long filenames + Copyright (C) 1988 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; + +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 +void +add_symlink_mangle(symlink, linkto, buffer) +char *symlink; +char *linkto; +char *buffer; +{ + 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 + +void +add_mangle (name, buffer) +char *name; +char *buffer; +{ + struct mangled *munge,*kludge; + + 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); +} + +void +write_mangled() +{ + struct mangled *munge; + struct stat hstat; + union record *header; + char *ptr1,*ptr2; + PTR the_buffer; + int size; + int bufsize; + + 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); + } + + 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; + } + bcopy(ptr1,header->charptr,size); + bzero(header->charptr+size,bufsize-size); + userec(header+(size-1)/RECORDSIZE); +} + +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)); + } + 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); + } +}