blob: 31abef0d9fb934652f9ea79e3e28ded596160543 [file] [log] [blame]
Luc Verhaegen1646a412009-06-16 08:22:14 +02001/*
2 * Copyright 2009 Luc Verhaegen <libv@skynet.be>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/*
20 * Test/Example code for LH5 extraction.
21 */
22
23#include <stdio.h>
24#include <errno.h>
25#include <string.h>
26#include <stdlib.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <sys/mman.h>
30#include <sys/stat.h>
31
32#include "lh5_extract.h"
33
34int
35main(int argc, char *argv[])
36{
37 char *filename;
38 unsigned short header_crc;
39 unsigned int header_size, original_size, packed_size;
40 int infd, outfd;
41 int LHABufferSize = 0;
42 unsigned char *LHABuffer, *OutBuffer;
43
44 if (argc != 2) {
45 fprintf(stderr, "Error: archive file not specified\n");
46 return 1;
47 }
48
49 /* open archive file */
50 infd = open(argv[1], O_RDONLY);
51 if (infd == -1) {
52 fprintf(stderr, "Error: Failed to open \"%s\": %s\n",
53 argv[1], strerror(errno));
54 return 1;
55 }
56
57 LHABufferSize = lseek(infd, 0, SEEK_END);
58 if (LHABufferSize < 0) {
59 fprintf(stderr, "Error: Failed to lseek \"%s\": %s\n",
60 argv[1], strerror(errno));
61 return 1;
62 }
63
64 LHABuffer = mmap(NULL, LHABufferSize, PROT_READ, MAP_PRIVATE, infd, 0);
65 if (LHABuffer == ((void *) -1)) {
66 fprintf(stderr, "Error: Failed to mmap %s: %s\n",
67 argv[1], strerror(errno));
68 return 1;
69 }
70
71 header_size = LH5HeaderParse(LHABuffer, LHABufferSize, &original_size,
72 &packed_size, &filename, &header_crc);
73 if (!header_size)
74 return 1;
75
76 if ((header_size + packed_size) < LHABufferSize) {
77 fprintf(stderr, "Error: LHA archive is bigger than \"%s\".\n",
78 argv[1]);
79 return 1;
80 }
81
82 outfd = open(filename, O_RDWR | O_TRUNC | O_CREAT, S_IRWXU);
83 if (outfd == -1) {
84 fprintf(stderr, "Error: Failed to open \"%s\": %s\n",
85 filename, strerror(errno));
86 return 1;
87 }
88
89 /* grow file */
90 if (lseek(outfd, original_size - 1, SEEK_SET) == -1) {
91 fprintf(stderr, "Error: Failed to grow \"%s\": %s\n",
92 filename, strerror(errno));
93 return 1;
94 }
95
96 if (write(outfd, "", 1) != 1) {
97 fprintf(stderr, "Error: Failed to write to \"%s\": %s\n",
98 filename, strerror(errno));
99 return 1;
100 }
101
102 OutBuffer = mmap(NULL, original_size, PROT_READ | PROT_WRITE, MAP_SHARED, outfd, 0);
103 if (OutBuffer == ((void *) -1)) {
104 fprintf(stderr, "Error: Failed to mmap %s: %s\n",
105 filename, strerror(errno));
106 return 1;
107 }
108
109 LH5Decode(LHABuffer + header_size, packed_size, OutBuffer, original_size);
110
111 if (CRC16Calculate(OutBuffer, original_size) != header_crc) {
112 fprintf(stderr, "Warning: invalid CRC on \"%s\"\n", filename);
113 return 1;
114 }
115
116 if (munmap(OutBuffer, original_size))
117 fprintf(stderr, "Warning: Failed to munmap \"%s\": %s\n",
118 filename, strerror(errno));
119
120 if (close(outfd))
121 fprintf(stderr, "Warning: Failed to close \"%s\": %s\n",
122 filename, strerror(errno));
123
124 free(filename);
125
126 /* get rid of our input file */
127 if (munmap(LHABuffer, LHABufferSize))
128 fprintf(stderr, "Warning: Failed to munmap \"%s\": %s\n",
129 argv[1], strerror(errno));
130
131 if (close(infd))
132 fprintf(stderr, "Warning: Failed to close \"%s\": %s\n",
133 argv[1], strerror(errno));
134
135 return 0;
136}