View of xos/tools/makeusrhdr.c


XOS | Parent Directory | View | Download

/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
/* Construit l'en-tete des archives de fichiers pour XOS.
 *
 * Utilisation : makeusrhdr bin_img lib_img
 *   bin_img  archive /bin
 *   lib_img  archive /lib
 * Options :
 *   -o filename  ecrire l'en-tete dans le fichier filename, au lieu de la
 *            sortie standard. */
 
#define _GNU_SOURCE
 
#include "usr_hdr.h"
 
#include <getopt.h>
#include <error.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
 
static void die(const char *s)
{
  error(EXIT_FAILURE, errno, s);
}
 
static void __attribute__ ((noreturn)) die_bad_usage()
{
  fprintf(stderr, "Try `%s --help' for more information.\n", program_invocation_name);
  exit(EXIT_FAILURE);
}
 
static void print_help()
{
  printf("Usage: %s BIN_ARCHIVE LIB_ARCHIVE\n", program_invocation_name);
  printf("Create archives header for XOS.\n");
  printf("\n");
  printf("  -h, --help         display this help and exit\n");
  printf("  -o, --output=FILE  write output in FILE instead of standard output\n");
}
 
static void makeusrhdr(const char *bin_filename, const char *lib_filename, FILE *output)
{
  usr_hdr_t usr_hdr;
  unsigned long offset;
  struct stat statbuf;
 
  offset = sizeof (usr_hdr);
  usr_hdr.bin_offset = offset;
  if (stat(bin_filename, &statbuf) == -1)
    error(EXIT_FAILURE, errno, "cannot stat `%s'", bin_filename);
  offset += statbuf.st_size;
  usr_hdr.lib_offset = offset;
 
  fwrite(&usr_hdr, sizeof (usr_hdr_t), 1, output);
}
 
int main(int argc, char **argv)
{
  static const struct option longopts[] = {
    {"help", no_argument, NULL, 'h'},
    {"output", required_argument, NULL, 'o'},
    {NULL, 0, NULL, 0}
  };
 
  char *output_filename;
  FILE *output;
  int c;
 
  /* options par defaut */
  output_filename = NULL;
 
  /* lecture des options de la ligne de commande */
  while ((c = getopt_long(argc, argv, "ho:", longopts, NULL)) != -1)
    switch (c) {
    case 'h':
      print_help();
      return EXIT_SUCCESS;
    case 'o':
      if (output_filename)
        free(output_filename);
      if (!(output_filename = strdup(optarg)))
        die("strdup");
      break;
    case '?':
      die_bad_usage();
    }
 
  if (output_filename) {
    if (!(output = fopen(output_filename, "w+")))
      die(output_filename);
    free(output_filename);
  }
  else
    output = stdout;
 
  argc -= optind - 1;
  argv += optind - 1;
  if (argc != 3)
    die_bad_usage();
  makeusrhdr(argv[1], argv[2], output);
 
  if (output != stdout)
    fclose(output);
 
  return EXIT_SUCCESS;
}