Pārlūkot izejas kodu

*** empty log message ***

François Pinard 30 gadi atpakaļ
vecāks
revīzija
1f738c1d1b
3 mainītis faili ar 543 papildinājumiem un 507 dzēšanām
  1. 541 505
      src/gnu.c
  2. 1 1
      src/port.h
  3. 1 1
      src/tar.h

+ 541 - 505
src/gnu.c

@@ -1,5 +1,5 @@
 /* GNU dump extensions to tar.
 /* 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.
 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;
 extern int errno;
 #endif
 #endif
 #include <time.h>
 #include <time.h>
-time_t time();
+time_t time ();
 
 
 #include "tar.h"
 #include "tar.h"
 #include "port.h"
 #include "port.h"
 
 
-#if defined(_POSIX_VERSION) || defined(DIRENT)
-#include <dirent.h>
-#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 <sys/dir.h>
-#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 <ndir.h>
-#define DP_NAMELEN(x) strlen((x)->d_name)
-#endif /* USG and not _POSIX_VERSION and not DIRENT */
-
 #ifndef S_ISLNK
 #ifndef S_ISLNK
 #define lstat stat
 #define lstat stat
 #endif
 #endif
@@ -59,452 +37,498 @@ time_t time();
 extern time_t new_time;
 extern time_t new_time;
 extern FILE *msg_file;
 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 struct dirname *dir_list;
 static time_t this_time;
 static time_t this_time;
 
 
 void
 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
 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
 #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
 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 *
 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
 /* Collect all the names from argv[] (or whatever), then expand them into
    a directory tree, and put all the directories at the beginning. */
    a directory tree, and put all the directories at the beginning. */
 void
 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
 #ifdef AIX
-		if (statx (n->name, &statbuf, STATSIZE, STX_HIDDEN|STX_LINK))
+      if (statx (n->name, &statbuf, STATSIZE, STX_HIDDEN | STX_LINK))
 #else
 #else
-		if(lstat(n->name,&statbuf)<0)
+      if (lstat (n->name, &statbuf) < 0)
 #endif /* AIX */
 #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
 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
 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 *
 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
 #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
 #else
-			if (0 != f_follow_links? stat(namebuf, &hs): lstat(namebuf, &hs))
+	  if (0 != f_follow_links ? stat (namebuf, &hs) : lstat (namebuf, &hs))
 #endif
 #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
 #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 */
 #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
 /* 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. . . */
    files is a directory, recurse on the subdirectory. . . */
 static void
 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. */
 /* Returns non-zero if p is . or ..   This could be a macro for speed. */
 int
 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
 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
 			   In any case, we don't have to delete any files out
 			   of it */
 			   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
 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;
 }
 }
-

+ 1 - 1
src/port.h

@@ -25,7 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <alloca.h>
 #include <alloca.h>
 #else /* not HAVE_ALLOCA_H */
 #else /* not HAVE_ALLOCA_H */
 #ifdef _AIX
 #ifdef _AIX
-#pragma alloca
+ #pragma alloca
 #else /* not _AIX */
 #else /* not _AIX */
 char *alloca ();
 char *alloca ();
 #endif /* not _AIX */
 #endif /* not _AIX */

+ 1 - 1
src/tar.h

@@ -275,7 +275,7 @@ void userec();
 union record *endofrecs();
 union record *endofrecs();
 void anno();
 void anno();
 
 
-#if !defined (VPRINTF_MISSING) && defined (__STDC__)
+#if defined (HAVE_VPRINTF) && __STDC__
 void msg(char *, ...);
 void msg(char *, ...);
 void msg_perror(char *, ...);
 void msg_perror(char *, ...);
 #else
 #else