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

file.c

/* 
   File routines
   --------------------------------------------------------------------
   VCHE - Virtual Console Hex Editor

   Copyright (C) 1998, 1999 Diego Javier Grigna <diego@grigna.com>

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"

/* The size of the file we are viewing or editing */
long vc_filesize;

int file_go_next( void)
{
 struct ll_file *p;

 if( ll_file_current == NULL) {
     lib_alert( "No more files", 0);
     do_exit( 1);
 }

 if( ll_file_current->next == NULL) {
     lib_alert( "No next file", 0);
     return -1;
 }

 p = ll_file_current;
 ll_file_current = p->next;

 file_open( ll_file_current->filename);

 return 1;
}

int file_go_prev( void)
{
 struct ll_file *p;

 if( ll_file_current == NULL) {
     lib_alert( "No more files", 0);
     do_exit( 1);
 }

 if( ll_file_current->prev == NULL) {
     lib_alert( "No previous file", 0);
     return -1;
 }

 p = ll_file_current;
 ll_file_current = p->prev;

 file_open( ll_file_current->filename);

 return 1;
}

void file_open( char *filename)
{
 char *buf;
 char *errptr;
 int open_flags;

 if( fd > 2)
     close( fd);

reopenit:

 if( flags.readonly)
     open_flags = O_RDONLY;
 else
     open_flags = O_RDWR;

 if( (fd = open( filename, open_flags)) == -1) {
     if( !flags.readonly) {
         flags.readonly = 1;
         set_flag( FLAG_READONLY);
         goto reopenit;
     }

     errptr = strerror( errno);
     buf = ( char *) allocate_mem( strlen( filename) + strlen( errptr) + 32);
     sprintf( buf, "Can't open \"%s\" : %s", filename, errptr);
     lib_alert( buf, 0);
     free( buf);
     file_cannot_open();
     return;
 }

 fstat( fd, &stbuf);

 if( ( stbuf.st_mode & S_IFMT) == S_IFDIR){
     buf = ( char *) allocate_mem( strlen( filename) + 32);
     sprintf( buf, "\"%s\" is a directory", filename);
     lib_alert( buf, 0);
     free( buf);
     file_cannot_open();
     return;
 }

 file_getsize();

}

void file_cannot_open( void)
{
 ll_file_delete();

 if( ll_file_current == NULL) {
     lib_alert( "No more files", 0);
     do_exit( 1);
 }

 file_open( ll_file_current->filename);
}

void file_next_line( void)
{
 if(  vc_filesize           >= 0 && ( 
      vc_filesize           <= bytes_to_read ||
     (vc_filesize - fpos)   <  bytes_to_read || 
     (fpos + bytes_to_read) == vc_filesize)  ) {
      term_beep();
      return;
 }

 fpos = lseek( fd, ( long) bytes_per_row, SEEK_CUR);

 hex_showfile();
}

void file_prev_line( void)
{
 if( vc_filesize >= 0 && fpos < bytes_per_row) {
     term_beep();
     fpos = lseek( fd, (long) 0, SEEK_SET);
     hex_showfile();
     return;
 }

 fpos = lseek( fd, ( long) -1 * bytes_per_row, SEEK_CUR);
 hex_showfile();
}

void file_next_byte( void)
{
 if(  vc_filesize           >= 0 && (
      vc_filesize           <= bytes_to_read ||
     (vc_filesize - fpos)   <  bytes_to_read ||
     (fpos + bytes_to_read) == vc_filesize)  ) {
      term_beep();
      return;
 }
 
 fpos = lseek( fd, ( long) 1, SEEK_CUR);
 hex_showfile();
}

void file_prev_byte( void)
{

 if( vc_filesize >= 0 && fpos == 0) {
     term_beep();
     return;
 }

 fpos = lseek( fd, ( long) -1, SEEK_CUR);
 hex_showfile();
}

void file_go_home( void)
{
 if( fpos == 0) {
     term_beep();
     return;
 }

 fpos = lseek( fd, (long) 0, SEEK_SET);
 hex_showfile();
}

void file_go_end( void)
{
 if(  vc_filesize           >= 0 && (
      vc_filesize           <= bytes_to_read ||
     (vc_filesize - fpos)   <  bytes_to_read ||
     (fpos + bytes_to_read) == vc_filesize)  ) {
      term_beep();
      return;
 }

 fpos = lseek( fd, (long) vc_filesize - (vc_filesize % bytes_to_read), SEEK_SET);
 hex_showfile();
}

void file_next_block( void)
{
 if(  vc_filesize           >= 0 && (
      vc_filesize           <= bytes_to_read ||
     (vc_filesize - fpos)   <  bytes_to_read ||
     (fpos + bytes_to_read) == vc_filesize)  ) {
      term_beep();
      return;
 }

 fpos = lseek( fd, (long) bytes_to_read, SEEK_CUR);
 hex_showfile();
}

