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

iso.c

/*
 *  Copyright 1993 Yggdrasil Computing, Incorporated
 *  Copyright (c) 1999-2004 J. Schilling
 *  Copyright (C) 2006 Giuseppe Torelli <colossus73@gmail.com>
 *  Copyright (c) 2006 Salvatore Santagati <salvatore.santagati@gmail.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 Library 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 "config.h"
#include "iso.h"
#include "string_utils.h"

unsigned char buffer[2048];

struct iso_primary_descriptor ipd;
struct iso_directory_record * idr;
struct iso_directory_record * idr_rr;

gboolean use_rock = 0;
gboolean use_joilet = 0;
short int iso_error_count = 0;
char * xtract = 0; 
int do_find = 0;    
int ucs_level = 0;

unsigned int sector_offset = 0;

struct todo * todo_idr = NULL;

char name_buf[256];
struct stat fstat_buf;

char xname[256];
unsigned char date_buf[9];

gchar *g_file_name;
gchar *g_file_permissions;
gchar *g_file_date;
unsigned long long int g_file_size;
unsigned long long int g_file_offset;

int   su_version = 0;
int   aa_version = 0;

int   found_rr;

char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

int parse_rr(unsigned char * pnt, int len, int cont_flag)
{
      int slen;
    int xlen;
    int ncount;
    int extent;
    int cont_extent, cont_offset, cont_size;
    int flag1, flag2;
    unsigned char *pnts;
    char symlinkname[1024];
    int goof;

    symlinkname[0] = 0;

      cont_extent = cont_offset = cont_size = extent = 0;
      ncount = 0;
      flag1 = flag2 = 0;
      while (len >= 4)
      {
            if (pnt[3] != 1 && pnt[3] != 2)
            {
                  g_print("**BAD RRVERSION (%d)\n", pnt[3]);
                  return (0);       /* JS ??? Is this right ??? */
            }
            ncount++;
            if (pnt[0] == 'R' && pnt[1] == 'R') flag1 = pnt[4] & 0xff;
            if (strncmp((char *)pnt, "PX", 2) == 0) flag2 |= 1;   /* POSIX attributes */
            if (strncmp((char *)pnt, "PN", 2) == 0) flag2 |= 2;   /* POSIX device number */
            if (strncmp((char *)pnt, "SL", 2) == 0) flag2 |= 4;   /* Symlink */
            if (strncmp((char *)pnt, "NM", 2) == 0) flag2 |= 8;   /* Alternate Name */
            if (strncmp((char *)pnt, "CL", 2) == 0) flag2 |= 16;  /* Child link */
            if (strncmp((char *)pnt, "PL", 2) == 0) flag2 |= 32;  /* Parent link */
            if (strncmp((char *)pnt, "RE", 2) == 0) flag2 |= 64;  /* Relocated Direcotry */
            if (strncmp((char *)pnt, "TF", 2) == 0) flag2 |= 128; /* Time stamp */
            if (strncmp((char *)pnt, "SP", 2) == 0)
            {
                  flag2 |= 1024;                            /* SUSP record */
                  su_version = pnt[3] & 0xff;
            }
            if (strncmp((char *)pnt, "AA", 2) == 0)
            {
                  flag2 |= 2048;                            /* Apple Signature record */
                  aa_version = pnt[3] & 0xff;
            }

            if (strncmp((char *)pnt, "PX", 2) == 0)
            {           /* POSIX attributes */
                  fstat_buf.st_mode = iso_733(pnt+4);
                  fstat_buf.st_nlink = iso_733(pnt+12);
                  fstat_buf.st_uid = iso_733(pnt+20);
                  fstat_buf.st_gid = iso_733(pnt+28);
            }

            if (strncmp((char *)pnt, "NM", 2) == 0)
            {     /* Alternate Name */
                  strncpy(name_buf, pnt+5, pnt[2] - 5);
                  name_buf[pnt[2] - 5] = 0;
            }

            if (strncmp((char *)pnt, "CE", 2) == 0)
            {           /* Continuation Area */
                  cont_extent = iso_733(pnt+4);
                  cont_offset = iso_733(pnt+12);
                  cont_size = iso_733(pnt+20);
          }

            if (strncmp((char *)pnt, "PL", 2) == 0 || strncmp((char *)pnt, "CL", 2) == 0)
                  extent = iso_733(pnt+4);

            if (strncmp((char *)pnt, "SL", 2) == 0)
            {           /* Symlink */
                  int   cflag;
                  cflag = pnt[4];
                  pnts = pnt+5;
                  slen = pnt[2] - 5;
                  while (slen >= 1)
                  {
                        switch (pnts[0] & 0xfe)
                        {
                              case 0:
                              strncat(symlinkname, (char *)(pnts+2), pnts[1]);
                              symlinkname[pnts[1]] = 0;
                              break;
                        
                              case 2:
                              strcat(symlinkname, ".");
                              break;

                              case 4:
                              strcat(symlinkname, "..");
                              break;

                              case 8:
                              strcat(symlinkname, "/");
                              break;

                              case 16:
                              strcat(symlinkname, "/mnt");
                              g_print ("Warning - mount point requested");
                              break;

                              case 32:
                              strcat(symlinkname, "kafka");
                              g_print ("Warning - host_name requested");
                              break;
                        
                              default:
                              g_print ("Reserved bit setting in symlink");
                              goof++;
                              break;
                        }
                        if ((pnts[0] & 0xfe) && pnts[1] != 0)
                              g_print ("Incorrect length in symlink component");

                        if (xname[0] == 0)
                              strcpy(xname, "-> ");
                        strcat(xname, symlinkname);
                        symlinkname[0] = 0;
                        xlen = strlen(xname);
                        if ((pnts[0] & 1) == 0 && xname[xlen-1] != '/')
                              strcat(xname, "/");

                        slen -= (pnts[1] + 2);
                        pnts += (pnts[1] + 2);
              }
                  symlinkname[0] = 0;
          }

            len -= pnt[2];
            pnt += pnt[2];
            if (len <= 3 && cont_extent)
            {
                  unsigned char sector[2048];

                  lseek(fileno(iso_stream), ((off_t)(cont_extent - sector_offset)) << 11, SEEK_SET);
                  read(fileno(iso_stream), sector, sizeof (sector));
                  flag2 |= parse_rr(&sector[cont_offset], cont_size, 1);
          }
      }
            /* for symbolic links, strip out the last '/' */
      if (xname[0] != 0 && xname[strlen(xname)-1] == '/')
            xname[strlen(xname)-1] = '\0';
      return (flag2);
}

