summaryrefslogtreecommitdiffstats
path: root/libk3b/tools/k3biso9660.h
blob: c25ef48d207b4e8a52ed4dec2bc20399237df763 (plain)
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/* 
 *
 * $Id: k3biso9660.h 619556 2007-01-03 17:38:12Z trueg $
 * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org>
 *
 * This file is part of the K3b project.
 * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * See the file "COPYING" for the exact licensing terms.
 */


#ifndef _K3B_ISO9660_H_
#define _K3B_ISO9660_H_

#include <sys/stat.h>
#include <sys/types.h>

#include <tqdatetime.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqdict.h>

#include "k3b_export.h"


namespace K3bDevice {
  class Device;
}

class K3bIso9660;
class K3bIso9660Backend;
struct iso_directory_record;
struct el_torito_boot_descriptor;
struct iso_primary_descriptor;

typedef long long sector_t;



/**
 * Simplyfied primary descriptor which just contains the fields
 * used by K3b.
 */
class LIBK3B_EXPORT K3bIso9660SimplePrimaryDescriptor
{
 public:
  /**
   * Creates an empty descriptor
   */
  K3bIso9660SimplePrimaryDescriptor();

  TQString volumeId;
  TQString systemId;
  TQString volumeSetId;
  TQString publisherId;
  TQString preparerId;
  TQString applicationId;
  int volumeSetSize;
  int volumeSetNumber;
  long logicalBlockSize;
  long long volumeSpaceSize;
};


LIBK3B_EXPORT bool operator==( const K3bIso9660SimplePrimaryDescriptor& d1,
			       const K3bIso9660SimplePrimaryDescriptor& d2 );
LIBK3B_EXPORT bool operator!=( const K3bIso9660SimplePrimaryDescriptor& d1,
			       const K3bIso9660SimplePrimaryDescriptor& d2 );


/**
 * Base class for all entries in a K3bIso9660 archive. A lot has been copied
 * from KArchive.
 */
class LIBK3B_EXPORT K3bIso9660Entry
{
 public:
  K3bIso9660Entry( K3bIso9660* archive,
		   const TQString& isoName,
		   const TQString& name,
		   int access,
		   int date,
		   int adate,
		   int cdate, 
		   const TQString& user,
		   const TQString& group,
		   const TQString& symlink );
  virtual ~K3bIso9660Entry();

  int adate() const { return m_adate; }
  int cdate() const { return m_cdate; }

  /**
   * Creation date of the file.
   * @return the creation date
   */
  TQDateTime datetime() const;

  /**
   * Creation date of the file.
   * @return the creation date in seconds since 1970
   */
  int date() const { return m_date; }

  /**
   * Name of the file without path.
   * @return The file name without path.
   */
  const TQString& name() const { return m_name; }

  /**
   * \return The raw name as saved in the ISO9660 tree
   */
  const TQString& isoName() const { return m_isoName; }

  /**
   * The permissions and mode flags as returned by the stat() function
   * in st_mode.
   * @return the permissions
   */
  mode_t permissions() const { return m_access; }

  /**
   * User who created the file.
   * @return the owner of the file
   */
  const TQString& user() const { return m_user; }

  /**
   * Group of the user who created the file.
   * @return the group of the file
   */
  const TQString& group() const { return m_group; }

  /**
   * Symlink if there is one.
   * @return the symlink, or TQString()
   */
  const TQString& symlink() const { return m_symlink; }

  /**
   * Checks whether the entry is a file.
   * @return true if this entry is a file
   */
  virtual bool isFile() const { return false; }

  /**
   * Checks whether the entry is a directory.
   * @return true if this entry is a directory
   */
  virtual bool isDirectory() const { return false; }

  K3bIso9660* archive() const { return m_archive; }

 private:
  int m_adate;
  int m_cdate;
  TQString m_name;
  TQString m_isoName;
  int m_date;
  mode_t m_access;
  TQString m_user;
  TQString m_group;
  TQString m_symlink;
  K3bIso9660* m_archive;
};


class LIBK3B_EXPORT K3bIso9660Directory : public K3bIso9660Entry
{
 public: 
  K3bIso9660Directory( K3bIso9660* archive, 
		       const TQString& isoName,
		       const TQString& name, 
		       int access, 
		       int date,
		       int adate,
		       int cdate, 
		       const TQString& user,
		       const TQString& group,
		       const TQString& symlink,
		       unsigned int pos = 0, 
		       unsigned int size = 0 );
  ~K3bIso9660Directory();

  /**
   * Returns a list of sub-entries.
   * @return the names of all entries in this directory (filenames, no path).
   */
  TQStringList entries() const;

  /**
   * Returns the entry with the given name.
   * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc.
   * @return a pointer to the entry in the directory.
   */
  K3bIso9660Entry* entry( const TQString& name );

  /**
   * Returns the entry with the given name.
   * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc.
   * @return a pointer to the entry in the directory.
   */
  const K3bIso9660Entry* entry( const TQString& name ) const;

  /**
   * Returns a list of sub-entries.
   * Searches for Iso9660 names.
   * @return the names of all entries in this directory (filenames, no path).
   */
  TQStringList iso9660Entries() const;

  /**
   * Returns the entry with the given name.
   * Searches for Iso9660 names.
   * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc.
   * @return a pointer to the entry in the directory.
   */
  K3bIso9660Entry* iso9660Entry( const TQString& name );

  /**
   * Returns the entry with the given name.
   * Searches for Iso9660 names.
   * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc.
   * @return a pointer to the entry in the directory.
   */
  const K3bIso9660Entry* iso9660Entry( const TQString& name ) const;

