Correct added language file: add to sources and set keywords
[maemo-rb.git] / tools / mi4.c
bloba76308cc8f87c2d5b08856093a2ca470256dbb32
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Dave Chapman
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
25 * CRC32 implementation taken from:
27 * efone - Distributed internet phone system.
29 * (c) 1999,2000 Krzysztof Dabrowski
30 * (c) 1999,2000 ElysiuM deeZine
32 * This program is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU General Public License
34 * as published by the Free Software Foundation; either version
35 * 2 of the License, or (at your option) any later version.
39 /* based on implementation by Finn Yannick Jacobs */
41 #include <stdio.h>
42 #include <stdlib.h>
44 /* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
45 * so make sure, you call it before using the other
46 * functions!
48 static unsigned int crc_tab[256];
50 /* chksum_crc() -- to a given block, this one calculates the
51 * crc32-checksum until the length is
52 * reached. the crc32-checksum will be
53 * the result.
55 static unsigned int chksum_crc32 (unsigned char *block, unsigned int length)
57 register unsigned long crc;
58 unsigned long i;
60 crc = 0;
61 for (i = 0; i < length; i++)
63 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *block++) & 0xFF];
65 return (crc);
68 /* chksum_crc32gentab() -- to a global crc_tab[256], this one will
69 * calculate the crcTable for crc32-checksums.
70 * it is generated to the polynom [..]
73 static void chksum_crc32gentab (void)
75 unsigned long crc, poly;
76 int i, j;
78 poly = 0xEDB88320L;
79 for (i = 0; i < 256; i++)
81 crc = i;
82 for (j = 8; j > 0; j--)
84 if (crc & 1)
86 crc = (crc >> 1) ^ poly;
88 else
90 crc >>= 1;
93 crc_tab[i] = crc;
97 static void int2le(unsigned int val, unsigned char* addr)
99 addr[0] = val & 0xFF;
100 addr[1] = (val >> 8) & 0xff;
101 addr[2] = (val >> 16) & 0xff;
102 addr[3] = (val >> 24) & 0xff;
105 int mi4_encode(char *iname, char *oname, int version, int magic,
106 char *model, char *type)
108 size_t len;
109 int length;
110 int mi4length;
111 FILE *file;
112 unsigned int crc = 0;
113 unsigned char *outbuf;
115 file = fopen(iname, "rb");
116 if (!file) {
117 perror(iname);
118 return -1;
120 fseek(file,0,SEEK_END);
121 length = ftell(file);
123 fseek(file,0,SEEK_SET);
125 /* Add 4 bytes to length (for magic), the 0x200 byte header and
126 then round to an even 0x400 bytes
128 mi4length = (length+4+0x200+0x3ff)&~0x3ff;
130 outbuf = malloc(mi4length);
132 if ( !outbuf ) {
133 printf("out of memory!\n");
134 return -1;
137 /* Clear the buffer to zero */
138 memset(outbuf, 0, mi4length);
140 len = fread(outbuf+0x200, 1, length, file);
141 if(len < length) {
142 perror(iname);
143 return -2;
145 fclose(file);
147 /* We need to write some data into the actual image - before calculating
148 the CRC. */
149 int2le(0x00000100, &outbuf[0x2e0]); /* magic */
150 int2le(magic, &outbuf[0x2e4]); /* magic */
151 int2le(length+4, &outbuf[0x2e8]); /* length plus 0xaa55aa55 */
153 int2le(0xaa55aa55, &outbuf[0x200+length]); /* More Magic */
155 strncpy((char *)outbuf+0x1f8, type, 4); /* type of binary (RBBL, RBOS) */
156 strncpy((char *)outbuf+0x1fc, model, 4); /* 4 character model id */
158 /* Calculate CRC32 checksum */
159 chksum_crc32gentab ();
160 crc = chksum_crc32 (outbuf+0x200,mi4length-0x200);
162 strncpy((char *)outbuf, "PPOS", 4); /* Magic */
163 int2le(version, &outbuf[0x04]); /* .mi4 version */
164 int2le(length+4, &outbuf[0x08]); /* Length of firmware plus magic */
165 int2le(crc, &outbuf[0x0c]); /* CRC32 of mi4 file */
166 int2le(0x00000002, &outbuf[0x10]); /* Encryption type: 2 = TEA */
167 int2le(mi4length, &outbuf[0x14]); /* Total .mi4 length */
168 int2le(mi4length-0x200, &outbuf[0x18]); /* Length of plaintext part */
170 /* v3 files require a dummy DSA signature */
171 if (version == 0x00010301) {
172 outbuf[0x2f]=0x01;
175 file = fopen(oname, "wb");
176 if (!file) {
177 perror(oname);
178 return -3;
181 len = fwrite(outbuf, 1, mi4length, file);
182 if(len < length) {
183 perror(oname);
184 return -4;
187 fclose(file);
189 fprintf(stderr, "File encoded successfully\n" );
191 return 0;