Logo Search packages:      
Sourcecode: cdrkit version File versions  Download package

dump.c

/*
 * This file has been modified for the cdrkit suite.
 *
 * The behaviour and appearence of the program code below can differ to a major
 * extent from the version distributed by the original author(s).
 *
 * For details, see Changelog file distributed with the cdrkit package. If you
 * received this file from another source then ask the distributing person for
 * a log of modifications.
 *
 */

/* @(#)dump.c     1.24 05/05/15 joerg */
/*
 * File dump.c - dump a file/device both in hex and in ASCII.
 *
 * Written by Eric Youngdale (1993).
 *
 * Copyright 1993 Yggdrasil Computing, Incorporated
 * Copyright (c) 1999-2004 J. Schilling
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 *
 * 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; see the file COPYING.  If not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <mconfig.h>
#include <stdxlib.h>
#include <unixstd.h>
#include <strdefs.h>
#include <utypes.h>

#include <stdio.h>
#include <standard.h>
#include <ttydefs.h>
#include <signal.h>
#include <schily.h>

#include "../scsi.h"
#include "../../wodim/defaults.h"

/*
 * Note: always use these macros to avoid problems.
 *
 * ISO_ROUND_UP(X)      may cause an integer overflow and thus give
 *                incorrect results. So avoid it if possible.
 *
 * ISO_BLOCKS(X)  is overflow safe. Prefer this when ever it is possible.
 */
#define     SECTOR_SIZE (2048)
#define     ISO_ROUND_UP(X)   (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
#define     ISO_BLOCKS(X)     (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0))

#define     infile      in_image
FILE        *infile = NULL;
static      off_t       file_addr;
static      off_t       sec_addr = (off_t)-1;
static      Uchar       sector[2048];
#define     PAGE  256
static      Uchar       buffer[PAGE];
static      Uchar       search[64];

#ifdef      USE_V7_TTY
static      struct sgttyb     savetty;
static      struct sgttyb     newtty;
#else
static      struct termios    savetty;
static      struct termios    newtty;
#endif

static void reset_tty(void);
static void set_tty(void);
static void onsusp(int sig);
static void crsr2(int row, int col);
static void readblock(void);
static void showblock(int flag);
static int  getbyte(void);
static void usage(int excode);

