~ubuntu-branches/ubuntu/oneiric/cabextract/oneiric

« back to all changes in this revision

Viewing changes to mspack/cabd.c

  • Committer: Bazaar Package Importer
  • Author(s): Eric Sharkey
  • Date: 2010-08-03 23:38:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100803233856-59ewqji0uo2tic1l
Tags: 1.3-1
New upstream version: Closes: #591552

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * and usually the last folder of each cabinet extends into the next
16
16
 * cabinet.
17
17
 *
18
 
 * For a complete description of the format, get the official Microsoft
19
 
 * CAB SDK. It can be found at the following URL:
20
 
 *
21
 
 *   http://msdn.microsoft.com/library/en-us/dncabsdk/html/cabdl.asp
22
 
 *
23
 
 * It is a self-extracting ZIP file, which can be extracted with the unzip
24
 
 * command.
 
18
 * For a complete description of the format, see the MSDN site:
 
19
 *   http://msdn.microsoft.com/en-us/library/cc483132.aspx
25
20
 */
26
21
 
27
22
/* CAB decompression implementation */
28
23
 
29
24
#include <system.h>
30
25
#include <cab.h>
31
 
 
32
 
#ifndef _FILE_OFFSET_BITS
33
 
#define _FILE_OFFSET_BITS 32
34
 
#endif
35
 
#if (_FILE_OFFSET_BITS < 64)
36
 
static char *largefile_msg =
37
 
  "library not compiled to support large files.";
38
 
#define LD "ld"
39
 
#else
40
 
#define LD "lld"
41
 
#endif
 
26
#include <assert.h>
42
27
 
43
28
/* Notes on compliance with cabinet specification:
44
29
 *
704
689
        /* if off_t is only 32-bits signed, there will be overflow problems
705
690
         * with cabinets reaching past the 2GB barrier (or just claiming to)
706
691
         */
707
 
#if _FILE_OFFSET_BITS < 64
 
692
#ifndef LARGEFILE_SUPPORT
708
693
        if (cablen_u32 & ~0x7FFFFFFF) {
709
694
          sys->message(fh, largefile_msg);
710
695
          cablen_u32 = 0x7FFFFFFF;
1034
1019
    this->d->offset = 0;
1035
1020
    this->d->block  = 0;
1036
1021
    this->d->i_ptr = this->d->i_end = &this->d->input[0];
 
1022
 
 
1023
    /* read_error lasts for the lifetime of a decompressor */
 
1024
    this->read_error = MSPACK_ERR_OK;
1037
1025
  }
1038
1026
 
1039
1027
  /* open file for output */
1049
1037
    int error;
1050
1038
    /* get to correct offset.
1051
1039
     * - use NULL fh to say 'no writing' to cabd_sys_write()
1052
 
     * - MSPACK_ERR_READ returncode indicates error in cabd_sys_read(),
1053
 
     *   the real error will already be stored in this->error
 
1040
     * - if cabd_sys_read() has an error, it will set this->read_error
 
1041
     *   and pass back MSPACK_ERR_READ
1054
1042
     */
1055
1043
    this->d->outfh = NULL;
1056
1044
    if ((bytes = file->offset - this->d->offset)) {
1057
1045
      error = this->d->decompress(this->d->state, bytes);
1058
 
      if (error != MSPACK_ERR_READ) this->error = error;
 
1046
      this->error = (error == MSPACK_ERR_READ) ? this->read_error : error;
1059
1047
    }
1060
1048
 
1061
1049
    /* if getting to the correct offset was error free, unpack file */
1062
1050
    if (!this->error) {
1063
1051
      this->d->outfh = fh;
1064
1052
      error = this->d->decompress(this->d->state, (off_t) file->length);
1065
 
      if (error != MSPACK_ERR_READ) this->error = error;
 
1053
      this->error = (error == MSPACK_ERR_READ) ? this->read_error : error;
1066
1054
    }
1067
1055
  }
1068
1056
 
1087
1075
{
1088
1076
  struct mspack_file *fh = (struct mspack_file *) this;
1089
1077
 
1090
 
  if (!this || !this->d) {
1091
 
    return this->error = MSPACK_ERR_ARGS;
1092
 
  }
 
1078
  assert(this && this->d);
1093
1079
 
1094
1080
  /* free any existing decompressor */
1095
1081
  cabd_free_decomp(this);
1176
1162
 
1177
1163
      /* check if we're out of input blocks, advance block counter */
1178
1164
      if (this->d->block++ >= this->d->folder->base.num_blocks) {
1179
 
        this->error = MSPACK_ERR_DATAFORMAT;
 
1165
        this->read_error = MSPACK_ERR_DATAFORMAT;
1180
1166
        break;
1181
1167
      }
1182
1168
 
1183
1169
      /* read a block */
1184
 
      this->error = cabd_sys_read_block(sys, this->d, &outlen, ignore_cksum);
1185
 
      if (this->error) return -1;
 
1170
      this->read_error = cabd_sys_read_block(sys, this->d, &outlen, ignore_cksum);
 
1171
      if (this->read_error) return -1;
1186
1172
 
1187
1173
      /* special Quantum hack -- trailer byte to allow the decompressor
1188
1174
       * to realign itself. CAB Quantum blocks, unlike LZX blocks, can have