home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Utilities / mkisofs-1.11-MIHS / eltorito.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-08  |  6.7 KB  |  264 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. #include <stdlib.h>
  33.  
  34. #include "mkisofs.h"
  35. #include "iso9660.h"
  36.  
  37. static struct eltorito_validation_entry valid_desc;
  38. static struct eltorito_defaultboot_entry default_desc;
  39.  
  40. /*
  41.  * Check for presence of boot catalog. If it does not exist then make it 
  42.  */
  43. void FDECL1(init_boot_catalog, const char *, path)
  44. {
  45.  
  46.     int          bcat;
  47.     char        * bootpath;                /* filename of boot catalog */
  48.     char        * buf;
  49.     struct stat      statbuf;
  50.     
  51.     bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
  52.     strcpy(bootpath, path);
  53.     if (bootpath[strlen(bootpath)-1] != '/') 
  54.     {
  55.     strcat(bootpath,"/");
  56.     }
  57.     
  58.     strcat(bootpath, boot_catalog);
  59.     
  60.     /*
  61.      * check for the file existing 
  62.      */
  63. #ifdef DEBUG_TORITO
  64.     printf("Looking for boot catalog file %s\n",bootpath);
  65. #endif
  66.     
  67.     if (!stat_filter(bootpath, &statbuf)) 
  68.     {
  69.     /*
  70.      * make sure its big enough to hold what we want 
  71.      */
  72.     if (statbuf.st_size == 2048) 
  73.     {
  74.         /*
  75.          * printf("Boot catalog exists, so we do nothing\n"); 
  76.          */
  77.         free(bootpath);
  78.         return;
  79.     }
  80.     else 
  81.     {
  82.         fprintf(stderr, "A boot catalog exists and appears corrupted.\n");
  83.         fprintf(stderr, "Please check the following file: %s.\n",bootpath);
  84.         fprintf(stderr, "This file must be removed before a bootable CD can be done.\n");
  85.         free(bootpath);
  86.         exit(1);
  87.     }
  88.     }
  89.     
  90.     /*
  91.      * file does not exist, so we create it 
  92.      * make it one CD sector long
  93.      */
  94.     bcat = open(bootpath, O_WRONLY | O_CREAT, S_IROTH | S_IRGRP | S_IRWXU );
  95.     if (bcat == -1) 
  96.     {
  97.     fprintf(stderr, "Error creating boot catalog, exiting...\n");
  98.     perror("");
  99.     exit(1);
  100.     }
  101.     
  102.     buf = (char *) e_malloc( 2048 );
  103.     write(bcat, buf, 2048);
  104.     close(bcat);
  105.     free(bootpath);
  106. } /* init_boot_catalog(... */
  107.  
  108. void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
  109. {
  110.     int                bootcat;
  111.     int                checksum;
  112.     unsigned char              * checksum_ptr;
  113.     struct directory_entry      * de;
  114.     struct directory_entry      * de2;
  115.     int                i;
  116.     int                nsectors;
  117.     
  118.     memset(boot_desc, 0, sizeof(*boot_desc));
  119.     boot_desc->id[0] = 0;
  120.     memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
  121.     boot_desc->version[0] = 1;
  122.     
  123.     memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID));
  124.     
  125.     /*
  126.      * search from root of iso fs to find boot catalog 
  127.      */
  128.     de2 = search_tree_file(root, boot_catalog);
  129.     if (!de2) 
  130.     {
  131.     fprintf(stderr,"Uh oh, I cant find the boot catalog!\n");
  132.     exit(1);
  133.     }
  134.     
  135.     set_731(boot_desc->bootcat_ptr,
  136.         (unsigned int) get_733(de2->isorec.extent));
  137.     
  138.     /* 
  139.      * now adjust boot catalog
  140.      * lets find boot image first 
  141.      */
  142.     de=search_tree_file(root, boot_image);
  143.     if (!de) 
  144.     {
  145.     fprintf(stderr,"Uh oh, I cant find the boot image!\n");
  146.     exit(1);
  147.     } 
  148.     
  149.     /* 
  150.      * we have the boot image, so write boot catalog information
  151.      * Next we write out the primary descriptor for the disc 
  152.      */
  153.     memset(&valid_desc, 0, sizeof(valid_desc));
  154.     valid_desc.headerid[0] = 1;
  155.     valid_desc.arch[0] = EL_TORITO_ARCH_x86;
  156.     
  157.     /*
  158.      * we'll shove start of publisher id into id field, may get truncated
  159.      * but who really reads this stuff!
  160.      */
  161.     if (publisher)
  162.     memcpy_max(valid_desc.id,  publisher, strlen(publisher));
  163.     
  164.     valid_desc.key1[0] = 0x55;
  165.     valid_desc.key2[0] = 0xAA;
  166.     
  167.     /*
  168.      * compute the checksum 
  169.      */
  170.     checksum=0;
  171.     checksum_ptr = (unsigned char *) &valid_desc;
  172.     for (i=0; i<sizeof(valid_desc); i+=2) 
  173.     {
  174.     /*
  175.      * skip adding in ckecksum word, since we dont have it yet! 
  176.      */
  177.     if (i == 28)
  178.     {
  179.         continue;
  180.     }
  181.     checksum += (unsigned int)checksum_ptr[i];
  182.     checksum += ((unsigned int)checksum_ptr[i+1])*256;
  183.     }
  184.     
  185.     /* 
  186.      * now find out the real checksum 
  187.      */
  188.     checksum = -checksum;
  189.     set_721(valid_desc.cksum, (unsigned int) checksum);
  190.     
  191.     /*
  192.      * now make the initial/default entry for boot catalog 
  193.      */
  194.     memset(&default_desc, 0, sizeof(default_desc));
  195.     default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
  196.     
  197.     /*
  198.      * use default BIOS loadpnt
  199.      */ 
  200.     set_721(default_desc.loadseg, 0);
  201.     default_desc.arch[0] = EL_TORITO_ARCH_x86;
  202.     
  203.     /*
  204.      * figure out size of boot image in sectors, for now hard code to
  205.      * assume 512 bytes/sector on a bootable floppy
  206.      */
  207.     nsectors = ((de->size + 511) & ~(511))/512;
  208.     printf("\nSize of boot image is %d sectors -> ", nsectors); 
  209.     
  210.     /*
  211.      * choose size of emulated floppy based on boot image size 
  212.      */
  213.     if (nsectors == 2880 ) 
  214.     {
  215.     default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
  216.     printf("Emulating a 1.44 meg floppy\n");
  217.     }
  218.     else if (nsectors == 5760 ) 
  219.     {
  220.     default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
  221.     printf("Emulating a 2.88 meg floppy\n");
  222.     }
  223.     else if (nsectors == 2400 ) 
  224.     {
  225.     default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
  226.     printf("Emulating a 1.2 meg floppy\n");
  227.     }
  228.     else 
  229.     {
  230.     fprintf(stderr,"\nError - boot image is not the an allowable size.\n");
  231.     exit(1);
  232.     }
  233.     
  234.     
  235.     /* 
  236.      * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! 
  237.      */
  238.     nsectors = 1;
  239.     set_721(default_desc.nsect, (unsigned int) nsectors );
  240. #ifdef DEBUG_TORITO
  241.     printf("Extent of boot images is %d\n",get_733(de->isorec.extent));
  242. #endif
  243.     set_731(default_desc.bootoff, 
  244.         (unsigned int) get_733(de->isorec.extent));
  245.     
  246.     /*
  247.      * now write it to disk 
  248.      */
  249.     bootcat = open(de2->whole_name, O_RDWR);
  250.     if (bootcat == -1) 
  251.     {
  252.     fprintf(stderr,"Error opening boot catalog for update.\n");
  253.     perror("");
  254.     exit(1);
  255.     }
  256.     
  257.     /* 
  258.      * write out 
  259.      */
  260.     write(bootcat, &valid_desc, 32);
  261.     write(bootcat, &default_desc, 32);
  262.     close(bootcat);
  263. } /* get_torito_desc(... */
  264.