annotate netinstall/tar.cc @ 4900:0eccfd4850d6

Add tests for the regexp-ranges-treat-control-1-chars badly bug. 2010-01-30 Aidan Kehoe <kehoea@parhasard.net> * automated/regexp-tests.el: Make sure that control-1 characters are no longer treated as second-class citizens in regexp ranges, as in http://mid.gmane.org/18829.34118.709782.704574@parhasard.net .
author Aidan Kehoe <kehoea@parhasard.net>
date Sat, 30 Jan 2010 19:23:43 +0000
parents 3d3049ae1304
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
1 /*
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
2 * Copyright (c) 2000, Red Hat, Inc.
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
3 *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
6 * the Free Software Foundation; either version 2 of the License, or
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
7 * (at your option) any later version.
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
8 *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
9 * A copy of the GNU General Public License can be found at
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
10 * http://www.gnu.org/
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
11 *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
12 * Written by DJ Delorie <dj@cygnus.com>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
13 *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
14 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
15
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
16 /* Built-in tar functionality. See tar.h for usage. */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
17
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
18 #include <stdio.h>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
19 #include <stdlib.h>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
20 #include <sys/types.h>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
21 #include <sys/stat.h>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
22
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
23 #include "win32.h"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
24 #include <zlib.h>
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
25 #include "tar.h"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
26 #include "mkdir.h"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
27 #include "log.h"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
28
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
29 #include "port.h"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
30
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
31 #if defined(CYGWIN) || defined(MINGW)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
32 #define FACTOR (0x19db1ded53ea710LL)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
33 #define NSPERSEC 10000000LL
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
34 #else
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
35 __int64 FACTOR=0x19db1ded53ea710L;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
36 __int64 NSPERSEC=10000000L;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
37 #endif
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
38 #define SYMLINK_COOKIE "!<symlink>"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
39
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
40 typedef struct {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
41 char name[100]; /* 0 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
42 char mode[8]; /* 100 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
43 char uid[8]; /* 108 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
44 char gid[8]; /* 116 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
45 char size[12]; /* 124 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
46 char mtime[12]; /* 136 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
47 char chksum[8]; /* 148 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
48 char typeflag; /* 156 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
49 char linkname[100]; /* 157 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
50 char magic[6]; /* 257 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
51 char version[2]; /* 263 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
52 char uname[32]; /* 265 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
53 char gname[32]; /* 297 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
54 char devmajor[8]; /* 329 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
55 char devminor[8]; /* 337 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
56 char prefix[155]; /* 345 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
57 char junk[12]; /* 500 */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
58 } tar_header_type;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
59
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
60 typedef struct tar_map_result_type_s {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
61 struct tar_map_result_type_s *next;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
62 char *stored_name;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
63 char *mapped_name;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
64 } tar_map_result_type;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
65
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
66 static tar_map_result_type *tar_map_result = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
67
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
68 static int err;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
69
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
70 static char file_name[_MAX_PATH+512];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
71 static char have_longname = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
72 static int file_length;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
73
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
74 static tar_header_type tar_header;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
75 static char buf[512];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
76
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
77 static int _tar_file_size = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
78 int _tar_verbose = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
79 FILE * _tar_vfile = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
80 #define vp if (_tar_verbose) fprintf
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
81 #define vp2 if (_tar_verbose>1) fprintf
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
82
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
83 static gzFile g = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
84
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
85 static char *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
86 xstrdup (char *c)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
87 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
88 char *r = (char *) malloc (strlen (c) + 1);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
89 if (!r)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
90 exit_setup (1);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
91 strcpy (r, c);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
92 return r;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
93 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
94
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
95 int
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
96 tar_open (char *pathname)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
97 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
98 struct stat s;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
99 if (_tar_vfile == 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
100 _tar_vfile = stderr;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
101
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
102 vp2 (_tar_vfile, "tar: open `%s'\n", pathname);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
103 if (stat (pathname, &s) < 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
104 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
105 _tar_file_size = s.st_size;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
106
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
107 g = gzopen (pathname, "rb");
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
108 if (sizeof (tar_header) != 512)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
109 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
110 /* drastic, but important */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
111 fprintf (stderr, "compilation error: tar header struct not 512"
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
112 " bytes (it's %d)\n", sizeof (tar_header));
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
113 exit_setup (1);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
114 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
115 err = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
116 return g ? 0 : 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
117 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
118
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
119 /* For some reason the cygwin version uses a function that is not in
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
120 the original source. We duplicate it here - although this does mean
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
121 revealing some internals. */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
122 extern "C" {
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
123 z_off_t ZEXPORT tar_gzctell (gzFile file);
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
124 typedef struct gz_stream {
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
125 z_stream stream;
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
126 int z_err; /* error code for last stream operation */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
127 int z_eof; /* set if end of input file */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
128 FILE *file; /* .gz file */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
129 Byte *inbuf; /* input buffer */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
130 Byte *outbuf; /* output buffer */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
131 uLong crc; /* crc32 of uncompressed data */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
132 char *msg; /* error message */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
133 char *path; /* path name for debugging only */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
134 int transparent; /* 1 if input file is not a .gz file */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
135 char mode; /* 'w' or 'r' */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
136 long startpos; /* start of compressed data in file (header skipped) */
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
137 } gz_stream;
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
138 };
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
139
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
140 z_off_t ZEXPORT tar_gzctell (gzFile file)
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
141 {
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
142 gz_stream *s = (gz_stream *)file;
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
143 return ftell(s->file);
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
144 }
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
145
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
146 int
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
147 tar_ftell ()
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
148 {
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
149 return tar_gzctell (g);
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
150 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
151
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
152 static void
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
153 skip_file ()
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
154 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
155 while (file_length > 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
156 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
157 gzread (g, buf, 512);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
158 file_length -= 512;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
159 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
160 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
161
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
162 char *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
163 tar_next_file ()
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
164 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
165 int r, n;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
166 char *c;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
167 r = gzread (g, &tar_header, 512);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
168
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
169 /* See if we're at end of file */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
170 if (r != 512)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
171 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
172
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
173 /* See if the header is all zeros (i.e. last block) */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
174 n = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
175 for (r = 512/sizeof (int); r; r--)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
176 n |= ((int *)&tar_header)[r-1];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
177 if (n == 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
178 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
179
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
180 if (!have_longname && tar_header.typeflag != 'L')
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
181 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
182 memcpy (file_name, tar_header.name, 100);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
183 file_name[100] = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
184 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
185
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
186 sscanf (tar_header.size, "%o", &file_length);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
187
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
188 vp2 (_tar_vfile, "%c %9d %s\n", tar_header.typeflag, file_length, file_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
189
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
190 switch (tar_header.typeflag)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
191 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
192 case 'L': /* GNU tar long name extension */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
193 if (file_length > _MAX_PATH)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
194 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
195 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
196 fprintf (stderr, "error: long file name exceeds %d characters\n",
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
197 _MAX_PATH);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
198 err ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
199 gzread (g, &tar_header, 512);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
200 sscanf (tar_header.size, "%o", &file_length);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
201 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
202 return tar_next_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
203 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
204 c = file_name;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
205 while (file_length > 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
206 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
207 int need = file_length > 512 ? 512 : file_length;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
208 if (gzread (g, buf, 512) < 512)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
209 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
210 memcpy (c, buf, need);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
211 c += need;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
212 file_length -= need;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
213 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
214 *c = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
215 have_longname = 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
216 return tar_next_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
217
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
218 case '3': /* char */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
219 case '4': /* block */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
220 case '6': /* fifo */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
221 fprintf (stderr, "warning: not extracting special file %s\n",
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
222 file_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
223 err ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
224 return tar_next_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
225
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
226 case '0': /* regular file */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
227 case 0: /* regular file also */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
228 case '2': /* symbolic link */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
229 case '5': /* directory */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
230 case '7': /* contiguous file */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
231 return file_name;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
232
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
233 case '1': /* hard link, we just copy */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
234 return file_name;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
235
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
236 default:
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
237 fprintf (stderr, "error: unknown (or unsupported) file type `%c'\n",
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
238 tar_header.typeflag);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
239 err ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
240 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
241 return tar_next_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
242 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
243 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
244
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
245 static void
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
246 fix_time_stamp (char *path)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
247 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
248 int mtime;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
249 #if defined(CYGWIN) || defined(MINGW)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
250 long long ftimev;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
251 #else
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
252 __int64 ftimev;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
253 #endif
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
254 FILETIME ftime;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
255 HANDLE h;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
256
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
257 sscanf (tar_header.mtime, "%o", &mtime);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
258 ftimev = mtime * NSPERSEC + FACTOR;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
259 ftime.dwHighDateTime = ftimev >> 32;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
260 ftime.dwLowDateTime = ftimev;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
261 h = CreateFileA (path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
262 0, OPEN_EXISTING,
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
263 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
264 if (h)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
265 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
266 SetFileTime (h, 0, 0, &ftime);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
267 CloseHandle (h);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
268 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
269 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
270
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
271 static FILE *
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
272 common_fopen (char *path)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
273 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
274 FILE *out;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
275 out = fopen (path, "wb");
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
276 if (!out)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
277 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
278 /* maybe we need to create a directory */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
279 if (mkdir_p (0, path))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
280 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
281 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
282 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
283 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
284 out = fopen (path, "wb");
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
285 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
286 if (!out)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
287 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
288 fprintf (stderr, "unable to write to file %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
289 perror ("The error was");
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
290 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
291 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
292 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
293 return out;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
294 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
295
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
296 static void
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
297 prepare_for_file (char *path)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
298 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
299 DWORD w;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
300 mkdir_p (0, path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
301
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
302 w = GetFileAttributes (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
303 if (w != 0xffffffff && w & FILE_ATTRIBUTE_DIRECTORY)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
304 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
305 char *tmp = (char *) malloc (strlen (path) + 10);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
306 int i = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
307 do {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
308 i++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
309 sprintf (tmp, "%s.old-%d", path, i);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
310 } while (GetFileAttributes (tmp) != 0xffffffff);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
311 fprintf (stderr, "warning: moving directory \"%s\" out of the way.\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
312 MoveFile (path, tmp);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
313 free (tmp);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
314 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
315
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
316 DeleteFileA (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
317 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
318
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
319 int
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
320 tar_read_file (char *path)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
321 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
322 FILE *out, *copy;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
323 HANDLE h;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
324 DWORD w;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
325 int got;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
326 tar_map_result_type *tmr;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
327
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
328 switch (tar_header.typeflag)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
329 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
330 case '0': /* regular files */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
331 case 0:
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
332 case '7':
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
333 vp (_tar_vfile, "F %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
334 prepare_for_file (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
335 out = common_fopen (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
336 if (!out)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
337 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
338
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
339 while (file_length > 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
340 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
341 int put;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
342 int want = file_length > 512 ? 512 : file_length;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
343 got = gzread (g, buf, 512);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
344 if (got < 512)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
345 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
346 fprintf (stderr, "tar: unexpected end of file reading %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
347 fclose (out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
348 remove (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
349 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
350 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
351 put = fwrite (buf, 1, want, out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
352 if (put < want)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
353 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
354 fprintf (stderr, "tar: out of disk space writing %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
355 fclose (out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
356 remove (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
357 skip_file ();
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
358 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
359 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
360 file_length -= want;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
361 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
362 fclose (out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
363
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
364 fix_time_stamp (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
365
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
366 /* we need this to do hard links below */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
367 tmr = (tar_map_result_type *) malloc (sizeof (tar_map_result_type));
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
368 tmr->next = tar_map_result;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
369 tmr->stored_name = xstrdup (file_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
370 tmr->mapped_name = xstrdup (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
371 tar_map_result = tmr;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
372
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
373 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
374
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
375 case '1': /* hard links; we just copy */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
376 for (tmr = tar_map_result; tmr; tmr=tmr->next)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
377 if (strcmp (tmr->stored_name, tar_header.linkname) == 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
378 break;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
379 if (!tmr)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
380 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
381 fprintf (stderr, "tar: can't find %s to link %s to\n",
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
382 tar_header.linkname, path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
383 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
384 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
385 vp (_tar_vfile, "H %s <- %s\n", path, tmr->mapped_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
386 prepare_for_file (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
387 copy = fopen (tmr->mapped_name, "rb");
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
388 if (!copy)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
389 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
390 fprintf (stderr, "tar: unable to read %s\n", tmr->mapped_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
391 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
392 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
393 out = common_fopen (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
394 if (!out)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
395 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
396
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
397 while ((got = fread (buf, 1, 512, copy)) > 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
398 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
399 int put = fwrite (buf, 1, got, out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
400 if (put < got)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
401 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
402 fprintf (stderr, "tar: out of disk space writing %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
403 fclose (out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
404 fclose (copy);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
405 remove (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
406 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
407 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
408 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
409 fclose (out);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
410 fclose (copy);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
411
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
412 fix_time_stamp (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
413 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
414
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
415 case '5': /* directories */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
416 vp (_tar_vfile, "D %s\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
417 while (path[0] && path[strlen (path)-1] == '/')
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
418 path[strlen (path) - 1] = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
419 return mkdir_p (1, path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
420
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
421
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
422 case '2': /* symbolic links */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
423 vp (_tar_vfile, "L %s -> %s\n", path, tar_header.linkname);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
424 prepare_for_file (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
425 h = CreateFileA (path, GENERIC_WRITE, 0, 0, CREATE_NEW,
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
426 FILE_ATTRIBUTE_NORMAL, 0);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
427 if (h == INVALID_HANDLE_VALUE)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
428 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
429 fprintf (stderr, "error: unable to create symlink \"%s\" -> \"%s\"\n",
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
430 path, tar_header.linkname);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
431 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
432 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
433 strcpy (buf, SYMLINK_COOKIE);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
434 strcat (buf, tar_header.linkname);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
435 if (WriteFile (h, buf, strlen (buf) + 1, &w, NULL))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
436 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
437 CloseHandle (h);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
438 SetFileAttributesA (path, FILE_ATTRIBUTE_SYSTEM);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
439 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
440 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
441 CloseHandle (h);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
442 fprintf (stderr, "error: unable to write symlink \"%s\"\n", path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
443 DeleteFileA (path);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
444 return 1;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
445 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
446
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
447 return 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
448 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
449
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
450 int
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
451 tar_close ()
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
452 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
453 #if 0
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
454 while (tar_map_result)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
455 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
456 tar_map_result_type *t = tar_map_result->next;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
457 free (tar_map_result->stored_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
458 free (tar_map_result->mapped_name);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
459 free (tar_map_result);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
460 tar_map_result = t;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
461 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
462 #endif
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
463 tar_map_result = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
464
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
465 if (gzclose (g))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
466 err ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
467 return err; /* includes errors for skipped files, etc */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
468 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
469
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
470 typedef struct {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
471 char *from;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
472 int from_len;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
473 char *to;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
474 int to_len;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
475 } map_type;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
476
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
477 static map_type *map;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
478 static int nmaps;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
479
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
480 int
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
481 tar_auto (char *pathname, char **maplist)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
482 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
483 char *c;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
484 int errcount = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
485 int i, j;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
486 map_type mtemp;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
487 char newname[_MAX_PATH+512];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
488 static char twiddles[] = "|\b/\b-\b\\\b";
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
489 int t = 0;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
490
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
491 for (nmaps=0; maplist[nmaps*2]; nmaps++) ;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
492 map = (map_type *) malloc ((nmaps+1) * sizeof (map_type));
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
493 for (nmaps=0; maplist[nmaps*2]; nmaps++)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
494 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
495 map[nmaps].from = maplist[nmaps*2];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
496 map[nmaps].from_len = strlen (maplist[nmaps*2]);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
497 map[nmaps].to = maplist[nmaps*2+1];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
498 map[nmaps].to_len = strlen (maplist[nmaps*2+1]);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
499 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
500 /* bubble sort - expect the maps to be short */
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
501 for (i=0; i<nmaps-1; i++)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
502 for (j=i+1; j<nmaps; j++)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
503 if (map[i].from_len < map[j].from_len)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
504 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
505 mtemp = map[i];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
506 map[i] = map[j];
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
507 map[j] = mtemp;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
508 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
509
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
510 if ((tar_open (pathname)))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
511 return 1;
452
3d3049ae1304 Import from CVS: tag r21-2-41
cvs
parents: 448
diff changeset
512 while ((c = tar_next_file ()))
448
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
513 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
514 int l = strlen (c);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
515 for (i=0; i<nmaps; i++)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
516 if (l >= map[i].from_len
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
517 && strncmp (c, map[i].from, map[i].from_len) == 0)
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
518 {
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
519 strcpy (newname, map[i].to);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
520 strcpy (newname+map[i].to_len, c + map[i].from_len);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
521 c = newname;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
522 break;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
523 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
524
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
525 t = (t+2) % 8;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
526 fwrite (twiddles+t, 1, 2, stderr);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
527
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
528 if (tar_read_file (c))
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
529 errcount ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
530 }
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
531 if (tar_close ())
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
532 errcount ++;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
533
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
534 fwrite (" \b", 1, 2, stderr);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
535
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
536 vp2 (_tar_vfile, "tar_auto returns %d\n", errcount);
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
537 return errcount;
3078fd1074e8 Import from CVS: tag r21-2-39
cvs
parents:
diff changeset
538 }