summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/tar/gnu.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/tar/gnu.c')
-rw-r--r--gnu/usr.bin/tar/gnu.c677
1 files changed, 0 insertions, 677 deletions
diff --git a/gnu/usr.bin/tar/gnu.c b/gnu/usr.bin/tar/gnu.c
deleted file mode 100644
index b51618e..0000000
--- a/gnu/usr.bin/tar/gnu.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/* GNU dump extensions to tar.
- Copyright (C) 1988, 1992, 1993 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 <stdio.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <errno.h>
-#ifndef STDC_HEADERS
-extern int errno;
-#endif
-#include <time.h>
-time_t time ();
-
-#include "tar.h"
-#include "port.h"
-
-#ifndef S_ISLNK
-#define lstat stat
-#endif
-
-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;
- };
-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;
-{
- 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 ()
-{
- 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 ();
-
- 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 (!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 ((unsigned char) *strp))
- strp++;
- ino = atol (strp);
- while (isspace ((unsigned char) *strp))
- strp++;
- while (isdigit ((unsigned char) *strp))
- strp++;
- strp++;
- add_dir (un_quote_string (strp), dev, ino, (char *) 0);
- }
- fclose (fp);
-}
-
-void
-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", (unsigned long) 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);
- }
- fclose (fp);
-}
-
-struct dirname *
-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;
-}
-
-
-/* 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 ()
-{
- 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))
-#else
- 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);
- }
- }
-
- 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;
-{
- 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;
-{
- char *frst, *scnd;
-
- frst = (*(char **) p1) + 1;
- scnd = (*(char **) p2) + 1;
-
- return strcmp (frst, scnd);
-}
-
-char *
-get_dir_contents (p, device)
- char *p;
- int device;
-{
- 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))
-#else
- 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);
-#ifdef AIX
- 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) (NLENGTH (d) + 1));
- }
- 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;
-{
- char *new_buf;
- char *p_buf;
-
- char *namebuf;
- int buflen;
- register int len;
- int sublen;
-
- /* PTR the_buffer;*/
-
- /* char *buf;*/
- /* char **vec,**p_vec;*/
- /* int n_strs,n_size;*/
-
- struct name *n;
-
- int dirent_cmp ();
-
- new_buf = get_dir_contents (p, device);
-
- for (n = namelist; n; n = n->next)
- {
- if (!strcmp (n->name, p))
- {
- n->dir_contents = new_buf ? new_buf : "\0\0\0\0";
- break;
- }
- }
-
- 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);
- }
- }
- free (namebuf);
- }
-}
-
-/* Returns non-zero if p is . or .. This could be a macro for speed. */
-int
-is_dot_or_dotdot (p)
- char *p;
-{
- return (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')));
-}
-
-
-
-
-
-
-void
-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 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;
- }
-
- 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;
- }
- 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 + 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);
- }
-
- }
- flush_buffer (the_buffer);
- free (archive_dir);
-}
-
-int
-recursively_delete (path)
- char *path;
-{
- 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);
- }
- closedir (dirp);
-
- if (rmdir (path) < 0)
- return 1;
- return 0;
- }
- if (unlink (path) < 0)
- return 1;
- return 0;
-}
OpenPOWER on IntegriCloud