123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <compiler.h>
- #define CHECKSUM_OFFSET (14*1024-4)
- #define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \
- | S_IWGRP | S_IROTH | S_IWOTH)
- struct var_size_header {
- uint32_t spl_size;
- uint32_t spl_checksum;
- uint32_t reserved[2];
- };
- static const char *prog_name;
- static void write_to_file(int ofd, void *buffer, int size)
- {
- if (write(ofd, buffer, size) == size)
- return;
- fprintf(stderr, "%s: Failed to write to output file: %s\n",
- prog_name, strerror(errno));
- exit(EXIT_FAILURE);
- }
- int main(int argc, char **argv)
- {
- unsigned char *buffer;
- int i, ifd, ofd;
- uint32_t checksum = 0;
- off_t len;
- int var_size_flag, read_size, count;
- struct stat stat;
- const int if_index = argc - 2;
- const int of_index = argc - 1;
-
- prog_name = strrchr(argv[0], '/');
- if (prog_name)
- prog_name++;
- else
- prog_name = argv[0];
- if ((argc < 3) ||
- (argc > 4) ||
- ((argc == 4) && strcmp(argv[1], "--vs"))) {
- fprintf(stderr, "Usage: %s [--vs] <infile> <outfile>\n",
- prog_name);
- exit(EXIT_FAILURE);
- }
-
- var_size_flag = (argc == 4);
- ifd = open(argv[if_index], O_RDONLY);
- if (ifd < 0) {
- fprintf(stderr, "%s: Can't open %s: %s\n",
- prog_name, argv[if_index], strerror(errno));
- exit(EXIT_FAILURE);
- }
- ofd = open(argv[of_index], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);
- if (ofd < 0) {
- fprintf(stderr, "%s: Can't open %s: %s\n",
- prog_name, argv[of_index], strerror(errno));
- exit(EXIT_FAILURE);
- }
- if (fstat(ifd, &stat)) {
- fprintf(stderr, "%s: Unable to get size of %s: %s\n",
- prog_name, argv[if_index], strerror(errno));
- exit(EXIT_FAILURE);
- }
- len = stat.st_size;
- if (var_size_flag) {
- read_size = len;
- count = len;
- } else {
- if (len > CHECKSUM_OFFSET) {
- fprintf(stderr,
- "%s: %s is too big (exceeds %d bytes)\n",
- prog_name, argv[if_index], CHECKSUM_OFFSET);
- exit(EXIT_FAILURE);
- }
- count = CHECKSUM_OFFSET;
- read_size = len;
- }
- buffer = malloc(count);
- if (!buffer) {
- fprintf(stderr,
- "%s: Failed to allocate %d bytes to store %s\n",
- prog_name, count, argv[if_index]);
- exit(EXIT_FAILURE);
- }
- if (read(ifd, buffer, read_size) != read_size) {
- fprintf(stderr, "%s: Can't read %s: %s\n",
- prog_name, argv[if_index], strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- if (read_size < count)
- memset((char *)buffer + read_size, 0xff, count - read_size);
- for (i = 0, checksum = 0; i < count; i++)
- checksum += buffer[i];
- checksum = cpu_to_le32(checksum);
- if (var_size_flag) {
-
- struct var_size_header vsh;
- uint32_t spl_size;
- memset(&vsh, 0, sizeof(vsh));
- memcpy(&vsh.spl_checksum, &checksum, sizeof(checksum));
- spl_size = cpu_to_le32(count + sizeof(struct var_size_header));
- memcpy(&vsh.spl_size, &spl_size, sizeof(spl_size));
- write_to_file(ofd, &vsh, sizeof(vsh));
- }
- write_to_file(ofd, buffer, count);
-
- if (!var_size_flag)
- write_to_file(ofd, &checksum, sizeof(checksum));
- close(ifd);
- close(ofd);
- free(buffer);
- return EXIT_SUCCESS;
- }
|