void find_rr(idr, pntp, lenp)
        struct iso_directory_record *idr;
        unsigned char   **pntp;
        int *lenp;
{
        struct iso_xa_dir_record *xadp;
        int len;
        unsigned char * pnt;

        len = idr->length[0] & 0xff;
        len -= offsetof(struct iso_directory_record, name[0]);
        len -= idr->name_len[0];

        pnt = (unsigned char *) idr;
        pnt += offsetof(struct iso_directory_record, name[0]);
        pnt += idr->name_len[0];
        if ((idr->name_len[0] & 1) == 0) {
                pnt++;
                len--;
        }
        if (len >= 14) {
                xadp = (struct iso_xa_dir_record *)pnt;

                if (xadp->signature[0] == 'X' && xadp->signature[1] == 'A' &&
                    xadp->reserved[0] == '\0') {
                        len -= 14;
                        pnt += 14;
                }
        }
        *pntp = pnt;
        *lenp = len;
}


int dump_rr(idr)
        struct iso_directory_record *idr;
{
    int len;
      unsigned char * pnt;

      find_rr(idr, &pnt, &len);
      return (parse_rr(pnt, len, 0));
}


void dump_stat(gchar *dir_name , int extent, XArchive *archive)
{
      int i;
      char outline[80];

      GValue *filename = NULL;
      GValue *permissions = NULL;
      GValue *size = NULL;
      GValue *date = NULL;
      GValue *offset = NULL;

      memset(outline, ' ', sizeof(outline));

      if(S_ISREG(fstat_buf.st_mode))
        outline[0] = '-';
    else if(S_ISDIR(fstat_buf.st_mode))
            outline[0] = 'd';
    else if(S_ISLNK(fstat_buf.st_mode))
            outline[0] = 'l';
    else if(S_ISCHR(fstat_buf.st_mode))
        outline[0] = 'c';
    else if(S_ISBLK(fstat_buf.st_mode))
            outline[0] = 'b';
    else if(S_ISFIFO(fstat_buf.st_mode))
            outline[0] = 'f';
    else if(S_ISSOCK(fstat_buf.st_mode))
            outline[0] = 's';
    else
            outline[0] = '?';

    memset(outline+1, '-', 9);
    if( fstat_buf.st_mode & S_IRUSR )
            outline[1] = 'r';
      if( fstat_buf.st_mode & S_IWUSR )
            outline[2] = 'w';
      if( fstat_buf.st_mode & S_IXUSR )
            outline[3] = 'x';

      if( fstat_buf.st_mode & S_IRGRP )
            outline[4] = 'r';
      if( fstat_buf.st_mode & S_IWGRP )
            outline[5] = 'w';
      if( fstat_buf.st_mode & S_IXGRP )
            outline[6] = 'x';

      if( fstat_buf.st_mode & S_IROTH )
            outline[7] = 'r';
      if( fstat_buf.st_mode & S_IWOTH )
            outline[8] = 'w';
      if( fstat_buf.st_mode & S_IXOTH )
            outline[9] = 'x';

      sprintf(outline+11, "%3d", fstat_buf.st_nlink); 
    sprintf(outline+15, "%4o", fstat_buf.st_uid);  
    sprintf(outline+20, "%4o", fstat_buf.st_gid); 
  
    g_file_size = fstat_buf.st_size ;

    if (date_buf[1] >= 1 && date_buf[1] <= 12)
            memcpy(outline+41, months[date_buf[1]-1], 3);

      sprintf(outline+45, "%2d", date_buf[2]);
    outline[63] = 0;
      sprintf(outline+48, "%4d", date_buf[0]+1900);

      sprintf(outline+53, "[%7d", extent);      /* XXX up to 20 GB */
    sprintf(outline+61, " %02X]", idr->flags[0]);

      for (i = 0; i < 66; i++)
      {
            if (outline[i] == 0)
                  outline[i] = ' ';
    }
      outline[66] = 0;

      g_file_date = g_strndup (&outline[41] , 11);

      for(i=0; i<10; i++)
            if(outline[i] == 0) outline[i] = ' ';
                  outline[10] = 0;

      g_file_permissions = outline;
      g_file_offset = extent;
      g_file_size = fstat_buf.st_size;    
      
      if ( (!use_rock) && (!use_joilet) )
            //strcpy (name_buf + strlen (name_buf)- 2, "  "); /* remove ";1" from file name */
            name_buf[strlen (name_buf)- 2] = '\0';
        
    if (strcmp (name_buf,"..") == 0 || strcmp (name_buf,".") == 0)
            return;

    if (outline[0] == 'd')
            archive->nr_of_dirs++;
    else
            archive->nr_of_files++;

      g_file_name = g_strconcat (dir_name, name_buf , NULL);     

      filename    = g_new0(GValue, 1);
      permissions = g_new0(GValue, 1);
      size        = g_new0(GValue, 1);
      date        = g_new0(GValue, 1);
      offset      = g_new0(GValue, 1);
                
      filename = g_value_init(filename, G_TYPE_STRING);
      g_value_set_string ( filename , g_strdup (g_file_name));

      permissions = g_value_init(permissions, G_TYPE_STRING);
      g_value_set_string ( permissions , g_strdup ( g_file_permissions ));
                
      size = g_value_init(size, G_TYPE_UINT64);
      g_value_set_uint64 ( size , g_file_size );

      date = g_value_init(date, G_TYPE_STRING);
      g_value_set_string ( date , g_strdup ( g_file_date ));

      offset = g_value_init(offset, G_TYPE_UINT64);
      g_value_set_uint64 ( offset , g_file_offset );

      g_free (g_file_name);
      archive->dummy_size+= g_value_get_uint64 (size);

      archive->row = g_list_prepend (archive->row , filename );
      archive->row = g_list_prepend (archive->row , permissions);
      archive->row = g_list_prepend (archive->row,  size);
      archive->row = g_list_prepend (archive->row,  date);
      archive->row = g_list_prepend (archive->row,  offset);
}

