aboutsummaryrefslogtreecommitdiff
#include <stdio.h>
#include <err.h>
#include <endian.h>
#include <stdint.h>
#include <sys/types.h>

#define ANSI_FG_RED "\033[0;31m"
#define ANSI_FG_DEFAULT "\033[0;39m"

/* This program pipes it's argument file to stdout */
/* prepending it with it's size (4 bytes, little endian). */
/* It is intended to be used with our bootloader. */

int main(int argc, const char **argv) {
  const char *image_file_name = "kernel.img";

  if (argc > 1)
    image_file_name = argv[1];

  FILE *image_file_handle = fopen(image_file_name, "r");

  if (!image_file_handle)
    err(-1, "couldn't open" ANSI_FG_RED "%s" ANSI_FG_DEFAULT,
	image_file_name);

  if (fseek(image_file_handle, 0, SEEK_END))
    err(-1, "error navigating through file");

  ssize_t image_size = ftell(image_file_handle);
  if (image_size < 0)
    err(-1, "couldn't get image file size");

  if (image_size >> 32)
    err(-1, "file to big (should be smaller than 4G)");

  if (fseek(image_file_handle, 0, SEEK_SET))
    err(-1, "error navigating through file");

  uint32_t image_size_le = htole32(image_size);

  if (fwrite((unsigned char*) &image_size_le, 4, 1, stdout) != 1)
    err(-1, "error writing number to stdout");

  ssize_t bytes_left = image_size;

  unsigned char buf[1024];
  while (bytes_left)
    {
      size_t bytes_read;
      if ((bytes_read = fread(buf, 1, sizeof(buf), image_file_handle))
	  < 1)
	err(-1, "error reading the file");

      if (fwrite((unsigned char*) buf, bytes_read, 1, stdout) != 1)
	err(-1, "error writing to stdout");

      bytes_left -= bytes_read;
    }
  
/*
  // not working - stdin breaks
  while(1)
  {
      int bytes_read=read(0,buf,sizeof(buf));
      if (fwrite((unsigned char*) buf, bytes_read, 1, stdout) != 1)
        err(-1, "error writing to stdout");
  }
  */

  return 0;
}