]>
cygwin.com Git - cygwin-apps/setup.git/blob - archive.cc
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
=
31 #include "io_stream.h"
33 #include "archive_tar.h"
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
40 * to federate into each class one might add a magic parameter to the constructor, which
41 * the class could test itself.
45 * offset 257 string ustar\040\040\0
49 #define longest_magic 265
52 archive::extract (io_stream
* original
)
56 char magic
[longest_magic
];
57 if (original
->peek (magic
, longest_magic
) > 0)
59 if (memcmp (&magic
[257], "ustar\040\040\0", 8) == 0)
62 archive_tar
*rv
= new archive_tar (original
);
68 else if (memcmp (magic
, "BZh", 3) == 0)
70 archive_bz
*rv
= new archive_bz (original
);
81 archive::extract_file (archive
* source
, String
const &prefixURL
, String
const &prefixPath
, String suffix
)
85 String
const destfilename
= prefixURL
+prefixPath
+ source
->next_file_name ()+ suffix
;
86 switch (source
->next_file_type ())
88 case ARCHIVE_FILE_REGULAR
:
91 /* TODO: remove in-the-way directories via mkpath_p */
92 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
94 log (LOG_TIMESTAMP
, String ("Failed to make the path for ") + destfilename
);
96 io_stream::remove (destfilename
);
97 io_stream
*tmp
= io_stream::open (destfilename
, "wb");
100 log (LOG_TIMESTAMP
, String ("Failed to open ") + destfilename
+ " for writing.");
103 io_stream
*in
= source
->extract_file ();
107 log (LOG_TIMESTAMP
, String("Failed to extract the file ") + destfilename
+ " from the archive");
110 if (io_stream::copy (in
, tmp
))
112 log (LOG_TIMESTAMP
, String("Failed to output ") + destfilename
);
114 io_stream::remove (destfilename
);
117 tmp
->set_mtime (in
->get_mtime ());
122 case ARCHIVE_FILE_SYMLINK
:
124 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
125 {log (LOG_TIMESTAMP
, "Failed to make the path for %s", destfilename
.cstr_oneuse());
127 io_stream::remove (destfilename
);
129 io_stream::mklink (destfilename
,
130 prefixURL
+ source
->linktarget (),
132 /* FIXME: check what tar's filelength is set to for symlinks */
133 source
->skip_file ();
136 case ARCHIVE_FILE_HARDLINK
:
138 if (io_stream::mkpath_p (PATH_TO_FILE
, destfilename
))
139 {log (LOG_TIMESTAMP
, "Failed to make the path for %s", destfilename
.cstr_oneuse());
141 io_stream::remove (destfilename
);
143 io_stream::mklink (destfilename
,
144 prefixURL
+ source
->linktarget (),
146 /* FIXME: check what tar's filelength is set to for hardlinks */
147 source
->skip_file ();
150 case ARCHIVE_FILE_DIRECTORY
:
152 char *path
= (char *) alloca (destfilename
.size());
153 strcpy (path
, destfilename
.cstr_oneuse());
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
);
159 case ARCHIVE_FILE_INVALID
:
160 source
->skip_file ();
167 ssize_t
archive::read (void *buffer
, size_t len
)
169 log (LOG_TIMESTAMP
, "archive::read called");
173 ssize_t
archive::write (void *buffer
, size_t len
)
175 log (LOG_TIMESTAMP
, "archive::write called");
179 ssize_t
archive::peek (void *buffer
, size_t len
)
181 log (LOG_TIMESTAMP
, "archive::peek called");
188 log (LOG_TIMESTAMP
, "bz::tell called");
195 log (LOG_TIMESTAMP
, "archive::error called");
200 archive::next_file_name ()
202 log (LOG_TIMESTAMP
, "archive::next_file_name called");
208 log (LOG_TIMESTAMP
, "archive::~archive called");
This page took 0.100738 seconds and 5 git commands to generate.