  /**
   * @internal
   * Adds a new entry to the directory.
   */
  void addEntry( K3bIso9660Entry* );

  /**
   * Checks whether this entry is a directory.
   * @return true, since this entry is a directory
   */
  bool isDirectory() const { return true; }

 private:
  void expand();

  TQDict<K3bIso9660Entry> m_entries;
  TQDict<K3bIso9660Entry> m_iso9660Entries;

  bool m_bExpanded;
  unsigned int m_startSector;
  unsigned int m_size;
};


class LIBK3B_EXPORT K3bIso9660File : public K3bIso9660Entry
{
 public: 
  /**
   * @param pos start sector
   */
  K3bIso9660File( K3bIso9660* archive, 
		  const TQString& isoName,
		  const TQString& name, 
		  int access, 
		  int date,
		  int adate,
		  int cdate, 
		  const TQString& user, 
		  const TQString& group,
		  const TQString& symlink, 
		  unsigned int pos, 
		  unsigned int size );
  ~K3bIso9660File();

  bool isFile() const { return true; }

  void setZF( char algo[2], char parms[2], int realsize );
  int realsize() const { return m_realsize; }

  /**
   * @return size in bytes.
   */
  unsigned int size() const { return m_size; }

  /**
   * Returnes the startSector of the file.
   */
  unsigned int startSector() const { return m_startSector; }

  /**
   * Returnes the startOffset of the file in bytes.
   */
  unsigned long long startPostion() const { return (unsigned long long)m_startSector * 2048; }

  /**
   * @param pos offset in bytes
   * @param len max number of bytes to read
   */
  int read( unsigned int pos, char* data, int len ) const;

  /**
   * Copy this file to a url.
   */
  bool copyTo( const TQString& url ) const;

 private:
  char m_algo[2];
  char m_parms[2];
  int m_realsize;

  unsigned int m_curpos;
  unsigned int m_startSector;
  unsigned int m_size;
};


/**
 * This class is based on the KIso class by
 * Gy�gy Szombathelyi <gyurco@users.sourceforge.net>.
 * A lot has been changed and bugfixed.
 * The API has been improved to be useful.
 *
 * Due to the stupid TQt which does not support large files as default
 * we cannot use TQIODevice with DVDs! That's why we have our own 
 * reading code which is not allowed by KArchive (which is limited to int
 * by the way... who the hell designed this?)
 * I also removed the KArchive inheritance because of the named reasons.
 * So this stuff contains a lot KArchive code which has been made usable.
 *
 * That does not mean that this class is well designed. No, it's not. :)
 *
 * Opening a K3bIso9660 object should be fast since creation of the directory 
 * and file entries is not done until a call to K3bIso9660Directory::entries.
*/
class LIBK3B_EXPORT K3bIso9660
{
 public:
  /**
   * Creates an instance that operates on the given filename.
   * using the compression filter associated to given mimetype.
   *
   * @param filename is a local path (e.g. "/home/weis/myfile.tgz")
   */
  K3bIso9660( const TQString& filename );

  /**
   * Special case which always reads the TOC from the specified sector
   * thus supporting multisession CDs.
   */
  K3bIso9660( K3bDevice::Device* dev, unsigned int startSector = 0 );

  /**
   * @param fd open file descriptor
   */
  K3bIso9660( int fd );

  /**
   * Directly specify the backend to read from.
   * K3bIso9660 will take ownership of the backend and delete it.
   */
  K3bIso9660( K3bIso9660Backend* );

  /**
   * If the .iso is still opened, then it will be
   * closed automatically by the destructor.
   */
  virtual ~K3bIso9660();

  /**
   * Set where to start reading in the source.
   */
  void setStartSector( unsigned int startSector );

  /**
   * If set to true before opening K3bIso9660 will ignore RR and joliet extensions
   * and only create plain iso9660 names.
   */
  void setPlainIso9660( bool );

  bool plainIso9660() const;

  /**
   * Opens the archive for reading.
   * Parses the directory listing of the archive
   * and creates the K3bIso9660Directory/K3bIso9660File entries.
   */
  bool open();

  bool isOpen() const;

  /**
   * Closes everything.
   * This is also called in the destructor
   */
  void close();

  /**
   * @param sector startsector
   * @param len number of sectors
   * @return number of sectors read or -1 on error
   */
  int read( unsigned int sector, char* data, int len );

  /**
   * The name of the os file, as passed to the constructor
   * Null if you did not use the TQString constructor.
   */
  const TQString& fileName() { return m_filename; }

  const K3bIso9660Directory* firstJolietDirEntry() const;
  const K3bIso9660Directory* firstRRDirEntry() const;
  const K3bIso9660Directory* firstIsoDirEntry() const;
  const K3bIso9660Directory* firstElToritoEntry() const;

  /**
   * @returns 0 if no joliet desc could be found
   *          the joliet level (1-3) otherwise
   */
  int jolietLevel() const { return m_joliet; }

  const K3bIso9660SimplePrimaryDescriptor& primaryDescriptor() const;

  void debug() const;

 private:
  /**
   * @internal
   */
  void addBoot( struct el_torito_boot_descriptor* bootdesc );
  void createSimplePrimaryDesc( struct iso_primary_descriptor* desc );

  void debugEntry( const K3bIso9660Entry*, int depth ) const;

  int m_joliet;

  // only used for creation
  static int read_callback( char* buf, sector_t start, long long len, void* udata );
  static int isofs_callback( struct iso_directory_record* idr, void *udata );
  K3bIso9660Directory *dirent;
  bool m_rr;
  friend class K3bIso9660Directory;
  
 private:
  TQString m_filename;

  class Private;
  Private * d;
};

#endif