X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=1b25750ca56b8908ac8d1b2aa878f1974a0a598f;hb=ff700d610ced2d037a04522b765b8b4020cbe167;hp=5d09f35ed15baf22695f86d9013265e48b511052;hpb=5789002e76b09d3b3286473e59cd66d7a6697984;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index 5d09f35..1b25750 100644 --- a/src/create.c +++ b/src/create.c @@ -91,8 +91,6 @@ extern struct name *gnu_list_name; extern void print_header(); union record *start_header(); -void add_mangle(); -void add_symlink_mangle(); void blank_name_list(); int check_exclude(); PTR ck_malloc(); @@ -115,7 +113,6 @@ void to_oct(); void dump_file(); void write_dir_file(); void write_eot(); -void write_mangled(); int zero_record(); /* This code moved from tar.h since create.c is the only file that cares @@ -177,15 +174,11 @@ create_archive() free(buf); } else { p = name_next(1); - if(!p) - dump_file(".", -1, 1); - else { - do dump_file(p, -1, 1); - while (p = name_next(1)); - } + do + dump_file(p, -1, 1); + while (p = name_next(1)); } - write_mangled(); write_eot(); close_archive(); if(f_gnudump) @@ -213,6 +206,7 @@ dump_file (p, curdev, toplevel) char save_linkflag; extern time_t new_time; int critical_error = 0; + time_t restore_times[2]; /* int sparse_ind = 0;*/ @@ -239,6 +233,9 @@ badfile: errors++; return; } + + restore_times[0] = hstat.st_atime; + restore_times[1] = hstat.st_utime; #ifdef S_ISHIDDEN if (S_ISHIDDEN (hstat.st_mode)) { @@ -302,13 +299,6 @@ badfile: char *link_name = lp->name; /* We found a link. */ - hstat.st_size = 0; - header = start_header(p, &hstat); - if (header == NULL) - { - critical_error = 1; - goto badfile; - } while(!f_absolute_paths && *link_name == '/') { static int link_warn = 0; @@ -318,16 +308,22 @@ badfile: } link_name++; } + if (link_name - lp->name >= NAMSIZ) + write_long (link_name, LF_LONGLINK); + + hstat.st_size = 0; + header = start_header(p, &hstat); + if (header == NULL) + { + critical_error = 1; + goto badfile; + } strncpy(header->header.linkname, link_name,NAMSIZ); - if(header->header.linkname[NAMSIZ-1]) { - char *mangled; - extern char *find_mangled(); - mangled=find_mangled(link_name); - msg("%s: link name too long: mangled to %s",link_name,mangled); - strncpy(header->header.linkname,mangled,NAMSIZ); - } + /* Force null truncated */ + header->header.linkname [NAMSIZ-1] = 0; + header->header.linkflag = LF_LINK; finish_header(header); /* FIXME: Maybe remove from list after all links found? */ @@ -577,6 +573,8 @@ badfile: if (unlink (p) == -1) msg_perror ("cannot remove %s", p); } + if (f_atime_preserve) + utime (p, restore_times); return; /* @@ -595,14 +593,27 @@ badfile: save_name=0; if(f>=0) (void)close(f); - return; + if (f_atime_preserve) + utime (p, restore_times); + return; } #ifdef S_ISLNK else if(S_ISLNK(hstat.st_mode)) { int size; - + char *buf = alloca (PATH_MAX + 1); + + size = readlink (p, buf, PATH_MAX + 1); + if (size < 0) + goto badperror; + buf[size] = '\0'; + if (size >= NAMSIZ) + write_long (buf, LF_LONGLINK); + + buf[NAMSIZ - 1] = '\0'; + if (size >= NAMSIZ) + size = NAMSIZ - 1; hstat.st_size = 0; /* Force 0 size on symlink */ header = start_header(p, &hstat); if (header == NULL) @@ -610,19 +621,7 @@ badfile: critical_error = 1; goto badfile; } - size = readlink(p, header->header.linkname, NAMSIZ); - if (size < 0) goto badperror; - if (size == NAMSIZ) { - char *buf = ck_malloc(PATH_MAX); - - readlink(p,buf,PATH_MAX); - /* next_mangle(header->header.linkname); */ - add_symlink_mangle(buf,p,header->header.linkname); - msg("symbolic link %s too long: mangling to %s",p, header->header.linkname); - /* size=strlen(header->header.linkname); */ - free(buf); - } else - header->header.linkname[size] = '\0'; + strcpy (header->header.linkname, buf); header->header.linkflag = LF_SYMLINK; finish_header(header); /* Nothing more to do to it */ if (f_remove_files) @@ -727,6 +726,8 @@ badfile: } if(f_multivol) save_name = 0; + if (f_atime_preserve) + utime (p, restore_times); return; } @@ -739,7 +740,7 @@ badfile: * See if we are crossing from one file system to another, * and avoid doing so if the user only wants to dump one file system. */ - if (f_local_filesys && toplevel && curdev != hstat.st_dev) { + if (f_local_filesys && !toplevel && curdev != hstat.st_dev) { if(f_verbose) msg("%s: is on a different filesystem; not dumped",p); return; @@ -784,6 +785,8 @@ badfile: closedir(dirp); free(namebuf); + if (f_atime_preserve) + utime (p, restore_times); return; } @@ -1172,6 +1175,9 @@ start_header(name, st) { register union record *header; + if (strlen (name) >= NAMSIZ) + write_long (name, LF_LONGNAME); + header = (union record *) findrec(); bzero(header->charptr, sizeof(*header)); /* XXX speed up */ @@ -1194,13 +1200,7 @@ start_header(name, st) } } strncpy(header->header.name, name, NAMSIZ); - if (header->header.name[NAMSIZ-1]) { -/* char *mangled;*/ - - /* next_mangle(header->header.name); */ - add_mangle(name,header->header.name); - msg("%s: is too long: mangling to %s", name, header->header.name); - } + header->header.name[NAMSIZE-1] = '\0'; to_oct((long) (st->st_mode & 07777), 8, header->header.mode); @@ -1335,3 +1335,38 @@ write_eot() userec(p); } } + +/* Write a LF_LONGLINK or LF_LONGNAME record. */ +void +write_long (p, type) + char *p; + char type; +{ + int size = strlen (p) + 1; + int bufsize; + union record *header; + + /* Link name won't fit, so we write + an LF_LONGLINK record. */ + hstat.st_size = size; + header = start_header ("././@LongLink", &hstat); + header->header.linkflag = type; + finish_header (header); + + header = findrec (); + + bufsize = endofrecs ()->charptr - header->charptr; + + while (bufsize < size) + { + bcopy (p, header->charptr, bufsize); + p += bufsize; + size -= bufsize; + userec (header + (bufsize - 1)/RECORDSIZE); + header = findrec (); + bufsize = endofrecs ()->charptr - header->charptr; + } + bcopy (p, header->charptr, size); + bzero (header->charptr + size, bufsize - size); + userec (header + (size - 1)/RECORDSIZE); +}