libmspackでキャビネットファイルを解凍する

extractでディレクトリの展開はしてくれない、と。

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>

#include <mspack.h>

static int open_cabinet_set(struct mscab_decompressor *cabd, struct mscabd_cabinet *cab) {
  struct mscabd_cabinet *c, *c2;

  for (c = cab; c && (c->flags & MSCAB_HDR_PREVCAB); c = c->prevcab) {
    if ((c2 = cabd->open(cabd, c->prevname)) == NULL) {
      return -1;
    }

    if (cabd->prepend(cabd, c, c2) != MSPACK_ERR_OK) {
      return -1;
    }
  }

  for (c = cab; c && (c->flags & MSCAB_HDR_NEXTCAB); c = c->nextcab) {
    if ((c2 = cabd->open(cabd, c->nextname)) == NULL) {
      return -1;
    }

    if (cabd->append(cabd, c, c2) != MSPACK_ERR_OK) {
      return -1;
    }
  }

  return 0;
}

static void list_cab_files( struct mscabd_cabinet *cab) {
  struct mscabd_file *file;

  for (file = cab->files; file; file = file->next) {
    printf("filename: %s\n", file->filename);
    printf("length  : %d\n", file->length);
  }
}

static int extract_cab_files(struct mscab_decompressor *cabd, struct mscabd_cabinet *cab) {
  struct mscabd_file *file;

  for (file = cab->files; file; file = file->next) {
    if (cabd->extract(cabd, file, basename(file->filename)) != MSPACK_ERR_OK) {
      return -1;
    }
  }

  return 0;
}

int main() {
  struct mscab_decompressor *cabd;
  struct mscabd_cabinet *cab;

  if ((cabd = mspack_create_cab_decompressor(NULL)) == NULL) {
    fprintf(stderr, "can't make decompressor\n");
    exit(1);
  }

  if ((cab = cabd->open(cabd, "test.cab")) == NULL) {
    fprintf(stderr, "%d\n", cabd->last_error(cabd));
    mspack_destroy_cab_decompressor(cabd);
    exit(1);
  }

  if (open_cabinet_set(cabd, cab) != 0) {
    fprintf(stderr, "%d\n", cabd->last_error(cabd));
    cabd->close(cabd, cab);
    mspack_destroy_cab_decompressor(cabd);
    exit(1);
  }

  list_cab_files(cab);
  extract_cab_files(cabd, cab);

  cabd->close(cabd, cab);
  mspack_destroy_cab_decompressor(cabd);

  return 0;
}