00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef MULTIFILE_H
00016 #define MULTIFILE_H
00017
00018 #include "pandabase.h"
00019
00020 #include "config_express.h"
00021 #include "streamWrapper.h"
00022 #include "subStream.h"
00023 #include "filename.h"
00024 #include "ordered_vector.h"
00025 #include "indirectLess.h"
00026 #include "referenceCount.h"
00027 #include "pvector.h"
00028 #include "openSSLWrapper.h"
00029
00030
00031
00032
00033
00034 class EXPCL_PANDAEXPRESS Multifile : public ReferenceCount {
00035 PUBLISHED:
00036 Multifile();
00037 ~Multifile();
00038
00039 private:
00040 Multifile(const Multifile ©);
00041 void operator = (const Multifile ©);
00042
00043 PUBLISHED:
00044 BLOCKING bool open_read(const Filename &multifile_name, const streampos &offset = 0);
00045 BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false, const streampos &offset = 0);
00046 BLOCKING bool open_write(const Filename &multifile_name);
00047 BLOCKING bool open_write(ostream *multifile_stream, bool owns_pointer = false);
00048 BLOCKING bool open_read_write(const Filename &multifile_name);
00049 BLOCKING bool open_read_write(iostream *multifile_stream, bool owns_pointer = false);
00050 BLOCKING void close();
00051
00052 INLINE const Filename &get_multifile_name() const;
00053 INLINE void set_multifile_name(const Filename &multifile_name);
00054
00055 INLINE bool is_read_valid() const;
00056 INLINE bool is_write_valid() const;
00057 INLINE bool needs_repack() const;
00058
00059 INLINE time_t get_timestamp() const;
00060
00061 INLINE void set_record_timestamp(bool record_timestamp);
00062 INLINE bool get_record_timestamp() const;
00063
00064 void set_scale_factor(size_t scale_factor);
00065 INLINE size_t get_scale_factor() const;
00066
00067 INLINE void set_encryption_flag(bool flag);
00068 INLINE bool get_encryption_flag() const;
00069 INLINE void set_encryption_password(const string &encryption_password);
00070 INLINE const string &get_encryption_password() const;
00071
00072 INLINE void set_encryption_algorithm(const string &encryption_algorithm);
00073 INLINE const string &get_encryption_algorithm() const;
00074 INLINE void set_encryption_key_length(int encryption_key_length);
00075 INLINE int get_encryption_key_length() const;
00076 INLINE void set_encryption_iteration_count(int encryption_iteration_count);
00077 INLINE int get_encryption_iteration_count() const;
00078
00079 string add_subfile(const string &subfile_name, const Filename &filename,
00080 int compression_level);
00081 string add_subfile(const string &subfile_name, istream *subfile_data,
00082 int compression_level);
00083 string update_subfile(const string &subfile_name, const Filename &filename,
00084 int compression_level);
00085
00086 #ifdef HAVE_OPENSSL
00087 class CertRecord {
00088 public:
00089 INLINE CertRecord(X509 *cert);
00090 INLINE CertRecord(const CertRecord ©);
00091 INLINE ~CertRecord();
00092 INLINE void operator = (const CertRecord &other);
00093 X509 *_cert;
00094 };
00095 typedef pvector<CertRecord> CertChain;
00096
00097 bool add_signature(const Filename &certificate,
00098 const Filename &chain,
00099 const Filename &pkey,
00100 const string &password = "");
00101 bool add_signature(const Filename &composite,
00102 const string &password = "");
00103 bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey);
00104 bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
00105
00106 int get_num_signatures() const;
00107 const CertChain &get_signature(int n) const;
00108 string get_signature_subject_name(int n) const;
00109 string get_signature_friendly_name(int n) const;
00110 string get_signature_public_key(int n) const;
00111 void print_signature_certificate(int n, ostream &out) const;
00112 void write_signature_certificate(int n, ostream &out) const;
00113
00114 int validate_signature_certificate(int n) const;
00115 #endif // HAVE_OPENSSL
00116
00117 BLOCKING bool flush();
00118 BLOCKING bool repack();
00119
00120 int get_num_subfiles() const;
00121 int find_subfile(const string &subfile_name) const;
00122 bool has_directory(const string &subfile_name) const;
00123 bool scan_directory(vector_string &contents,
00124 const string &subfile_name) const;
00125 void remove_subfile(int index);
00126 INLINE bool remove_subfile(const string &subfile_name);
00127 const string &get_subfile_name(int index) const;
00128 MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name);
00129 size_t get_subfile_length(int index) const;
00130 time_t get_subfile_timestamp(int index) const;
00131 bool is_subfile_compressed(int index) const;
00132 bool is_subfile_encrypted(int index) const;
00133 bool is_subfile_text(int index) const;
00134
00135 streampos get_index_end() const;
00136 streampos get_subfile_internal_start(int index) const;
00137 size_t get_subfile_internal_length(int index) const;
00138
00139 BLOCKING INLINE string read_subfile(int index);
00140 BLOCKING istream *open_read_subfile(int index);
00141 BLOCKING static void close_read_subfile(istream *stream);
00142 BLOCKING bool extract_subfile(int index, const Filename &filename);
00143 BLOCKING bool extract_subfile_to(int index, ostream &out);
00144 BLOCKING bool compare_subfile(int index, const Filename &filename);
00145
00146 void output(ostream &out) const;
00147 void ls(ostream &out = cout) const;
00148
00149 static INLINE string get_magic_number();
00150
00151 void set_header_prefix(const string &header_prefix);
00152 INLINE const string &get_header_prefix() const;
00153
00154 public:
00155 bool read_subfile(int index, string &result);
00156 bool read_subfile(int index, pvector<unsigned char> &result);
00157
00158 private:
00159 enum SubfileFlags {
00160 SF_deleted = 0x0001,
00161 SF_index_invalid = 0x0002,
00162 SF_data_invalid = 0x0004,
00163 SF_compressed = 0x0008,
00164 SF_encrypted = 0x0010,
00165 SF_signature = 0x0020,
00166 SF_text = 0x0040,
00167 };
00168
00169 class Subfile {
00170 public:
00171 INLINE Subfile();
00172 INLINE bool operator < (const Subfile &other) const;
00173 streampos read_index(istream &read, streampos fpos,
00174 Multifile *multfile);
00175 streampos write_index(ostream &write, streampos fpos,
00176 Multifile *multifile);
00177 streampos write_data(ostream &write, istream *read, streampos fpos,
00178 Multifile *multifile);
00179 void rewrite_index_data_start(ostream &write, Multifile *multifile);
00180 void rewrite_index_flags(ostream &write);
00181 INLINE bool is_deleted() const;
00182 INLINE bool is_index_invalid() const;
00183 INLINE bool is_data_invalid() const;
00184 INLINE bool is_cert_special() const;
00185 INLINE streampos get_last_byte_pos() const;
00186
00187 string _name;
00188 streampos _index_start;
00189 size_t _index_length;
00190 streampos _data_start;
00191 size_t _data_length;
00192 size_t _uncompressed_length;
00193 time_t _timestamp;
00194 istream *_source;
00195 Filename _source_filename;
00196 int _flags;
00197 int _compression_level;
00198 #ifdef HAVE_OPENSSL
00199 EVP_PKEY *_pkey;
00200 #endif
00201 };
00202
00203 INLINE streampos word_to_streampos(size_t word) const;
00204 INLINE size_t streampos_to_word(streampos fpos) const;
00205 INLINE streampos normalize_streampos(streampos fpos) const;
00206 streampos pad_to_streampos(streampos fpos);
00207
00208 void add_new_subfile(Subfile *subfile, int compression_level);
00209 istream *open_read_subfile(Subfile *subfile);
00210 string standardize_subfile_name(const string &subfile_name) const;
00211
00212 void clear_subfiles();
00213 bool read_index();
00214 bool write_header();
00215
00216 void check_signatures();
00217
00218 static INLINE char tohex(unsigned int nibble);
00219
00220 typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles;
00221 Subfiles _subfiles;
00222 typedef pvector<Subfile *> PendingSubfiles;
00223 PendingSubfiles _new_subfiles;
00224 PendingSubfiles _removed_subfiles;
00225 PendingSubfiles _cert_special;
00226
00227 #ifdef HAVE_OPENSSL
00228 typedef pvector<CertChain> Certificates;
00229 Certificates _signatures;
00230 #endif
00231
00232 streampos _offset;
00233 IStreamWrapper *_read;
00234 ostream *_write;
00235 bool _owns_stream;
00236 streampos _next_index;
00237 streampos _last_index;
00238 streampos _last_data_byte;
00239
00240 bool _needs_repack;
00241 time_t _timestamp;
00242 bool _timestamp_dirty;
00243 bool _record_timestamp;
00244 size_t _scale_factor;
00245 size_t _new_scale_factor;
00246
00247 bool _encryption_flag;
00248 string _encryption_password;
00249 string _encryption_algorithm;
00250 int _encryption_key_length;
00251 int _encryption_iteration_count;
00252
00253 pifstream _read_file;
00254 IStreamWrapper _read_filew;
00255 pofstream _write_file;
00256 pfstream _read_write_file;
00257 StreamWrapper _read_write_filew;
00258 Filename _multifile_name;
00259 string _header_prefix;
00260
00261 int _file_major_ver;
00262 int _file_minor_ver;
00263
00264 static const char _header[];
00265 static const size_t _header_size;
00266 static const int _current_major_ver;
00267 static const int _current_minor_ver;
00268
00269 static const char _encrypt_header[];
00270 static const size_t _encrypt_header_size;
00271
00272 friend class Subfile;
00273 };
00274
00275 #include "multifile.I"
00276
00277 #endif