void file_prev_block( void)
{
 if( vc_filesize >= 0 && fpos < bytes_to_read) {
     term_beep();
     fpos = lseek( fd, (long) 0, SEEK_SET);
     hex_showfile();
     return;
 }

 fpos = lseek( fd, (long) -1 * bytes_to_read, SEEK_CUR);
 hex_showfile();
}

/*
 * Get the size of the file we opened.
 *
 * Some code for getting the size of devices were obtained from the
 * e2fsprogs v1.06 package made by Theodore Ts'o and Remy Card.
 */
void file_getsize( void)
{
#if defined(VCHE_NC)
 WINDOW *w;
#endif
#ifdef FDGETPRM 
 struct floppy_struct floppy_data;
#endif
 char errstr[ 2048];
 char size_str[ 64]; /* File size string */
 double high = 0; /* I use "double" because the binary search could
                     give wrong offsets if the device is too big,
                     anyway, it will give wrong offsets when the device
                     size is greater than LONG_MAX */
 double low  = 0;
 int i = 0;

 vc_filesize = stbuf.st_size;

 /*
  * If the file opened is not a regular file,
  * we must find his size, because fstat(2) will not
  * give us that information.
  */
 if( ( stbuf.st_mode & S_IFMT) != S_IFREG) {

       i = lib_ask( "You are opening a device, how do yo want to get his size?", " Ask kernel ", " Let vche guess it ", " Enter it manually ", 0);
       term_hide_cursor();

       switch( i) {
               /* Ask the kernel */
               case 0:
#ifdef BLKGETSIZE
            {
                  long size = 0;
                       /* The ioctl call to get the size of block devices */
                       if( ioctl( fd, BLKGETSIZE, &size) >= 0) {
                           vc_filesize = size * 512;
                           break;
                       }
            }
#endif

#ifdef FDGETPRM
                       /* The ioctl call to get data about floppies */
                       if( ioctl( fd, FDGETPRM, &floppy_data) >= 0) {
                           vc_filesize = floppy_data.size * 512;
                           break;
                       }
#endif
                       sprintf( errstr, "Can't get device size, truncating to %ld",
#ifdef LONG_MAX
                                         LONG_MAX);
#else
                                         2147483647);
#endif
                       lib_alert( errstr, 0);
#ifdef LONG_MAX
                       vc_filesize = LONG_MAX;
#else
                       vc_filesize = 2147483647;
#endif

                       return;
               /* Let vche guess it */
               case 1:
                       /*
                        * If we can not get the size of the device with an ioctl,
                        * we must use another method, so use binary search.
                        */

                       low = 0;
                       for( high = 1024; file_is_a_valid_offset( (long) high); high *= 2)
                            low = high;

                       while( low < high - 1) {
                              const double mid = ( low + high) / 2;

                              if( file_is_a_valid_offset( (long) mid))
                                  low = mid;
                              else
                                  high = mid;
                       }
                       lseek( fd, 0L, SEEK_SET);

                       vc_filesize = ( long) low + 1;

                       break;
               /* Enter it manually */ 
               case 2:
                       memset( &size_str, 0, 63);
                       size_str[ 0] = '0';
#if defined(VCHE_VC) || defined(VCHE_RAW)
                       lib_save_screen();
#endif

#if defined(VCHE_NC)
                       w =
#endif
                       lib_dialog( "Enter device size: ", size_str, 38, VC_COLOR_BACKCYAN, VC_COLOR_WHITE);

#if defined(VCHE_VC) || defined(VCHE_RAW)
                       term_goto( (vc_cols - 38) / 2, vc_lines / 2);
                       key_scanf( size_str, 38);
#elif defined(VCHE_NC)
                       term_wgoto( w, 2, 2);
                       key_scanf( w, size_str, 38);
#endif

                       if( !strncasecmp( size_str, "0x", 2))
                           sscanf( size_str, "%lx", &vc_filesize);
                       else
                           vc_filesize = atol( size_str);

#if defined(VCHE_VC) || defined(VCHE_RAW)
                       lib_load_screen();
#elif defined(VCHE_NC)
                       delwin( w);
#endif
                       break;
        } /* end switch( i) */

       if( vc_filesize < 0) {
           sprintf( errstr, "Device size too big, truncating to %ld",
#ifdef LONG_MAX
                    LONG_MAX);
#else
                    2147483647);
#endif
           lib_alert( errstr, 0);
#ifdef LONG_MAX
           vc_filesize = LONG_MAX;
#else
           vc_filesize = 2147483647;
#endif
       }

 } /* end if( stbuf.st_mode & S_IFMT != S_IFREG) */

}

int file_is_a_valid_offset( long offset)
{
 char c;

 if( lseek( fd, offset, SEEK_SET) < 0)
     return 0;

 if( read( fd, &c, 1) < 1)
     return 0;

 return 1;
}


Generated by  Doxygen 1.6.0   Back to index