makesfx.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:6k
源码类别:

压缩解压

开发平台:

MultiPlatform

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