home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
newc_dev
/
ppdo.lha
/
PPDO
/
PPDO.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-21
|
10KB
|
453 lines
/* PPDO (PowerPackerDataOnly)
*
* (c) 1992 Thies Wellpott
* This program is freely distributable.
*
* (De-/Re-)crunches files using the powerpacker.library (© Nico François).
*
* compile: comp PPDO -cfistu -v -O REGISTER
* ( LC -cfistu -v -O -rr -Hprecompiled PPDO
* BLink FROM LIB:c.o,PPDO.o TO PPDO SC SD ND LIB LIB:lcr.lib )
*
* HISTORY
*
* V0.90 4.8.92
* first code, first working version
* V1.00 4.8.92
* de-/recrunching added
* V1.10 4.8.92
* MINSIZE, PRI option added; Ctrl-C/D handling changed; minor fixes
* V1.20 5.9.92
* DESTDIR option added; text output changed a bit
* V1.21 6.9.92
* DESTDIR "" possible
*
*
* TODO
*
* - patterns in filenames
* - GUI (?)
*
*/
#include <proto/powerpacker.h>
#include <libraries/ppbase.h>
#include <stdio.h>
#define VERSION "1.21"
#define DATE "6.9.92"
#define MAX_FNAMES 32
#define CRUNCH 0
#define RECRUNCH 1
#define DECRUNCH 2
/***** Variablen, Daten *****/
char version[] = "\0%VER: PPDO V"VERSION" ("DATE")";
struct PPBase *PPBase = NULL;
struct Task *mytask;
BYTE pri = -1, oldpri;
LONG minsize = 0;
ULONG crun_speed = CRUN_BEST;
ULONG buf_size = SPEEDUP_BUFFLARGE;
ULONG decrun_color = DECR_POINTER;
UBYTE mode = CRUNCH;
BOOL suffix = FALSE;
char destdir[128] = {-1, };
char *fname[MAX_FNAMES] = {NULL, }; /* init to NULL */
int anz_fnames = 0;
/***** Routinen *****/
int CXBRK(void) {return(0);} /* disable Ctrl-C */
void chkabort(void) {}
void close_all(char *s, int err)
{
int i;
SetTaskPri(mytask, oldpri);
if (PPBase) CloseLibrary((struct Library *)PPBase);
for (i = 0; i < MAX_FNAMES; i++)
if (fname[i])
free(fname[i]);
if (s) printf("%s!\n", s);
exit(err);
}
void add_filename(char *name)
{
if (!(fname[anz_fnames] = strdup(name)))
close_all("Out of memory", 20);
anz_fnames++;
}
void usage(void)
{
printf("\2334mPPDO (PowerPackerDataOnly) V"VERSION" ("DATE")\2330m\
FreeWare © 1992 Thies Wellpott\n\n\
Usage: PPDO [FAST|MEDIOCRE|GOOD|VERYGOOD|BEST] [SMALL|MEDIUM|LARGE]\n\
[COLOR0|COLOR1|POINTER|SCROLL|NONE] [CRUNCH|RECRUNCH|DECRUNCH]\n\
[SUFFIX] [DESTDIR dir] [MINSIZE size] [PRI pri] File/M\n\
default: BEST LARGE POINTER CRUNCH MINSIZE 0 PRI -1\n\n\
FAST .. BEST\t\tcrunch speed/efficiency\n\
SMALL .. LARGE\t\tsize of speedup buffer\n\
COLOR0 .. NONE\t\tflash type\n\
CRUNCH\t\t\tonly crunch uncrunched files\n\
RECRUNCH\t\tcrunch uncrunched, recrunch crunched files\n\
DECRUNCH\t\tonly decrunch crunched files\n\
\t(repeat the last three lines quickly ten times :^) )\n\
SUFFIX\t\t\tadd/sub \".pp\" suffix to/from uncrunched/crunched files\n\
DESTDIR dir\t\tsave files to dir, \"\" for current dir\n\
MINSIZE size\t\tfile must at least have size bytes to be crunched\n\
PRI pri\t\t\tset task priority to pri\n\
File\t\t\tone or more filenames (use SPat for patterns)\n");
exit(5);
}
void handle_args(int argc, char *argv[])
{
int i;
if ((argc == 1) || ((argc == 2) && (*argv[1] == '?')))
usage();
for (i = 1; i < argc; i++)
{
if (!stricmp(argv[i], "FAST"))
crun_speed = CRUN_FAST;
else if (!stricmp(argv[i], "MEDIOCRE"))
crun_speed = CRUN_FAST;
else if (!stricmp(argv[i], "GOOD"))
crun_speed = CRUN_GOOD;
else if (!stricmp(argv[i], "VERYGOOD"))
crun_speed = CRUN_VERYGOOD;
else if (!stricmp(argv[i], "BEST"))
crun_speed = CRUN_BEST;
else if (!stricmp(argv[i], "SMALL"))
buf_size = SPEEDUP_BUFFSMALL;
else if (!stricmp(argv[i], "MEDIUM"))
buf_size = SPEEDUP_BUFFMEDIUM;
else if (!stricmp(argv[i], "LARGE"))
buf_size = SPEEDUP_BUFFLARGE;
else if (!stricmp(argv[i], "COLOR0"))
decrun_color = DECR_COL0;
else if (!stricmp(argv[i], "COLOR1"))
decrun_color = DECR_COL1;
else if (!stricmp(argv[i], "POINTER"))
decrun_color = DECR_POINTER;
else if (!stricmp(argv[i], "SCROLL"))
decrun_color = DECR_SCROLL;
else if (!stricmp(argv[i], "NONE"))
decrun_color = DECR_NONE;
else if (!stricmp(argv[i], "CRUNCH"))
mode = CRUNCH;
else if (!stricmp(argv[i], "RECRUNCH"))
mode = RECRUNCH;
else if (!stricmp(argv[i], "DECRUNCH"))
mode = DECRUNCH;
else if (!stricmp(argv[i], "SUFFIX"))
suffix = TRUE;
else if (!stricmp(argv[i], "DESTDIR"))
{
if (i == argc-1) /* ein Arg. muß folgen */
usage();
if (*argv[++i] == 0)
destdir[0] = 0;
else
{
strcpy(destdir, argv[i]);
if ((destdir[strlen(destdir)-1] != '/') &&
(destdir[strlen(destdir)-1] != ':'))
strcat(destdir, "/");
}
}
else if (!stricmp(argv[i], "MINSIZE"))
{
if (i == argc-1)
usage();
minsize = atol(argv[++i]);
}
else if (!stricmp(argv[i], "PRI"))
{
if (i == argc-1)
usage();
pri = (BYTE)atoi(argv[++i]);
}
else
add_filename(argv[i]);
} /* for (i) */
}
void open_all(void)
{
if (!(PPBase = (struct PPBase *)OpenLibrary(PPNAME, 35)))
close_all("No powerpacker.lib (V35+)", 20);
}
BOOL __stdargs __saveds print_crun(ULONG lensofar, ULONG crunlen,
ULONG totlen, APTR userdata)
{
if (lensofar)
{
printf("%ld%% crunched (%ld%% gain) \015",
(lensofar * 100 << 1) / totlen + 1 >> 1, /* round result */
100 - ((100 * crunlen << 1) / lensofar + 1 >> 1));
}
/* check for Ctrl-C and Ctrl-D and clear Ctrl-D bit */
if (SetSignal(0L, SIGBREAKF_CTRL_D) & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
return(FALSE);
return(TRUE);
}
void print_head(void)
{
printf("PPDO: ");
switch (mode)
{
case CRUNCH:
printf("Crunch");
break;
case RECRUNCH:
printf("Recrunch");
break;
case DECRUNCH:
printf("Decrunch");
break;
} /* switch () */
if (mode != DECRUNCH)
{
switch (crun_speed)
{
case CRUN_FAST:
printf(" fast, ");
break;
case CRUN_MEDIOCRE:
printf(" mediocre, ");
break;
case CRUN_GOOD:
printf(" good, ");
break;
case CRUN_VERYGOOD:
printf(" very good, ");
break;
case CRUN_BEST:
printf(" best, ");
break;
} /* switch () */
switch (buf_size)
{
case SPEEDUP_BUFFSMALL:
printf("small");
break;
case SPEEDUP_BUFFMEDIUM:
printf("medium");
break;
case SPEEDUP_BUFFLARGE:
printf("large");
break;
} /* switch () */
printf(" buffer");
if (suffix)
printf(", append suffix");
if (minsize > 0)
printf(", minsize %d", minsize);
} /* if (mode != DECRUNCH) */
else
{
if (suffix)
printf(", remove suffix");
}
printf("\n");
}
void doit(void)
{
int i;
ULONG filelen, crunlen, err;
UBYTE *filebuf;
BOOL succ, crunched;
BPTR fhd;
APTR cruninfo;
char name[128], savename[128];
cruninfo = ppAllocCrunchInfo(crun_speed, buf_size, &print_crun, NULL);
print_head();
for (i = 0; (i < anz_fnames) && !(SetSignal(0L, SIGBREAKF_CTRL_C) &
SIGBREAKF_CTRL_C); i++)
{
printf("Loading \"\2330;32m%s\2330;31m\" ... ", fname[i]);
if (fhd = Open(fname[i], MODE_OLDFILE))
{
Seek(fhd, 0, OFFSET_END);
filelen = Seek(fhd, 0, OFFSET_BEGINNING);
printf("%ld bytes, ", filelen);
err = 0; /* I don`t want to waste a new variable */
Read(fhd, &err, 4);
if (err == (('P' << 24) | ('P' << 16) | ('2' << 8) | ('0')) )
crunched = TRUE;
else
crunched = FALSE;
Close(fhd);
}
else
{
printf("can`t open file!\n");
continue; /*** ugly code, I`m a bit lazy ***/
}
if (crunched && (mode == CRUNCH))
printf("already crunched, skipping\n");
else if (!crunched && (mode == DECRUNCH))
printf("not crunched, skipping\n");
else if (!crunched && (filelen < minsize))
printf("file too short, skipping\n");
else
{
err = ppLoadData(fname[i], decrun_color, 0L, &filebuf, &filelen, NULL);
if (err == 0)
{
if (crunched)
printf("decrunched %ld bytes\n", filelen);
else
printf("ok\n");
strcpy(name, fname[i]);
if (mode != DECRUNCH)
{
crunlen = ppCrunchBuffer(cruninfo, filebuf, filelen);
if (crunlen == PP_CRUNCHABORTED)
{
printf("Crunching aborted! \n");
crunlen = 0;
}
else if (crunlen == PP_BUFFEROVERFLOW)
{
printf("Buffer overflow, crunching aborted!\n");
crunlen = 0;
}
else
{
print_crun(filelen, crunlen, filelen, NULL);
printf("\n");
if (suffix && stricmp(".pp", &name[strlen(name)-3]))
strcat(name, ".pp");
}
} /* if (mode != DECRUNCH) */
else
{
crunlen = filelen;
if (suffix)
{
if (!stricmp(".pp", &name[strlen(name)-3]))
name[strlen(name)-3] = 0;
}
}
if (crunlen)
{
if (destdir[0] != -1)
{
int j;
strcpy(savename, destdir);
for (j = strlen(name)-1; j >= 0; j--)
{
if ((name[j] == ':') || (name[j] == '/'))
break;
} /* for (j) */
strcat(savename, &name[j+1]);
}
else
strcpy(savename, name);
printf("Saving to \"%s\" ... ", savename);
if (fhd = Open(savename, MODE_NEWFILE))
{
if (mode != DECRUNCH)
succ = ppWriteDataHeader(fhd, crun_speed, FALSE, 0);
else
succ = TRUE;
if (succ)
succ = (Write(fhd, filebuf, crunlen) == crunlen);
if (succ)
printf("%ld bytes (+ header)\n", crunlen);
else
printf("write error!\n");
Close(fhd);
}
else
printf("\007can`t open file!\n");
} /* if (crunlen) */
FreeMem(filebuf, filelen);
} /* if (err == 0) */
else
{
switch (err)
{
case PP_OPENERR:
printf("can`t open file!\n");
break;
case PP_READERR:
printf("read error!\n");
break;
case PP_NOMEMORY:
printf("out of memory!\n");
break;
case PP_PASSERR:
printf("sorry, wrong password!\n");
break;
case PP_EMPTYFILE:
printf("file is empty!\n");
break;
case PP_UNKNOWNPP:
printf("unknown packer type!\n");
break;
} /* switch (err) */
} /* else (err == 0) */
} /* if (!skipped) */
} /* for (i) */
ppFreeCrunchInfo(cruninfo);
}
void main(int argc, char *argv[])
{
handle_args(argc, argv);
mytask = FindTask(NULL);
oldpri = SetTaskPri(mytask, pri);
open_all();
doit();
close_all(NULL, 0);
}