• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/lzma2eva.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3     lzma2eva - convert lzma-compressed file to AVM EVA bootloader format
  4     Copyright (C) 2007  Enrik Berkhan <Enrik.Berkhan@inka.de>
  5 */
  6 
  7 #include <stdint.h>
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <zlib.h> /* crc32 */
 11 
 12 #define checksum_add32(csum, data) \
 13   csum += ((uint8_t *)&data)[0]; \
 14   csum += ((uint8_t *)&data)[1]; \
 15   csum += ((uint8_t *)&data)[2]; \
 16   csum += ((uint8_t *)&data)[3];
 17 
 18 void
 19 usage(void)
 20 {
 21   fprintf(stderr, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n");
 22   exit(1);
 23 }
 24 
 25 void
 26 pexit(const char *msg)
 27 {
 28   perror(msg);
 29   exit(1);
 30 }
 31 
 32 int
 33 main(int argc, char *argv[])
 34 {
 35 
 36   const char *infile, *outfile;
 37   FILE *in, *out;
 38   static uint8_t buf[4096];
 39   size_t elems;
 40 
 41   uint8_t properties;
 42   uint32_t dictsize;
 43   uint64_t datasize;
 44 
 45   uint32_t magic = 0xfeed1281L;
 46   uint32_t reclength = 0;
 47   fpos_t reclengthpos;
 48   uint32_t loadaddress = 0;
 49   uint32_t type = 0x075a0201L; /* might be 7Z 2.1? */
 50   uint32_t checksum = 0;
 51 
 52   uint32_t compsize = 0;
 53   fpos_t compsizepos;
 54   uint32_t datasize32 = 0;
 55   uint32_t datacrc32 = crc32(0, 0, 0);
 56 
 57   uint32_t zero = 0;
 58   uint32_t entry = 0;
 59 
 60   if (argc != 5)
 61     usage();
 62 
 63   /* "parse" command line */
 64   loadaddress = strtoul(argv[1], 0, 0);
 65   entry = strtoul(argv[2], 0, 0);
 66   infile = argv[3];
 67   outfile = argv[4];
 68 
 69   in = fopen(infile, "rb");
 70   if (!in)
 71     pexit("fopen");
 72   out = fopen(outfile, "w+b");
 73   if (!out)
 74     pexit("fopen");
 75 
 76   /* read LZMA header */
 77   if (1 != fread(&properties, sizeof properties, 1, in))
 78     pexit("fread");
 79   if (1 != fread(&dictsize, sizeof dictsize, 1, in))
 80     pexit("fread");
 81   if (1 != fread(&datasize, sizeof datasize, 1, in))
 82     pexit("fread");
 83 
 84   /* write EVA header */
 85   if (1 != fwrite(&magic, sizeof magic, 1, out))
 86     pexit("fwrite");
 87   if (fgetpos(out, &reclengthpos))
 88     pexit("fgetpos");
 89   if (1 != fwrite(&reclength, sizeof reclength, 1, out))
 90     pexit("fwrite");
 91   if (1 != fwrite(&loadaddress, sizeof loadaddress, 1, out))
 92     pexit("fwrite");
 93   if (1 != fwrite(&type, sizeof type, 1, out))
 94     pexit("fwrite");
 95 
 96   /* write EVA LZMA header */
 97   if (fgetpos(out, &compsizepos))
 98     pexit("fgetpos");
 99   if (1 != fwrite(&compsize, sizeof compsize, 1, out))
100     pexit("fwrite");
101   /* XXX check length */
102   datasize32 = (uint32_t)datasize;
103   if (1 != fwrite(&datasize32, sizeof datasize32, 1, out))
104     pexit("fwrite");
105   if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out))
106     pexit("fwrite");
107 
108   /* write modified LZMA header */
109   if (1 != fwrite(&properties, sizeof properties, 1, out))
110     pexit("fwrite");
111   if (1 != fwrite(&dictsize, sizeof dictsize, 1, out))
112     pexit("fwrite");
113   if (1 != fwrite(&zero, 3, 1, out))
114     pexit("fwrite");
115 
116   /* copy compressed data, calculate crc32 */
117   while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, in))) {
118     compsize += elems;
119     if (elems != fwrite(&buf, sizeof buf[0], elems, out))
120       pexit("fwrite");
121     datacrc32 = crc32(datacrc32, buf, elems);
122   }
123   if (ferror(in))
124     pexit("fread");
125   fclose(in);
126 
127   /* re-write record length */
128   reclength = compsize + 24;
129   if (fsetpos(out, &reclengthpos))
130     pexit("fsetpos");
131   if (1 != fwrite(&reclength, sizeof reclength, 1, out))
132     pexit("fwrite");
133 
134   /* re-write EVA LZMA header including size and data crc */
135   if (fsetpos(out, &compsizepos))
136     pexit("fsetpos");
137   if (1 != fwrite(&compsize, sizeof compsize, 1, out))
138     pexit("fwrite");
139   if (1 != fwrite(&datasize32, sizeof datasize32, 1, out))
140     pexit("fwrite");
141   if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out))
142     pexit("fwrite");
143 
144   /* calculate record checksum */
145   checksum += reclength;
146   checksum += loadaddress;
147   checksum_add32(checksum, type);
148   checksum_add32(checksum, compsize);
149   checksum_add32(checksum, datasize32);
150   checksum_add32(checksum, datacrc32);
151   if (fseek(out, 0, SEEK_CUR))
152     pexit("fseek");
153   while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, out))) {
154     size_t i;
155     for (i = 0; i < elems; ++i)
156       checksum += buf[i];
157   }
158   if (ferror(out))
159     pexit("fread");
160   if (fseek(out, 0, SEEK_CUR))
161     pexit("fseek");
162 
163   checksum = ~checksum + 1;
164   if (1 != fwrite(&checksum, sizeof checksum, 1, out))
165     pexit("fwrite");
166 
167   /* write entry record */
168   if (1 != fwrite(&zero, sizeof zero, 1, out))
169     pexit("fwrite");
170   if (1 != fwrite(&entry, sizeof entry, 1, out))
171     pexit("fwrite");
172 
173   if (fclose(out))
174     pexit("fclose");
175 
176   return 0;
177 }
178 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt