This file is indexed.

/usr/include/crystalspace-2.0/csutil/archive.h is in libcrystalspace-dev 2.0+dfsg-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
    ZIP archive support for Crystal Space 3D library
    Copyright (C) 1998,1999 by Andrew Zabolotny <bit@eltech.ru>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_ARCHIVE_H__
#define __CS_ARCHIVE_H__

/**\file
 * ZIP archive support
 */

#include "csextern.h"

#include "iutil/databuff.h"
#include "iutil/vfs.h"
#include "csutil/csstring.h"
#include "csutil/databuf.h"
#include "csutil/parray.h"
#include "csutil/ref.h"
#include "csutil/stringarray.h"
#include "csutil/zip.h"

struct csFileTime;

/**
 * This class can be used to work with standard ZIP archives.
 * Constructor accepts a file name - if such a file is not found, it is
 * created. After this you can examine archive directory, read files,
 * delete or write files in archive.
 * 
 * Operations which changes archive file will be deferred until Flush()
 * method is called. Before calling Flush() you can do any number of
 * deletions and writes, but read operations will not be affected by
 * these until Flush() will be called.
 * 
 * Known quirks:
 * - No CRC check is done on reading, although ZIP file format allows it.
 *   This design 'flaw' was allowed to achieve maximal speed. However, when
 *   a file is added to archive, its CRC is computed and updated correctly.
 * - Several methods of the csArchive class requires approximatively 20K of
 *   stack space when invoked.
 * - Doesn't like files >4GB.
 */
class CS_CRYSTALSPACE_EXPORT csArchive
{
public:
  static const char hdr_central[4];
  static const char hdr_local[4];
  static const char hdr_endcentral[4];
  static const char hdr_extlocal[4];

private:
  /// csArchive entry class
  class ArchiveEntry
  {
  public:
    char *filename;
    ZIP_central_directory_file_header info;
    char *buffer;
    size_t buffer_pos;
    size_t buffer_size;
    char *extrafield, *comment;
    bool faked;

    ArchiveEntry (const char *name, ZIP_central_directory_file_header &cdfh);
    ~ArchiveEntry ();
    bool Append (const void *data, size_t size);
    bool WriteLFH (iFile* file);
    bool WriteCDFH (iFile* file);
    bool ReadExtraField (iFile* file, size_t extra_field_length);
    bool ReadFileComment (iFile* file, size_t file_comment_length);
    bool WriteFile (iFile* file);
    void FreeBuffer ();
  };
  friend class ArchiveEntry;

  /// A vector of ArchiveEntries
  class CS_CRYSTALSPACE_EXPORT ArchiveEntryVector
  	: public csPDelArray<ArchiveEntry, CS::Container::ArrayAllocDefault,
  	                     csArrayCapacityFixedGrow<256> >
  {
  public:
    ArchiveEntryVector () : csPDelArray<ArchiveEntry, 
      CS::Container::ArrayAllocDefault, csArrayCapacityFixedGrow<256> > (256) {}
    static int Compare (ArchiveEntry* const& Item1, ArchiveEntry* const& Item2)
    { return strcmp (Item1->filename, Item2->filename); }
    static int CompareKey (ArchiveEntry* const& Item, char const* const& Key)
    { return strcmp (Item->filename, Key); }
  };

  ArchiveEntryVector dir;	// Archive directory: chain head (sorted)
  csStringArray del;		// Files that should be deleted (sorted)
  csArray<ArchiveEntry*> lazy;	// Lazy operations (unsorted)

  char *filename;		// Archive file name
  // Archive file pointer.
  csRef<iFile> file;

  size_t comment_length;	// Archive comment length
  char *comment;		// Archive comment

  void ReadDirectory ();
  bool IsDeleted (const char *name) const;
  void UnpackTime (ush zdate, ush ztime, csFileTime &rtime) const;
  void PackTime (const csFileTime &ztime, ush &rdate, ush &rtime) const;
  bool ReadArchiveComment (iFile* file, size_t zipfile_comment_length);
  void LoadECDR (ZIP_end_central_dir_record &ecdr, char *buff);
  bool ReadCDFH (ZIP_central_directory_file_header &cdfh, iFile* file);
  bool ReadLFH (ZIP_local_file_header &lfh, iFile* file);
  bool WriteECDR (ZIP_end_central_dir_record &ecdr, iFile* file);
  bool WriteZipArchive ();
  bool WriteCentralDirectory (iFile* temp);
  void UpdateDirectory ();
  void ReadZipDirectory (iFile *infile);
  ArchiveEntry *InsertEntry (const char *name,
    ZIP_central_directory_file_header &cdfh);
  void ReadZipEntries (iFile* infile);
  bool ReadEntry (iFile* infile, ArchiveEntry *f, char* buf);
  ArchiveEntry *CreateArchiveEntry (const char *name,
    size_t size = 0, bool pack = true);
  void ResetArchiveEntry (ArchiveEntry *f, size_t size, bool pack);

public:
  /// Open the archive.
  csArchive (const char *filename);
  /// Close the archive.
  ~csArchive ();