void parse_dir (gchar *dir_name , int extent, int len, XArchive *archive)
{
      char testname[256];
      struct todo *td;
      int i;
      struct iso_directory_record *idr;

      while (len > 0 )
      {
            lseek(fileno(iso_stream), (extent - sector_offset) << 11, 0);
            read(fileno(iso_stream), buffer, sizeof(buffer));
            len -= sizeof(buffer);
            extent++;
            i = 0;
            while( 1 == 1 )
            {
                  idr = (struct iso_directory_record *) &buffer[i];
                  if (idr->length[0] == 0)
                        break;
                  memset(&fstat_buf, 0, sizeof(fstat_buf));
                  name_buf[0] = xname[0] = 0;
                  fstat_buf.st_size = iso_733((unsigned char *)idr->size);
                  if( idr->flags[0] & 2)
                        fstat_buf.st_mode |= S_IFDIR;
                  else
                        fstat_buf.st_mode |= S_IFREG;
                  if(idr->name_len[0] == 1 && idr->name[0] == 0)
                        strcpy(name_buf, ".");
                  else if(idr->name_len[0] == 1 && idr->name[0] == 1)
                  strcpy(name_buf, "..");
                  else
                  {
                        switch (ucs_level)
                        {
                              case 3:
                              /* Unicode name.  Convert as best we can. */
                              {
                                    int i;
                                    for(i=0; i < idr->name_len[0] / 2; i++)
                                          name_buf[i] = idr->name[i*2+1];
                                    name_buf[idr->name_len[0]/2] = '\0';
                    }
                              break;

                              case 0:
                              /* Normal non-Unicode name. */
                              strncpy(name_buf, idr->name, idr->name_len[0]);
                              name_buf[idr->name_len[0]] = 0;
                              break;
            
                    /* Don't know how to do these yet.Maybe they are the same as one of the above. */
                        }
            };
                  memcpy(date_buf, idr->date, 9);
                  if (use_rock)
                        dump_rr(idr);
                  if(   (idr->flags[0] & 2) != 0 && (idr->name_len[0] != 1 || (idr->name[0] != 0 && idr->name[0] != 1)))
                  {
                        /* Add this directory to the todo list. */
                        td = todo_idr;
                        if( td != NULL ) 
                        {
                              while(td->next != NULL)
                                    td = td->next;
                              td->next = (struct todo *) malloc(sizeof(*td));
                              td = td->next;
                        }
                        else
                              todo_idr = td = (struct todo *) malloc(sizeof(*td));
                        
                        td->next = NULL;
                        td->extent = iso_733((unsigned char *)idr->extent);
                        td->length = iso_733((unsigned char *)idr->size);
                        td->name = (char *) malloc(strlen(dir_name) + strlen(name_buf) + 2);
                        strcpy(td->name, dir_name);
                        strcat(td->name, name_buf);
                        strcat(td->name, "/");
                  }
                  else
                  {
                        strcpy(testname, dir_name);
                        strcat(testname, name_buf);
                  }
                  if( do_find && (idr->name_len[0] != 1 || (idr->name[0] != 0 && idr->name[0] != 1)))
                  {
                        strcpy(testname, dir_name);
                        strcat(testname, name_buf);
                  }
                  dump_stat(dir_name , iso_733((unsigned char *)idr->extent), archive);
                  i += buffer[i];
                  if (i > 2048 - sizeof(struct iso_directory_record))
                        break;
            }
      }
}

