home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / PPCxDMSWOS.lha / source.lha / src / xdms.c < prev   
C/C++ Source or Header  |  1998-02-17  |  13KB  |  518 lines

  1.  
  2. /*
  3.  *     xDMS  v1.0  -  Portable DMS archive unpacker  -  Public Domain
  4.  *     Written by     Andre R. de la Rocha  <adlroc@usa.net>
  5.  *
  6.  */
  7.  
  8.  
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "cdata.h"
  16. #include "pfile.h"
  17. #include "crc_csum.h"
  18.  
  19.  
  20. /* Program exit codes */
  21. #define EXIT_OK 0
  22. #define EXIT_FAIL 10
  23.  
  24.  
  25. #define FNAME_MAXC 500
  26.  
  27.  
  28. static void Usage(void);
  29. static int strcmpnc(char *, char *);
  30. static void strcpymax(char *, char *, int);
  31. static void strcatmax(char *, char *, int);
  32. static void ErrMsg(USHORT, char *, char *);
  33.  
  34.  
  35.  
  36. void main(int argc, char **argv){
  37.     USHORT i, cmd=0, opt=0, ret, ext, PCRC=0, pwd=0;
  38.     char iname[FNAME_MAXC+1], oname[FNAME_MAXC+1], cmdstr[FNAME_MAXC+20], *tname, *inm, *onm, *p, *q, *destdir=NULL;
  39.  
  40.  
  41.     if (argc < 3) {
  42.         Usage();
  43.         exit(EXIT_FAIL);
  44.     }
  45.  
  46.     i = 1;
  47.  
  48.     /*  proccess options in the command line  */
  49.     while ((i<argc) && (argv[i][0] == '-')){
  50.         if (strlen(argv[i])>2) {
  51.             fprintf(stderr,"Unknown option !\n");
  52.             Usage();
  53.             exit(EXIT_FAIL);
  54.         }
  55.         switch (tolower(argv[i][1])){
  56.             case 'q' :
  57.                 opt = OPT_QUIET;
  58.                 break;
  59.             case 'v' :
  60.                 opt = OPT_VERBOSE;
  61.                 break;
  62.             case 'd' :
  63.                 if (++i == argc) {
  64.                     Usage();
  65.                     exit(EXIT_FAIL);
  66.                 }
  67.                 destdir = argv[i];
  68.                 break;
  69.             case 'p' :
  70.                 if (++i == argc) {
  71.                     Usage();
  72.                     exit(EXIT_FAIL);
  73.                 }
  74.                 PCRC = CreateCRC((UCHAR*)argv[i],(ULONG)strlen(argv[i]));
  75.                 pwd = 1;
  76.                 break;
  77.             default:
  78.                 fprintf(stderr,"Unknown option !\n");
  79.                 Usage();
  80.                 exit(EXIT_FAIL);
  81.         }
  82.         i++;
  83.     }
  84.  
  85.     if ((i == argc) || (strlen(argv[i])>1)) {
  86.         Usage();
  87.         exit(EXIT_FAIL);
  88.     }
  89.  
  90.  
  91.     switch(tolower(argv[i][0])) {
  92.         case 'u':
  93.             cmd = CMD_UNPACK;
  94.             break;
  95.         case 'z':
  96.             cmd = CMD_UNPKGZ;
  97.             break;
  98.         case 'x':
  99.             cmd = CMD_EXTRACT;
  100.             break;
  101.         case 't':
  102.             cmd = CMD_TEST;
  103.             break;
  104.         case 'v':
  105.             cmd = CMD_VIEW;
  106.             break;
  107.         case 'f':
  108.             cmd = CMD_VIEWFULL;
  109.             break;
  110.         case 'd':
  111.             cmd = CMD_SHOWDIZ;
  112.             break;
  113.         case 'b':
  114.             cmd = CMD_SHOWBANNER;
  115.             break;
  116.         default:
  117.             fprintf(stderr,"Unknown command !\n");
  118.             Usage();
  119.             exit(EXIT_FAIL);
  120.     }
  121.  
  122.     if (++i == argc) {
  123.         Usage();
  124.         exit(EXIT_FAIL);
  125.     }
  126.  
  127.     ext = EXIT_OK;
  128.  
  129.     while (i < argc) {
  130.  
  131.         if (!strcmpnc("stdin",argv[i])) {
  132.             inm = NULL;
  133.         } else {
  134.             strcpymax(iname,argv[i],FNAME_MAXC);
  135.             if ((strlen(iname)<4) || (strcmpnc(".dms",iname+strlen(iname)-4))) strcatmax(iname,".dms",FNAME_MAXC);
  136.             inm = iname;
  137.         }
  138.         i++;
  139.  
  140.  
  141.         /*  generate the output filename  */
  142.         if ((i < argc) && (argv[i][0]=='+')) {
  143.             if ((strcmpnc("stdout",argv[i]+1)==0) || (destdir && (strcmpnc("stdout",destdir)==0))) {
  144.                 strcpy(oname,"");
  145.                 onm = NULL;
  146.             } else {
  147.                 if (destdir) {
  148.                     strcpymax(oname,destdir,FNAME_MAXC-1);
  149.                     p = oname + strlen(oname) - 1;
  150.                     if (!strchr(DIR_SEPARATORS,*p)) {
  151.                         *(p+1) = DIR_CHAR;
  152.                         *(p+2) = '\0';
  153.                     }
  154.                 } else strcpy(oname,"");
  155.                 strcatmax(oname,argv[i]+1,FNAME_MAXC);
  156.                 if (((cmd == CMD_UNPACK) || (cmd == CMD_UNPKGZ)) && (strlen(oname)>0)) {
  157.                     p = oname + strlen(oname) - 1;
  158.                     if (strchr(DIR_SEPARATORS,*p)) {
  159.                         if (inm) {
  160.                             p = q = iname;
  161.                             while(*p) {
  162.                                 if (strchr(DIR_SEPARATORS,*p)) q = p+1;
  163.                                 p++;
  164.                             }
  165.                             strcatmax(oname,q,FNAME_MAXC);
  166.                             if ((strlen(oname)>4) && (strcmpnc(oname+strlen(oname)-4,".dms")==0)) {
  167.                                 if (cmd == CMD_UNPKGZ)
  168.                                     strcpy(oname+strlen(oname)-4,".adz");
  169.                                 else
  170.                                     strcpy(oname+strlen(oname)-4,".adf");
  171.                             } else {
  172.                                 if (cmd == CMD_UNPKGZ)
  173.                                     strcatmax(oname,".adz",FNAME_MAXC);
  174.                                 else
  175.                                     strcatmax(oname,".adf",FNAME_MAXC);
  176.                             }
  177.                         } else {
  178.                             if (cmd == CMD_UNPKGZ)
  179.                                 strcatmax(oname,"stdin.adz",FNAME_MAXC);
  180.                             else
  181.                                 strcatmax(oname,"stdin.adf",FNAME_MAXC);
  182.                         }
  183.  
  184.                     }
  185.                 }
  186.  
  187.                 onm = oname;
  188.             }
  189.             i++;
  190.         } else if (destdir && (strcmpnc("stdout",destdir)==0)) {
  191.             strcpy(oname,"");
  192.             onm = NULL;
  193.         } else {
  194.  
  195.             if (destdir)
  196.                 strcpymax(oname,destdir,FNAME_MAXC-1);
  197.             else
  198.                 strcpy(oname,"");
  199.  
  200.             if ((cmd == CMD_UNPACK) || (cmd == CMD_UNPKGZ)) {
  201.  
  202.                 if (strlen(oname)>0) {
  203.                     p = oname + strlen(oname) - 1;
  204.                     if (!strchr(DIR_SEPARATORS,*p)) {
  205.                         *(p+1) = DIR_CHAR;
  206.                         *(p+2) = '\0';
  207.                     }
  208.                 }
  209.  
  210.                 if (inm) {
  211.                     p = q = iname;
  212.                     while(*p) {
  213.                         if (strchr(DIR_SEPARATORS,*p)) q = p+1;
  214.                         p++;
  215.                     }
  216.                     strcatmax(oname,q,FNAME_MAXC);
  217.                     if ((strlen(oname)>4) && (strcmpnc(oname+strlen(oname)-4,".dms")==0)) {
  218.                         if (cmd == CMD_UNPKGZ)
  219.                             strcpy(oname+strlen(oname)-4,".adz");
  220.                         else
  221.                             strcpy(oname+strlen(oname)-4,".adf");
  222.                     } else {
  223.                         if (cmd == CMD_UNPKGZ)
  224.                             strcatmax(oname,".adz",FNAME_MAXC);
  225.                         else
  226.                             strcatmax(oname,".adf",FNAME_MAXC);
  227.                     }
  228.                 } else {
  229.                     if (cmd == CMD_UNPKGZ)
  230.                         strcatmax(oname,"stdin.adz",FNAME_MAXC);
  231.                     else
  232.                         strcatmax(oname,"stdin.adf",FNAME_MAXC);
  233.                 }
  234.  
  235.             }
  236.  
  237.             onm = oname;
  238.  
  239.         }
  240.  
  241.  
  242.  
  243.         if (opt == OPT_VERBOSE) {
  244.             if ((cmd == CMD_UNPACK)) {
  245.                 if (inm)
  246.                     fprintf(stderr,"Unpacking file %s to ",inm);
  247.                 else
  248.                     fprintf(stderr,"Unpacking data from stdin to ");
  249.                 if (onm)
  250.                     fprintf(stderr,"%s\n",onm);
  251.                 else
  252.                     fprintf(stderr,"stdout\n");
  253.             } else if ((cmd == CMD_EXTRACT) || (cmd == CMD_UNPKGZ)) {
  254.                 if (inm)
  255.                     fprintf(stderr,"Unpacking file %s\n",inm);
  256.                 else
  257.                     fprintf(stderr,"Unpacking data from stdin\n");
  258.             } else if (cmd == CMD_TEST) {
  259.                 if (inm)
  260.                     fprintf(stderr,"Testing file %s\n",inm);
  261.                 else
  262.                     fprintf(stderr,"Testing data from stdin\n");
  263.             } else if (cmd == CMD_SHOWDIZ) {
  264.                 if (inm)
  265.                     printf("Showing FILEID.DIZ in %s :\n",inm);
  266.                 else
  267.                     printf("Showing FILEID.DIZ in stdin :\n");
  268.             } else if (cmd == CMD_SHOWBANNER) {
  269.                 if (inm)
  270.                     printf("Showing Banner in %s :\n",inm);
  271.                 else
  272.                     printf("Showing Banner in stdin :\n");
  273.             }
  274.  
  275.         }
  276.  
  277.  
  278.         if ((cmd == CMD_UNPKGZ) || (cmd == CMD_EXTRACT)) {
  279.             tname = tmpnam(NULL);
  280.             #ifdef UNDER_DOS
  281.             p = tname;
  282.             if (p) {
  283.                 while (*p) {
  284.                     if (*p == '/') *p = '\\';
  285.                     p++;
  286.                 }
  287.             }
  288.             #endif
  289.             ret = Process_File(inm, tname, CMD_UNPACK, opt, PCRC, pwd);
  290.             if (opt != OPT_QUIET) ErrMsg(ret, inm, "Temporary file");
  291.             if (ret == NO_PROBLEM) {
  292.                 if (cmd == CMD_UNPKGZ) {
  293.                     if (opt == OPT_VERBOSE) {
  294.                         fprintf(stderr,"Repacking unpacked data with gzip\n");
  295.                     }
  296.                     if (onm)
  297.                         #ifdef UNDER_DOS
  298.                         /*  DOS sucks  */
  299.                         sprintf(cmdstr,"gzip -c -f -q %s >%s",tname,onm);
  300.                         #else
  301.                         sprintf(cmdstr,"gzip -c -f -q \"%s\" >\"%s\"",tname,onm);
  302.                         #endif
  303.                     else
  304.                         #ifdef UNDER_DOS
  305.                         sprintf(cmdstr,"gzip -c -f -q %s",tname);
  306.                         #else
  307.                         sprintf(cmdstr,"gzip -c -f -q \"%s\"",tname);
  308.                         #endif
  309.                     if (system(cmdstr)) ret = ERR_GZIP;
  310.                     if (opt != OPT_QUIET) ErrMsg(ret, inm, onm);
  311.                 } else {
  312.                     if (opt == OPT_VERBOSE) {
  313.                         fprintf(stderr,"Extracting files from unpacked data with readdisk\n");
  314.                     }
  315.                     if ((onm) && (strlen(onm)>0))
  316.                         #ifdef UNDER_DOS
  317.                         sprintf(cmdstr,"readdisk %s %s",tname,onm);
  318.                         #else
  319.                         sprintf(cmdstr,"readdisk \"%s\" \"%s\"",tname,onm);
  320.                         #endif
  321.                     else
  322.                         #ifdef UNDER_DOS
  323.                         sprintf(cmdstr,"readdisk %s",tname);
  324.                         #else
  325.                         sprintf(cmdstr,"readdisk \"%s\"",tname);
  326.                         #endif
  327.                     if (system(cmdstr)) ret = ERR_READDISK;
  328.                     if (opt != OPT_QUIET) ErrMsg(ret, inm, onm);
  329.                 }
  330.             }
  331.             remove(tname);
  332.         } else {
  333.             ret = Process_File(inm, onm, cmd, opt, PCRC, pwd);
  334.             if (opt != OPT_QUIET) ErrMsg(ret, inm, onm);
  335.         }
  336.  
  337.         if (ret != NO_PROBLEM) ext = EXIT_FAIL;
  338.  
  339.         if ((ret == NO_PROBLEM) && (opt != OPT_QUIET)) {
  340.             switch (cmd) {
  341.                 case CMD_UNPACK:
  342.                     if (inm)
  343.                         fprintf(stderr,"File %s was correctly unpacked to ",inm);
  344.                     else
  345.                         fprintf(stderr,"Data from stdin was correctly unpacked to ");
  346.                     if (onm)
  347.                         fprintf(stderr,"%s\n",onm);
  348.                     else
  349.                         fprintf(stderr,"stdout\n");
  350.                     break;
  351.                 case CMD_UNPKGZ:
  352.                     if (inm)
  353.                         fprintf(stderr,"File %s was correctly converted to ",inm);
  354.                     else
  355.                         fprintf(stderr,"Data from stdin was correctly converted to ");
  356.                     if (onm)
  357.                         fprintf(stderr,"%s\n",onm);
  358.                     else
  359.                         fprintf(stderr,"stdout\n");
  360.                     break;
  361.                 case CMD_EXTRACT:
  362.                     if (inm)
  363.                         fprintf(stderr,"The files were correctly extracted from %s\n",inm);
  364.                     else
  365.                         fprintf(stderr,"The files were correctly extracted from stdin\n");
  366.                     break;
  367.                 case CMD_TEST:
  368.                     if (inm)
  369.                         fprintf(stderr,"File %s is ok\n",inm);
  370.                     else
  371.                         fprintf(stderr,"Data from stdin is ok\n");
  372.                     break;
  373.                 default:
  374.                     break;
  375.             }
  376.         }
  377.  
  378.         if (opt != OPT_QUIET) fprintf(stderr,"\n");
  379.  
  380.     }
  381.  
  382.     exit((int)ext);
  383.  
  384. }
  385.  
  386.  
  387.  
  388. static int strcmpnc(char *s1, char *s2){
  389.     while (*s1 && (tolower(*s1)==tolower(*s2))) {s1++; s2++;}
  390.     return tolower(*s1)-tolower(*s2);
  391. }
  392.  
  393.  
  394.  
  395. static void strcpymax(char *s1, char *s2, int max){
  396.     if (strlen(s2)>max){
  397.         memcpy(s1,s2,max);
  398.         *(s1+max) = 0;
  399.     } else
  400.         strcpy(s1,s2);
  401. }
  402.  
  403.  
  404.  
  405. static void strcatmax(char *s1, char *s2, int max){
  406.     if (strlen(s1)+strlen(s2)>max){
  407.         memcpy(s1+strlen(s1),s2,max-strlen(s1));
  408.         *(s1+max) = 0;
  409.     } else
  410.         strcat(s1,s2);
  411. }
  412.  
  413.  
  414.  
  415. static void Usage(void){
  416.     printf("\n");
  417.     printf(" xDMS  v1.0  -  Portable DMS archive unpacker  -  Public Domain\n");
  418.     printf(" Written by     Andre R. de la Rocha  <adlroc@usa.net> \n\n");
  419.     printf(" Usage: xdms [options] <command> {<dms_file[.dms]> [+output]} \n\n");
  420.     printf(" Commands :\n");
  421.     printf("     t : Test DMS archives\n");
  422.     printf("     u : Unpack DMS archives to disk images\n");
  423.     printf("     z : Unpack to disk images and compress it with gzip\n");
  424.     printf("     x : Extract files inside DMS archives using readdisk\n");
  425.     printf("     v : View DMS archives information\n");
  426.     printf("     f : View full information\n");
  427.     printf("     d : Show attached FILEID.DIZ\n");
  428.     printf("     b : Show attached Banner\n\n");
  429.     printf(" Options :\n");
  430.     printf("    -q : Quiet\n");
  431.     printf("    -v : Verbose\n");
  432.     printf("    -d <destdir>  : Set destination directory\n");
  433.     printf("    -p <password> : Decrypt encrypted archives using password\n");
  434.     printf("\n");
  435. }
  436.  
  437.  
  438.  
  439. static void ErrMsg(USHORT err, char *i, char *o){
  440.  
  441.     if (!i) i = "stdin";
  442.     if (!o) o = "stdout";
  443.  
  444.     switch (err) {
  445.         case NO_PROBLEM:
  446.         case FILE_END:
  447.             return;
  448.         case ERR_NOMEMORY:
  449.             fprintf(stderr,"Not enough memory for buffers !\n");
  450.             break;
  451.         case ERR_CANTOPENIN:
  452.             fprintf(stderr,"Can't open %s for reading !\n",i);
  453.             break;
  454.         case ERR_CANTOPENOUT:
  455.             fprintf(stderr,"Can't open %s for writing !\n",o);
  456.             break;
  457.         case ERR_NOTDMS:
  458.             fprintf(stderr,"File %s is not a DMS archive !\n",i);
  459.             break;
  460.         case ERR_SREAD:
  461.             fprintf(stderr,"Error reading file %s : unexpected end of file !\n",i);
  462.             break;
  463.         case ERR_HCRC:
  464.             fprintf(stderr,"Error in file %s : header CRC error !\n",i);
  465.             break;
  466.         case ERR_NOTTRACK:
  467.             fprintf(stderr,"Error in file %s : track header not found !\n",i);
  468.             break;
  469.         case ERR_BIGTRACK:
  470.             fprintf(stderr,"Error in file %s : track too big !\n",i);
  471.             break;
  472.         case ERR_THCRC:
  473.             fprintf(stderr,"Error in file %s : track header CRC error !\n",i);
  474.             break;
  475.         case ERR_TDCRC:
  476.             fprintf(stderr,"Error in file %s : track data CRC error !\n",i);
  477.             break;
  478.         case ERR_CSUM:
  479.             fprintf(stderr,"Error in file %s : checksum error after unpacking !\n",i);
  480.             fprintf(stderr,"This file seems ok, but the unpacking failed.\n");
  481.             fprintf(stderr,"This can be caused by a bug in xDMS. Please contact the author\n");
  482.             break;
  483.         case ERR_CANTWRITE:
  484.             fprintf(stderr,"Error : can't write to file %s  !\n",o);
  485.             break;
  486.         case ERR_BADDECR:
  487.             fprintf(stderr,"Error in file %s : error unpacking !\n",i);
  488.             fprintf(stderr,"This file seems ok, but the unpacking failed.\n");
  489.             fprintf(stderr,"This can be caused by a bug in xDMS. Please contact the author\n");
  490.             break;
  491.         case ERR_UNKNMODE:
  492.             fprintf(stderr,"Error in file %s : unknown compression mode used !\n",i);
  493.             break;
  494.         case ERR_NOPASSWD:
  495.             fprintf(stderr,"Can't process file %s : file is encrypted !\n",i);
  496.             break;
  497.         case ERR_BADPASSWD:
  498.             fprintf(stderr,"Error unpacking file %s . The password is probably wrong.\n",i);
  499.             break;
  500.         case ERR_FMS:
  501.             fprintf(stderr,"Error in file %s : this file is not really a compressed disk image, but an FMS archive !\n",i);
  502.             break;
  503.         case ERR_GZIP:
  504.             fprintf(stderr,"Can't convert file %s : gzip failed !\n",i);
  505.             break;
  506.         case ERR_READDISK:
  507.             fprintf(stderr,"Can't extract files from %s : readdisk failed !\n",i);
  508.             break;
  509.         default:
  510.             fprintf(stderr,"Error while processing file  %s : internal error !\n",i);
  511.             fprintf(stderr,"This is a bug in xDMS\n");
  512.             fprintf(stderr,"Please contact the author\n");
  513.             break;
  514.     }
  515. }
  516.  
  517.  
  518.