]>
cygwin.com Git - cygwin-apps/setup.git/blob - archive.cc
fa70cbee9c6cf12944920d47c7d1e42d366820a9
2 * Copyright (c) 2001, Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* Archive IO operations
20 static const char *cvsid
=
24 #include "LogSingleton.h"
26 #include "io_stream.h"
28 #include "archive_tar.h"
30 /* This file is the sole user of alloca(), so do this here.
31 * This will go away when this file is useing proper C++ string handling. */
36 #define alloca __builtin_alloca
40 /* In case you are wondering why the file magic is not in one place:
41 * It could be. But there is little (any?) benefit.
42 * What is important is that the file magic required for any _task_ is centralised.
43 * One such task is identifying archives
45 * to federate into each class one might add a magic parameter to the constructor, which
46 * the class could test itself.
50 * offset 257 string ustar\040\040\0
54 #define longest_magic 265
57 archive::extract (io_stream
* original
)
61 char magic
[longest_magic
];
62 if (original
->peek (magic
, longest_magic
) > 0)
64 if (memcmp (&magic
[257], "ustar\040\040\0", 8) == 0)
67 archive_tar
*rv
= new archive_tar (original
);
73 else if (memcmp (magic
, "BZh", 3) == 0)
75 archive_bz
*rv
= new archive_bz (original
);
86 archive::extract_file (archive
* source
, const std::string
& prefixURL
,
87 const std::string
& prefixPath
, std::string suffix
)
91 const std::string destfilename
= prefixURL
+ prefixPath
92 + source
->next_file_name() + suffix
;
93 switch (source
->next_file_type ())
95 case ARCHIVE_FILE_REGULAR
:
98 /* TODO: remove in-the-way directories via mkpath_p */
99 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
101 log (LOG_TIMESTAMP
) << "Failed to make the path for " << destfilename
105 io_stream::remove (destfilename
);
106 io_stream
*tmp
= io_stream::open (destfilename
, "wb");
109 log (LOG_TIMESTAMP
) << "Failed to open " << destfilename
;
110 log (LOG_TIMESTAMP
) << " for writing." << endLog
;
113 io_stream
*in
= source
->extract_file ();
117 log (LOG_TIMESTAMP
) << "Failed to extract the file "
118 << destfilename
<< " from the archive"
122 if (io_stream::copy (in
, tmp
))
124 log (LOG_TIMESTAMP
) << "Failed to output " << destfilename
127 io_stream::remove (destfilename
);
130 tmp
->set_mtime (in
->get_mtime ());
135 case ARCHIVE_FILE_SYMLINK
:
137 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
139 log (LOG_TIMESTAMP
) << "Failed to make the path for %s"
140 << destfilename
<< endLog
;
142 io_stream::remove (destfilename
);
144 io_stream::mklink (destfilename
,
145 prefixURL
+ source
->linktarget (),
147 /* FIXME: check what tar's filelength is set to for symlinks */
148 source
->skip_file ();
151 case ARCHIVE_FILE_HARDLINK
:
153 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
155 log (LOG_TIMESTAMP
) << "Failed to make the path for %s"
156 << destfilename
<< endLog
;
159 io_stream::remove (destfilename
);
161 io_stream::mklink (destfilename
,
162 prefixURL
+ prefixPath
+ source
->linktarget (),
164 /* FIXME: check what tar's filelength is set to for hardlinks */
165 source
->skip_file ();
168 case ARCHIVE_FILE_DIRECTORY
:
170 char *path
= (char *) alloca (destfilename
.size());
171 strcpy (path
, destfilename
.c_str());
172 while (path
[0] && path
[strlen (path
) - 1] == '/')
173 path
[strlen (path
) - 1] = 0;
174 source
->skip_file ();
175 return io_stream::mkpath_p (PATH_TO_DIR
, path
);
177 case ARCHIVE_FILE_INVALID
:
178 source
->skip_file ();
184 archive::~archive () {};
187 ssize_t
archive::read (void *buffer
, size_t len
)
189 log (LOG_TIMESTAMP
, "archive::read called");
193 ssize_t
archive::write (void *buffer
, size_t len
)
195 log (LOG_TIMESTAMP
, "archive::write called");
199 ssize_t
archive::peek (void *buffer
, size_t len
)
201 log (LOG_TIMESTAMP
, "archive::peek called");
208 log (LOG_TIMESTAMP
, "bz::tell called");
215 log (LOG_TIMESTAMP
, "archive::error called");
220 archive::next_file_name ()
222 log (LOG_TIMESTAMP
, "archive::next_file_name called");
This page took 0.042814 seconds and 4 git commands to generate.