gboolean xa_extract_single_iso_file (XArchive *archive, gchar *permission, gchar *destination_path, gchar *_filename , unsigned long long int file_size, unsigned long long file_offset )
{
      gchar *filename = NULL;
      gchar *multiple_directories = NULL;
      gchar *final_path = NULL;
      gboolean result;

      if (strstr (permission , "d") )
      {
            final_path = g_strconcat (destination_path, _filename,NULL);
            if (xa_create_directory_with_parents ( final_path, 0755 ) < 0)
            {
                  response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't create directory:"),g_strerror(errno) );
                  g_free (final_path);
                  return TRUE;
            }
            else
            {
                  g_free (final_path);
                  return FALSE;
            }
      }
      if (archive->full_path == 0)
      {
            filename = g_strconcat (destination_path , StripPathFromFilename ( _filename , "/" ) , NULL);
            result = xa_write_file_to_disk ( archive->path, filename, file_size, file_offset );
            g_free (filename);
            return result;
      }
      else
      {
            if ( CountCharacter ( _filename, '/' ) > 1)
            {
                  multiple_directories = remove_level_from_path ( _filename );
                  final_path = g_strconcat (destination_path, multiple_directories,NULL);
                  g_free (multiple_directories);
                  if ( xa_create_directory_with_parents ( final_path , 0755 ) < 0)
                  {
                        response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't create directory:"),g_strerror(errno) );
                        g_free (final_path);
                        return FALSE;
                  }
                  g_free (final_path);
            }
      }
      final_path = g_strconcat (destination_path, _filename, NULL);
      result = xa_write_file_to_disk ( archive->path, final_path, file_size, file_offset );
      g_free (final_path);
      return result;
}

