root/tools/perf/util/lzma.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lzma_strerror
  2. lzma_decompress_to_file
  3. lzma_is_compressed

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <errno.h>
   3 #include <lzma.h>
   4 #include <stdio.h>
   5 #include <linux/compiler.h>
   6 #include <sys/types.h>
   7 #include <sys/stat.h>
   8 #include <fcntl.h>
   9 #include "compress.h"
  10 #include "debug.h"
  11 #include <string.h>
  12 #include <unistd.h>
  13 #include <internal/lib.h>
  14 
  15 #define BUFSIZE 8192
  16 
  17 static const char *lzma_strerror(lzma_ret ret)
  18 {
  19         switch ((int) ret) {
  20         case LZMA_MEM_ERROR:
  21                 return "Memory allocation failed";
  22         case LZMA_OPTIONS_ERROR:
  23                 return "Unsupported decompressor flags";
  24         case LZMA_FORMAT_ERROR:
  25                 return "The input is not in the .xz format";
  26         case LZMA_DATA_ERROR:
  27                 return "Compressed file is corrupt";
  28         case LZMA_BUF_ERROR:
  29                 return "Compressed file is truncated or otherwise corrupt";
  30         default:
  31                 return "Unknown error, possibly a bug";
  32         }
  33 }
  34 
  35 int lzma_decompress_to_file(const char *input, int output_fd)
  36 {
  37         lzma_action action = LZMA_RUN;
  38         lzma_stream strm   = LZMA_STREAM_INIT;
  39         lzma_ret ret;
  40         int err = -1;
  41 
  42         u8 buf_in[BUFSIZE];
  43         u8 buf_out[BUFSIZE];
  44         FILE *infile;
  45 
  46         infile = fopen(input, "rb");
  47         if (!infile) {
  48                 pr_err("lzma: fopen failed on %s: '%s'\n",
  49                        input, strerror(errno));
  50                 return -1;
  51         }
  52 
  53         ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
  54         if (ret != LZMA_OK) {
  55                 pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
  56                         lzma_strerror(ret), ret);
  57                 goto err_fclose;
  58         }
  59 
  60         strm.next_in   = NULL;
  61         strm.avail_in  = 0;
  62         strm.next_out  = buf_out;
  63         strm.avail_out = sizeof(buf_out);
  64 
  65         while (1) {
  66                 if (strm.avail_in == 0 && !feof(infile)) {
  67                         strm.next_in  = buf_in;
  68                         strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
  69 
  70                         if (ferror(infile)) {
  71                                 pr_err("lzma: read error: %s\n", strerror(errno));
  72                                 goto err_fclose;
  73                         }
  74 
  75                         if (feof(infile))
  76                                 action = LZMA_FINISH;
  77                 }
  78 
  79                 ret = lzma_code(&strm, action);
  80 
  81                 if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
  82                         ssize_t write_size = sizeof(buf_out) - strm.avail_out;
  83 
  84                         if (writen(output_fd, buf_out, write_size) != write_size) {
  85                                 pr_err("lzma: write error: %s\n", strerror(errno));
  86                                 goto err_fclose;
  87                         }
  88 
  89                         strm.next_out  = buf_out;
  90                         strm.avail_out = sizeof(buf_out);
  91                 }
  92 
  93                 if (ret != LZMA_OK) {
  94                         if (ret == LZMA_STREAM_END)
  95                                 break;
  96 
  97                         pr_err("lzma: failed %s\n", lzma_strerror(ret));
  98                         goto err_fclose;
  99                 }
 100         }
 101 
 102         err = 0;
 103 err_fclose:
 104         fclose(infile);
 105         return err;
 106 }
 107 
 108 bool lzma_is_compressed(const char *input)
 109 {
 110         int fd = open(input, O_RDONLY);
 111         const uint8_t magic[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
 112         char buf[6] = { 0 };
 113         ssize_t rc;
 114 
 115         if (fd < 0)
 116                 return -1;
 117 
 118         rc = read(fd, buf, sizeof(buf));
 119         close(fd);
 120         return rc == sizeof(buf) ?
 121                memcmp(buf, magic, sizeof(buf)) == 0 : false;
 122 }

/* [<][>][^][v][top][bottom][index][help] */