From: François Pinard Date: Wed, 16 Nov 1994 02:49:36 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=commitdiff_plain;h=1f738c1d1b74b948dd37e34309371e086c1eba08 *** empty log message *** --- diff --git a/src/gnu.c b/src/gnu.c index ca865d0..ef51f2b 100644 --- a/src/gnu.c +++ b/src/gnu.c @@ -1,5 +1,5 @@ /* GNU dump extensions to tar. - Copyright (C) 1988, 1992 Free Software Foundation + Copyright (C) 1988, 1992, 1993 Free Software Foundation This file is part of GNU Tar. @@ -25,33 +25,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ extern int errno; #endif #include -time_t time(); +time_t time (); #include "tar.h" #include "port.h" -#if defined(_POSIX_VERSION) || defined(DIRENT) -#include -#ifdef direct -#undef direct -#endif /* direct */ -#define direct dirent -#define DP_NAMELEN(x) strlen((x)->d_name) -#endif /* _POSIX_VERSION or DIRENT */ -#if !defined(_POSIX_VERSION) && !defined(DIRENT) && defined(BSD42) -#include -#define DP_NAMELEN(x) (x)->d_namlen -#endif /* not _POSIX_VERSION and BSD42 */ -#ifdef __MSDOS__ -#include "msd_dir.h" -#define DP_NAMELEN(x) (x)->d_namlen -#define direct dirent -#endif -#if defined(USG) && !defined(_POSIX_VERSION) && !defined(DIRENT) -#include -#define DP_NAMELEN(x) strlen((x)->d_name) -#endif /* USG and not _POSIX_VERSION and not DIRENT */ - #ifndef S_ISLNK #define lstat stat #endif @@ -59,452 +37,498 @@ time_t time(); extern time_t new_time; extern FILE *msg_file; -void addname(); -int check_exclude(); -extern PTR ck_malloc(); -extern PTR ck_realloc(); -int confirm(); -extern PTR init_buffer(); -extern char *get_buffer(); -int is_dot_or_dotdot(); -extern void add_buffer(); -extern void flush_buffer(); -void name_gather(); -int recursively_delete(); -void skip_file(); -char *un_quote_string(); - -extern char *new_name(); - -static void add_dir_name(); - -struct dirname { - struct dirname *next; - char *name; - char *dir_text; - int dev; - int ino; - int allnew; -}; +void addname (); +int check_exclude (); +extern PTR ck_malloc (); +extern PTR ck_realloc (); +int confirm (); +extern PTR init_buffer (); +extern char *get_buffer (); +int is_dot_or_dotdot (); +extern void add_buffer (); +extern void flush_buffer (); +void name_gather (); +int recursively_delete (); +void skip_file (); +char *un_quote_string (); + +extern char *new_name (); + +static void add_dir_name (); + +struct dirname + { + struct dirname *next; + char *name; + char *dir_text; + int dev; + int ino; + int allnew; + }; static struct dirname *dir_list; static time_t this_time; void -add_dir(name,dev,ino,text) -char *name; -char *text; -dev_t dev; -ino_t ino; +add_dir (name, dev, ino, text) + char *name; + char *text; + dev_t dev; + ino_t ino; { - struct dirname *dp; - - dp=(struct dirname *)malloc(sizeof(struct dirname)); - if(!dp) - abort(); - dp->next=dir_list; - dir_list=dp; - dp->dev=dev; - dp->ino=ino; - dp->name=malloc(strlen(name)+1); - strcpy(dp->name,name); - dp->dir_text=text; - dp->allnew=0; + struct dirname *dp; + + dp = (struct dirname *) ck_malloc (sizeof (struct dirname)); + if (!dp) + abort (); + dp->next = dir_list; + dir_list = dp; + dp->dev = dev; + dp->ino = ino; + dp->name = ck_malloc (strlen (name) + 1); + strcpy (dp->name, name); + dp->dir_text = text; + dp->allnew = 0; } void -read_dir_file() +read_dir_file () { - int dev; - int ino; - char *strp; - FILE *fp; - char buf[512]; - static char *path = 0; - - if (path == 0) - path = ck_malloc(PATH_MAX); - time(&this_time); - if(gnu_dumpfile[0]!='/') { -#if defined(__MSDOS__) || defined(USG) || defined(_POSIX_VERSION) - if(!getcwd(path,PATH_MAX)) - msg("Couldn't get current directory."); - exit(EX_SYSTEM); + int dev; + int ino; + char *strp; + FILE *fp; + char buf[512]; + static char *path = 0; + + if (path == 0) + path = ck_malloc (PATH_MAX); + time (&this_time); + if (gnu_dumpfile[0] != '/') + { +#if defined(__MSDOS__) || defined(HAVE_GETCWD) || defined(_POSIX_VERSION) + if (!getcwd (path, PATH_MAX)) + { + msg ("Couldn't get current directory."); + exit (EX_SYSTEM); + } #else - char *getwd(); + char *getwd (); - if(!getwd(path)) { - msg("Couldn't get current directory: %s",path); - exit(EX_SYSTEM); - } -#endif - /* If this doesn't fit, we're in serious trouble */ - strcat(path,"/"); - strcat(path,gnu_dumpfile); - gnu_dumpfile=path; - } - fp=fopen(gnu_dumpfile,"r"); - if(fp==0 && errno!=ENOENT) { - msg_perror("Can't open %s",gnu_dumpfile); - return; + if (!getwd (path)) + { + msg ("Couldn't get current directory: %s", path); + exit (EX_SYSTEM); } - if(!fp) - return; - fgets(buf,sizeof(buf),fp); - if(!f_new_files) { - f_new_files++; - new_time=atol(buf); - } - while(fgets(buf,sizeof(buf),fp)) { - strp= &buf[strlen(buf)]; - if(strp[-1]=='\n') - strp[-1]='\0'; - strp=buf; - dev=atol(strp); - while(isdigit(*strp)) - strp++; - ino=atol(strp); - while(isspace(*strp)) - strp++; - while(isdigit(*strp)) - strp++; - strp++; - add_dir(un_quote_string(strp),dev,ino,(char *)0); - } - fclose(fp); +#endif + /* If this doesn't fit, we're in serious trouble */ + strcat (path, "/"); + strcat (path, gnu_dumpfile); + gnu_dumpfile = path; + } + fp = fopen (gnu_dumpfile, "r"); + if (fp == 0 && errno != ENOENT) + { + msg_perror ("Can't open %s", gnu_dumpfile); + return; + } + if (!fp) + return; + fgets (buf, sizeof (buf), fp); + if (!f_new_files) + { + f_new_files++; + new_time = atol (buf); + } + while (fgets (buf, sizeof (buf), fp)) + { + strp = &buf[strlen (buf)]; + if (strp[-1] == '\n') + strp[-1] = '\0'; + strp = buf; + dev = atol (strp); + while (isdigit (*strp)) + strp++; + ino = atol (strp); + while (isspace (*strp)) + strp++; + while (isdigit (*strp)) + strp++; + strp++; + add_dir (un_quote_string (strp), dev, ino, (char *) 0); + } + fclose (fp); } void -write_dir_file() +write_dir_file () { - FILE *fp; - struct dirname *dp; - char *str; - extern char *quote_copy_string(); - - fp=fopen(gnu_dumpfile,"w"); - if(fp==0) { - msg_perror("Can't write to %s",gnu_dumpfile); - return; - } - fprintf(fp,"%lu\n",this_time); - for(dp=dir_list;dp;dp=dp->next) { - if(!dp->dir_text) - continue; - str=quote_copy_string(dp->name); - if(str) { - fprintf(fp,"%u %u %s\n",dp->dev,dp->ino,str); - free(str); - } else - fprintf(fp,"%u %u %s\n",dp->dev,dp->ino,dp->name); + FILE *fp; + struct dirname *dp; + char *str; + extern char *quote_copy_string (); + + fp = fopen (gnu_dumpfile, "w"); + if (fp == 0) + { + msg_perror ("Can't write to %s", gnu_dumpfile); + return; + } + fprintf (fp, "%lu\n", this_time); + for (dp = dir_list; dp; dp = dp->next) + { + if (!dp->dir_text) + continue; + str = quote_copy_string (dp->name); + if (str) + { + fprintf (fp, "%u %u %s\n", dp->dev, dp->ino, str); + free (str); } - fclose(fp); + else + fprintf (fp, "%u %u %s\n", dp->dev, dp->ino, dp->name); + } + fclose (fp); } struct dirname * -get_dir(name) -char *name; +get_dir (name) + char *name; { - struct dirname *dp; - - for(dp=dir_list;dp;dp=dp->next) { - if(!strcmp(dp->name,name)) - return dp; - } - return 0; + struct dirname *dp; + + for (dp = dir_list; dp; dp = dp->next) + { + if (!strcmp (dp->name, name)) + return dp; + } + return 0; } /* Collect all the names from argv[] (or whatever), then expand them into a directory tree, and put all the directories at the beginning. */ void -collect_and_sort_names() +collect_and_sort_names () { - struct name *n,*n_next; - int num_names; - struct stat statbuf; - int name_cmp(); - char *merge_sort(); - - name_gather(); - - if(gnu_dumpfile) - read_dir_file(); - if(!namelist) addname("."); - for(n=namelist;n;n=n_next) { - n_next=n->next; - if(n->found || n->dir_contents) - continue; - if(n->regexp) /* FIXME just skip regexps for now */ - continue; - if(n->change_dir) - if(chdir(n->change_dir)<0) { - msg_perror("can't chdir to %s",n->change_dir); - continue; - } + struct name *n, *n_next; + int num_names; + struct stat statbuf; + int name_cmp (); + char *merge_sort (); + + name_gather (); + + if (gnu_dumpfile) + read_dir_file (); + if (!namelist) + addname ("."); + for (n = namelist; n; n = n_next) + { + n_next = n->next; + if (n->found || n->dir_contents) + continue; + if (n->regexp) /* FIXME just skip regexps for now */ + continue; + if (n->change_dir) + if (chdir (n->change_dir) < 0) + { + msg_perror ("can't chdir to %s", n->change_dir); + continue; + } #ifdef AIX - if (statx (n->name, &statbuf, STATSIZE, STX_HIDDEN|STX_LINK)) + if (statx (n->name, &statbuf, STATSIZE, STX_HIDDEN | STX_LINK)) #else - if(lstat(n->name,&statbuf)<0) + if (lstat (n->name, &statbuf) < 0) #endif /* AIX */ - { - msg_perror("can't stat %s",n->name); - continue; - } - if(S_ISDIR(statbuf.st_mode)) { - n->found++; - add_dir_name(n->name,statbuf.st_dev); - } + { + msg_perror ("can't stat %s", n->name); + continue; } - - num_names=0; - for(n=namelist;n;n=n->next) - num_names++; - namelist=(struct name *)merge_sort((PTR)namelist,num_names,(char *)(&(namelist->next))-(char *)namelist,name_cmp); - - for(n=namelist;n;n=n->next) { - n->found=0; + if (S_ISDIR (statbuf.st_mode)) + { + n->found++; + add_dir_name (n->name, statbuf.st_dev); } - if(gnu_dumpfile) - write_dir_file(gnu_dumpfile); + } + + num_names = 0; + for (n = namelist; n; n = n->next) + num_names++; + namelist = (struct name *) merge_sort ((PTR) namelist, num_names, (char *) (&(namelist->next)) - (char *) namelist, name_cmp); + + for (n = namelist; n; n = n->next) + { + n->found = 0; + } + if (gnu_dumpfile) + write_dir_file (); } int -name_cmp(n1,n2) -struct name *n1,*n2; +name_cmp (n1, n2) + struct name *n1, *n2; { - if(n1->found) { - if(n2->found) - return strcmp(n1->name,n2->name); - else - return -1; - } else if(n2->found) - return 1; - else - return strcmp(n1->name,n2->name); + if (n1->found) + { + if (n2->found) + return strcmp (n1->name, n2->name); + else + return -1; + } + else if (n2->found) + return 1; + else + return strcmp (n1->name, n2->name); } int -dirent_cmp(p1,p2) -const PTR p1; -const PTR p2; +dirent_cmp (p1, p2) + const PTR p1; + const PTR p2; { - char *frst,*scnd; + char *frst, *scnd; - frst= (*(char **)p1)+1; - scnd= (*(char **)p2)+1; + frst = (*(char **) p1) + 1; + scnd = (*(char **) p2) + 1; - return strcmp(frst,scnd); + return strcmp (frst, scnd); } char * -get_dir_contents(p,device) -char *p; -int device; +get_dir_contents (p, device) + char *p; + int device; { - DIR *dirp; - register struct direct *d; - char *new_buf; - char *namebuf; - int bufsiz; - int len; - PTR the_buffer; - char *buf; - size_t n_strs; -/* int n_size;*/ - char *p_buf; - char **vec,**p_vec; - - extern int errno; - - errno=0; - dirp=opendir(p); - bufsiz=strlen(p)+NAMSIZ; - namebuf=ck_malloc(bufsiz+2); - if(!dirp) { - if(errno) - msg_perror("can't open directory %s",p); - else - msg("error opening directory %s",p); - new_buf=NULL; - } else { - struct dirname *dp; - int all_children; - - dp=get_dir(p); - all_children= dp ? dp->allnew : 0; - (void) strcpy(namebuf,p); - if(p[strlen(p)-1]!='/') - (void) strcat(namebuf,"/"); - len=strlen(namebuf); - - the_buffer=init_buffer(); - while(d=readdir(dirp)) { - struct stat hs; - - /* Skip . and .. */ - if(is_dot_or_dotdot(d->d_name)) - continue; - if(DP_NAMELEN(d) + len >=bufsiz) { - bufsiz+=NAMSIZ; - namebuf=ck_realloc(namebuf,bufsiz+2); - } - (void) strcpy(namebuf+len,d->d_name); + DIR *dirp; + register struct dirent *d; + char *new_buf; + char *namebuf; + int bufsiz; + int len; + PTR the_buffer; + char *buf; + size_t n_strs; + /* int n_size;*/ + char *p_buf; + char **vec, **p_vec; + + extern int errno; + + errno = 0; + dirp = opendir (p); + bufsiz = strlen (p) + NAMSIZ; + namebuf = ck_malloc (bufsiz + 2); + if (!dirp) + { + if (errno) + msg_perror ("can't open directory %s", p); + else + msg ("error opening directory %s", p); + new_buf = NULL; + } + else + { + struct dirname *dp; + int all_children; + + dp = get_dir (p); + all_children = dp ? dp->allnew : 0; + (void) strcpy (namebuf, p); + if (p[strlen (p) - 1] != '/') + (void) strcat (namebuf, "/"); + len = strlen (namebuf); + + the_buffer = init_buffer (); + while (d = readdir (dirp)) + { + struct stat hs; + + /* Skip . and .. */ + if (is_dot_or_dotdot (d->d_name)) + continue; + if (NLENGTH (d) + len >= bufsiz) + { + bufsiz += NAMSIZ; + namebuf = ck_realloc (namebuf, bufsiz + 2); + } + (void) strcpy (namebuf + len, d->d_name); #ifdef AIX - if (0 != f_follow_links? - statx(namebuf, &hs, STATSIZE, STX_HIDDEN): - statx(namebuf, &hs, STATSIZE, STX_HIDDEN|STX_LINK)) + if (0 != f_follow_links ? + statx (namebuf, &hs, STATSIZE, STX_HIDDEN) : + statx (namebuf, &hs, STATSIZE, STX_HIDDEN | STX_LINK)) #else - if (0 != f_follow_links? stat(namebuf, &hs): lstat(namebuf, &hs)) + if (0 != f_follow_links ? stat (namebuf, &hs) : lstat (namebuf, &hs)) #endif - { - msg_perror("can't stat %s",namebuf); - continue; - } - if( (f_local_filesys && device!=hs.st_dev) - || (f_exclude && check_exclude(namebuf))) - add_buffer(the_buffer,"N",1); + { + msg_perror ("can't stat %s", namebuf); + continue; + } + if ((f_local_filesys && device != hs.st_dev) + || (f_exclude && check_exclude (namebuf))) + add_buffer (the_buffer, "N", 1); #ifdef AIX - else if (S_ISHIDDEN (hs.st_mode)) { - add_buffer (the_buffer, "D", 1); - strcat (d->d_name, "A"); - d->d_namlen++; - } + else if (S_ISHIDDEN (hs.st_mode)) + { + add_buffer (the_buffer, "D", 1); + strcat (d->d_name, "A"); + d->d_namlen++; + } #endif /* AIX */ - else if(S_ISDIR(hs.st_mode)) { - if(dp=get_dir(namebuf)) { - if( dp->dev!=hs.st_dev - || dp->ino!=hs.st_ino) { - if(f_verbose) - msg("directory %s has been renamed.",namebuf); - dp->allnew=1; - dp->dev=hs.st_dev; - dp->ino=hs.st_ino; - } - dp->dir_text=""; - } else { - if(f_verbose) - msg("Directory %s is new",namebuf); - add_dir(namebuf,hs.st_dev,hs.st_ino,""); - dp=get_dir(namebuf); - dp->allnew=1; - } - if(all_children) - dp->allnew=1; - - add_buffer(the_buffer,"D",1); - } else if( !all_children - && f_new_files - && new_time>hs.st_mtime - && ( f_new_files>1 - || new_time>hs.st_ctime)) - add_buffer(the_buffer,"N",1); - else - add_buffer(the_buffer,"Y",1); - add_buffer(the_buffer,d->d_name,(int)(DP_NAMELEN(d)+1)); + else if (S_ISDIR (hs.st_mode)) + { + if (dp = get_dir (namebuf)) + { + if (dp->dev != hs.st_dev + || dp->ino != hs.st_ino) + { + if (f_verbose) + msg ("directory %s has been renamed.", namebuf); + dp->allnew = 1; + dp->dev = hs.st_dev; + dp->ino = hs.st_ino; + } + dp->dir_text = ""; } - add_buffer(the_buffer,"\000\000",2); - closedir(dirp); - - /* Well, we've read in the contents of the dir, now sort them */ - buf=get_buffer(the_buffer); - if(buf[0]=='\0') { - flush_buffer(the_buffer); - new_buf=NULL; - } else { - n_strs=0; - for(p_buf=buf;*p_buf;) { - int tmp; - - tmp=strlen(p_buf)+1; - n_strs++; - p_buf+=tmp; - } - vec=(char **)malloc(sizeof(char *)*(n_strs+1)); - for(p_vec=vec,p_buf=buf;*p_buf;p_buf+=strlen(p_buf)+1) - *p_vec++= p_buf; - *p_vec= 0; - qsort((PTR)vec,n_strs,sizeof(char *),dirent_cmp); - new_buf=(char *)malloc(p_buf-buf+2); - for(p_vec=vec,p_buf=new_buf;*p_vec;p_vec++) { - char *p_tmp; - - for(p_tmp= *p_vec;*p_buf++= *p_tmp++;) - ; - } - *p_buf++='\0'; - free(vec); - flush_buffer(the_buffer); + else + { + if (f_verbose) + msg ("Directory %s is new", namebuf); + add_dir (namebuf, hs.st_dev, hs.st_ino, ""); + dp = get_dir (namebuf); + dp->allnew = 1; } + if (all_children) + dp->allnew = 1; + + add_buffer (the_buffer, "D", 1); + } + else if (!all_children + && f_new_files + && new_time > hs.st_mtime + && (f_new_files > 1 + || new_time > hs.st_ctime)) + add_buffer (the_buffer, "N", 1); + else + add_buffer (the_buffer, "Y", 1); + add_buffer (the_buffer, d->d_name, (int) (NLENGTH (d) + 1)); } - free(namebuf); - return new_buf; + add_buffer (the_buffer, "\000\000", 2); + closedir (dirp); + + /* Well, we've read in the contents of the dir, now sort them */ + buf = get_buffer (the_buffer); + if (buf[0] == '\0') + { + flush_buffer (the_buffer); + new_buf = NULL; + } + else + { + n_strs = 0; + for (p_buf = buf; *p_buf;) + { + int tmp; + + tmp = strlen (p_buf) + 1; + n_strs++; + p_buf += tmp; + } + vec = (char **) ck_malloc (sizeof (char *) * (n_strs + 1)); + for (p_vec = vec, p_buf = buf; *p_buf; p_buf += strlen (p_buf) + 1) + *p_vec++ = p_buf; + *p_vec = 0; + qsort ((PTR) vec, n_strs, sizeof (char *), dirent_cmp); + new_buf = (char *) ck_malloc (p_buf - buf + 2); + for (p_vec = vec, p_buf = new_buf; *p_vec; p_vec++) + { + char *p_tmp; + + for (p_tmp = *p_vec; *p_buf++ = *p_tmp++;) + ; + } + *p_buf++ = '\0'; + free (vec); + flush_buffer (the_buffer); + } + } + free (namebuf); + return new_buf; } /* p is a directory. Add all the files in P to the namelist. If any of the files is a directory, recurse on the subdirectory. . . */ static void -add_dir_name(p,device) -char *p; -int device; +add_dir_name (p, device) + char *p; + int device; { - char *new_buf; - char *p_buf; + char *new_buf; + char *p_buf; - char *namebuf; - int buflen; - register int len; - int sublen; + char *namebuf; + int buflen; + register int len; + int sublen; -/* PTR the_buffer;*/ + /* PTR the_buffer;*/ -/* char *buf;*/ -/* char **vec,**p_vec;*/ -/* int n_strs,n_size;*/ + /* char *buf;*/ + /* char **vec,**p_vec;*/ + /* int n_strs,n_size;*/ - struct name *n; + struct name *n; - int dirent_cmp(); + int dirent_cmp (); - new_buf=get_dir_contents(p,device); + new_buf = get_dir_contents (p, device); - for(n=namelist;n;n=n->next) { - if(!strcmp(n->name,p)) { - n->dir_contents = new_buf; - break; - } + for (n = namelist; n; n = n->next) + { + if (!strcmp (n->name, p)) + { + n->dir_contents = new_buf ? new_buf : "\0\0\0\0"; + break; } - - len=strlen(p); - buflen= NAMSIZ<=len ? len + NAMSIZ : NAMSIZ; - namebuf= ck_malloc(buflen+1); - - (void)strcpy(namebuf,p); - if(namebuf[len-1]!='/') { - namebuf[len++]='/'; - namebuf[len]='\0'; + } + + if (new_buf) + { + len = strlen (p); + buflen = NAMSIZ <= len ? len + NAMSIZ : NAMSIZ; + namebuf = ck_malloc (buflen + 1); + + (void) strcpy (namebuf, p); + if (namebuf[len - 1] != '/') + { + namebuf[len++] = '/'; + namebuf[len] = '\0'; } - for(p_buf=new_buf;*p_buf;p_buf+=sublen+1) { - sublen=strlen(p_buf); - if(*p_buf=='D') { - if(len+sublen>=buflen) { - buflen+=NAMSIZ; - namebuf= ck_realloc(namebuf,buflen+1); - } - (void)strcpy(namebuf+len,p_buf+1); - addname(namebuf); - add_dir_name(namebuf,device); + for (p_buf = new_buf; *p_buf; p_buf += sublen + 1) + { + sublen = strlen (p_buf); + if (*p_buf == 'D') + { + if (len + sublen >= buflen) + { + buflen += NAMSIZ; + namebuf = ck_realloc (namebuf, buflen + 1); } + (void) strcpy (namebuf + len, p_buf + 1); + addname (namebuf); + add_dir_name (namebuf, device); + } } - free(namebuf); + free (namebuf); + } } /* Returns non-zero if p is . or .. This could be a macro for speed. */ int -is_dot_or_dotdot(p) -char *p; +is_dot_or_dotdot (p) + char *p; { - return (p[0]=='.' && (p[1]=='\0' || (p[1]=='.' && p[2]=='\0'))); + return (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0'))); } @@ -513,129 +537,141 @@ char *p; void -gnu_restore(skipcrud) -int skipcrud; +gnu_restore (skipcrud) + int skipcrud; { - char *current_dir; -/* int current_dir_length; */ - - char *archive_dir; -/* int archive_dir_length; */ - PTR the_buffer; - char *p; - DIR *dirp; - struct direct *d; - char *cur,*arc; - extern struct stat hstat; /* Stat struct corresponding */ - long size,copied; - char *from,*to; - extern union record *head; - - dirp=opendir(skipcrud+head->header.name); - - if(!dirp) { - /* The directory doesn't exist now. It'll be created. + char *current_dir; + /* int current_dir_length; */ + + char *archive_dir; + /* int archive_dir_length; */ + PTR the_buffer; + char *p; + DIR *dirp; + struct dirent *d; + char *cur, *arc; + extern struct stat hstat; /* Stat struct corresponding */ + long size, copied; + char *from, *to; + extern union record *head; + + dirp = opendir (skipcrud + current_file_name); + + if (!dirp) + { + /* The directory doesn't exist now. It'll be created. In any case, we don't have to delete any files out of it */ - skip_file((long)hstat.st_size); - return; + skip_file ((long) hstat.st_size); + return; + } + + the_buffer = init_buffer (); + while (d = readdir (dirp)) + { + if (is_dot_or_dotdot (d->d_name)) + continue; + + add_buffer (the_buffer, d->d_name, (int) (NLENGTH (d) + 1)); + } + closedir (dirp); + add_buffer (the_buffer, "", 1); + + current_dir = get_buffer (the_buffer); + archive_dir = (char *) ck_malloc (hstat.st_size); + if (archive_dir == 0) + { + msg ("Can't allocate %d bytes for restore", hstat.st_size); + skip_file ((long) hstat.st_size); + return; + } + to = archive_dir; + for (size = hstat.st_size; size > 0; size -= copied) + { + from = findrec ()->charptr; + if (!from) + { + msg ("Unexpected EOF in archive\n"); + break; } - - the_buffer=init_buffer(); - while(d=readdir(dirp)) { - if(is_dot_or_dotdot(d->d_name)) - continue; - - add_buffer(the_buffer,d->d_name,(int)(DP_NAMELEN(d)+1)); + copied = endofrecs ()->charptr - from; + if (copied > size) + copied = size; + bcopy ((PTR) from, (PTR) to, (int) copied); + to += copied; + userec ((union record *) (from + copied - 1)); + } + + for (cur = current_dir; *cur; cur += strlen (cur) + 1) + { + for (arc = archive_dir; *arc; arc += strlen (arc) + 1) + { + arc++; + if (!strcmp (arc, cur)) + break; } - closedir(dirp); - add_buffer(the_buffer,"",1); - - current_dir=get_buffer(the_buffer); - archive_dir=(char *)malloc(hstat.st_size); - if(archive_dir==0) { - msg("Can't allocate %d bytes for restore",hstat.st_size); - skip_file((long)hstat.st_size); - return; + if (*arc == '\0') + { + p = new_name (skipcrud + current_file_name, cur); + if (f_confirm && !confirm ("delete", p)) + { + free (p); + continue; + } + if (f_verbose) + fprintf (msg_file, "%s: deleting %s\n", tar, p); + if (recursively_delete (p)) + { + msg ("%s: Error while deleting %s\n", tar, p); + } + free (p); } - to=archive_dir; - for(size=hstat.st_size;size>0;size-=copied) { - from=findrec()->charptr; - if(!from) { - msg("Unexpected EOF in archive\n"); - break; - } - copied=endofrecs()->charptr - from; - if(copied>size) - copied=size; - bcopy((PTR)from,(PTR)to,(int)copied); - to+=copied; - userec((union record *)(from+copied-1)); - } - - for(cur=current_dir;*cur;cur+=strlen(cur)+1) { - for(arc=archive_dir;*arc;arc+=strlen(arc)+1) { - arc++; - if(!strcmp(arc,cur)) - break; - } - if(*arc=='\0') { - p=new_name(skipcrud+head->header.name,cur); - if(f_confirm && !confirm("delete",p)) { - free(p); - continue; - } - if(f_verbose) - fprintf(msg_file,"%s: deleting %s\n",tar,p); - if(recursively_delete(p)) { - msg("%s: Error while deleting %s\n",tar,p); - } - free(p); - } - } - flush_buffer(the_buffer); - free(archive_dir); + } + flush_buffer (the_buffer); + free (archive_dir); } int -recursively_delete(path) -char *path; +recursively_delete (path) + char *path; { - struct stat sbuf; - DIR *dirp; - struct direct *dp; - char *path_buf; - /* int path_len; */ - - - if(lstat(path,&sbuf)<0) - return 1; - if(S_ISDIR(sbuf.st_mode)) { - - /* path_len=strlen(path); */ - dirp=opendir(path); - if(dirp==0) - return 1; - while(dp=readdir(dirp)) { - if(is_dot_or_dotdot(dp->d_name)) - continue; - path_buf=new_name(path,dp->d_name); - if(recursively_delete(path_buf)) { - free(path_buf); - closedir(dirp); - return 1; - } - free(path_buf); - } - closedir(dirp); - - if(rmdir(path)<0) - return 1; - return 0; + struct stat sbuf; + DIR *dirp; + struct dirent *dp; + char *path_buf; + /* int path_len; */ + + + if (lstat (path, &sbuf) < 0) + return 1; + if (S_ISDIR (sbuf.st_mode)) + { + + /* path_len=strlen(path); */ + dirp = opendir (path); + if (dirp == 0) + return 1; + while (dp = readdir (dirp)) + { + if (is_dot_or_dotdot (dp->d_name)) + continue; + path_buf = new_name (path, dp->d_name); + if (recursively_delete (path_buf)) + { + free (path_buf); + closedir (dirp); + return 1; + } + free (path_buf); } - if(unlink(path)<0) - return 1; - return 0; + closedir (dirp); + + if (rmdir (path) < 0) + return 1; + return 0; + } + if (unlink (path) < 0) + return 1; + return 0; } - diff --git a/src/port.h b/src/port.h index b57ba0f..4e1e0c4 100644 --- a/src/port.h +++ b/src/port.h @@ -25,7 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #else /* not HAVE_ALLOCA_H */ #ifdef _AIX -#pragma alloca + #pragma alloca #else /* not _AIX */ char *alloca (); #endif /* not _AIX */ diff --git a/src/tar.h b/src/tar.h index e3530c3..c6d79c4 100644 --- a/src/tar.h +++ b/src/tar.h @@ -275,7 +275,7 @@ void userec(); union record *endofrecs(); void anno(); -#if !defined (VPRINTF_MISSING) && defined (__STDC__) +#if defined (HAVE_VPRINTF) && __STDC__ void msg(char *, ...); void msg_perror(char *, ...); #else