gboolean xa_extract_iso_file (XArchive *archive, gchar *permission, gchar *destination_path, gchar *_filename , unsigned long long int file_size, unsigned long long file_offset )
{
      gchar *filename = NULL;
      
      if (archive->full_path == 0)
      {
            if (strstr (permission , "d") )
                  return TRUE;
            filename = g_strconcat (destination_path , StripPathFromFilename ( _filename , "/" ) , NULL);
      }
      else
      {
            filename = g_strconcat (destination_path , _filename , NULL);
            if (strstr (permission , "d") )
            {
                  if ( g_file_test ( filename , G_FILE_TEST_EXISTS) == FALSE )
                  {
                        if ( xa_create_directory_with_parents (filename, 0755) < 0 )
                        {
                              response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't create directory:"),g_strerror(errno) );
                              g_free (filename);
                              return FALSE;
                        }
                  }
                  return TRUE;
            }
      }

      if (archive->overwrite == FALSE && g_file_test ( filename , G_FILE_TEST_EXISTS) == TRUE)
      {
            g_free (filename);
            return TRUE;
      }
      xa_write_file_to_disk ( archive->path, filename, file_size, file_offset );
      g_free (filename);
      return TRUE;
}

gboolean xa_write_file_to_disk (gchar *source,gchar *dest, unsigned long long int file_size, unsigned long long file_offset )
{
      FILE *fdest;
      FILE *fsource;
      unsigned long long int tlen;
      char buf[2048];
      
      if ((fsource = fopen (source, "r")) == NULL)
            return FALSE;
      if ((fdest = fopen (dest, "w")) == NULL)
      {
            gchar *msg = g_strdup_printf (_("Can't write file \"%s\":"), dest);
            response = ShowGtkMessageDialog (GTK_WINDOW (MainWindow),GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,msg,g_strerror(errno) );
            g_free (msg);
            iso_error_count++;
        return FALSE;
      }

      while (file_size > 0)
      {
            while (gtk_events_pending() )
                  gtk_main_iteration();
            fseek(fsource, (off_t) file_offset << 11, SEEK_SET);
            tlen = (file_size > sizeof (buf) ? sizeof (buf) : file_size);
            fread (buf, 1 , tlen , fsource);
            file_size -= tlen;
            file_offset++;
            fwrite (buf, 1 , tlen , fdest);
      }

      fclose(fdest);
      fclose(fsource);
      return TRUE;
}

int xa_create_directory_with_parents (const gchar * pathname, int mode)
{
      #if GLIB_CHECK_VERSION (2, 8, 0)
            return g_mkdir_with_parents (pathname, mode);
      #else
      {
            gchar *fn, *p;

            if (pathname == NULL || *pathname == '\0')
            {
                  errno = EINVAL;
                  return -1;
            }

            fn = g_strdup (pathname);

            if (g_path_is_absolute (fn))
                  p = (gchar *) g_path_skip_root (fn);
            else
                  p = fn;

            do
            {
                  while (*p && !G_IS_DIR_SEPARATOR (*p))
                        p++;

                  if (!*p)
                        p = NULL;
                  else
                        *p = '\0';

                  if (!g_file_test (fn, G_FILE_TEST_EXISTS))
                  {
                        if (g_mkdir (fn, mode) == -1)
                        {
                              int errno_save = errno;
                              g_free (fn);
                              errno = errno_save;
                              return -1;
                        }
                  }
                  else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
                  {
                        g_free (fn);
                        errno = ENOTDIR;
                        return -1;
                  }
                  if (p)
                  {
                        *p++ = G_DIR_SEPARATOR;
                        while (*p && G_IS_DIR_SEPARATOR (*p))
                        p++;
                  }
            }
            while (p);

            g_free (fn);
            return 0;
      }
      #endif
}

