home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / cdrom / mkisofs.105 / source / mkisofs.c < prev    next >
C/C++ Source or Header  |  1977-12-31  |  28KB  |  956 lines

  1. #include "amigadef.h"
  2. /*
  3.  * Program mkisofs.c - generate iso9660 filesystem  based upon directory
  4.  * tree on hard disk.
  5.  
  6.    Written by Eric Youngdale (1993).
  7.  
  8.    Copyright 1993 Yggdrasil Computing, Incorporated
  9.  
  10.    This program is free software; you can redistribute it and/or modify
  11.    it under the terms of the GNU General Public License as published by
  12.    the Free Software Foundation; either version 2, or (at your option)
  13.    any later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.    You should have received a copy of the GNU General Public License
  21.    along with this program; if not, write to the Free Software
  22.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  23.  
  24. /* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
  25.  
  26. #include <errno.h>
  27. #include "mkisofs.h"
  28.  
  29. #ifdef linux
  30. #include <getopt.h>
  31. #endif
  32.  
  33. #include "iso9660.h"
  34. #include <ctype.h>
  35.  
  36. #ifndef VMS
  37. #include <time.h>
  38. #else
  39. #include <sys/time.h>
  40. #include "vms.h"
  41. #endif
  42.  
  43. #include <stdlib.h>
  44. #include <sys/stat.h>
  45.  
  46. #ifndef VMS
  47. #include <unistd.h>
  48. #endif
  49.  
  50. #include "exclude.h"
  51.  
  52. #ifdef __NetBSD__
  53. #include <sys/time.h>
  54. #include <sys/resource.h>
  55. #endif
  56.  
  57. struct directory * root = NULL;
  58.  
  59. static char version_string[] = "mkisofs v1.05";
  60.  
  61. FILE * discimage;
  62. unsigned int next_extent = 0;
  63. unsigned int last_extent = 0;
  64. unsigned int path_table_size = 0;
  65. unsigned int path_table[4] = {0,};
  66. unsigned int path_blocks = 0;
  67. struct iso_directory_record root_record;
  68. static int timezone_offset;
  69. char * extension_record = NULL;
  70. int extension_record_extent = 0;
  71. static  int extension_record_size = 0;
  72.  
  73. /* These variables are associated with command line options */
  74. int use_RockRidge = 0;
  75. int verbose = 0;
  76. int all_files  = 0;
  77. int follow_links = 0;
  78. int rationalize = 0;
  79. int generate_tables = 0;
  80. char * preparer = PREPARER_DEFAULT;
  81. char * publisher = PUBLISHER_DEFAULT;
  82. char * appid = APPID_DEFAULT;
  83. char * copyright = COPYRIGHT_DEFAULT;
  84. char * biblio = BIBLIO_DEFAULT;
  85. char * abstract = ABSTRACT_DEFAULT;
  86. char * volset_id = VOLSET_ID_DEFAULT;
  87. char * volume_id = VOLUME_ID_DEFAULT;
  88. char * system_id = SYSTEM_ID_DEFAULT;
  89.  
  90. int omit_period = 0;             /* Violates iso9660, but these are a pain */
  91. int transparent_compression = 0; /* So far only works with linux */
  92. int omit_version_number = 0;     /* May violate iso9660, but noone uses vers*/
  93. int RR_relocation_depth = 6;     /* Violates iso9660, but most systems work */
  94. int full_iso9660_filenames = 0;  /* Used with Amiga. Disc will not work with
  95.                   DOS */
  96. int allow_leading_dots = 0;     /* DOS cannot read names with leading dots */
  97.  
  98. struct rcopts{
  99.   char * tag;
  100.   char ** variable;
  101. };
  102.  
  103. struct rcopts rcopt[] = {
  104.   {"PREP", &preparer},
  105.   {"PUBL", &publisher},
  106.   {"APPI", &appid},
  107.   {"COPY", ©right},
  108.   {"BIBL", &biblio},
  109.   {"ABST", &abstract},
  110.   {"VOLS", &volset_id},
  111.   {"VOLI", &volume_id},
  112.   {"SYSI", &system_id},
  113.   {NULL, NULL}
  114. };
  115.  
  116. #ifdef ultrix
  117. char *strdup(s)
  118. char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;}
  119. #endif
  120.  
  121. void FDECL1(read_rcfile, char *, appname)
  122. {
  123.   FILE * rcfile;
  124.   struct rcopts * rco;
  125.   char * pnt, *pnt1;
  126.   char linebuffer[256];
  127.   static char rcfn[] = ".mkisofsrc";
  128.   char filename[1000];
  129.   int linum;
  130.  
  131.   strcpy(filename, rcfn);
  132.   rcfile = fopen(filename, "r");
  133.   if (!rcfile && errno != ENOENT)
  134.     perror(filename);
  135.  
  136.   if (!rcfile)
  137.     {
  138.       pnt = getenv("HOME");
  139.       if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= sizeof(filename))
  140.     {
  141.       strcpy(filename, pnt);
  142.       strcat(filename, "/");
  143.       strcat(filename, rcfn);
  144.       rcfile = fopen(filename, "r");
  145.       if (!rcfile && errno != ENOENT)
  146.         perror(filename);
  147.     }
  148.     }
  149.   if (!rcfile && strlen(appname)+sizeof(rcfn)+2 <= sizeof(filename))
  150.     {
  151.       strcpy(filename, appname);
  152.       pnt = strrchr(filename, '/');
  153. #ifdef AMIGAdirs
  154.       if (pnt==0)
  155.        {
  156.        pnt = strrchr(filename, ':');
  157.        }
  158. #endif
  159.       if (pnt)
  160.     {
  161.       strcpy(pnt + 1, rcfn);
  162.       rcfile = fopen(filename, "r");
  163.       if (!rcfile && errno != ENOENT)
  164.         perror(filename);
  165.     }
  166.     }
  167.   if (!rcfile)
  168.     return;
  169.   fprintf(stderr, "Using \"%s\"\n", filename);
  170.   /* OK, we got it.  Now read in the lines and parse them */
  171.   linum = 0;
  172.   while (fgets(linebuffer, sizeof(linebuffer), rcfile))
  173.     {
  174.       char *name;
  175.       char *name_end;
  176.       ++linum;
  177.       /* skip any leading white space */
  178.     pnt = linebuffer;
  179.       while (*pnt == ' ' || *pnt == '\t')
  180.     ++pnt;
  181.       /* If we are looking at a # character, this line is a comment. */
  182.     if (*pnt == '#')
  183.       continue;
  184.       /* The name should begin in the left margin.  Make sure it is in
  185.      upper case.  Stop when we see white space or a comment. */
  186.     name = pnt;
  187.       while (*pnt && isalpha(*pnt))
  188.     {
  189.       if(islower(*pnt))
  190.         *pnt = toupper(*pnt);
  191.       pnt++;
  192.     }
  193.       if (name == pnt)
  194.     {
  195.       fprintf(stderr, "%s:%d: name required\n", filename, linum);
  196.       continue;
  197.     }
  198.       name_end = pnt;
  199.       /* Skip past white space after the name */
  200.       while (*pnt == ' ' || *pnt == '\t')
  201.     pnt++;
  202.       /* silently ignore errors in the rc file. */
  203.       if (*pnt != '=')
  204.     {
  205.       fprintf(stderr, "%s:%d: equals sign required\n", filename, linum);
  206.       continue;
  207.     }
  208.       /* Skip pas the = sign, and any white space following it */
  209.       pnt++; /* Skip past '=' sign */
  210.       while (*pnt == ' ' || *pnt == '\t')
  211.     pnt++;
  212.       +       /* now it is safe to NUL terminate the name */
  213.     *name_end = 0;
  214.       /* Now get rid of trailing newline */
  215.       pnt1 = pnt;
  216.       while (*pnt1)
  217.     {
  218.       if (*pnt1 == '\n')
  219.         {
  220.           *pnt1 = 0;
  221.           break;
  222.         }
  223.       pnt1++;
  224.     };
  225.       /* OK, now figure out which option we have */
  226.       for(rco = rcopt; rco->tag; rco++) {
  227.     if(strcmp(rco->tag, name) == 0)
  228.       {
  229.         *rco->variable = strdup(pnt);
  230.         break;
  231.       };
  232.       }
  233.       if (rco->tag == NULL)
  234.     {
  235.       fprintf(stderr, "%s:%d: field name \"%s\" unknown\n", filename, linum,
  236.           name);
  237.     }
  238.      }
  239.   if (ferror(rcfile))
  240.     perror(filename);
  241.   fclose(rcfile);
  242. }
  243.  
  244. char * path_table_l = NULL;
  245. char * path_table_m = NULL;
  246. int goof = 0;
  247.  
  248. void usage(){
  249.     fprintf(stderr,"Usage:\n");
  250.     fprintf(stderr,
  251. "mkisofs [-o outfile] [-R] [-V volid] [-v] [-a] \
  252. [-T]\n [-l] [-d] [-V] [-D] [-L] [-p preparer] \
  253. [-P publisher] [ -A app_id ] [-z] \
  254. [-x path -x path ...] path\n");
  255.     exit(1);
  256. }
  257.  
  258. int get_iso9660_timezone_offset(){
  259.   struct tm gm;
  260.   struct tm * pt;
  261.   time_t ctime;
  262.   int local_min, gmt_min;
  263.  
  264.   time(&ctime);
  265.   pt = gmtime(&ctime);
  266.   gm = *pt;
  267.   pt = localtime(&ctime);
  268.  
  269.   if(gm.tm_year < pt->tm_year)
  270.     gm.tm_yday = -1;
  271.  
  272.   if(gm.tm_year > pt->tm_year)
  273.     pt->tm_yday = -1;
  274.  
  275.   gmt_min = gm.tm_min + 60*(gm.tm_hour + 24*gm.tm_yday);
  276.   local_min = pt->tm_min + 60*(pt->tm_hour + 24*pt->tm_yday);
  277.   return (gmt_min - local_min)/15;
  278. }
  279.  
  280.  
  281. /* Fill in date in the iso9660 format */
  282. int FDECL2(iso9660_date,char *, result, time_t, ctime){
  283.   struct tm *local;
  284.   local = localtime(&ctime);
  285.   result[0] = local->tm_year;
  286.   result[1] = local->tm_mon + 1;
  287.   result[2] = local->tm_mday;
  288.   result[3] = local->tm_hour;
  289.   result[4] = local->tm_min;
  290.   result[5] = local->tm_sec;
  291.   result[6] = timezone_offset;
  292.   return 0;
  293. }
  294.  
  295. int FDECL3(iso9660_file_length,const char*, name, struct directory_entry *, sresult, 
  296.             int, dirflag){
  297.   int seen_dot = 0;
  298.   int seen_semic = 0;
  299.   char * result;
  300.   int priority = 32767;
  301.   int tildes = 0;
  302.   int ignore = 0;
  303.   int extra = 0;
  304.   int current_length = 0;
  305.   int chars_after_dot = 0;
  306.   int chars_before_dot = 0;
  307.   const char * pnt;
  308.   result = sresult->isorec.name;
  309.  
  310.   if(strcmp(name,".") == 0){
  311.     if(result) *result = 0;
  312.     return 1;
  313.   };
  314.  
  315.   if(strcmp(name,"..") == 0){
  316.     if(result) {
  317.         *result++ = 1;
  318.         *result++ = 0;
  319.     }
  320.     return 1;
  321.   };
  322.  
  323.   pnt = name;
  324.   while(*pnt){
  325. #ifdef VMS
  326.     if(strcmp(pnt,".DIR;1") == 0) break;
  327. #endif
  328.     if(*pnt == '#') {priority = 1; pnt++; continue; };
  329.     if(*pnt == '~') {priority = 1; tildes++; pnt++; continue;};
  330.     if(*pnt == ';') {seen_semic = 1; *result++ = *pnt++; continue; };
  331.     if(ignore) {pnt++; continue;};
  332.     if(seen_semic){
  333.       if(*pnt >= '0' && *pnt <= '9') *result++ = *pnt;
  334.       extra++;
  335.       pnt++;
  336.       continue;
  337.     };
  338.     if(full_iso9660_filenames) {
  339.       /* Here we allow a more relaxed syntax. */
  340.       if(*pnt == '.') {
  341.     if (seen_dot) {ignore++; continue;}
  342.     seen_dot++;
  343.       }
  344.       if(current_length < 30) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
  345.     } else { /* Dos style filenames */
  346.       if(*pnt == '.') {
  347.         if (!chars_before_dot && !allow_leading_dots) {
  348.       /* DOS can't read files with dot first */
  349.           chars_before_dot++;
  350.           if (result) *result++ = '_'; /* Substitute underscore */
  351.         } else {
  352.           if (seen_dot) {ignore++; continue;}
  353.       if(result) *result++ = '.';
  354.       seen_dot++;
  355.         }
  356.       } else if (seen_dot) {
  357.     if(chars_after_dot < 3) {
  358.       chars_after_dot++;
  359.       if(result) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
  360.     }
  361.       } else {
  362.     if(chars_before_dot < 8) {
  363.       chars_before_dot++;
  364.       if(result) *result++ = (islower(*pnt) ? toupper(*pnt) : *pnt);
  365.     };
  366.       };
  367.     };
  368.     current_length++;
  369.     pnt++;
  370.   };
  371.   
  372.   if(tildes == 2){
  373.     int prio1 = 0;
  374.     pnt = name;
  375.     while (*pnt && *pnt != '~') pnt++;
  376.     if (*pnt) pnt++;
  377.     while(*pnt && *pnt != '~'){
  378.       prio1 = 10*prio1 + *pnt - '0';
  379.       pnt++;
  380.     };
  381.     priority = prio1;
  382.   };
  383.     
  384.   if (!dirflag){
  385.     if (!seen_dot && !omit_period) {
  386.       if (result) *result++ = '.'; 
  387.       extra++;
  388.     };
  389.     if(!omit_version_number && !seen_semic) {
  390.       if(result){
  391.     *result++ = ';';
  392.     *result++ = '1';
  393.       };
  394.       extra += 2;
  395.     }
  396.   };
  397.             
  398.   if(result) *result++ = 0;
  399.   sresult->priority = priority;
  400.   return chars_before_dot + chars_after_dot + seen_dot + extra;
  401. }
  402.  
  403. #ifdef ADD_FILES
  404.  
  405. struct file_adds *root_file_adds = NULL;
  406.  
  407. void
  408. FDECL2(add_one_file, char *, addpath, char *, path )
  409. {
  410.   char *cp;
  411.   char *name;
  412.   struct file_adds *f;
  413.   struct file_adds *tmp;
  414.  
  415.   f = root_file_adds;
  416.   tmp = NULL;
  417.  
  418.   name = rindex (addpath, PATH_SEPARATOR);
  419.   if (name == NULL) {
  420.     name = addpath;
  421.   } else {
  422.     name++;
  423.   }
  424.  
  425.   cp = strtok (addpath, SPATH_SEPARATOR);
  426.  
  427.   while (cp != NULL && strcmp (name, cp)) {
  428.      if (f == NULL) {
  429.         root_file_adds = e_malloc (sizeof *root_file_adds);
  430.         f=root_file_adds;
  431.         f->name = NULL;
  432.         f->child = NULL;
  433.         f->next = NULL;
  434.         f->add_count = 0;
  435.         f->adds = NULL;
  436.     f->used = 0;
  437.      }
  438.     if (f->child) {
  439.       for (tmp = f->child; tmp->next != NULL; tmp =tmp->next) {
  440.          if (strcmp (tmp->name, cp) == 0) {
  441.            f = tmp;
  442.            goto next;
  443.          }
  444.       }
  445.       if (strcmp (tmp->name, cp) == 0) {
  446.           f=tmp;
  447.           goto next;
  448.       }
  449.       /* add a new node. */
  450.       tmp->next = e_malloc (sizeof (*tmp->next));
  451.       f=tmp->next;
  452.       f->name = strdup (cp);
  453.       f->child = NULL;
  454.       f->next = NULL;
  455.       f->add_count = 0;
  456.       f->adds = NULL;
  457.       f->used = 0;
  458.     } else {
  459.       /* no children. */
  460.       f->child = e_malloc (sizeof (*f->child));
  461.       f = f->child;
  462.       f->name = strdup (cp);
  463.       f->child = NULL;
  464.       f->next = NULL;
  465.       f->add_count = 0;
  466.       f->adds = NULL;
  467.       f->used = 0;
  468.  
  469.     }
  470.    next:
  471.      cp = strtok (NULL, SPATH_SEPARATOR);
  472.    }
  473.   /* Now f if non-null points to where we should add things */
  474.   if (f == NULL) {
  475.      root_file_adds = e_malloc (sizeof *root_file_adds);
  476.      f=root_file_adds;
  477.      f->name = NULL;
  478.      f->child = NULL;
  479.      f->next = NULL;
  480.      f->add_count = 0;
  481.      f->adds = NULL;
  482.    }
  483.  
  484.   /* Now f really points to where we should add this name. */
  485.   f->add_count++;
  486.   f->adds = realloc (f->adds, sizeof (*f->adds)*f->add_count);
  487.   f->adds[f->add_count-1].path = strdup (path);
  488.   f->adds[f->add_count-1].name = strdup (name);
  489. }
  490.  
  491. void
  492. FDECL3(add_file_list, int, argc, char **,argv, int, ind)
  493. {
  494.   char *ptr;
  495.   char *dup_arg;
  496.  
  497. #ifdef AMIGA
  498. printf("\nAMIGA® Version\n\n");
  499. #endif
  500.  
  501.   while (ind < argc) {
  502.      dup_arg = strdup (argv[ind]);
  503.      ptr = index (dup_arg,'=');
  504.      if (ptr == NULL) {
  505.         free (dup_arg);
  506.         return;
  507.      }
  508.      *ptr = 0;
  509.      ptr++;
  510.      add_one_file (dup_arg, ptr);
  511.      free (dup_arg);
  512.      ind++;
  513.   }
  514. }
  515. void
  516. FDECL1(add_file, char *, filename)
  517. {
  518.   char buff[1024];
  519.   FILE *f;
  520.   char *ptr;
  521.   char *p2;
  522.   int count=0;
  523.  
  524.   if (strcmp (filename, "-") == 0) {
  525.     f = stdin;
  526.   } else {
  527.     f = fopen (filename, "r");
  528.     if (f == NULL) {
  529.       perror ("fopen");
  530.       exit (1);
  531.     }
  532.   }
  533.   while (fgets (buff, 1024, f)) {
  534.     count++;
  535.     ptr = buff;
  536.     while (isspace (*ptr)) ptr++;
  537.     if (*ptr==0) continue;
  538.     if (*ptr=='#') continue;
  539.  
  540.     if (ptr[strlen(ptr)-1]== '\n') ptr[strlen(ptr)-1]=0;
  541.     p2 = index (ptr, '=');
  542.     if (p2 == NULL) {
  543.       fprintf (stderr, "Error in line %d: %s\n", count, buff);
  544.       exit (1);
  545.     }
  546.     *p2 = 0;
  547.     p2++;
  548.     add_one_file (ptr, p2);
  549.   }
  550.   if (f != stdin) fclose (f);
  551. }
  552.  
  553. #endif
  554.  
  555. int FDECL2(main, int, argc, char **, argv){
  556.   char * outfile;
  557.   struct directory_entry de;
  558. #ifndef AMIGA
  559.   unsigned int mem_start;
  560. #endif
  561.   struct stat statbuf;
  562.   char * scan_tree;
  563.   int c;
  564.  
  565. #ifdef AMIGA
  566. printf("\nAMIGA® Version\n\n");
  567. #endif
  568.  
  569. #ifdef ADD_FILES
  570.   char *add_file_file = NULL;
  571. #endif
  572.  
  573.   if (argc < 2)
  574.     usage();
  575.  
  576.   /* Get the defaults from the .mkisofsrc file */
  577.   read_rcfile(argv[0]);
  578.  
  579.   outfile = NULL;
  580.   while ((c = getopt(argc, argv, "i:o:V:RrfvaTp:P:x:dDlLNzA:")) != EOF)
  581.     switch (c)
  582.       {
  583.       case 'p':
  584.     preparer = optarg;
  585.     if(strlen(preparer) > 128) {
  586.         fprintf(stderr,"Preparer string too long\n");
  587.         exit(1);
  588.     };
  589.     break;
  590.       case 'P':
  591.     publisher = optarg;
  592.     if(strlen(publisher) > 128) {
  593.         fprintf(stderr,"Publisher string too long\n");
  594.         exit(1);
  595.     };
  596.     break;
  597.       case 'A':
  598.     appid = optarg;
  599.     if(strlen(appid) > 128) {
  600.         fprintf(stderr,"Application-id string too long\n");
  601.         exit(1);
  602.     };
  603.     break;
  604.       case 'd':
  605.     omit_period++;
  606.     break;
  607.       case 'D':
  608.     RR_relocation_depth = 32767;
  609.     break;
  610.       case 'l':
  611.     full_iso9660_filenames++;
  612.     break;
  613.       case 'L':
  614.         allow_leading_dots++;
  615.         break;
  616.       case 'N':
  617.     omit_version_number++;
  618.     break;
  619.       case 'o':
  620.     outfile = optarg;
  621.     break;
  622.       case 'f':
  623.     follow_links++;
  624.     break;
  625.       case 'R':
  626.     use_RockRidge++;
  627.     break;
  628.       case 'r':
  629.     rationalize++;
  630.     use_RockRidge++;
  631.     break;
  632.       case 'V':
  633.     volume_id = optarg;
  634.     break;
  635.       case 'v':
  636.     verbose++;
  637.     break;
  638.       case 'a':
  639.     all_files++;
  640.     break;
  641.       case 'T':
  642.     generate_tables++;
  643.     break;
  644.       case 'z':
  645. #ifdef VMS
  646.     fprintf(stderr,"Transparent compression not supported with VMS\n");
  647.     exit(1);
  648. #else
  649.     transparent_compression++;
  650. #endif
  651.     break;
  652.       case 'x':
  653.         exclude(optarg);
  654.     break;
  655.       case 'i':
  656. #ifdef ADD_FILES
  657.     add_file_file = optarg;
  658.     break;
  659. #endif
  660.       default:
  661.     usage();
  662.     exit(1);
  663.       }
  664. #ifdef __NetBSD__
  665.     {
  666.     int resource;
  667.     struct rlimit rlp;
  668.     if (getrlimit(RLIMIT_DATA,&rlp) == -1) 
  669.         perror("Warning: getrlimit");
  670.     else {
  671.         rlp.rlim_cur=33554432;
  672.         if (setrlimit(RLIMIT_DATA,&rlp) == -1)
  673.             perror("Warning: setrlimit");
  674.         }
  675.     }
  676. #endif
  677. #ifndef AMIGA
  678.   mem_start = (unsigned int) sbrk(0);
  679. #endif
  680.  
  681.   if(verbose) fprintf(stderr,"%s\n", version_string);
  682. /************************************************************************/
  683. /************************************************************************/
  684. /************************************************************************/
  685. /************************************************************************/
  686. /************************************************************************/
  687. /************************************************************************/
  688. /************************************************************************/
  689. /************************************************************************/
  690.   /* Now find the timezone offset */
  691. #ifdef AMIGAprintcomments
  692. printf("Now find the timezone offset\n");
  693. #endif
  694. /************************************************************************/
  695. /************************************************************************/
  696. /************************************************************************/
  697. /************************************************************************/
  698. /************************************************************************/
  699. /************************************************************************/
  700. /************************************************************************/
  701. /************************************************************************/
  702.  
  703.   timezone_offset = get_iso9660_timezone_offset();
  704.  
  705.  
  706.  
  707. /************************************************************************/
  708. /************************************************************************/
  709. /************************************************************************/
  710. /************************************************************************/
  711. /************************************************************************/
  712. /************************************************************************/
  713. /************************************************************************/
  714. /************************************************************************/
  715. /************************************************************************/
  716. /************************************************************************/
  717. /************************************************************************/
  718. /*  The first step is to scan the directory tree, and take some notes */
  719. #ifdef AMIGAprintcomments
  720. printf("The first step is to scan the directory tree, and take some notes\n");
  721. #endif
  722. /************************************************************************/
  723. /************************************************************************/
  724. /************************************************************************/
  725. /************************************************************************/
  726. /************************************************************************/
  727. /************************************************************************/
  728. /************************************************************************/
  729. /************************************************************************/
  730. /************************************************************************/
  731. /************************************************************************/
  732.  
  733.   scan_tree = argv[optind];
  734.  
  735. #ifdef ADD_FILES
  736.   if (add_file_file) {
  737.     add_file(add_file_file);
  738.   }
  739.   add_file_list (argc, argv, optind+1);
  740. #endif
  741.  
  742.   if(!scan_tree){
  743.       usage();
  744.       exit(1);
  745.   };
  746.  
  747. #ifndef VMS
  748.   if(
  749.     (scan_tree[strlen(scan_tree)-1] != '/') 
  750. #ifdef AMIGAdirs
  751.         &&
  752.     (scan_tree[strlen(scan_tree)-1] != ':') 
  753. #endif
  754.     )
  755.   {    
  756. scan_tree = (char *) e_malloc(strlen(argv[optind])+2);
  757.     strcpy(scan_tree, argv[optind]);
  758.     strcat(scan_tree, "/");
  759.   };
  760. #endif
  761.  
  762.   if(use_RockRidge){
  763. #if 1
  764.     extension_record = generate_rr_extension_record("RRIP_1991A",
  765.                        "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
  766.                        "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE.  SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size);
  767. #else
  768.     extension_record = generate_rr_extension_record("IEEE_P1282",
  769.                        "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
  770.                        "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size);
  771. #endif
  772.   };
  773.  
  774.   stat_filter(argv[optind], &statbuf);
  775.   add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
  776.  
  777.   de.filedir = root;  /* We need this to bootstrap */
  778.   scan_directory_tree(argv[optind], &de);
  779. printf("Tree now scanned...\n");
  780.   root->self = root->contents;  /* Fix this up so that the path tables get done right */
  781.  
  782.   if(reloc_dir) sort_n_finish(reloc_dir);
  783.  
  784.   if (goof) exit(1);
  785.   
  786.   if (outfile){
  787.       discimage = fopen(outfile, "w");
  788.       if (!discimage){
  789.           fprintf(stderr,"Unable to open disc image file\n");
  790.           exit(1);
  791.  
  792.       };
  793.   } else
  794.       discimage =  stdout;
  795.  
  796. /************************************************************************/
  797. /************************************************************************/
  798. /************************************************************************/
  799. /************************************************************************/
  800. /************************************************************************/
  801. /************************************************************************/
  802. /************************************************************************/
  803. /************************************************************************/
  804. /************************************************************************/
  805. /************************************************************************/
  806.   /* Now assign addresses on the disc for the path table. */
  807. #ifdef AMIGAprintcomments
  808. printf("Now assign addresses on the disc for the path table\n");
  809. #endif
  810. /************************************************************************/
  811. /************************************************************************/
  812. /************************************************************************/
  813. /************************************************************************/
  814. /************************************************************************/
  815. /************************************************************************/
  816. /************************************************************************/
  817. /************************************************************************/
  818. /************************************************************************/
  819.  
  820.   path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11;
  821.   if (path_blocks & 1) path_blocks++;
  822.   path_table[0] = 0x14;
  823.   path_table[1] = path_table[0] + path_blocks;
  824.   path_table[2] = path_table[1] + path_blocks;
  825.   path_table[3] = path_table[2] + path_blocks;
  826.  
  827.   last_extent = path_table[3] + path_blocks;  /* The next free block */
  828.  
  829. /************************************************************************/
  830. /************************************************************************/
  831. /************************************************************************/
  832. /************************************************************************/
  833. /************************************************************************/
  834. /************************************************************************/
  835. /************************************************************************/
  836. /************************************************************************/
  837.   /* The next step is to go through the directory tree and assign extent
  838.      numbers for all of the directories */
  839. #ifdef AMIGAprintcomments
  840. printf("The next step is to go through the directory tree and assign extent numbers for all of the directories\n");
  841. #endif
  842. /************************************************************************/
  843. /************************************************************************/
  844. /************************************************************************/
  845. /************************************************************************/
  846. /************************************************************************/
  847. /************************************************************************/
  848. /************************************************************************/
  849.  
  850.   assign_directory_addresses(root);
  851.  
  852.   if(extension_record) {
  853.       struct directory_entry * s_entry;
  854.       extension_record_extent = last_extent++;
  855.       s_entry = root->contents;
  856.       set_733(s_entry->rr_attributes + s_entry->rr_attr_size - 24,
  857.           extension_record_extent);
  858.       set_733(s_entry->rr_attributes + s_entry->rr_attr_size - 8,
  859.           extension_record_size);
  860.   };
  861.  
  862.   if (use_RockRidge && reloc_dir)
  863.       finish_cl_pl_entries();
  864.  
  865. /************************************************************************/
  866. /************************************************************************/
  867. /************************************************************************/
  868. /************************************************************************/
  869. /************************************************************************/
  870. /************************************************************************/
  871. /************************************************************************/
  872. /************************************************************************/
  873. /************************************************************************/
  874.   /* Now we generate the path tables that are used by DOS to improve directory
  875.      access times. */
  876. #ifdef AMIGAprintcomments
  877. printf("Now we generate the path tables that are used by DOS to improve directory access times\n");
  878. #endif
  879. /************************************************************************/
  880. /************************************************************************/
  881. /************************************************************************/
  882. /************************************************************************/
  883. /************************************************************************/
  884. /************************************************************************/
  885. /************************************************************************/
  886. /************************************************************************/
  887.   generate_path_tables();
  888.  
  889. /************************************************************************/
  890. /************************************************************************/
  891. /************************************************************************/
  892. /************************************************************************/
  893. /************************************************************************/
  894. /************************************************************************/
  895. /************************************************************************/
  896. /************************************************************************/
  897.   /* Generate root record for volume descriptor. */
  898. #ifdef AMIGAprintcomments
  899. printf("Generate root record for volume descriptor\n");
  900. #endif
  901. /************************************************************************/
  902. /************************************************************************/
  903. /************************************************************************/
  904. /************************************************************************/
  905. /************************************************************************/
  906. /************************************************************************/
  907. /************************************************************************/
  908.   generate_root_record();
  909.  
  910.   if (verbose)
  911.     dump_tree(root);
  912.  
  913. /************************************************************************/
  914. /************************************************************************/
  915. /************************************************************************/
  916. /************************************************************************/
  917. /************************************************************************/
  918. /************************************************************************/
  919. #ifdef AMIGAprintcomments
  920. printf("Write the ISO-Image\n");
  921. #endif
  922. /************************************************************************/
  923. /************************************************************************/
  924. /************************************************************************/
  925. /************************************************************************/
  926. /************************************************************************/
  927. /************************************************************************/
  928.   iso_write(discimage);
  929.  
  930. #ifndef AMIGA
  931.   fprintf(stderr,"Max brk space used %x\n", 
  932.       ((unsigned int)sbrk(0)) - mem_start);
  933. #endif
  934.   fprintf(stderr,"%d extents written (%d Mb)\n", last_extent, last_extent >> 9);
  935. #ifdef VMS
  936.   return 1;
  937. #else
  938.   return 0;
  939. #endif
  940. }
  941.  
  942.  
  943.  
  944. /*_______________________________________________________________*/
  945. void *e_malloc(size_t size)
  946. {
  947. void* pt;
  948.  
  949.  
  950.     if((pt=malloc(size))==NULL) {
  951.         printf("Not enougth memory\n");
  952.         exit (1);
  953.         }
  954. return pt;
  955. }
  956.