home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / new / disk / cdrom / mkisofs / mkisofs.c < prev    next >
C/C++ Source or Header  |  1994-06-23  |  12KB  |  524 lines

  1. /*
  2.  * Program mkisofs.c - generate iso9660 filesystem  based upon directory
  3.  * tree on hard disk.
  4.  
  5.    Written by Eric Youngdale (1993).
  6.  
  7.    Copyright 1993 Yggdrasil Computing, 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. #include "mkisofs.h"
  24.  
  25. #ifdef linux
  26. #include <getopt.h>
  27. #endif
  28.  
  29. #include "iso9660.h"
  30. #include <ctype.h>
  31. #include <time.h>
  32. #include <stdlib.h>
  33. #ifndef AMIGA
  34. #include <sys/stat.h>
  35. #endif
  36.  
  37. #ifndef VMS
  38. #ifndef AMIGA
  39. #include <unistd.h>
  40. #endif
  41. #endif
  42.  
  43. #ifdef AMIGA
  44. #ifdef LATTICE
  45. #include <proto/exec.h>
  46. #include <proto/utility.h>
  47. #endif
  48. #if defined(__GNUC__) || defined(AZTEC_C)
  49. #include <clib/exec_protos.h>
  50. #include <clib/utility_protos.h>
  51. #endif
  52. #endif
  53.  
  54. struct Library *UtilityBase = NULL;
  55.  
  56. #include "exclude.h"
  57.  
  58. struct directory * root = NULL;
  59.  
  60. static char version_string[] = "$VER: mkisofs-1.00-Amiga 1.5 (23.06.94)";
  61.  
  62. FILE * discimage;
  63. unsigned int next_extent = 0;
  64. unsigned int last_extent = 0;
  65. unsigned int path_table_size = 0;
  66. unsigned int path_table[4] = {0,};
  67. unsigned int path_blocks = 0;
  68. struct iso_directory_record root_record;
  69. int use_RockRidge = 0;
  70. int verbose = 0;
  71. int all_files  = 0;
  72. int follow_links = 0;
  73. int generate_tables = 0;
  74. static int timezone_offset;
  75. char * extension_record = NULL;
  76. int extension_record_extent = 0;
  77. static  int extension_record_size = 0;
  78. int cdtv_trademark_file = 0;
  79.  
  80. int convert_filenames = 1;
  81. int inhibit_relocation = 0;
  82. int sort_extents = 0;
  83. int progress_indicator = 1;
  84. int short_filenames = 1;
  85. int map_filenames = 1;
  86. int preallocate = 0;
  87.  
  88. char * preparer = NULL;
  89. char * publisher = NULL;
  90. char * system_identifier = NULL;
  91.  
  92.  
  93. char * path_table_l = NULL;
  94. char * path_table_m = NULL;
  95. int goof = 0;
  96.  
  97. void usage(void){
  98.   fprintf(stderr,
  99.     "Usage:\n"
  100.     "mkisofs [-RvaTcres12AB] [-o outfile] [-V volid] [-p preparer]\n"
  101.     "        [-P publisher] [-S systemid] [-D path -D path ...]\n"
  102.     "        [-x path -x path ...] [--cdtv] path\n"
  103.     );
  104.   exit(1);
  105. }
  106.  
  107. int get_iso9660_timezone_offset(void){
  108. #ifdef AMIGA
  109.   return 0;
  110. #else
  111.   struct tm gm;
  112.   struct tm * pt;
  113.   time_t ctime;
  114.   int local_min, gmt_min;
  115.  
  116.   time(&ctime);
  117.   pt = gmtime(&ctime);
  118.   gm = *pt;
  119.   pt = localtime(&ctime);
  120.  
  121.   if(gm.tm_year < pt->tm_year)
  122.     gm.tm_yday = -1;
  123.  
  124.   if(gm.tm_year > pt->tm_year)
  125.     pt->tm_yday = -1;
  126.  
  127.   gmt_min = gm.tm_min + 60*(gm.tm_hour + 24*gm.tm_yday);
  128.   local_min = pt->tm_min + 60*(pt->tm_hour + 24*pt->tm_yday);
  129.   return (gmt_min - local_min)/15;
  130. #endif
  131. }
  132.  
  133.  
  134. /* Fill in date in the iso9660 format */
  135. int FDECL2(iso9660_date,char *, result, time_t, ctime){
  136.   struct tm *local;
  137. #ifdef AMIGA
  138.   local = gmtime(&ctime);
  139. #else
  140.   local = localtime(&ctime);
  141. #endif
  142.   result[0] = local->tm_year;
  143.   result[1] = local->tm_mon + 1;
  144.   result[2] = local->tm_mday;
  145.   result[3] = local->tm_hour;
  146.   result[4] = local->tm_min;
  147.   result[5] = local->tm_sec;
  148.   result[6] = timezone_offset;
  149.   return 0;
  150. }
  151.  
  152. int FDECL3(iso9660_file_length,const char*, name, struct directory_entry *, sresult, 
  153.             int, dirflag){
  154.   char buf[33];
  155.   char *result = buf;
  156.   const char * pnt;
  157. #if 0
  158.   int seen_dot = 0;
  159.   int priority = 32767;
  160.   int tildes = 0;
  161.   int ignore = 0;
  162.   int extra = 0;
  163.   int chars_after_dot = 0;
  164.   int chars_before_dot = 0;
  165. #endif
  166.  
  167.   if(strcmp(name,".") == 0){
  168.     sresult->isorec.iso_name = "";
  169.     return 1;
  170.   };
  171.  
  172.   if(strcmp(name,"..") == 0){
  173.     sresult->isorec.iso_name = "\1";
  174.     return 1;
  175.   };
  176.  
  177.   if (!convert_filenames) {
  178.     int i;
  179.     for (pnt=name, i=0; *pnt && i < 30; i++)
  180.       *result++ = *pnt++;
  181.     if (!dirflag) {
  182.       *result++ = ';';
  183.       *result++ = '1';
  184.     }
  185.     *result++ = 0;
  186.     sresult->isorec.iso_name = strdup_forever (buf);
  187.     return i+(dirflag?0:2);
  188.   }
  189.  
  190.   sresult->isorec.iso_name =
  191.     strdup_forever (dirflag ? convert_dirname (name) :
  192.                     convert_filename (name));
  193.   sresult->priority = 32767;
  194.   return (int) strlen (sresult->isorec.iso_name);
  195.  
  196. #if 0
  197.  
  198.   pnt = name;
  199.   while(*pnt){
  200.     if(*pnt == '#') {priority = 1; pnt++; continue; };
  201.     if(*pnt == '~') {priority = 1; tildes++; pnt++; continue;};
  202.     if(ignore) {pnt++; continue;};
  203.     if(*pnt == '.') {
  204.       if (seen_dot) {ignore++; continue;}
  205.       *result++ = '.';
  206.       seen_dot++;
  207.     } else if (seen_dot) {
  208.       if(chars_after_dot < 3) {
  209.     chars_after_dot++;
  210.     *result++ = toupper(*pnt);
  211.       }
  212.     } else {
  213.       if(chars_before_dot < 8) {
  214.     chars_before_dot++;
  215.     *result++ = toupper(*pnt);
  216.       };
  217.     };
  218.     pnt++;
  219.   };
  220.   
  221.   if(tildes == 2){
  222.     int prio1 = 0;
  223.     pnt = name;
  224.     while (*pnt && *pnt != '~') pnt++;
  225.     if (*pnt) pnt++;
  226.     while(*pnt && *pnt != '~'){
  227.       prio1 = 10*prio1 + *pnt - '0';
  228.       pnt++;
  229.     };
  230.     priority = prio1;
  231.   };
  232.     
  233.   if (!dirflag){
  234.     if (!seen_dot) {
  235.       *result++ = '.'; 
  236.       extra++;
  237.     };
  238.     *result++ = ';';
  239.     *result++ = '1';
  240.     extra += 2;
  241.   };
  242.             
  243.   *result++ = 0;
  244.   sresult->priority = priority;
  245.   sresult->isorec.iso_name = strdup_forever (buf);
  246.   return chars_before_dot + chars_after_dot + seen_dot + extra;
  247. #endif
  248. }
  249.  
  250. #ifdef AMIGA
  251. static void Cleanup (void)
  252. {
  253.   if (UtilityBase)
  254.     CloseLibrary (UtilityBase);
  255. }
  256. #endif
  257.  
  258. int FDECL2(main, int, argc, char **, argv){
  259.   char * outfile, *volid;
  260.   struct directory_entry de;
  261. #ifndef AMIGA
  262.   unsigned int mem_start;
  263.   struct stat statbuf;
  264. #endif
  265.   char * scan_tree;
  266.   int c;
  267.   char * trademark_filename;
  268.  
  269.   if (argc < 2)
  270.     usage();
  271.  
  272. #ifdef AMIGA
  273.   UtilityBase = OpenLibrary ((UBYTE*) "utility.library", 0);
  274.   if (!UtilityBase) {
  275.     fprintf (stderr, "cannot open utility.library!\n");
  276.     exit (10);
  277.   }
  278.   atexit (Cleanup);
  279. #endif
  280.  
  281.   outfile = NULL;
  282.   volid = "CDROM";
  283.   while ((c = getopt(argc, argv, "acefo:p:rsvx:ABCD:P:RS:TV:-:12")) != EOF)
  284.                                  
  285.     switch (c)
  286.       {
  287.       case '-':
  288.         if (strcmp (optarg, "cdtv") == 0) {
  289.       convert_filenames = 0;
  290.       cdtv_trademark_file = 1;
  291.       inhibit_relocation = 1;
  292.       system_identifier = "CDTV";
  293.       all_files++;
  294.     } else {
  295.       fprintf (stderr, "unknown option --%s\n", optarg);
  296.       exit (1);
  297.     }
  298.     break;
  299.       case 'c':
  300.         convert_filenames = 0;
  301.         break;
  302.       case 'C':
  303.         cdtv_trademark_file = 1;
  304.         break;
  305.       case 'D':
  306.         convert_filenames = 0;
  307.     include_conv (optarg);
  308.         break;
  309.       case 'r':
  310.         inhibit_relocation = 1;
  311.     break;
  312.       case 'e':
  313.         sort_extents = 1;
  314.         break;
  315.       case 's':
  316.         preallocate = 1;
  317.         break;
  318.       case 'p':
  319.     preparer = optarg;
  320.     if(strlen(preparer) > 128) {
  321.         fprintf(stderr,"Preparer string too long\n");
  322.         exit(1);
  323.     };
  324.     break;
  325.       case 'P':
  326.     publisher = optarg;
  327.     if(strlen(publisher) > 128) {
  328.         fprintf(stderr,"Publisher string too long\n");
  329.         exit(1);
  330.     };
  331.     break;
  332.       case 'S':
  333.         system_identifier = optarg;
  334.     if(strlen(system_identifier) > 32) {
  335.         fprintf(stderr,"System identifier string too long\n");
  336.         exit (1);
  337.     }
  338.     break;
  339.       case 'o':
  340.     outfile = optarg;
  341.     break;
  342.       case 'f':
  343.     follow_links++;
  344.     break;
  345.       case 'R':
  346.     use_RockRidge++;
  347.     break;
  348.       case 'V':
  349. #ifdef AMIGA
  350.     if (strlen (optarg) > 30) {
  351.       fprintf (stderr, "volume name too long (max. 30 characters)\n");
  352.       exit (1);
  353.     }
  354. #endif
  355.     volid = optarg;
  356.     break;
  357.       case 'v':
  358.     verbose++;
  359.     progress_indicator=0;
  360.     break;
  361.       case 'a':
  362.     all_files++;
  363.     break;
  364.       case 'T':
  365.     generate_tables++;
  366.     break;
  367.       case 'x':
  368.         exclude(optarg);
  369.     break;
  370.       case '1':
  371.         short_filenames = 1;
  372.     break;
  373.       case '2':
  374.         short_filenames = 0;
  375.     break;
  376.       case 'A':
  377.         map_filenames = 1;
  378.     break;
  379.       case 'B':
  380.         map_filenames = 0;
  381.     break;
  382.       default:
  383.     usage();
  384.     exit(1);
  385.       }
  386.  
  387. #ifndef AMIGA
  388.   mem_start