void OpenISO ( XArchive *archive )
{
      int   c;
      struct todo *td;
      int extent;
      int block;  
      int toc_offset = 0;
      iso_error_count = 0;

    archive->dummy_size = 0;
    archive->nr_of_files = 0;
    archive->nr_of_dirs = 0;
      archive->format ="ISO";
      char *names[]= {(_("Filename")),(_("Permission")),(_("Size")),(_("Date")),(_("Offset"))};
    GType types[]= {G_TYPE_STRING,G_TYPE_STRING,G_TYPE_UINT64,G_TYPE_STRING,G_TYPE_UINT64};
      xa_create_liststore ( 5, names , (GType *)types );

      iso_stream = fopen ( archive->path ,"r" );
        
      lseek (fileno(iso_stream), DetectImage(iso_stream), 0);
      read(fileno(iso_stream), &ipd, sizeof(ipd));
      idr = (struct iso_directory_record *) &ipd.root_directory_record;
      extent = iso_733((unsigned char *)idr->extent);
      lseek (fileno(iso_stream),((off_t)(extent - sector_offset)) <<11, SEEK_SET);
      read(fileno(iso_stream), buffer, sizeof (buffer));
      idr_rr = (struct iso_directory_record *) buffer;
        
      /* Detect Rock Ridge exstension */
      if ((c = dump_rr(idr_rr)) != 0) 
      {                 
            if (c & 1024) 
            {
                  use_rock = TRUE;              
                  archive->tmp = g_strdup_printf (_("Rock Ridge version %d"),su_version);
            } 
        else 
                  archive->tmp = g_strdup (_("Rock Ridge - unknown version"));      
                     
        /* This is currently a no op! We need to check the first plain file instead of the '.' entry in the root directory.*/
            if (c & 2048) 
                  archive->tmp = g_strdup_printf (_("Apple version %d"),aa_version);
    }                   
    /* else 
            g_print ("NO Rock Ridge present\n"); */
      if( ! use_rock)
      { 
            lseek(fileno(iso_stream), (16 + toc_offset) <<11, 0);
        read(fileno(iso_stream), &ipd, sizeof(ipd));
      
        block = 16;

        while( (unsigned char) ipd.type[0] != ISO_VD_END )
        {
                  /* Find the UCS escape sequence. */
            if(    ipd.escape_sequences[0] == '%'
                              && ipd.escape_sequences[1] == '/'
                              && ipd.escape_sequences[3] == '\0'
                    && (    ipd.escape_sequences[2] == '@'
                    || ipd.escape_sequences[2] == 'C'
                    || ipd.escape_sequences[2] == 'E') )
                break;

                  block++;
            lseek(fileno(iso_stream), (block + sector_offset) <<11, 0);
            read(fileno(iso_stream), &ipd, sizeof(ipd));
        }
                
            if( (unsigned char) ipd.type[0] == ISO_VD_END )
                  archive->tmp = g_strdup (_("Standard ISO without extension"));
            else 
                  use_joilet = 1;

            switch(ipd.escape_sequences[2])
            { 
                  case '@':
                  ucs_level = 1;
                  archive->tmp = g_strdup_printf (_("Joliet Level %d"),ucs_level);
                  break;
                  
                  case 'C':
                  ucs_level = 2;
                  archive->tmp = g_strdup_printf (_("Joliet Level %d"),ucs_level);
                  break;
                  
                  case 'E':
                  ucs_level = 3;
                  archive->tmp = g_strdup_printf (_("Joliet Level %d"),ucs_level);
                  break;
            }
            /*if( ucs_level < 3 )
                  g_print ("Don't know what ucs_level == %d means\n", ucs_level);*/
      }
      idr = (struct iso_directory_record *) &ipd.root_directory_record;
      if (!use_joilet) 
      {
            lseek(fileno(iso_stream),(16 + toc_offset) <<11, 0);   
            read(fileno(iso_stream), &ipd, sizeof(ipd));
      }
      parse_dir ("/" , iso_733((unsigned char *)idr->extent), iso_733((unsigned char *)idr->size), archive);
      xa_append_rows ( archive , 5 );

      td = todo_idr;    

      while(td)
      {
            parse_dir( td->name , td->extent, td->length, archive);
            g_free (td->name);
            xa_append_rows ( archive , 5 );
            td = td->next;
      }
      fclose(iso_stream);

      use_rock = FALSE;
      use_joilet = FALSE;
      ucs_level = 0;

      g_free (td);
      g_free (todo_idr);
      td = NULL;
      todo_idr = NULL;
        
      xa_set_button_state (1,1,0,1,1);
      OffTooltipPadlock();
      archive->status = XA_ARCHIVESTATUS_IDLE;
      gtk_widget_set_sensitive ( properties , TRUE );
      gtk_tree_view_set_model (GTK_TREE_VIEW(treeview1), model);
      g_object_unref (model);
      gtk_widget_set_sensitive ( iso_info , TRUE );
      gtk_widget_set_sensitive ( view_shell_output1 , FALSE );
      gtk_window_set_title (GTK_WINDOW(MainWindow),archive->path);
      gtk_widget_set_sensitive (close1,TRUE);
      Update_StatusBar ( _("Operation completed.") );
}

int iso_723 ( unsigned char *p)
{
    return (( p[0] & 0xff) | ((p[1] & 0xff) << 8));
}

int iso_731 ( unsigned char *p)
{
    return ((p[0] & 0xff) | ((p[1] & 0xff) << 8) | ((p[2] & 0xff) << 16) | ((p[3] & 0xff) << 24));
}

