X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=cea58c1f7b32ddd7c1004451687d89b6f4b2555d;hb=083205ad13a86ee50983f1faf3fbefd3efe99453;hp=5d09f35ed15baf22695f86d9013265e48b511052;hpb=40836b8e8901b1ccb9396bc66dc9e5f91cec8cca;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index 5d09f35..cea58c1 100644 --- a/src/create.c +++ b/src/create.c @@ -49,6 +49,16 @@ extern int errno; #include #endif +#if defined (_POSIX_VERSION) +#include +#else +struct utimbuf +{ + long actime; + long modtime; +}; +#endif + #if defined(_POSIX_VERSION) || defined(DIRENT) #include #ifdef direct @@ -91,8 +101,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 +123,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 +184,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 +216,7 @@ dump_file (p, curdev, toplevel) char save_linkflag; extern time_t new_time; int critical_error = 0; + struct utimbuf restore_times; /* int sparse_ind = 0;*/ @@ -239,6 +243,9 @@ badfile: errors++; return; } + + restore_times.actime = hstat.st_atime; + restore_times.modtime = hstat.st_mtime; #ifdef S_ISHIDDEN if (S_ISHIDDEN (hstat.st_mode)) { @@ -302,13 +309,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 +318,23 @@ badfile: } link_name++; } - strncpy(header->header.linkname, + if (link_name - lp->name >= NAMSIZ) + write_long (link_name, LF_LONGLINK); + current_link_name = link_name; + + hstat.st_size = 0; + header = start_header(p, &hstat); + if (header == NULL) + { + critical_error = 1; + goto badfile; + } + strncpy(header->header.arch_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.arch_linkname [NAMSIZ-1] = 0; + header->header.linkflag = LF_LINK; finish_header(header); /* FIXME: Maybe remove from list after all links found? */ @@ -577,6 +584,8 @@ badfile: if (unlink (p) == -1) msg_perror ("cannot remove %s", p); } + if (f_atime_preserve) + utime (p, &restore_times); return; /* @@ -595,13 +604,24 @@ 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); + current_link_name = buf; hstat.st_size = 0; /* Force 0 size on symlink */ header = start_header(p, &hstat); @@ -610,19 +630,8 @@ 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'; + strncpy (header->header.arch_linkname, buf, NAMSIZ); + header->header.arch_linkname[NAMSIZ - 1] = '\0'; header->header.linkflag = LF_SYMLINK; finish_header(header); /* Nothing more to do to it */ if (f_remove_files) @@ -727,6 +736,8 @@ badfile: } if(f_multivol) save_name = 0; + if (f_atime_preserve) + utime (p, &restore_times); return; } @@ -739,7 +750,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 +795,8 @@ badfile: closedir(dirp); free(namebuf); + if (f_atime_preserve) + utime (p, &restore_times); return; } @@ -1172,6 +1185,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 */ @@ -1193,14 +1209,9 @@ start_header(name, st) msg("Removing leading / from absolute path names in the archive."); } } - 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); - } + current_file_name = name; + strncpy(header->header.arch_name, name, NAMSIZ); + header->header.arch_name[NAMSIZ-1] = '\0'; to_oct((long) (st->st_mode & 07777), 8, header->header.mode); @@ -1335,3 +1346,39 @@ write_eot() userec(p); } } + +/* Write a LF_LONGLINK or LF_LONGNAME record. */ +write_long (p, type) + char *p; + char type; +{ + int size = strlen (p) + 1; + int bufsize; + union record *header; + struct stat foo; + + + bzero (&foo, sizeof foo); + foo.st_size = size; + + header = start_header ("././@LongLink", &foo); + 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); +}