Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
  3.  
  4.   See the accompanying file LICENSE, version 2000-Apr-09 or later
  5.   (the contents of which are also included in unzip.h) for terms of use.
  6.   If, for some reason, all these files are missing, the Info-ZIP license
  7.   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
  8. */
  9. /*
  10.  * makesfx - Makes a QDOS sfx zip file
  11.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  12.  * created by Jonathan Hudson, 04/09/95
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20.  
  21. #define SFXFLAG "??Special Flag for unzipsfx hack  ??"
  22.  
  23. #ifdef QDOS
  24. # include <qdos.h>
  25. # define ZMODE (X_OK|R_OK)
  26. # define rev_long(x) (x)
  27. # define XFLAG 0x4afb
  28. #else
  29. # define ZMODE (R_OK)
  30. # define getchid(p1) p1
  31. # include <sys/stat.h>
  32.   long rev_long(long l);
  33. # define XFLAG 0xfb4a
  34.  
  35. typedef struct
  36. {
  37.     long id;
  38.     long dlen;
  39. } NTC;
  40.  
  41. struct qdirect  {
  42.     long            d_length __attribute__ ((packed));  /* file length */
  43.     unsigned char   d_access __attribute__ ((packed));  /* file access type */
  44.     unsigned char   d_type __attribute__ ((packed));    /* file type */
  45.     long            d_datalen __attribute__ ((packed)); /* data length */
  46.     long            d_reserved __attribute__ ((packed));/* Unused */
  47.     short           d_szname __attribute__ ((packed));  /* size of name */
  48.     char            d_name[36] __attribute__ ((packed));/* name area */
  49.     long            d_update __attribute__ ((packed));  /* last update */
  50.     long            d_refdate __attribute__ ((packed));
  51.     long            d_backup __attribute__ ((packed));   /* EOD */
  52. } ;
  53.  
  54. int fs_headr (int fd, long t, struct qdirect *qs, short size)
  55. {
  56.     NTC ntc;
  57.     int r = -1;
  58.     struct stat s;
  59.  
  60.     fstat(fd, &s);
  61.     qs->d_length = s.st_size;
  62.     lseek(fd, -8, SEEK_END);
  63.     read(fd, &ntc, 8);
  64.     if(ntc.id == *(long *)"XTcc")
  65.     {
  66.         qs->d_datalen = ntc.dlen;    /* This is big endian */
  67.         qs->d_type = 1;
  68.         r = 0;
  69.     }
  70.     lseek(fd, 0, 0);
  71.     return 42;                       /* why not ??? */
  72. }
  73.  
  74. typedef unsigned char uch;
  75.  
  76. long rev_long (long l)
  77. {
  78.     uch cc[4];
  79.     cc[0] = (uch)(l >> 24);
  80.     cc[1] = (uch)((l >> 16) & 0xff);
  81.     cc[2] = (uch)((l >> 8) & 0xff);
  82.     cc[3] = (uch)(l & 0xff);
  83.     return *(long *)cc;
  84. }
  85.  
  86. #endif
  87.  
  88. #define RBUFSIZ 4096
  89.  
  90. void usage(void)
  91. {
  92.     fputs("makesfx -o outfile -z zipfile -xunzipsfx -sstubfile\n", stderr);
  93.     exit(0);
  94. }
  95.  
  96. int main (int ac, char **av)
  97. {
  98.     int fd, fo;
  99.     static char local_sig[4] = "PK\003\004";
  100.     char *p, tmp[4];
  101.     short ok = 0;
  102.     char *of = NULL;
  103.     char *xf = NULL;
  104.     char *zf = NULL;
  105.     char *sf = NULL;
  106.     int c;
  107.  
  108.     while((c = getopt(ac, av, "o:z:x:s:h")) != EOF)
  109.     {
  110.         switch(c)
  111.         {
  112.             case 'o':
  113.                 of = optarg;
  114.                 break;
  115.             case 'z':
  116.                 zf = optarg;
  117.                 break;
  118.             case 'x':
  119.                 xf = optarg;
  120.                 break;
  121.             case 's':
  122.                 sf = optarg;
  123.                 break;
  124.             case 'h':
  125.                 usage();
  126.                 break;
  127.         }
  128.     }
  129.  
  130.  
  131.     if(zf && xf && of && sf)
  132.     {
  133.         if((fd = open(zf, O_RDONLY)) > 0)
  134.         {
  135.             if((read(fd, tmp, 4) == 4))
  136.             {
  137.                 if(*(long *)tmp == *(long *)local_sig)
  138.                 {
  139.                     ok = 1;
  140.                 }
  141.             }
  142.             close(fd);
  143.         }
  144.         if(!ok)
  145.         {
  146.             fprintf(stderr,
  147.                     "Huum, %s doesn't look like a ZIP file to me\n", zf);
  148.             exit(0);
  149.         }
  150.  
  151.         if(strstr(xf, "unzipsfx"))
  152.         {
  153.             if(access(xf, ZMODE))
  154.             {
  155.                 fprintf(stderr, "Sorry, don't like the look of %s\n", xf);
  156.                 exit(0);
  157.             }
  158.         }
  159.  
  160.         if((fo = open(of, O_CREAT|O_TRUNC|O_RDWR, 0666)) != -1)
  161.         {
  162.             struct qdirect sd,xd;
  163.             int n;
  164.             int dsoff = 0;
  165.             int nfoff = 0;
  166.             int zlen = 0;
  167.  
  168.             if((fd = open(sf, O_RDONLY)) != -1)
  169.             {
  170.                 if(fs_headr(getchid(fd), -1, &sd, sizeof(sd)) > 0)
  171.                 {
  172.                     unsigned short *q;
  173.                     p = malloc(sd.d_length);
  174.                     n = read(fd, p, sd.d_length);
  175.                     for(q = (unsigned short *)p;
  176.                         q != (unsigned short *)(p+sd.d_length); q++)
  177.                     {
  178.                         if(*q == XFLAG && *(q+1) == XFLAG)
  179.                         {
  180.                             dsoff = (int)q-(int)p;
  181.                             break;
  182.                         }
  183.                     }
  184.                     write(fo, p, n);
  185.                     close(fd);
  186.                 }
  187.             }
  188.  
  189.             if(dsoff == 0)
  190.             {
  191.                 puts("Fails");
  192.  
  193.                 exit(0);
  194.             }
  195.  
  196.             if((fd = open(xf, O_RDONLY)) != -1)
  197.             {
  198.                 char *q;
  199.                 if(fs_headr(getchid(fd), -1, &xd, sizeof(xd)) > 0)
  200.                 {
  201.                     p = realloc(p, xd.d_length);
  202.                     n = read(fd, p, xd.d_length);
  203.                     {
  204.                         for(q = p; q < p+xd.d_length ; q++)
  205.                         {
  206.                             if(*q == '?')
  207.                             {
  208.                                 if(memcmp(q, SFXFLAG, sizeof(SFXFLAG)-1) == 0)
  209.                                 {
  210.                                     nfoff = (int)(q-p);
  211.                                     break;
  212.                                 }
  213.                             }
  214.                         }
  215.                     }
  216.                     write(fo, p, n);
  217.                     close(fd);
  218.  
  219.                     if((fd = open(zf, O_RDONLY)) > 0)
  220.                     {
  221.                         p = realloc(p, RBUFSIZ);
  222.                         while((n = read(fd, p, RBUFSIZ)) > 0)
  223.                         {
  224.                             write(fo, p, n);
  225.                             zlen += n;
  226.                         }
  227.                         close(fd);
  228.                     }
  229.                     lseek(fo, dsoff+4, SEEK_SET);
  230.                     n = rev_long((sd.d_length-dsoff));
  231.                     write(fo, &n, sizeof(long));
  232.                     n = rev_long(xd.d_length);
  233.                     write(fo, &n, sizeof(long));
  234.                     write(fo, &xd.d_datalen, sizeof(long));
  235.                     n = rev_long(nfoff);
  236.                     write(fo, &n, sizeof(long));
  237.                     n = rev_long(zlen);
  238.                     write(fo, &n, sizeof(long));
  239.                     close(fo);
  240.                 }
  241.                 else
  242.                 {
  243.                     close(fd);
  244.                     fputs("Can't read unzipsfx header", stderr);
  245.                     exit(0);
  246.                 }
  247.             }
  248.             free(p);
  249.         }
  250.     }
  251.     else
  252.         usage();
  253.  
  254.     return 0;
  255. }
  256.