aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.bin/tar/mangle.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/tar/mangle.c')
-rw-r--r--gnu/usr.bin/tar/mangle.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/gnu/usr.bin/tar/mangle.c b/gnu/usr.bin/tar/mangle.c
new file mode 100644
index 000000000000..628168473a1b
--- /dev/null
+++ b/gnu/usr.bin/tar/mangle.c
@@ -0,0 +1,270 @@
+/* mangle.c -- encode long filenames
+ Copyright (C) 1988, 1992 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 <time.h>
+time_t time ();
+
+#include "tar.h"
+#include "port.h"
+
+void add_buffer ();
+extern PTR ck_malloc ();
+void finish_header ();
+extern PTR init_buffer ();
+extern char *quote_copy_string ();
+extern char *get_buffer ();
+char *un_quote_string ();
+
+extern union record *start_header ();
+
+extern struct stat hstat; /* Stat struct corresponding */
+
+struct mangled
+ {
+ struct mangled *next;
+ int type;
+ char mangled[NAMSIZ];
+ char *linked_to;
+ char normal[1];
+ };
+
+
+/* Should use a hash table, etc. . */
+struct mangled *first_mangle;
+int mangled_num = 0;
+
+#if 0 /* Deleted because there is now a better way to do all this */
+
+char *
+find_mangled (name)
+ char *name;
+{
+ struct mangled *munge;
+
+ for (munge = first_mangle; munge; munge = munge->next)
+ if (!strcmp (name, munge->normal))
+ return munge->mangled;
+ return 0;
+}
+
+
+#ifdef S_ISLNK
+void
+add_symlink_mangle (symlink, linkto, buffer)
+ char *symlink;
+ char *linkto;
+ char *buffer;
+{
+ struct mangled *munge, *kludge;
+
+ munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (symlink) + strlen (linkto) + 2);
+ if (!first_mangle)
+ first_mangle = munge;
+ else
+ {
+ for (kludge = first_mangle; kludge->next; kludge = kludge->next)
+ ;
+ kludge->next = munge;
+ }
+ munge->type = 1;
+ munge->next = 0;
+ strcpy (munge->normal, symlink);
+ munge->linked_to = munge->normal + strlen (symlink) + 1;
+ strcpy (munge->linked_to, linkto);
+ sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
+ strncpy (buffer, munge->mangled, NAMSIZ);
+}
+
+#endif
+
+void
+add_mangle (name, buffer)
+ char *name;
+ char *buffer;
+{
+ struct mangled *munge, *kludge;
+
+ munge = (struct mangled *) ck_malloc (sizeof (struct mangled) + strlen (name));
+ if (!first_mangle)
+ first_mangle = munge;
+ else
+ {
+ for (kludge = first_mangle; kludge->next; kludge = kludge->next)
+ ;
+ kludge->next = munge;
+ }
+ munge->next = 0;
+ munge->type = 0;
+ strcpy (munge->normal, name);
+ sprintf (munge->mangled, "@@MaNgLeD.%d", mangled_num++);
+ strncpy (buffer, munge->mangled, NAMSIZ);
+}
+
+void
+write_mangled ()
+{
+ struct mangled *munge;
+ struct stat hstat;
+ union record *header;
+ char *ptr1, *ptr2;
+ PTR the_buffer;
+ int size;
+ int bufsize;
+
+ if (!first_mangle)
+ return;
+ the_buffer = init_buffer ();
+ for (munge = first_mangle, size = 0; munge; munge = munge->next)
+ {
+ ptr1 = quote_copy_string (munge->normal);
+ if (!ptr1)
+ ptr1 = munge->normal;
+ if (munge->type)
+ {
+ add_buffer (the_buffer, "Symlink ", 8);
+ add_buffer (the_buffer, ptr1, strlen (ptr1));
+ add_buffer (the_buffer, " to ", 4);
+
+ if (ptr2 = quote_copy_string (munge->linked_to))
+ {
+ add_buffer (the_buffer, ptr2, strlen (ptr2));
+ free (ptr2);
+ }
+ else
+ add_buffer (the_buffer, munge->linked_to, strlen (munge->linked_to));
+ }
+ else
+ {
+ add_buffer (the_buffer, "Rename ", 7);
+ add_buffer (the_buffer, munge->mangled, strlen (munge->mangled));
+ add_buffer (the_buffer, " to ", 4);
+ add_buffer (the_buffer, ptr1, strlen (ptr1));
+ }
+ add_buffer (the_buffer, "\n", 1);
+ if (ptr1 != munge->normal)
+ free (ptr1);
+ }
+
+ bzero (&hstat, sizeof (struct stat));
+ hstat.st_atime = hstat.st_mtime = hstat.st_ctime = time (0);
+ ptr1 = get_buffer (the_buffer);
+ hstat.st_size = strlen (ptr1);
+
+ header = start_header ("././@MaNgLeD_NaMeS", &hstat);
+ header->header.linkflag = LF_NAMES;
+ finish_header (header);
+ size = hstat.st_size;
+ header = findrec ();
+ bufsize = endofrecs ()->charptr - header->charptr;
+
+ while (bufsize < size)
+ {
+ bcopy (ptr1, header->charptr, bufsize);
+ ptr1 += bufsize;
+ size -= bufsize;
+ userec (header + (bufsize - 1) / RECORDSIZE);
+ header = findrec ();
+ bufsize = endofrecs ()->charptr - header->charptr;
+ }
+ bcopy (ptr1, header->charptr, size);
+ bzero (header->charptr + size, bufsize - size);
+ userec (header + (size - 1) / RECORDSIZE);
+}
+
+#endif
+
+void
+extract_mangle (head)
+ union record *head;
+{
+ char *buf;
+ char *fromtape;
+ char *to;
+ char *ptr, *ptrend;
+ char *nam1, *nam1end;
+ int size;
+ int copied;
+
+ size = hstat.st_size;
+ buf = to = ck_malloc (size + 1);
+ buf[size] = '\0';
+ while (size > 0)
+ {
+ fromtape = findrec ()->charptr;
+ if (fromtape == 0)
+ {
+ msg ("Unexpected EOF in mangled names!");
+ return;
+ }
+ copied = endofrecs ()->charptr - fromtape;
+ if (copied > size)
+ copied = size;
+ bcopy (fromtape, to, copied);
+ to += copied;
+ size -= copied;
+ userec ((union record *) (fromtape + copied - 1));
+ }
+ for (ptr = buf; *ptr; ptr = ptrend)
+ {
+ ptrend = index (ptr, '\n');
+ *ptrend++ = '\0';
+
+ if (!strncmp (ptr, "Rename ", 7))
+ {
+ nam1 = ptr + 7;
+ nam1end = index (nam1, ' ');
+ while (strncmp (nam1end, " to ", 4))
+ {
+ nam1end++;
+ nam1end = index (nam1end, ' ');
+ }
+ *nam1end = '\0';
+ if (ptrend[-2] == '/')
+ ptrend[-2] = '\0';
+ un_quote_string (nam1end + 4);
+ if (rename (nam1, nam1end + 4))
+ msg_perror ("Can't rename %s to %s", nam1, nam1end + 4);
+ else if (f_verbose)
+ msg ("Renamed %s to %s", nam1, nam1end + 4);
+ }
+#ifdef S_ISLNK
+ else if (!strncmp (ptr, "Symlink ", 8))
+ {
+ nam1 = ptr + 8;
+ nam1end = index (nam1, ' ');
+ while (strncmp (nam1end, " to ", 4))
+ {
+ nam1end++;
+ nam1end = index (nam1end, ' ');
+ }
+ *nam1end = '\0';
+ un_quote_string (nam1);
+ un_quote_string (nam1end + 4);
+ if (symlink (nam1, nam1end + 4) && (unlink (nam1end + 4) || symlink (nam1, nam1end + 4)))
+ msg_perror ("Can't symlink %s to %s", nam1, nam1end + 4);
+ else if (f_verbose)
+ msg ("Symlinkd %s to %s", nam1, nam1end + 4);
+ }
+#endif
+ else
+ msg ("Unknown demangling command %s", ptr);
+ }
+}