int iso_733 (unsigned char * p)
{
      return (iso_731 (p));
}

int DetectImage (FILE *iso)
{
      char buf[12];

      fseek (iso, 0L, SEEK_SET);
      fseek (iso, 32768, SEEK_CUR);
      fread (buf, sizeof (char), 8, iso);
      if (memcmp ("\x01\x43\x44\x30\x30\x31\x01\x00", buf, 8))
      {
            fseek (iso, 0L, SEEK_SET);
            fread ( &ipd, 1, sizeof(ipd), iso );
            fread (buf, sizeof (char), 12, iso);
            if (!memcmp ("\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", buf, 12))
            {
                  fseek (iso, 0L, SEEK_SET);
                  fseek (iso, 2352, SEEK_CUR);
                  fread (buf, sizeof (char), 12, iso);
                  if (!memcmp ("\x80\xC0\x80\x80\x80\x80\x80\xC0\x80\x80\x80\x80", buf, 12))
                        return (39184);
                  else
                        return(37648);
            }
        else
                  return (-1);
    }
      else
            return(32768);
}

GtkWidget *create_iso_properties_window ()
{
      iso_properties_window = gtk_dialog_new_with_buttons (_("ISO Information Window"),
                                                                        GTK_WINDOW (MainWindow), GTK_DIALOG_DESTROY_WITH_PARENT,
                                                                        GTK_STOCK_CLOSE, GTK_RESPONSE_NONE, NULL);
      gtk_window_set_destroy_with_parent (GTK_WINDOW (iso_properties_window), TRUE);
      gtk_window_set_position (GTK_WINDOW (iso_properties_window), GTK_WIN_POS_CENTER);
      gtk_window_set_resizable (GTK_WINDOW (iso_properties_window), FALSE);
      gtk_window_set_modal (GTK_WINDOW (iso_properties_window), TRUE);
      gtk_window_set_type_hint (GTK_WINDOW (iso_properties_window), GDK_WINDOW_TYPE_HINT_UTILITY);
        
      g_signal_connect(iso_properties_window, "response", G_CALLBACK(gtk_widget_destroy), NULL);
      g_signal_connect(iso_properties_window, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL);

      table1 = gtk_table_new (15, 2, TRUE);
      gtk_widget_show (table1);
      gtk_container_add (GTK_CONTAINER (GTK_DIALOG (iso_properties_window)->vbox), table1);
      gtk_table_set_row_spacings (GTK_TABLE (table1), 6);
      gtk_table_set_col_spacings (GTK_TABLE (table1), 6);

      name_label = gtk_label_new ("");
      set_label ( name_label , _("Filename:"));
      gtk_widget_show (name_label);
      gtk_table_attach (GTK_TABLE (table1), name_label, 0, 1, 0, 1,
                     (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (name_label), 0.99, 0.5);

      size_label = gtk_label_new ("");
      set_label ( size_label , _("Size:"));
      gtk_widget_show (size_label);
      gtk_table_attach (GTK_TABLE (table1), size_label, 0, 1, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (size_label), 0.99, 0.5);

      image_type_label = gtk_label_new ("");
      set_label ( image_type_label , _("Image type:"));
      gtk_widget_show (image_type_label);
      gtk_table_attach (GTK_TABLE (table1), image_type_label, 0, 1, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (image_type_label), 0.99, 0.5);

      system_id_label = gtk_label_new ("");
      set_label ( system_id_label , _("System ID:"));
    gtk_widget_show (system_id_label);
      gtk_table_attach (GTK_TABLE (table1), system_id_label, 0, 1, 4 , 5,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (system_id_label), 0.99, 0.5);

      volume_id_label = gtk_label_new ("");
      set_label ( volume_id_label , _("Volume ID:"));
      gtk_widget_show (volume_id_label);
      gtk_table_attach (GTK_TABLE (table1), volume_id_label, 0, 1, 5, 6,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (volume_id_label), 0.99, 0.5);

      application_label = gtk_label_new ("");
      set_label ( application_label , _("Application:"));
      gtk_widget_show (application_label);
      gtk_table_attach (GTK_TABLE (table1), application_label, 0, 1, 6, 7,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (application_label), 0.99, 0.5);

      publisher_label = gtk_label_new ("");
      set_label ( publisher_label , _("Publisher:"));
      gtk_widget_show (publisher_label);
      gtk_table_attach (GTK_TABLE (table1), publisher_label, 0, 1, 7, 8,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (publisher_label), 0.99, 0.5);

      preparer_label = gtk_label_new ("");
      set_label ( preparer_label , _("Preparer:"));
      gtk_widget_show (preparer_label);
      gtk_table_attach (GTK_TABLE (table1), preparer_label, 0, 1, 8, 9,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (preparer_label), 0.99, 0.5);

      creation_date_label = gtk_label_new ("");
      set_label ( creation_date_label , _("Creation date:"));
      gtk_widget_show (creation_date_label);
      gtk_table_attach (GTK_TABLE (table1), creation_date_label, 0, 1, 10, 11,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (creation_date_label), 0.99, 0.5);

      modified_date_label = gtk_label_new ("");
      set_label ( modified_date_label , _("Modified date:"));
      gtk_widget_show (modified_date_label);
      gtk_table_attach (GTK_TABLE (table1), modified_date_label, 0, 1, 11, 12,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (modified_date_label), 0.99, 0.5);

      expiration_date_label = gtk_label_new ("");
      set_label ( expiration_date_label , _("Expiration date:"));
      gtk_widget_show (expiration_date_label);
      gtk_table_attach (GTK_TABLE (table1), expiration_date_label, 0, 1, 12, 13,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (expiration_date_label), 0.99, 0.5);

      effective_date_label = gtk_label_new ("");
      set_label ( effective_date_label , _("Effective date:"));
      gtk_widget_show (effective_date_label);
      gtk_table_attach (GTK_TABLE (table1), effective_date_label, 0, 1, 13, 14,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0);
      gtk_misc_set_alignment (GTK_MISC (effective_date_label), 0.99, 0.5);

    filename_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (filename_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (filename_entry), FALSE);
      gtk_widget_show (filename_entry);
      gtk_table_attach (GTK_TABLE (table1), filename_entry, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      size_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (size_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (size_entry), FALSE);
      gtk_widget_show (size_entry);
      gtk_table_attach (GTK_TABLE (table1), size_entry, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      image_type_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (image_type_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (image_type_entry), FALSE);
      gtk_widget_show (image_type_entry);
      gtk_table_attach (GTK_TABLE (table1), image_type_entry, 1, 2, 2, 3,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      system_id_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (system_id_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (system_id_entry), FALSE);
      gtk_widget_show (system_id_entry);
      gtk_table_attach (GTK_TABLE (table1), system_id_entry, 1, 2, 4, 5,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);
        
      volume_id_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (volume_id_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (volume_id_entry), FALSE);
      gtk_widget_show (volume_id_entry);
      gtk_table_attach (GTK_TABLE (table1), volume_id_entry, 1, 2, 5, 6,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      application_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (application_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (application_entry), FALSE);
      gtk_widget_show (application_entry);
      gtk_table_attach (GTK_TABLE (table1), application_entry, 1, 2, 6, 7,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      publisher_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (publisher_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (publisher_entry), FALSE);
      gtk_widget_show (publisher_entry);
      gtk_table_attach (GTK_TABLE (table1), publisher_entry, 1, 2, 7, 8,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      preparer_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (preparer_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (preparer_entry), FALSE);
      gtk_widget_show (preparer_entry);
      gtk_table_attach (GTK_TABLE (table1), preparer_entry, 1, 2, 8, 9,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      creation_date_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (creation_date_entry), FALSE);
    gtk_entry_set_has_frame (GTK_ENTRY (creation_date_entry), FALSE);
      gtk_widget_show (creation_date_entry);
      gtk_table_attach (GTK_TABLE (table1), creation_date_entry, 1, 2, 10, 11,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      modified_date_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (modified_date_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (modified_date_entry), FALSE);
      gtk_widget_show (modified_date_entry);
      gtk_table_attach (GTK_TABLE (table1), modified_date_entry, 1, 2, 11, 12,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      expiration_date_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (expiration_date_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (expiration_date_entry), FALSE);
      gtk_widget_show (expiration_date_entry);
      gtk_table_attach (GTK_TABLE (table1), expiration_date_entry, 1, 2, 12, 13,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);

      effective_date_entry = gtk_entry_new ();
      gtk_editable_set_editable (GTK_EDITABLE (effective_date_entry), FALSE);
      gtk_entry_set_has_frame (GTK_ENTRY (effective_date_entry), FALSE);
      gtk_widget_show (effective_date_entry);
      gtk_table_attach (GTK_TABLE (table1), effective_date_entry, 1, 2, 13, 14,
                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
                    (GtkAttachOptions) (0), 0, 0);
        
      return iso_properties_window;
}


Generated by  Doxygen 1.6.0   Back to index