1
1
// SPDX-License-Identifier: GPL-2.0
2
2
#include <stdio.h>
3
3
#include <stdlib.h>
4
+ #include <stdint.h>
5
+ #include <stdbool.h>
4
6
#include <sys/types.h>
5
7
#include <sys/stat.h>
6
8
#include <string.h>
25
27
static unsigned int offset ;
26
28
static unsigned int ino = 721 ;
27
29
static time_t default_mtime ;
30
+ static bool do_csum = false;
28
31
29
32
struct file_handler {
30
33
const char * type ;
@@ -78,7 +81,7 @@ static void cpio_trailer(void)
78
81
79
82
sprintf (s , "%s%08X%08X%08lX%08lX%08X%08lX"
80
83
"%08X%08X%08X%08X%08X%08X%08X" ,
81
- " 070701" , /* magic */
84
+ do_csum ? "070702" : " 070701" , /* magic */
82
85
0 , /* ino */
83
86
0 , /* mode */
84
87
(long ) 0 , /* uid */
@@ -110,7 +113,7 @@ static int cpio_mkslink(const char *name, const char *target,
110
113
name ++ ;
111
114
sprintf (s ,"%s%08X%08X%08lX%08lX%08X%08lX"
112
115
"%08X%08X%08X%08X%08X%08X%08X" ,
113
- " 070701" , /* magic */
116
+ do_csum ? "070702" : " 070701" , /* magic */
114
117
ino ++ , /* ino */
115
118
S_IFLNK | mode , /* mode */
116
119
(long ) uid , /* uid */
@@ -159,7 +162,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
159
162
name ++ ;
160
163
sprintf (s ,"%s%08X%08X%08lX%08lX%08X%08lX"
161
164
"%08X%08X%08X%08X%08X%08X%08X" ,
162
- " 070701" , /* magic */
165
+ do_csum ? "070702" : " 070701" , /* magic */
163
166
ino ++ , /* ino */
164
167
mode , /* mode */
165
168
(long ) uid , /* uid */
@@ -253,7 +256,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
253
256
name ++ ;
254
257
sprintf (s ,"%s%08X%08X%08lX%08lX%08X%08lX"
255
258
"%08X%08X%08X%08X%08X%08X%08X" ,
256
- " 070701" , /* magic */
259
+ do_csum ? "070702" : " 070701" , /* magic */
257
260
ino ++ , /* ino */
258
261
mode , /* mode */
259
262
(long ) uid , /* uid */
@@ -293,6 +296,29 @@ static int cpio_mknod_line(const char *line)
293
296
return rc ;
294
297
}
295
298
299
+ static int cpio_mkfile_csum (int fd , unsigned long size , uint32_t * csum )
300
+ {
301
+ while (size ) {
302
+ unsigned char filebuf [65536 ];
303
+ ssize_t this_read ;
304
+ size_t i , this_size = MIN (size , sizeof (filebuf ));
305
+
306
+ this_read = read (fd , filebuf , this_size );
307
+ if (this_read <= 0 || this_read > this_size )
308
+ return -1 ;
309
+
310
+ for (i = 0 ; i < this_read ; i ++ )
311
+ * csum += filebuf [i ];
312
+
313
+ size -= this_read ;
314
+ }
315
+ /* seek back to the start for data segment I/O */
316
+ if (lseek (fd , 0 , SEEK_SET ) < 0 )
317
+ return -1 ;
318
+
319
+ return 0 ;
320
+ }
321
+
296
322
static int cpio_mkfile (const char * name , const char * location ,
297
323
unsigned int mode , uid_t uid , gid_t gid ,
298
324
unsigned int nlinks )
@@ -305,6 +331,7 @@ static int cpio_mkfile(const char *name, const char *location,
305
331
int rc = -1 ;
306
332
int namesize ;
307
333
unsigned int i ;
334
+ uint32_t csum = 0 ;
308
335
309
336
mode |= S_IFREG ;
310
337
@@ -332,6 +359,11 @@ static int cpio_mkfile(const char *name, const char *location,
332
359
goto error ;
333
360
}
334
361
362
+ if (do_csum && cpio_mkfile_csum (file , buf .st_size , & csum ) < 0 ) {
363
+ fprintf (stderr , "Failed to checksum file %s\n" , location );
364
+ goto error ;
365
+ }
366
+
335
367
size = 0 ;
336
368
for (i = 1 ; i <= nlinks ; i ++ ) {
337
369
/* data goes on last link */
@@ -343,7 +375,7 @@ static int cpio_mkfile(const char *name, const char *location,
343
375
namesize = strlen (name ) + 1 ;
344
376
sprintf (s ,"%s%08X%08X%08lX%08lX%08X%08lX"
345
377
"%08lX%08X%08X%08X%08X%08X%08X" ,
346
- " 070701" , /* magic */
378
+ do_csum ? "070702" : " 070701" , /* magic */
347
379
ino , /* ino */
348
380
mode , /* mode */
349
381
(long ) uid , /* uid */
@@ -356,7 +388,7 @@ static int cpio_mkfile(const char *name, const char *location,
356
388
0 , /* rmajor */
357
389
0 , /* rminor */
358
390
namesize , /* namesize */
359
- 0 ); /* chksum */
391
+ size ? csum : 0 ); /* chksum */
360
392
push_hdr (s );
361
393
push_string (name );
362
394
push_pad ();
@@ -464,7 +496,7 @@ static int cpio_mkfile_line(const char *line)
464
496
static void usage (const char * prog )
465
497
{
466
498
fprintf (stderr , "Usage:\n"
467
- "\t%s [-t <timestamp>] <cpio_list>\n"
499
+ "\t%s [-t <timestamp>] [-c] <cpio_list>\n"
468
500
"\n"
469
501
"<cpio_list> is a file containing newline separated entries that\n"
470
502
"describe the files to be included in the initramfs archive:\n"
@@ -499,7 +531,8 @@ static void usage(const char *prog)
499
531
"\n"
500
532
"<timestamp> is time in seconds since Epoch that will be used\n"
501
533
"as mtime for symlinks, special files and directories. The default\n"
502
- "is to use the current time for these entries.\n" ,
534
+ "is to use the current time for these entries.\n"
535
+ "-c: calculate and store 32-bit checksums for file data.\n" ,
503
536
prog );
504
537
}
505
538
@@ -541,7 +574,7 @@ int main (int argc, char *argv[])
541
574
542
575
default_mtime = time (NULL );
543
576
while (1 ) {
544
- int opt = getopt (argc , argv , "t:h " );
577
+ int opt = getopt (argc , argv , "t:ch " );
545
578
char * invalid ;
546
579
547
580
if (opt == -1 )
@@ -556,6 +589,9 @@ int main (int argc, char *argv[])
556
589
exit (1 );
557
590
}
558
591
break ;
592
+ case 'c' :
593
+ do_csum = true;
594
+ break ;
559
595
case 'h' :
560
596
case '?' :
561
597
usage (argv [0 ]);
0 commit comments