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