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