  /// Type a directory listing of the archive to the console.
  void Dir () const;

  /**
   * Create a new file in the archive. If the file already exists
   * it will be overwritten.
   * 
   * Returns 0 if not succesful. Otherwise it returns a pointer
   * that can be passed to 'Write' routine. You won't see any changes
   * to archive until 'Flush' will be called.
   * 
   * 'size' is the _advisory_ file size. There is no problem if you will
   * write more or less bytes, its just a matter of performance - if you
   * set the right size, archive manager will have to allocate memory
   * only once; however if you set size to zero and then write all the
   * data in one call, it will have same performance.
   */
  void *NewFile (const char *name, size_t size = 0, bool pack = true);

  /**
   * Delete a file from the archive. You won't see any changes
   * to archive until 'Flush' will be called.
   */
  bool DeleteFile (const char *name);

  /**
   * Return true if a path exists. Also return the
   * size of the file if needed.
   */
  bool FileExists (const char *name, size_t *size = 0) const;

  /**
   * Read a file completely. After finishing with the returned
   * data you need to 'delete[]' it. If the file does not exists
   * this function returns 0. If "size" is not null, it is set
   * to unpacked size of the file.
   */
  char *Read (const char *name, size_t *size = 0);

  /**
   * Read a file completely into a buffer allocated with the given
   * allocator. If the file does not exists this function returns 0. 
   */
  template<typename Allocator>
  csPtr<iDataBuffer> Read (const char *name, Allocator& alloc)
  {
    ArchiveEntry *f = (ArchiveEntry *) FindName (name);
  
    if (!f)
      return 0;

    csRef<iDataBuffer> buf;
    buf.AttachNew (new CS::DataBuffer<Allocator> (f->info.ucsize, alloc));
    if (!ReadEntry (file, f, buf->GetData()))
      return 0;
    return csPtr<iDataBuffer> (buf);
  }

  /**
   * Read a file completely. If the file does not exists
   * this function returns 0. 
   */
  csPtr<iDataBuffer> Read (const char *name)
  {
    CS::Memory::AllocatorMalloc alloc;
    return Read (name, alloc);
  }

  /**
   * Write data to a file. Note that 'size' need not be
   * the overall file size if this was given in 'NewFile',
   * but this function will fail if the total size of written
   * data exceeds the maximum size given to 'NewFile'.
   */
  bool Write (void *entry, const char *data, size_t size);

  /**
   * Execute all pending operations involving writes to archive
   * Neither DeleteFile or NewFile will have effect until this
   * function will be called. Returns false if operation failed.
   * If operation failed, postponed operations remains in the
   * same state as before calling Flush(), i.e. for example
   * user can be prompted to free some space on drive then retry
   * Flush().
   */
  bool Flush ();

  /// Get Nth file in archive or 0
  void *GetFile (size_t no)
  { return (no < dir.GetSize ()) ? dir.Get (no) : 0; }

  /// Find a file in archive; returns a handle or 0
  void *FindName (const char *name) const;
  /// Query name from handle
  char *GetFileName (void *entry) const
  { return ((ArchiveEntry*)entry)->filename; }
  /// Query file size from handle
  size_t GetFileSize (void *entry) const
  { return ((ArchiveEntry*)entry)->info.ucsize; }
  /// Query filetime from handle
  void GetFileTime (void *entry, csFileTime &ztime) const;
  /// Set filetime for handle
  void SetFileTime (void *entry, const csFileTime &ztime);

  /// Query archive filename
  char *GetName () const
  { return filename; }
  /// Query archive comment
  char *GetComment () const
  { return comment; }
};

inline void csArchive::GetFileTime (void *entry, csFileTime &ztime) const
{
  if (entry)
  {
    UnpackTime (((ArchiveEntry*)entry)->info.last_mod_file_date,
                ((ArchiveEntry*)entry)->info.last_mod_file_time,
                ztime);
  }
}

inline void csArchive::SetFileTime (void *entry, const csFileTime &ztime)
{
  if (entry)
  {
    PackTime (ztime,
              ((ArchiveEntry*)entry)->info.last_mod_file_date,
              ((ArchiveEntry*)entry)->info.last_mod_file_time);
  }
}

#endif // __CS_ARCHIVE_H__