]> cygwin.com Git - cygwin-apps/setup.git/blame - archive.cc
2002-01-27 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / archive.cc
CommitLineData
b24c88b3
RC
1/*
2 * Copyright (c) 2001, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16/* Archive IO operations
17 */
18
19#if 0
20static const char *cvsid =
21 "\n%%% $Id$\n";
22#endif
23
24#include "win32.h"
25#include <stdio.h>
26#include <stdlib.h>
27#include "log.h"
28#include "port.h"
29#include "concat.h"
30
31#include "io_stream.h"
32#include "archive.h"
33#include "archive_tar.h"
34
35/* In case you are wondering why the file magic is not in one place:
36 * It could be. But there is little (any?) benefit.
37 * What is important is that the file magic required for any _task_ is centralised.
38 * One such task is identifying archives
39 *
40 * to federate into each class one might add a magic parameter to the constructor, which
41 * the class could test itself.
42 */
43
44/* GNU TAR:
45 * offset 257 string ustar\040\040\0
46 */
47
48
49#define longest_magic 265
50
51archive *
52archive::extract (io_stream * original)
53{
54 if (!original)
55 return NULL;
56 char magic[longest_magic];
57 if (original->peek (magic, longest_magic) > 0)
58 {
59 if (memcmp (&magic[257], "ustar\040\040\0", 8) == 0)
60 {
61 /* tar */
62 archive_tar *rv = new archive_tar (original);
63 if (!rv->error ())
64 return rv;
65 return NULL;
66 }
67#if 0
68 else if (memcmp (magic, "BZh", 3) == 0)
69 {
70 archive_bz *rv = new archive_bz (original);
71 if (!rv->error ())
72 return rv;
73 return NULL;
74 }
75#endif
76 }
77 return NULL;
78}
79
80int
6dc75764 81archive::extract_file (archive * source, const char *prefixURL, const char *prefixPath, const char *suffix)
b24c88b3
RC
82{
83 if (!source)
84 return 1;
6dc75764 85 const char *destfilename = concat (prefixURL,prefixPath, source->next_file_name (), suffix, 0);
b24c88b3
RC
86 switch (source->next_file_type ())
87 {
88 case ARCHIVE_FILE_REGULAR:
89 {
90
91 /* TODO: remove in-the-way directories via mkpath_p */
92 if (io_stream::mkpath_p (PATH_TO_FILE, destfilename))
93 {
94 log (LOG_TIMESTAMP, "Failed to make the path for %s", destfilename);
95 return 1;}
96 io_stream::remove (destfilename);
97 io_stream *tmp = io_stream::open (destfilename, "wb");
98 if (!tmp)
99 {
100 log (LOG_TIMESTAMP, "Failed to open %s for writing", destfilename);
101 return 1;
102 }
103 io_stream *in = source->extract_file ();
104 if (!in)
105 {
106 delete tmp;
107 log (LOG_TIMESTAMP, "Failed to extract the file %s from the archive",destfilename);
108 return 1;
109 }
341988b9 110 if (io_stream::copy (in, tmp))
b24c88b3 111 {
341988b9
RC
112 log (LOG_TIMESTAMP, "Failed to output %s", destfilename);
113 delete tmp;
114 io_stream::remove (destfilename);
115 return 1;
b24c88b3
RC
116 }
117 tmp->set_mtime (in->get_mtime ());
118 delete in;
119 delete tmp;
b24c88b3
RC
120 }
121 break;
122 case ARCHIVE_FILE_SYMLINK:
123 {
124 if (io_stream::mkpath_p (PATH_TO_FILE, destfilename))
125 {log (LOG_TIMESTAMP, "Failed to make the path for %s", destfilename);
126 return 1;}
127 io_stream::remove (destfilename);
128 int ok =
129 io_stream::mklink (destfilename,
6dc75764 130 concat (prefixURL, source->linktarget (), 0),
b24c88b3
RC
131 IO_STREAM_SYMLINK);
132 /* FIXME: check what tar's filelength is set to for symlinks */
133 source->skip_file ();
134 return ok;
135 }
136 case ARCHIVE_FILE_HARDLINK:
137 {
138 if (io_stream::mkpath_p (PATH_TO_FILE, destfilename))
139 {log (LOG_TIMESTAMP, "Failed to make the path for %s", destfilename);
140 return 1;}
141 io_stream::remove (destfilename);
142 int ok =
143 io_stream::mklink (destfilename,
6dc75764 144 concat (prefixURL, source->linktarget (), 0),
b24c88b3
RC
145 IO_STREAM_HARDLINK);
146 /* FIXME: check what tar's filelength is set to for hardlinks */
147 source->skip_file ();
148 return ok;
149 }
150 case ARCHIVE_FILE_DIRECTORY:
151 {
152 char *path = (char *) alloca (strlen (destfilename));
153 strcpy (path, destfilename);
154 while (path[0] && path[strlen (path) - 1] == '/')
155 path[strlen (path) - 1] = 0;
156 source->skip_file ();
157 return io_stream::mkpath_p (PATH_TO_DIR, path);
158 }
159 case ARCHIVE_FILE_INVALID:
160 source->skip_file ();
161 break;
162 }
163 return 0;
164}
165
166#if 0
167ssize_t archive::read (void *buffer, size_t len)
168{
169 log (LOG_TIMESTAMP, "archive::read called");
170 return 0;
171}
172
173ssize_t archive::write (void *buffer, size_t len)
174{
175 log (LOG_TIMESTAMP, "archive::write called");
176 return 0;
177}
178
179ssize_t archive::peek (void *buffer, size_t len)
180{
181 log (LOG_TIMESTAMP, "archive::peek called");
182 return 0;
183}
184
185long
186archive::tell ()
187{
188 log (LOG_TIMESTAMP, "bz::tell called");
189 return 0;
190}
191
192int
193archive::error ()
194{
195 log (LOG_TIMESTAMP, "archive::error called");
196 return 0;
197}
198
199const char *
200archive::next_file_name ()
201{
202 log (LOG_TIMESTAMP, "archive::next_file_name called");
203 return NULL;
204}
205
206archive::~archive ()
207{
208 log (LOG_TIMESTAMP, "archive::~archive called");
209 return;
210}
211#endif
This page took 0.0436 seconds and 5 git commands to generate.