static void
reset_tty()
{
#ifdef USE_V7_TTY
      if (ioctl(STDIN_FILENO, TIOCSETN, &savetty) == -1) {
#else
#ifdef TCSANOW
      if (tcsetattr(STDIN_FILENO, TCSANOW, &savetty) == -1) {
#else
      if (ioctl(STDIN_FILENO, TCSETAF, &savetty) == -1) {
#endif
#endif
#ifdef      USE_LIBSCHILY
            comerr("Cannot put tty into normal mode\n");
#else
            printf("Cannot put tty into normal mode\n");
            exit(1);
#endif
      }
}

static void
set_tty()
{
#ifdef USE_V7_TTY
      if (ioctl(STDIN_FILENO, TIOCSETN, &newtty) == -1) {
#else
#ifdef TCSANOW
      if (tcsetattr(STDIN_FILENO, TCSANOW, &newtty) == -1) {
#else
      if (ioctl(STDIN_FILENO, TCSETAF, &newtty) == -1) {
#endif
#endif
#ifdef      USE_LIBSCHILY
            comerr("Cannot put tty into raw mode\n");
#else
            printf("Cannot put tty into raw mode\n");
            exit(1);
#endif
      }
}


/*
 * Come here when we get a suspend signal from the terminal
 */
static void
onsusp(int sig)
{
#ifdef      SIGTTOU
      /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
      signal(SIGTTOU, SIG_IGN);
#endif
      reset_tty();
      fflush(stdout);
#ifdef      SIGTTOU
      signal(SIGTTOU, SIG_DFL);
      /* Send the TSTP signal to suspend our process group */
      signal(SIGTSTP, SIG_DFL);
      /*    sigsetmask(0);*/
      kill(0, SIGTSTP);
      /* Pause for station break */

      /* We're back */
      signal(SIGTSTP, onsusp);
#endif
      set_tty();
}


static void
crsr2(int row, int col)
{
      printf("\033[%d;%dH", row, col);
}

static void
readblock()
{
      off_t dpos = file_addr - sec_addr;

      if (sec_addr < 0 ||
          dpos < 0 || (dpos + sizeof (buffer)) > sizeof (sector)) {
            sec_addr = file_addr & ~2047;
#ifdef      USE_SCG
            readsecs(sec_addr/2048, sector, ISO_BLOCKS(sizeof (sector)));
#else
            lseek(fileno(infile), sec_addr, SEEK_SET);
            read(fileno(infile), sector, sizeof (sector));
#endif
            dpos = file_addr - sec_addr;
      }
      movebytes(&sector[dpos], buffer, sizeof (buffer));
}

static void
showblock(int flag)
{
      unsigned int      k;
      int         i;
      int         j;

      readblock();
      if (flag) {
            for (i = 0; i < 16; i++) {
                  crsr2(i+3, 1);
                  if (sizeof (file_addr) > sizeof (long)) {
                        printf("%16.16llx ", (Llong)file_addr+(i<<4));
                  } else {
                        printf("%8.8lx ", (long)file_addr+(i<<4));
                  }
                  for (j = 15; j >= 0; j--) {
                        printf("%2.2x", buffer[(i<<4)+j]);
                        if (!(j & 0x3))
                              printf(" ");
                  }
                  for (j = 0; j < 16; j++) {
                        k = buffer[(i << 4) + j];
                        if (k >= ' ' && k < 0x80)
                              printf("%c", k);
                        else
                              printf(".");
                  }
            }
      }
      crsr2(20, 1);
      if (sizeof (file_addr) > sizeof (long)) {
            printf(" Zone, zone offset: %14llx %12.12llx  ",
                  (Llong)file_addr>>11, (Llong)file_addr & 0x7ff);
      } else {
            printf(" Zone, zone offset: %6lx %4.4lx  ",
                  (long)(file_addr>>11), (long)(file_addr & 0x7ff));
      }
      fflush(stdout);
}

static int
getbyte()
{
      char  c1;

      c1 = buffer[file_addr & (PAGE-1)];
      file_addr++;
      if ((file_addr & (PAGE-1)) == 0)
            showblock(0);
      return (c1);
}

static void
usage(int excode)
{
      errmsgno(EX_BAD, "Usage: %s [options] [image]\n",
                                    get_progname());

      fprintf(stderr, "Options:\n");
      fprintf(stderr, "\t-help, -h  Print this help\n");
      fprintf(stderr, "\t-version   Print version info and exit\n");
      fprintf(stderr, "\t-i filename      Filename to read ISO-9660 image from\n");
      fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n");
      fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n");
      exit(excode);
}

int
main(int argc, char *argv[])
{
      int   cac;
      char  * const *cav;
      char  *opts = "help,h,version,i*,dev*";
      BOOL  help = FALSE;
      BOOL  prvers = FALSE;
      char  *filename = NULL;
      char  *devname = NULL;
      char  c;
      int   i;
      int   j;

      save_args(argc, argv);

      cac = argc - 1;
      cav = argv + 1;
      if (getallargs(&cac, &cav, opts, &help, &help, &prvers,
                  &filename, &devname) < 0) {
            errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]);
            usage(EX_BAD);
      }
      if (help)
            usage(0);
      if (prvers) {
            printf("devdump %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM);
            exit(0);
      }
      cac = argc - 1;
      cav = argv + 1;
      if (filename == NULL && devname == NULL) {
            if (getfiles(&cac, &cav, opts) != 0) {
                  filename = cav[0];
                  cac--, cav++;
            }
      }
      if (getfiles(&cac, &cav, opts) != 0) {
            errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]);
            usage(EX_BAD);
      }
      if (filename != NULL && devname != NULL) {
            errmsgno(EX_BAD, "Only one of -i or dev= allowed\n");
            usage(EX_BAD);
      }
#ifdef      USE_SCG
      if (filename == NULL && devname == NULL)
            cdr_defaults(&devname, NULL, NULL, NULL);
#endif
      if (filename == NULL && devname == NULL) {
#ifdef      USE_LIBSCHILY
            errmsgno(EX_BAD, "ISO-9660 image not specified\n");
#else
            fprintf(stderr, "ISO-9660 image not specified\n");
#endif
            usage(EX_BAD);
      }

      if (filename != NULL)
            infile = fopen(filename, "rb");
      else
            filename = devname;

      if (infile != NULL) {
            /* EMPTY */;
#ifdef      USE_SCG
      } else if (scsidev_open(filename) < 0) {
#else
      } else {
#endif
#ifdef      USE_LIBSCHILY
            comerr("Cannot open '%s'\n", filename);
#else
            fprintf(stderr, "Cannot open '%s'\n", filename);
            exit(1);
#endif
      }

      for (i = 0; i < 30; i++)
            printf("\n");
      file_addr = (off_t)0;

      /*
       * Now setup the keyboard for single character input.
       */
#ifdef USE_V7_TTY
      if (ioctl(STDIN_FILENO, TIOCGETP, &savetty) == -1) {
#else
#ifdef TCSANOW
      if (tcgetattr(STDIN_FILENO, &savetty) == -1) {
#else
      if (ioctl(STDIN_FILENO, TCGETA, &savetty) == -1) {
#endif
#endif
#ifdef      USE_LIBSCHILY
            comerr("Stdin must be a tty\n");
#else
            printf("Stdin must be a tty\n");
            exit(1);
#endif
      }
      newtty = savetty;
#ifdef USE_V7_TTY
      newtty.sg_flags  &= ~(ECHO|CRMOD);
      newtty.sg_flags  |= CBREAK;
#else
      newtty.c_lflag   &= ~ICANON;
      newtty.c_lflag   &= ~ECHO;
      newtty.c_cc[VMIN] = 1;
#endif
      set_tty();
#ifdef      SIGTSTP
      signal(SIGTSTP, onsusp);
#endif
      on_comerr((void(*)(int, void *))reset_tty, NULL);

      do {
            if (file_addr < (off_t)0) file_addr = (off_t)0;
            showblock(1);
            read(STDIN_FILENO, &c, 1); /* FIXME: check return value */
            if (c == 'a')
                  file_addr -= PAGE;
            if (c == 'b')
                  file_addr += PAGE;
            if (c == 'g') {
                  crsr2(20, 1);
                  printf("Enter new starting block (in hex):");
                  if (sizeof (file_addr) > sizeof (long)) {
                        Llong ll;
                        scanf("%llx", &ll); /* FIXME: check return value */
                        file_addr = (off_t)ll;
                  } else {
                        long  l;
                        scanf("%lx", &l); /* FIXME: check return value */
                        file_addr = (off_t)l;
                  }
                  file_addr = file_addr << 11;
                  crsr2(20, 1);
                  printf("                                     ");
            }
            if (c == 'f') {
                  crsr2(20, 1);
                  printf("Enter new search string:");
                  fgets((char *)search, sizeof (search), stdin); /* FIXME: check return value */
                  while (search[strlen((char *)search)-1] == '\n')
                        search[strlen((char *)search)-1] = 0;
                  crsr2(20, 1);
                  printf("                                     ");
            }
            if (c == '+') {
                  while (1 == 1) {
                        int   slen;

                        while (1 == 1) {
                              c = getbyte();
                              if (c == search[0])
                                    break;
                        }
                        slen = (int)strlen((char *)search);
                        for (j = 1; j < slen; j++) {
                              if (search[j] != getbyte())
                                    break;
                        }
                        if (j == slen)
                              break;
                  }
                  file_addr &= ~(PAGE-1);
                  showblock(1);
            }
            if (c == 'q')
                  break;
      } while (1 == 1);
      reset_tty();
      if (infile != NULL)
            fclose(infile);
      return (0);
}

Generated by  Doxygen 1.6.0   Back to index