home *** CD-ROM | disk | FTP | other *** search
/ Dream 49 / Amiga_Dream_49.iso / beos / utils / mkisofs-1.000 / mkisofs-1.11-beos / eltorito.c < prev    next >
C/C++ Source or Header  |  1997-04-09  |  7KB  |  263 lines

  1. /*
  2.  * Program eltorito.c - Handle El Torito specific extensions to iso9660.
  3.  * 
  4.  
  5.    Written by Michael Fulbright <msf@redhat.com> (1996).
  6.  
  7.    Copyright 1996 RedHat Software, Incorporated
  8.  
  9.    This program is free software; you can redistribute it and/or modify
  10.    it under the terms of the GNU General Public License as published by
  11.    the Free Software Foundation; either version 2, or (at your option)
  12.    any later version.
  13.  
  14.    This program is distributed in the hope that it will be useful,
  15.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.    GNU General Public License for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License
  20.    along with this program; if not, write to the Free Software
  21.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */
  22.  
  23.  
  24. static char rcsid[] ="$Id: eltorito.c,v 1.5 1997/03/08 17:27:01 eric Rel $";
  25.  
  26. #include <stdio.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <unistd.h>
  30. #include <fcntl.h>
  31. #include <malloc.h>
  32.  
  33. #include "mkisofs.h"
  34. #include "iso9660.h"
  35.  
  36. static struct eltorito_validation_entry valid_desc;
  37. static struct eltorito_defaultboot_entry default_desc;
  38.  
  39. /*
  40.  * Check for presence of boot catalog. If it does not exist then make it 
  41.  */
  42. void FDECL1(init_boot_catalog, const char *, path)
  43. {
  44.  
  45.     int          bcat;
  46.     char        * bootpath;                /* filename of boot catalog */
  47.     char        * buf;
  48.     struct stat      statbuf;
  49.     
  50.     bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
  51.     strcpy(bootpath, path);
  52.     if (bootpath[strlen(bootpath)-1] != '/') 
  53.     {
  54.     strcat(bootpath,"/");
  55.     }
  56.     
  57.     strcat(bootpath, boot_catalog);
  58.     
  59.     /*
  60.      * check for the file existing 
  61.      */
  62. #ifdef DEBUG_TORITO
  63.     printf("Looking for boot catalog file %s\n",bootpath);
  64. #endif
  65.     
  66.     if (!stat_filter(bootpath, &statbuf)) 
  67.     {
  68.     /*
  69.      * make sure its big enough to hold what we want 
  70.      */
  71.     if (statbuf.st_size == 2048) 
  72.     {
  73.         /*
  74.          * printf("Boot catalog exists, so we do nothing\n"); 
  75.          */
  76.         free(bootpath);
  77.         return;
  78.     }
  79.     else 
  80.     {
  81.         fprintf(stderr, "A boot catalog exists and appears corrupted.\n");
  82.         fprintf(stderr, "Please check the following file: %s.\n",bootpath);
  83.         fprintf(stderr, "This file must be removed before a bootable CD can be done.\n");
  84.         free(bootpath);
  85.         exit(1);
  86.     }
  87.     }
  88.     
  89.     /*
  90.      * file does not exist, so we create it 
  91.      * make it one CD sector long
  92.      */
  93.     bcat = open(bootpath, O_WRONLY | O_CREAT, S_IROTH | S_IRGRP | S_IRWXU );
  94.     if (bcat == -1) 
  95.     {
  96.     fprintf(stderr, "Error creating boot catalog, exiting...\n");
  97.     perror("");
  98.     exit(1);
  99.     }
  100.     
  101.     buf = (char *) e_malloc( 2048 );
  102.     write(bcat, buf, 2048);
  103.     close(bcat);
  104.     free(bootpath);
  105. } /* init_boot_catalog(... */
  106.  
  107. void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
  108. {
  109.     int                bootcat;
  110.     int                checksum;
  111.     unsigned char              * checksum_ptr;
  112.     struct directory_entry      * de;
  113.     struct directory_entry      * de2;
  114.     int                i;
  115.     int                nsectors;
  116.     
  117.     memset(boot_desc, 0, sizeof(*boot_desc));
  118.     boot_desc->id[0] = 0;
  119.     memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
  120.     boot_desc->version[0] = 1;
  121.     
  122.     memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));
  123.     
  124.     /*
  125.      * search from root of iso fs to find boot catalog 
  126.      */
  127.     de2 = search_tree_file(root, boot_catalog);
  128.     if (!de2) 
  129.     {
  130.     fprintf(stderr,"Uh oh, I cant find the boot catalog!\n");
  131.     exit(1);
  132.     }
  133.     
  134.     set_731(boot_desc->bootcat_ptr,
  135.         (unsigned int) get_733(de2->isorec.extent));
  136.     
  137.     /* 
  138.      * now adjust boot catalog
  139.      * lets find boot image first 
  140.      */
  141.     de=search_tree_file(root, boot_image);
  142.     if (!de) 
  143.     {
  144.     fprintf(stderr,"Uh oh, I cant find the boot image!\n");
  145.     exit(1);
  146.     } 
  147.     
  148.     /* 
  149.      * we have the boot image, so write boot catalog information
  150.      * Next we write out the primary descriptor for the disc 
  151.      */
  152.     memset(&valid_desc, 0, sizeof(valid_desc));
  153.     valid_desc.headerid[0] = 1;
  154.     valid_desc.arch[0] = EL_TORITO_ARCH_x86;
  155.     
  156.     /*
  157.      * we'll shove start of publisher id into id field, may get truncated
  158.      * but who really reads this stuff!
  159.      */
  160.     if (publisher)
  161.     memcpy_max(valid_desc.id,  publisher, strlen(publisher));
  162.     
  163.     valid_desc.key1[0] = 0x55;
  164.     valid_desc.key2[0] = 0xAA;
  165.     
  166.     /*
  167.      * compute the checksum 
  168.      */
  169.     checksum=0;
  170.     checksum_ptr = (unsigned char *) &valid_desc;
  171.     for (i=0; i<sizeof(valid_desc); i+=2) 
  172.     {
  173.     /*
  174.      * skip adding in ckecksum word, since we dont have it yet! 
  175.      */
  176.     if (i == 28)
  177.     {
  178.         continue;
  179.     }
  180.     checksum += (unsigned int)checksum_ptr[i];
  181.     checksum += ((unsigned int)checksum_ptr[i+1])*256;
  182.     }
  183.     
  184.     /* 
  185.      * now find out the real checksum 
  186.      */
  187.     checksum = -checksum;
  188.     set_721(valid_desc.cksum, (unsigned int) checksum);
  189.     
  190.     /*
  191.      * now make the initial/default entry for boot catalog 
  192.      */
  193.     memset(&default_desc, 0, sizeof(default_desc));
  194.     default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
  195.     
  196.     /*
  197.      * use default BIOS loadpnt
  198.      */ 
  199.     set_721(default_desc.loadseg, 0);
  200.     default_desc.arch[0] = EL_TORITO_ARCH_x86;
  201.     
  202.     /*
  203.      * figure out size of boot image in sectors, for now hard code to
  204.      * assume 512 bytes/sector on a bootable floppy
  205.      */
  206.     nsectors = ((de->size + 511) & ~(511))/512;
  207.     printf("\nSize of boot image is %d sectors -> ", nsectors); 
  208.     
  209.     /*
  210.      * choose size of emulated floppy based on boot image size 
  211.      */
  212.     if (nsectors == 2880 ) 
  213.     {
  214.     default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
  215.     printf("Emulating a 1.44 meg floppy\n");
  216.     }
  217.     else if (nsectors == 5760 ) 
  218.     {
  219.     default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
  220.     printf("Emulating a 2.88 meg floppy\n");
  221.     }
  222.     else if (nsectors == 2400 ) 
  223.     {
  224.     default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
  225.     printf("Emulating a 1.2 meg floppy\n");
  226.     }
  227.     else 
  228.     {
  229.     fprintf(stderr,"\nError - boot image is not the an allowable size.\n");
  230.     exit(1);
  231.     }
  232.     
  233.     
  234.     /* 
  235.      * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! 
  236.      */
  237.     nsectors = 1;
  238.     set_721(default_desc.nsect, (unsigned int) nsectors );
  239. #ifdef DEBUG_TORITO
  240.     printf("Extent of boot images is %d\n",get_733(de->isorec.extent));
  241. #endif
  242.     set_731(default_desc.bootoff, 
  243.         (unsigned int) get_733(de->isorec.extent));
  244.     
  245.     /*
  246.      * now write it to disk 
  247.      */
  248.     bootcat = open(de2->whole_name, O_RDWR);
  249.     if (bootcat == -1) 
  250.     {
  251.     fprintf(stderr,"Error opening boot catalog for update.\n");
  252.     perror("");
  253.     exit(1);
  254.     }
  255.     
  256.     /* 
  257.      * write out 
  258.      */
  259.     write(bootcat, &valid_desc, 32);
  260.     write(bootcat, &default_desc, 32);
  261.     close(bootcat);
  262. } /* get_torito_desc(... */
  263.