home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / ARCHIVERS / lhasrc.lzh / header.c < prev    next >
Text File  |  1992-05-13  |  25KB  |  885 lines

  1. /*----------------------------------------------------------------------*/
  2. /*    header.c (from lharc.c)    -- header manipulate functions         */
  3. /*    Original                      by Y.Tagawa                         */
  4. /*    modified  Dec 16 1991         by M.Oki                            */
  5. /*----------------------------------------------------------------------*/
  6.  
  7. #include "lharc.h"
  8. extern int header_level;
  9.  
  10. int
  11. calc_sum (p, len)
  12. register char *p;
  13. register int len;
  14. {
  15.     register int sum;
  16.  
  17.     for (sum = 0; len; len --)
  18.         sum += *p++;
  19.  
  20.     return sum & 0xff;
  21. }
  22.  
  23. static char *get_ptr;
  24. #define setup_get(PTR)  (get_ptr = (PTR))
  25. #define get_byte()      (*get_ptr++ & 0xff)
  26. #define put_ptr         get_ptr
  27. #define setup_put(PTR)  (put_ptr = (PTR))
  28. #define put_byte(c)     (*put_ptr++ = (char)(c))
  29.  
  30. static unsigned short
  31. get_word ()
  32. {
  33.     int b0, b1;
  34.  
  35.     b0 = get_byte ();
  36.     b1 = get_byte ();
  37.     return (b1 << 8) + b0;
  38. }
  39.  
  40. static void
  41. put_word (v)
  42. unsigned int v;
  43. {
  44.     put_byte (v);
  45.     put_byte (v >> 8);
  46. }
  47.  
  48. static long
  49. get_longword ()
  50. {
  51.     long b0, b1, b2, b3;
  52.  
  53.     b0 = get_byte ();
  54.     b1 = get_byte ();
  55.     b2 = get_byte ();
  56.     b3 = get_byte ();
  57.     return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
  58. }
  59.  
  60. static void
  61. put_longword (v)
  62. long v;
  63. {
  64.     put_byte (v);
  65.     put_byte (v >> 8);
  66.     put_byte (v >> 16);
  67.     put_byte (v >> 24);
  68. }
  69.  
  70.  
  71. static void
  72. msdos_to_unix_filename (name, len)
  73. register char *name;
  74. register int len;
  75. {
  76.     register int i;
  77.  
  78. #ifdef MULTIBYTE_CHAR
  79.     for (i = 0; i < len; i ++)
  80.     {
  81.         if (MULTIBYTE_FIRST_P (name[i]) &&
  82.             MULTIBYTE_SECOND_P (name[i+1]))
  83.             i ++;
  84.         else if (name[i] == '\\')
  85.             name[i] = '/';
  86.         else if (isupper (name[i]))
  87.             name[i] = tolower (name[i]);
  88.     }
  89. #else
  90.     for (i = 0; i < len; i ++)
  91.     {
  92.         if (name[i] == '\\')
  93.             name[i] = '/';
  94.         else if (isupper (name[i]))
  95.             name[i] = tolower (name[i]);
  96. #ifdef OSK
  97.         else if (name[i] < 0x2e || (name[i] > '9' && name[i] < 'A') ||
  98.                 (name[i] > 'Z' && name[i] < 'a') || name[i] > 'z')
  99.             name[i] = '_';
  100. #endif /* OSK */
  101.     }
  102. #endif
  103. }
  104.  
  105. static void
  106. generic_to_unix_filename (name, len)
  107. register char *name;
  108. register int len;
  109. {
  110.     register int i;
  111.     boolean lower_case_used = FALSE;
  112.     char *p;
  113.  
  114. #ifdef MULTIBYTE_CHAR
  115.     for (i = 0; i < len; i ++)
  116.     {
  117.         if (MULTIBYTE_FIRST_P (name[i]) &&
  118.             MULTIBYTE_SECOND_P (name[i+1]))
  119.             i ++;
  120.         else if (islower (name[i]))
  121.         {
  122.             lower_case_used = TRUE;
  123.             break;
  124.         }
  125.     }
  126.     for (i = 0; i < len; i ++)
  127.     {
  128.         if (MULTIBYTE_FIRST_P (name[i]) &&
  129.             MULTIBYTE_SECOND_P (name[i+1]))
  130.             i ++;
  131.         else if (name[i] == '\\')
  132.             name[i] = '/';
  133.         else if (!lower_case_used && isupper (name[i]))
  134.             name[i] = tolower (name[i]);
  135.     }
  136. #else
  137.     for (i = 0; i < len; i ++)
  138.         if (islower (name[i]))
  139.         {
  140.             lower_case_used = TRUE;
  141.             break;
  142.         }
  143.     for (i = 0; i < len; i ++)
  144.     {
  145.         if (name[i] == '\\')
  146.             name[i] = '/';
  147.         else if (!lower_case_used && isupper (name[i]))
  148.             name[i] = tolower (name[i]);
  149. #ifdef OSK
  150.         else if (name[i] < 0x2e || (name[i] > '9' && name[i] < 'A') ||
  151.             (name[i] > 'Z' && name[i] < 'a') || name[i] > 'z')
  152.             name[i] = '_';
  153. #endif /* OSK */
  154.     }
  155. #endif
  156. }
  157.  
  158. static void
  159. macos_to_unix_filename (name, len)
  160. register char *name;
  161. register int len;
  162. {
  163.     register int i;
  164.  
  165.     for (i = 0; i < len; i ++)
  166.     {
  167.         if (name[i] == ':')
  168.             name[i] = '/';
  169.         else if (name[i] == '/')
  170.             name[i] = ':';
  171. #ifdef OSK
  172.         else if (name[i] < 0x2e || (name[i] > '9' && name[i] < 'A') ||
  173.             (name[i] > 'Z' && name[i] < 'a') || name[i] > 'z')
  174.             name[i] = '_';
  175. #endif /* OSK */
  176.     }
  177. }
  178.  
  179. static void
  180. unix_to_generic_filename (name, len)
  181. register char *name;
  182. register int len;
  183. {
  184.     register int i;
  185.  
  186.     for (i = 0; i < len; i ++)
  187.     {
  188.         if (name[i] == '/')
  189.             name[i] = '\\';
  190.         else if (islower (name[i]))
  191.             name[i] = toupper (name[i]);
  192.     }
  193. }
  194.  
  195. /*----------------------------------------------------------------------*/
  196. /*                                                                      */
  197. /*    Generic stamp format:                                             */
  198. /*                                                                      */
  199. /*     31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16                  */
  200. /*    |<-------- year ------->|<- month ->|<-- day -->|                 */
  201. /*                                                                      */
  202. /*     15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0                  */
  203. /*    |<--- hour --->|<---- minute --->|<- second*2 ->|                 */
  204. /*                                                                      */
  205. /*----------------------------------------------------------------------*/
  206.  
  207. /* NOTE : If you don't have `gettimeofday(2)', or your gettimeofday(2)
  208.    returns bogus timezone information, try FTIME, MKTIME, TIMELOCAL or
  209.    TZSET. */
  210.  
  211. /* choose one */
  212. #if defined(MKTIME)
  213. #ifdef TIMELOCAL
  214. #undef TIMELOCAL
  215. #endif
  216. #endif /* defined(MKTIME) */
  217.  
  218. #if defined(MKTIME) || defined(TIMELOCAL)
  219. #ifdef TZSET
  220. #undef TZSET
  221. #endif
  222. #endif /* defined(MKTIME) || defined(TIMELOCAL) */
  223.  
  224. #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET)
  225. #ifdef FTIME
  226. #undef FTIME
  227. #endif
  228. #endif
  229.  
  230. #if defined(MKTIME) || defined(TIMELOCAL) || defined(TZSET) || defined(FTIME)
  231. #ifdef GETTIMEOFDAY
  232. #undef GETTIMEOFDAY
  233. #endif
  234. #else
  235. #ifndef GETTIMEOFDAY
  236. #define GETTIMEOFDAY    /* use gettimeofday() */
  237. #endif
  238. #endif
  239.  
  240. #ifdef FTIME
  241. #include <sys/timeb.h>
  242. #endif
  243.  
  244. /* You may define as : 
  245.     #define TIMEZONE_HOOK        \
  246.         extern long timezone ;    \
  247.         extern void tzset();
  248. */
  249. #ifdef TIMEZONE_HOOK
  250. TIMEZONE_HOOK
  251. /* Which do you like better, `TIMEZONE_HOOK' or `TIMEZONE_HOOK;' ? */
  252. #endif
  253.  
  254. #if defined(TZSET) && defined(_MINIX)
  255. extern long timezone;    /* not defined in time.h */
  256. #endif
  257.  
  258. #if defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET)
  259. static long
  260. gettz ()
  261. #ifdef TZSET
  262. {
  263.     tzset();
  264.     return timezone;
  265. }
  266. #elif defined(FTIME)
  267. {
  268.     struct timeb buf;
  269.  
  270.     ftime(&buf);
  271.     return buf.timezone * 60L;
  272. }
  273. #else /* maybe defined(GETTIMEOFDAY) */
  274. {
  275.     struct timeval tp;
  276.     struct timezone tzp;
  277.     gettimeofday (&tp, &tzp);    /* specific to 4.3BSD */
  278.     /* return (tzp.tz_minuteswest * 60L + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/
  279.     return (tzp.tz_minuteswest * 60L);
  280. }
  281. #endif
  282. #endif /* defined(FTIME) || defined(GETTIMEOFDAY) || defined(TZSET) */
  283.  
  284. #ifdef NOT_USED
  285. static struct tm *
  286. msdos_to_unix_stamp_tm (a)
  287. long a;
  288. {
  289.     static struct tm t;
  290.  
  291.     t.tm_sec    =  (a          & 0x1f) * 2;
  292.     t.tm_min    =  (a >>    5) & 0x3f;
  293.     t.tm_hour   =  (a >>   11) & 0x1f;
  294.     t.tm_mday   =  (a >>   16) & 0x1f;
  295.     t.tm_mon    = ((a >> 16+5) & 0x0f) - 1;
  296.     t.tm_year   = ((a >> 16+9) & 0x7f) + 80;
  297.     return &t;
  298. }
  299. #endif
  300.  
  301. static time_t
  302. generic_to_unix_stamp (t)
  303. long t;
  304. #if defined(MKTIME) || defined(TIMELOCAL)
  305. {
  306.     struct tm dostm;
  307.  
  308.     /* special case:  if MSDOS format date and time were zero, then we set
  309.          time to be zero here too. */
  310.     if (t == 0)
  311.         return (time_t)0;
  312.  
  313.     dostm.tm_sec   = (t         & 0x1f) * 2;
  314.     dostm.tm_min   =  t >> 5    & 0x3f;
  315.     dostm.tm_hour  =  t >> 11   & 0x1f;
  316.     dostm.tm_mday  =  t >> 16   & 0x1f;
  317.     dostm.tm_mon   = (t >> 16+5 & 0x0f) - 1;    /* 0..11 */
  318.     dostm.tm_year  = (t >> 16+9 & 0x7f) + 80;
  319.     dostm.tm_isdst = 0;            /*is 0 correct? */
  320. #ifdef MKTIME
  321.     return (time_t)mktime(&dostm);
  322. #else /* maybe defined(TIMELOCAL) */
  323.     return (time_t)timelocal(&dostm);
  324. #endif
  325. }
  326. #else /* defined(MKTIME) || defined(TIMELOCAL) */
  327. {
  328.     int year, month, day, hour, min, sec;
  329.     long longtime;
  330.     static unsigned int dsboy[12] = { 
  331.         0, 31, 59, 90, 120, 151,
  332.         181, 212, 243, 273, 304, 334    };
  333.     unsigned int days;
  334.  
  335.     /* special case:  if MSDOS format date and time were zero, then we set
  336.          time to be zero here too. */
  337.     if (t == 0)
  338.         return (time_t)0;
  339.  
  340.     year  = ((int)(t >> 16+9) & 0x7f) + 1980;
  341.     month =  (int)(t >> 16+5) & 0x0f;    /* 1..12 means Jan..Dec */
  342.     day   =  (int)(t >> 16)   & 0x1f;    /* 1..31 means 1st,...31st */
  343.  
  344.     hour  = ((int)t  >> 11)   & 0x1f;
  345.     min   = ((int)t  >> 5)    & 0x3f;
  346.     sec   = ((int)t           & 0x1f) * 2;
  347.  
  348.     /* Calculate days since 1970.01.01 */
  349.     days = (365 * (year - 1970) + /* days due to whole years */
  350.     (year - 1970 + 1) / 4 +       /* days due to leap years */
  351.     dsboy[month-1] +              /* days since beginning of this year */
  352.     day-1);                       /* days since beginning of month */
  353.  
  354.     if ((year % 4 == 0) &&
  355.         (year % 400 != 0) &&
  356.         (month >= 3))             /* if this is a leap year and month */
  357.         days ++;                  /* is March or later, add a day */
  358.  
  359.     /* Knowing the days, we can find seconds */
  360.     longtime = (((days * 24) + hour) * 60 + min) * 60 + sec;
  361.     longtime += gettz ();          /* adjust for timezone */
  362.  
  363.     /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00.  */
  364.     return (time_t)longtime;
  365. }
  366. #endif /* defined(MKTIME) || defined(TIMELOCAL) */
  367.  
  368. static long
  369. unix_to_generic_stamp (t)
  370. time_t t;
  371. {
  372.     struct tm *tm = localtime (&t);
  373.  
  374.     return ((((long)(tm->tm_year - 80)) << 25) +
  375.         (((long)(tm->tm_mon + 1)) << 21) +
  376.         (((long)tm->tm_mday) << 16) +
  377.         (long)((tm->tm_hour << 11) +
  378.         (tm->tm_min << 5) +
  379.         (tm->tm_sec / 2)));
  380. }
  381.  
  382. /*----------------------------------------------------------------------*/
  383. /*            build header functions                                    */
  384. /*----------------------------------------------------------------------*/
  385.  
  386. boolean
  387. get_header (fp, hdr)
  388. FILE *fp;
  389. register LzHeader *hdr;
  390. {
  391.     int header_size;
  392.     int name_length;
  393.     char data[LZHEADER_STRAGE];
  394.     char dirname[FILENAME_LENGTH];
  395.     int dir_length = 0;
  396.     int checksum;
  397.     int i;
  398.     char *ptr;
  399.  
  400.     bzero (hdr, sizeof (LzHeader));
  401.  
  402.     if (((header_size = getc (fp)) == EOF) || (header_size == 0))
  403.     {
  404.         return FALSE;        /* finish */
  405.     }
  406.  
  407.     if (fread (data + I_HEADER_CHECKSUM,
  408.     sizeof (char), header_size + 1, fp) < header_size + 1)
  409.     {
  410.         fatal_error ("Invalid header (LHarc file ?)");
  411.         return FALSE;        /* finish */
  412.     }
  413.  
  414.     setup_get (data + I_HEADER_CHECKSUM);
  415.     checksum = get_byte();
  416.  
  417.     hdr->header_size = header_size;
  418.     bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  419. #ifdef OLD
  420.     if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  421.         (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  422.         (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  423.         (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0))
  424.     {
  425.         warning ("Unknown method (LHarc file ?)", "");
  426.         return FALSE;        /* invalid method */
  427.     }
  428. #endif
  429.     setup_get (data + I_PACKED_SIZE);
  430.     hdr->packed_size         = get_longword ();
  431.     hdr->original_size       = get_longword ();
  432.     hdr->last_modified_stamp = get_longword ();
  433.     hdr->attribute           = get_byte ();
  434.  
  435.     if ((hdr->header_level   = get_byte ()) != 2) {
  436.         if (calc_sum (data + I_METHOD, header_size) != checksum)
  437.             warning ("Checksum error (LHarc file?)", "");
  438.         name_length          = get_byte ();
  439.         for (i = 0; i < name_length; i ++)
  440.             hdr->name[i] = (char)get_byte ();
  441.         hdr->name[name_length] = '\0';
  442. #ifdef DEBUG
  443.        printf("Old File: %s\n",hdr->name);
  444. #endif
  445.  
  446. #ifdef OSK
  447.         hdr->unix_last_modified_stamp = 
  448.             generic_to_unix_stamp(hdr->last_modified_stamp);
  449. #endif
  450.     } 
  451.     else {
  452.         hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
  453.         name_length = 0;
  454.     }
  455.  
  456.     /* defaults for other type */
  457. #ifdef OSK
  458.     hdr->unix_mode    = OSK_RW_RW_RW;
  459. #else
  460.     hdr->unix_mode    = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
  461. #endif
  462.     hdr->unix_gid     = 0;
  463.     hdr->unix_uid     = 0;
  464.  
  465.     if (header_size - name_length >= 24)
  466.     {                /* EXTEND FORMAT */
  467.         hdr->crc            = get_word ();
  468.         hdr->extend_type    = get_byte ();
  469.         hdr->has_crc        = TRUE;
  470.     }
  471.     else if (header_size - name_length == 22)
  472.     {                /* Generic with CRC */
  473.         hdr->crc            = get_word ();
  474.         hdr->extend_type    = EXTEND_GENERIC;
  475.         hdr->has_crc        = TRUE;
  476.     }
  477.     else if (header_size - name_length == 20)
  478.     {                /* Generic no CRC */
  479.         hdr->extend_type    = EXTEND_GENERIC;
  480.         hdr->has_crc        = FALSE;
  481.     }
  482.     else
  483.     {
  484.         warning ("Unknown header (LHarc file ?)", "");
  485.         return FALSE;
  486.     }
  487.  
  488.     if (hdr->extend_type == EXTEND_UNIX && hdr->header_level == 0)
  489.     {
  490.         hdr->minor_version              = get_byte ();
  491.         hdr->unix_last_modified_stamp   = (time_t)get_longword ();
  492.         hdr->unix_mode                  = get_word ();
  493. #ifdef OSK
  494.         if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY)
  495.             hdr->unix_mode              = OSK_DIRECTORY_PERM | OSK_RW_RW_RW;
  496.         else
  497.             hdr->unix_mode              = OSK_RW_RW_RW;
  498. #endif
  499.         hdr->unix_uid                   = get_word ();
  500.         hdr->unix_gid                   = get_word ();
  501.         return TRUE;
  502.     }
  503.  
  504.     if (hdr->extend_type == EXTEND_OS68K && hdr->header_level == 0)
  505.     {
  506.         hdr->minor_version              = get_byte ();
  507.         hdr->unix_last_modified_stamp   = (time_t)get_longword ();
  508.         /* Skip the old creation date no longer used */
  509.         (time_t)get_longword ();
  510.         hdr->unix_mode                  = get_word ();
  511. #ifndef OSK
  512.         if ((hdr->unix_mode & OSK_DIRECTORY_PERM) == OSK_DIRECTORY_PERM)
  513.             hdr->unix_mode              = UNIX_FILE_DIRECTORY | UNIX_RW_RW_RW;
  514.         else
  515.             hdr->unix_mode              = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
  516. #endif
  517.         hdr->unix_uid                   = get_word ();
  518.         hdr->unix_gid                   = get_word ();
  519.         return TRUE;
  520.     }
  521.  
  522.     if (hdr->header_level > 0) {
  523.         /* Extend Header */
  524.         if (hdr->header_level != 2) setup_get(data + hdr->header_size);
  525.         ptr = get_ptr;
  526.         while((header_size = get_word()) != 0)
  527.         {
  528.             if (hdr->header_level != 2 &&
  529.                 ((data + LZHEADER_STRAGE - get_ptr < header_size) ||
  530.                 fread(get_ptr, sizeof(char), header_size, fp) < header_size))
  531.             {
  532.                 fatal_error ("Invalid header (LHa file ?)");
  533.                 return FALSE;
  534.             }
  535.             switch (get_byte()) {
  536.             case 0:
  537.                 /*
  538.                  * header crc
  539.                  */
  540.                 setup_get(get_ptr + header_size - 3);
  541.                 break;
  542.             case 1:
  543.                 /*
  544.                  * filename
  545.                  */
  546.                 for (i = 0; i < header_size - 3; i++)
  547.                     hdr->name[i] =(char)get_byte ();
  548.                 hdr->name[header_size - 3] = '\0';
  549.                 break;
  550.             case 2:
  551.                 /*
  552.                  * directory
  553.                  */
  554.                 for (i = 0; i < header_size - 3; i++)
  555.                     dirname[i] = (char)get_byte ();
  556.                 dirname[header_size - 3] = '\0';
  557.                 convdelim(dirname, DELIM);
  558.                 dir_length = header_size-3;
  559.                 break;
  560.             case 0x40:
  561.                 /*
  562.                  * MS-DOS attribute
  563.                  */
  564.                 if (hdr->extend_type == EXTEND_MSDOS ||
  565.                     hdr->extend_type == EXTEND_HUMAN ||
  566.                     hdr->extend_type == EXTEND_GENERIC)
  567.                     hdr->attribute = get_word();
  568.                 break;
  569.             case 0x50:
  570.                 /*
  571.                  * UNIX permission
  572.                  */
  573.                 if (hdr->extend_type == EXTEND_UNIX || \
  574.                     hdr->extend_type == EXTEND_OS68K)
  575.                     hdr->unix_mode = get_word();
  576.                 break;
  577.             case 0x51:
  578.                 /*
  579.                  * UNIX gid and uid
  580.                  */
  581.                 if (hdr->extend_type == EXTEND_UNIX || \
  582.                     hdr->extend_type == EXTEND_OS68K)
  583.                 {
  584.                     hdr->unix_gid = get_word();
  585.                     hdr->unix_uid = get_word();
  586.                 }
  587.                 break;
  588.             case 0x52:
  589.                 /*
  590.                  * UNIX group name
  591.                  */
  592.                 setup_get(get_ptr + header_size - 3);
  593.                 break;
  594.             case 0x53:
  595.                 /*
  596.                  * UNIX user name
  597.                  */
  598.                 setup_get(get_ptr + header_size - 3);
  599.                 break;
  600.             case 0x54:
  601.                 /*
  602.                  * UNIX last modified time
  603.                  */
  604.                 if (hdr->extend_type == EXTEND_UNIX || \
  605.                     hdr->extend_type == EXTEND_OS68K) 
  606.                     hdr->unix_last_modified_stamp = (time_t)get_longword();
  607.                 break;
  608.             default:
  609.                 /*
  610.                  * other headers
  611.                  */
  612.                 setup_get(get_ptr + header_size - 3);
  613.                 break;
  614.             }
  615.         }
  616.         if (hdr->header_level != 2 && get_ptr - ptr != 2) {
  617.             hdr->packed_size -= get_ptr - ptr - 2;
  618.             hdr->header_size += get_ptr - ptr - 2;
  619.         }
  620.     }
  621.     if (dir_length)
  622.     {
  623.         strcat(dirname, hdr->name);
  624.         strcpy(hdr->name, dirname);
  625.         name_length += dir_length;
  626.     }
  627.  
  628.     switch (hdr->extend_type)
  629.     {
  630.     case EXTEND_MSDOS:
  631.         msdos_to_unix_filename (hdr->name, name_length);
  632.     case EXTEND_HUMAN:
  633.         if (hdr->header_level == 2)
  634.             hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
  635.         else
  636.             hdr->unix_last_modified_stamp    =
  637.                 generic_to_unix_stamp (hdr->last_modified_stamp);
  638.         break;
  639.  
  640.     case EXTEND_OS68K:
  641. #ifndef OSK
  642.         if ((hdr->unix_mode & OSK_DIRECTORY_PERM) == OSK_DIRECTORY_PERM)
  643.             hdr->unix_mode = UNIX_FILE_DIRECTORY | UNIX_RW_RW_RW;
  644.         else
  645.             hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
  646. #endif
  647.     case EXTEND_XOSK:
  648.         break;
  649.  
  650.     case EXTEND_UNIX:
  651. #ifdef OSK
  652.         if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY)
  653.             hdr->unix_mode = OSK_DIRECTORY_PERM | OSK_RW_RW_RW;
  654.         else
  655.             hdr->unix_mode = OSK_RW_RW_RW;
  656. #endif
  657.         break;
  658.  
  659.     case EXTEND_MACOS:
  660.         macos_to_unix_filename (hdr->name, name_length);
  661.         hdr->unix_last_modified_stamp    =
  662.             generic_to_unix_stamp (hdr->last_modified_stamp);
  663.         break;
  664.  
  665.     default:
  666. #ifdef OSK /* Don't lowercase the directories */
  667.         if (hdr->attribute != GENERIC_DIRECTORY_ATTRIBUTE)
  668. #endif
  669.             generic_to_unix_filename (hdr->name, name_length);
  670.         if (hdr->header_level == 2)
  671.             hdr->unix_last_modified_stamp = hdr->last_modified_stamp;
  672.         else
  673.             hdr->unix_last_modified_stamp    =
  674.                 generic_to_unix_stamp (hdr->last_modified_stamp);
  675.     }
  676.  
  677.     return TRUE;
  678. }
  679.  
  680. void
  681. init_header (name, v_stat, hdr)
  682. char *name;
  683. STAT *v_stat;
  684. LzHeader *hdr;
  685. {
  686.     int len;
  687.     time_t last_mod;
  688.  
  689.     if ( compress_method == 5 )
  690.         bcopy (LZHUFF5_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  691.     else if ( compress_method )
  692.         bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  693.     else
  694.         bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  695.  
  696.     hdr->packed_size            = 0;
  697. #ifdef OSK
  698.     hdr->original_size          = makelong(v_stat->st_size);
  699.     last_mod                    = (time_t)lm_to_time_t(v_stat->st_mtime);
  700. #else
  701.     hdr->original_size          = v_stat->st_size;
  702.     last_mod                    = v_stat->st_mtime;
  703. #endif
  704.     hdr->last_modified_stamp    = unix_to_generic_stamp (last_mod);
  705.     hdr->attribute              = GENERIC_ATTRIBUTE;
  706.     hdr->header_level           = header_level;
  707.     strcpy (hdr->name, name);
  708.     len = strlen (name);
  709.     hdr->crc                    = 0x0000;
  710. #ifdef OSK
  711.     hdr->extend_type            = EXTEND_OS68K;
  712. #else
  713.     hdr->extend_type            = EXTEND_UNIX;
  714. #endif
  715.     hdr->unix_last_modified_stamp   = last_mod;
  716.     /* since 00:00:00 JAN.1.1970 */
  717. #ifdef NOT_COMPATIBLE_MODE
  718.     /*  Please need your modification in this space. */
  719. #else
  720.     hdr->unix_mode              = v_stat->st_mode;
  721. #endif
  722.  
  723.     hdr->unix_uid               = v_stat->st_uid;
  724.     hdr->unix_gid               = v_stat->st_gid;
  725.  
  726.     if (is_directory (v_stat))
  727.     {
  728.         bcopy (LZHDIRS_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  729.         hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
  730.         hdr->original_size = 0;
  731.         if (len > 0 && hdr->name[len-1] != '/')
  732.             strcpy (&hdr->name[len++], "/");
  733.     }
  734.     if (generic_format)
  735.         unix_to_generic_filename (hdr->name, len);
  736. }
  737.  
  738. /* Write unix extended header or generic header. */
  739. void
  740. write_header (nafp, hdr)
  741. FILE *nafp;
  742. LzHeader *hdr;
  743. {
  744.     int header_size;
  745.     int name_length;
  746.     char data[LZHEADER_STRAGE];
  747.     char *p;
  748.  
  749.     bzero (data, LZHEADER_STRAGE);
  750.     bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
  751.     setup_put (data + I_PACKED_SIZE);
  752.     put_longword (hdr->packed_size);
  753.     put_longword (hdr->original_size);
  754.  
  755.     if (hdr->header_level == HEADER_LEVEL2)
  756.         put_longword ((long)hdr->unix_last_modified_stamp);
  757.     else
  758.         put_longword (hdr->last_modified_stamp);
  759.  
  760.     switch (hdr->header_level)
  761.     {
  762.     case HEADER_LEVEL0:
  763.         put_byte (hdr->attribute);
  764.         break;
  765.     case HEADER_LEVEL1:
  766.     case HEADER_LEVEL2:
  767.         put_byte (0x20);
  768.         break;
  769.     }
  770.  
  771.     put_byte (hdr->header_level);
  772.  
  773.     convdelim(hdr->name, DELIM2);
  774.     if (hdr->header_level != HEADER_LEVEL2)
  775.     {
  776.         if (p = (char *)rindex(hdr->name, DELIM2))
  777.             name_length = strlen(++p);
  778.         else
  779.             name_length = strlen(hdr->name);
  780.         put_byte (name_length);
  781.         bcopy (p ? p : hdr->name, data + I_NAME, name_length);
  782.         setup_put (data + I_NAME + name_length);
  783.     }
  784.  
  785.     put_word (hdr->crc);
  786.     if (generic_format)
  787.     {
  788.         header_size = I_GENERIC_HEADER_BOTTOM - 2 + name_length;
  789.         data[I_HEADER_SIZE] = header_size;
  790.         data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size);
  791.     }
  792.     else if (header_level == HEADER_LEVEL0)
  793.     {
  794.         /* write old-style extend header */
  795. #ifdef OSK
  796.         put_byte (EXTEND_OS68K);
  797. #else
  798.         put_byte (EXTEND_UNIX);
  799. #endif
  800.         put_byte (CURRENT_UNIX_MINOR_VERSION);
  801.         put_longword ((long)hdr->unix_last_modified_stamp);
  802. #ifdef OSK
  803.         /* just mimick the old creation date stuff */
  804.         put_longword ((long)hdr->unix_last_modified_stamp);
  805. #endif
  806.         put_word (hdr->unix_mode);
  807.         put_word (hdr->unix_uid);
  808.         put_word (hdr->unix_gid);
  809. #ifdef OSK
  810.         header_size = I_UNIX_EXTEND_BOTTOM + 2 + name_length;
  811. #else
  812.         header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
  813. #endif
  814.         data[I_HEADER_SIZE] = header_size;
  815.         data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size);
  816.     }
  817.     else
  818.     {
  819.         /* write extend header. */
  820.         char *ptr;
  821. #ifdef OSK
  822.         put_byte (EXTEND_OS68K);
  823. #else
  824.         put_byte (EXTEND_UNIX);
  825. #endif
  826.         ptr = put_ptr;
  827.         put_word(5);
  828.         if (hdr->header_level == HEADER_LEVEL1)
  829.             header_size = put_ptr - data - 2;
  830.         put_byte(0x50);        /* permission */
  831.         put_word(hdr->unix_mode);
  832.         put_word(7);
  833.         put_byte(0x51);        /* gid and uid */
  834.         put_word(hdr->unix_gid);
  835.         put_word(hdr->unix_uid);
  836.         if (p = (char *)rindex(hdr->name, DELIM2))
  837.         {
  838.             int i;
  839.             name_length = p - hdr->name + 1;
  840.             put_word(name_length + 3);
  841.             put_byte(2);        /* dirname */
  842.             for (i = 0; i < name_length; i++)
  843.                 put_byte(hdr->name[i]);
  844.         }
  845.         if (header_level != HEADER_LEVEL2)
  846.         {
  847.             put_word(7);
  848.             put_byte(0x54);    /* time stamp */
  849.             put_longword(hdr->unix_last_modified_stamp);
  850.             hdr->packed_size += put_ptr - ptr;
  851.             ptr = put_ptr;
  852.             setup_put (data + I_PACKED_SIZE);
  853.             put_longword (hdr->packed_size);
  854.             put_ptr = ptr;
  855.             data[I_HEADER_SIZE] = header_size;
  856.             data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size);
  857.         }
  858.         else
  859.         {
  860.             int i;
  861.             if (p = (char *)rindex(hdr->name, DELIM2))
  862.                 name_length = strlen(++p);
  863.             else
  864.             {
  865.                 p = hdr->name;
  866.                 name_length = strlen(hdr->name);
  867.             }
  868.             put_word(name_length + 3);
  869.             put_byte(1);        /* filename */
  870.             for (i = 0; i < name_length; i++)
  871.                 put_byte(*p++);
  872.         }
  873.         header_size = put_ptr - data;
  874.     }
  875.     if (header_level == HEADER_LEVEL2)
  876.     {
  877.         setup_put(data + I_HEADER_SIZE);
  878.         put_word(header_size);
  879.     }
  880.     if (fwrite (data, sizeof (char), header_size + 2, nafp) == 0)
  881.         fatal_error ("Cannot write to temporary file");
  882.     convdelim(hdr->name, DELIM);
  883. }
  884.  
  885.