home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / newc_dev / ppdo.lha / PPDO / PPDO.c < prev    next >
C/C++ Source or Header  |  1992-11-21  |  10KB  |  453 lines

  1. /* PPDO (PowerPackerDataOnly)
  2.  *
  3.  * (c) 1992 Thies Wellpott
  4.  * This program is freely distributable.
  5.  *
  6.  * (De-/Re-)crunches files using the powerpacker.library (© Nico François).
  7.  *
  8.  * compile: comp PPDO -cfistu -v -O REGISTER
  9.  *         ( LC -cfistu -v -O -rr -Hprecompiled PPDO
  10.  *           BLink FROM LIB:c.o,PPDO.o TO PPDO SC SD ND LIB LIB:lcr.lib )
  11.  *
  12.  * HISTORY
  13.  *
  14.  * V0.90  4.8.92
  15.  *   first code, first working version
  16.  * V1.00  4.8.92
  17.  *   de-/recrunching added
  18.  * V1.10  4.8.92
  19.  *   MINSIZE, PRI option added; Ctrl-C/D handling changed; minor fixes
  20.  * V1.20  5.9.92
  21.  *   DESTDIR option added; text output changed a bit
  22.  * V1.21  6.9.92
  23.  *   DESTDIR "" possible
  24.  *
  25.  *
  26.  * TODO
  27.  *
  28.  * - patterns in filenames
  29.  * - GUI (?)
  30.  *
  31.  */
  32.  
  33. #include <proto/powerpacker.h>
  34. #include <libraries/ppbase.h>
  35. #include <stdio.h>
  36.  
  37. #define VERSION "1.21"
  38. #define DATE "6.9.92"
  39.  
  40. #define MAX_FNAMES 32
  41. #define CRUNCH 0
  42. #define RECRUNCH 1
  43. #define DECRUNCH 2
  44.  
  45. /***** Variablen, Daten *****/
  46.  
  47. char version[] = "\0%VER: PPDO V"VERSION" ("DATE")";
  48.  
  49. struct PPBase *PPBase = NULL;
  50. struct Task *mytask;
  51. BYTE pri = -1, oldpri;
  52. LONG minsize = 0;
  53.  
  54. ULONG crun_speed = CRUN_BEST;
  55. ULONG buf_size = SPEEDUP_BUFFLARGE;
  56. ULONG decrun_color = DECR_POINTER;
  57. UBYTE mode = CRUNCH;
  58. BOOL suffix = FALSE;
  59. char destdir[128] = {-1, };
  60.  
  61. char *fname[MAX_FNAMES] = {NULL, };         /* init to NULL */
  62. int anz_fnames = 0;
  63.  
  64. /***** Routinen *****/
  65.  
  66. int CXBRK(void) {return(0);}                 /* disable Ctrl-C */
  67. void chkabort(void) {}
  68.  
  69.  
  70. void close_all(char *s, int err)
  71. {
  72.    int i;
  73.  
  74.    SetTaskPri(mytask, oldpri);
  75.    if (PPBase) CloseLibrary((struct Library *)PPBase);
  76.  
  77.    for (i = 0; i < MAX_FNAMES; i++)
  78.       if (fname[i])
  79.      free(fname[i]);
  80.  
  81.    if (s) printf("%s!\n", s);
  82.    exit(err);
  83. }
  84.  
  85.  
  86. void add_filename(char *name)
  87. {
  88.    if (!(fname[anz_fnames] = strdup(name)))
  89.       close_all("Out of memory", 20);
  90.    anz_fnames++;
  91. }
  92.  
  93.  
  94. void usage(void)
  95. {
  96.    printf("\2334mPPDO (PowerPackerDataOnly) V"VERSION" ("DATE")\2330m\
  97.   FreeWare © 1992 Thies Wellpott\n\n\
  98. Usage: PPDO [FAST|MEDIOCRE|GOOD|VERYGOOD|BEST] [SMALL|MEDIUM|LARGE]\n\
  99.         [COLOR0|COLOR1|POINTER|SCROLL|NONE] [CRUNCH|RECRUNCH|DECRUNCH]\n\
  100.         [SUFFIX] [DESTDIR dir] [MINSIZE size] [PRI pri] File/M\n\
  101. default: BEST LARGE POINTER CRUNCH MINSIZE 0 PRI -1\n\n\
  102. FAST .. BEST\t\tcrunch speed/efficiency\n\
  103. SMALL .. LARGE\t\tsize of speedup buffer\n\
  104. COLOR0 .. NONE\t\tflash type\n\
  105. CRUNCH\t\t\tonly crunch uncrunched files\n\
  106. RECRUNCH\t\tcrunch uncrunched, recrunch crunched files\n\
  107. DECRUNCH\t\tonly decrunch crunched files\n\
  108. \t(repeat the last three lines quickly ten times :^) )\n\
  109. SUFFIX\t\t\tadd/sub \".pp\" suffix to/from uncrunched/crunched files\n\
  110. DESTDIR dir\t\tsave files to dir, \"\" for current dir\n\
  111. MINSIZE size\t\tfile must at least have size bytes to be crunched\n\
  112. PRI pri\t\t\tset task priority to pri\n\
  113. File\t\t\tone or more filenames (use SPat for patterns)\n");
  114.  
  115.    exit(5);
  116. }
  117.  
  118.  
  119. void handle_args(int argc, char *argv[])
  120. {
  121.    int i;
  122.  
  123.    if ((argc == 1) || ((argc == 2) && (*argv[1] == '?')))
  124.       usage();
  125.  
  126.    for (i = 1; i < argc; i++)
  127.    {
  128.       if (!stricmp(argv[i], "FAST"))
  129.      crun_speed = CRUN_FAST;
  130.       else if (!stricmp(argv[i], "MEDIOCRE"))
  131.      crun_speed = CRUN_FAST;
  132.       else if (!stricmp(argv[i], "GOOD"))
  133.      crun_speed = CRUN_GOOD;
  134.       else if (!stricmp(argv[i], "VERYGOOD"))
  135.      crun_speed = CRUN_VERYGOOD;
  136.       else if (!stricmp(argv[i], "BEST"))
  137.      crun_speed = CRUN_BEST;
  138.       else if (!stricmp(argv[i], "SMALL"))
  139.      buf_size = SPEEDUP_BUFFSMALL;
  140.       else if (!stricmp(argv[i], "MEDIUM"))
  141.      buf_size = SPEEDUP_BUFFMEDIUM;
  142.       else if (!stricmp(argv[i], "LARGE"))
  143.      buf_size = SPEEDUP_BUFFLARGE;
  144.       else if (!stricmp(argv[i], "COLOR0"))
  145.      decrun_color = DECR_COL0;
  146.       else if (!stricmp(argv[i], "COLOR1"))
  147.      decrun_color = DECR_COL1;
  148.       else if (!stricmp(argv[i], "POINTER"))
  149.      decrun_color = DECR_POINTER;
  150.       else if (!stricmp(argv[i], "SCROLL"))
  151.      decrun_color = DECR_SCROLL;
  152.       else if (!stricmp(argv[i], "NONE"))
  153.      decrun_color = DECR_NONE;
  154.       else if (!stricmp(argv[i], "CRUNCH"))
  155.      mode = CRUNCH;
  156.       else if (!stricmp(argv[i], "RECRUNCH"))
  157.      mode = RECRUNCH;
  158.       else if (!stricmp(argv[i], "DECRUNCH"))
  159.      mode = DECRUNCH;
  160.       else if (!stricmp(argv[i], "SUFFIX"))
  161.      suffix = TRUE;
  162.       else if (!stricmp(argv[i], "DESTDIR"))
  163.       {
  164.      if (i == argc-1)                       /* ein Arg. muß folgen */
  165.         usage();
  166.      if (*argv[++i] == 0)
  167.         destdir[0] = 0;
  168.      else
  169.      {
  170.         strcpy(destdir, argv[i]);
  171.         if ((destdir[strlen(destdir)-1] != '/') &&
  172.         (destdir[strlen(destdir)-1] != ':'))
  173.            strcat(destdir, "/");
  174.      }
  175.       }
  176.       else if (!stricmp(argv[i], "MINSIZE"))
  177.       {
  178.      if (i == argc-1)
  179.         usage();
  180.      minsize = atol(argv[++i]);
  181.       }
  182.       else if (!stricmp(argv[i], "PRI"))
  183.       {
  184.      if (i == argc-1)
  185.         usage();
  186.      pri = (BYTE)atoi(argv[++i]);
  187.       }
  188.       else
  189.      add_filename(argv[i]);
  190.    } /* for (i) */
  191. }
  192.  
  193.  
  194. void open_all(void)
  195. {
  196.    if (!(PPBase = (struct PPBase *)OpenLibrary(PPNAME, 35)))
  197.       close_all("No powerpacker.lib (V35+)", 20);
  198. }
  199.  
  200.  
  201. BOOL __stdargs __saveds print_crun(ULONG lensofar, ULONG crunlen,
  202.                     ULONG totlen, APTR userdata)
  203. {
  204.    if (lensofar)
  205.    {
  206.       printf("%ld%% crunched (%ld%% gain)  \015",
  207.      (lensofar * 100 << 1) / totlen + 1 >> 1,     /* round result */
  208.      100 - ((100 * crunlen << 1) / lensofar + 1 >> 1));
  209.    }
  210.  
  211.    /* check for Ctrl-C and Ctrl-D and clear Ctrl-D bit */
  212.    if (SetSignal(0L, SIGBREAKF_CTRL_D) & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
  213.       return(FALSE);
  214.  
  215.    return(TRUE);
  216. }
  217.  
  218.  
  219. void print_head(void)
  220. {
  221.    printf("PPDO: ");
  222.    switch (mode)
  223.    {
  224.       case CRUNCH:
  225.      printf("Crunch");
  226.      break;
  227.       case RECRUNCH:
  228.      printf("Recrunch");
  229.      break;
  230.       case DECRUNCH:
  231.      printf("Decrunch");
  232.      break;
  233.    } /* switch () */
  234.  
  235.    if (mode != DECRUNCH)
  236.    {
  237.       switch (crun_speed)
  238.       {
  239.      case CRUN_FAST:
  240.         printf(" fast, ");
  241.         break;
  242.      case CRUN_MEDIOCRE:
  243.         printf(" mediocre, ");
  244.         break;
  245.      case CRUN_GOOD:
  246.         printf(" good, ");
  247.         break;
  248.      case CRUN_VERYGOOD:
  249.         printf(" very good, ");
  250.         break;
  251.      case CRUN_BEST:
  252.         printf(" best, ");
  253.         break;
  254.       } /* switch () */
  255.  
  256.       switch (buf_size)
  257.       {
  258.      case SPEEDUP_BUFFSMALL:
  259.         printf("small");
  260.         break;
  261.      case SPEEDUP_BUFFMEDIUM:
  262.         printf("medium");
  263.         break;
  264.      case SPEEDUP_BUFFLARGE:
  265.         printf("large");
  266.         break;
  267.       } /* switch () */
  268.       printf(" buffer");
  269.  
  270.       if (suffix)
  271.      printf(", append suffix");
  272.       if (minsize > 0)
  273.      printf(", minsize %d", minsize);
  274.    } /* if (mode != DECRUNCH) */
  275.    else
  276.    {
  277.       if (suffix)
  278.      printf(", remove suffix");
  279.    }
  280.    printf("\n");
  281. }
  282.  
  283.  
  284. void doit(void)
  285. {
  286.    int i;
  287.    ULONG filelen, crunlen, err;
  288.    UBYTE *filebuf;
  289.    BOOL succ, crunched;
  290.    BPTR fhd;
  291.    APTR cruninfo;
  292.    char name[128], savename[128];
  293.  
  294.    cruninfo = ppAllocCrunchInfo(crun_speed, buf_size, &print_crun, NULL);
  295.  
  296.    print_head();
  297.  
  298.    for (i = 0; (i < anz_fnames) && !(SetSignal(0L, SIGBREAKF_CTRL_C) &
  299.      SIGBREAKF_CTRL_C); i++)
  300.    {
  301.       printf("Loading \"\2330;32m%s\2330;31m\" ... ", fname[i]);
  302.       if (fhd = Open(fname[i], MODE_OLDFILE))
  303.       {
  304.      Seek(fhd, 0, OFFSET_END);
  305.      filelen = Seek(fhd, 0, OFFSET_BEGINNING);
  306.      printf("%ld bytes, ", filelen);
  307.  
  308.      err = 0;         /* I don`t want to waste a new variable */
  309.      Read(fhd, &err, 4);
  310.      if (err == (('P' << 24) | ('P' << 16) | ('2' << 8) | ('0')) )
  311.         crunched = TRUE;
  312.      else
  313.         crunched = FALSE;
  314.      Close(fhd);
  315.       }
  316.       else
  317.       {
  318.      printf("can`t open file!\n");
  319.      continue;          /*** ugly code, I`m a bit lazy ***/
  320.       }
  321.  
  322.       if (crunched && (mode == CRUNCH))
  323.      printf("already crunched, skipping\n");
  324.       else if (!crunched && (mode == DECRUNCH))
  325.      printf("not crunched, skipping\n");
  326.       else if (!crunched && (filelen < minsize))
  327.      printf("file too short, skipping\n");
  328.       else
  329.       {
  330.      err = ppLoadData(fname[i], decrun_color, 0L, &filebuf, &filelen, NULL);
  331.      if (err == 0)
  332.      {
  333.         if (crunched)
  334.            printf("decrunched %ld bytes\n", filelen);
  335.         else
  336.            printf("ok\n");
  337.  
  338.         strcpy(name, fname[i]);
  339.         if (mode != DECRUNCH)
  340.         {
  341.            crunlen = ppCrunchBuffer(cruninfo, filebuf, filelen);
  342.            if (crunlen == PP_CRUNCHABORTED)
  343.            {
  344.           printf("Crunching aborted!       \n");
  345.           crunlen = 0;
  346.            }
  347.            else if (crunlen == PP_BUFFEROVERFLOW)
  348.            {
  349.           printf("Buffer overflow, crunching aborted!\n");
  350.           crunlen = 0;
  351.            }
  352.            else
  353.            {
  354.           print_crun(filelen, crunlen, filelen, NULL);
  355.           printf("\n");
  356.           if (suffix && stricmp(".pp", &name[strlen(name)-3]))
  357.              strcat(name, ".pp");
  358.            }
  359.         } /* if (mode != DECRUNCH) */
  360.         else
  361.         {
  362.            crunlen = filelen;
  363.            if (suffix)
  364.            {
  365.           if (!stricmp(".pp", &name[strlen(name)-3]))
  366.              name[strlen(name)-3] = 0;
  367.            }
  368.         }
  369.  
  370.         if (crunlen)
  371.         {
  372.            if (destdir[0] != -1)
  373.            {
  374.           int j;
  375.           strcpy(savename, destdir);
  376.           for (j = strlen(name)-1; j >= 0; j--)
  377.           {
  378.              if ((name[j] == ':') || (name[j] == '/'))
  379.             break;
  380.           } /* for (j) */
  381.           strcat(savename, &name[j+1]);
  382.            }
  383.            else
  384.           strcpy(savename, name);
  385.  
  386.            printf("Saving to \"%s\" ... ", savename);
  387.            if (fhd = Open(savename, MODE_NEWFILE))
  388.            {
  389.           if (mode != DECRUNCH)
  390.              succ = ppWriteDataHeader(fhd, crun_speed, FALSE, 0);
  391.           else
  392.              succ = TRUE;
  393.  
  394.           if (succ)
  395.              succ = (Write(fhd, filebuf, crunlen) == crunlen);
  396.  
  397.           if (succ)
  398.              printf("%ld bytes (+ header)\n", crunlen);
  399.           else
  400.              printf("write error!\n");
  401.  
  402.           Close(fhd);
  403.            }
  404.            else
  405.           printf("\007can`t open file!\n");
  406.         } /* if (crunlen) */
  407.  
  408.         FreeMem(filebuf, filelen);
  409.      } /* if (err == 0) */
  410.      else
  411.      {
  412.         switch (err)
  413.         {
  414.            case PP_OPENERR:
  415.           printf("can`t open file!\n");
  416.           break;
  417.            case PP_READERR:
  418.           printf("read error!\n");
  419.           break;
  420.            case PP_NOMEMORY:
  421.           printf("out of memory!\n");
  422.           break;
  423.            case PP_PASSERR:
  424.           printf("sorry, wrong password!\n");
  425.           break;
  426.            case PP_EMPTYFILE:
  427.           printf("file is empty!\n");
  428.           break;
  429.            case PP_UNKNOWNPP:
  430.           printf("unknown packer type!\n");
  431.           break;
  432.         } /* switch (err) */
  433.      } /* else (err == 0) */
  434.       } /* if (!skipped) */
  435.    } /* for (i) */
  436.  
  437.    ppFreeCrunchInfo(cruninfo);
  438. }
  439.  
  440.  
  441. void main(int argc, char *argv[])
  442. {
  443.    handle_args(argc, argv);
  444.    mytask = FindTask(NULL);
  445.    oldpri = SetTaskPri(mytask, pri);
  446.    open_all();
  447.  
  448.    doit();
  449.  
  450.    close_all(NULL, 0);
  451. }
  452.  
  453.