home *** CD-ROM | disk | FTP | other *** search
- #define NAME "xadUnDisk"
- #define DISTRIBUTION "(Freeware) "
- #define REVISION "8"
- #define DATE "12.04.2000"
-
- /* Programmheader
-
- Name: xadUnDisk
- Author: SDI
- Distribution: Freeware
- Description: dearchives disk archives
- Compileropts: -
- Linkeropts: -gsi -l amiga
-
- 1.0 18.11.98 : first version
- 1.1 23.12.98 : added support for FILEDESCRIPT
- 1.2 04.02.99 : added file corrupt message, new InfoText system and SAVETEXTS
- 1.3 16.02.99 : bug fix in report hook
- 1.4 28.02.99 : little bug fix in chunk hook
- 1.5 15.09.99 : added insert disk question
- 1.6 20.02.00 : added FORMAT keyword and ADF to disk
- 1.7 19.03.00 : bug fix
- 1.8 12.04.00 : image question only, if XADERR_FILETYPE
- */
-
- #include <proto/xadmaster.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
- #include <exec/memory.h>
- #include <devices/trackdisk.h>
- #include <dos/dosasl.h>
- #include <dos/filehandler.h>
- #include <utility/hooks.h>
- #include "SDI_version.h"
- #include "SDI_compiler.h"
- #define SDI_TO_ANSI
- #include "SDI_ASM_STD_protos.h"
-
- struct xadMasterBase * xadMasterBase = 0;
- struct DosLibrary * DOSBase = 0;
- struct ExecBase * SysBase = 0;
-
- #define PARAM "FROM/A,TO,LOWCYL/N,HIGHCYL/N,ENTRY/N,PASSWORD,SAVETEXTS/K," \
- "NE=NOEXTERN/S,INFO=LIST/S,SHOWTEXTS/S,OW=OVERWRITE/S," \
- "IG=IGNOREGEOMETRY/S,FORMAT/S,DIMG=DISKIMAGE/S"
-
- struct Args {
- STRPTR from;
- STRPTR to;
- LONG * lowcyl;
- LONG * highcyl;
- LONG * entry;
- STRPTR password;
- STRPTR savetexts;
- ULONG noextern;
- ULONG info;
- ULONG showtexts;
- ULONG overwrite;
- ULONG ignoregeometry;
- ULONG format;
- ULONG diskimage;
- };
-
- ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *),
- REG(a1, struct xadProgressInfo *));
- struct Hook prhook = {{0,0},(ULONG (*)()) progrhook, 0, 0};
- void ShowTexts(struct xadTextInfo *ti);
- void SaveTexts(struct xadTextInfo *ti, STRPTR name);
- LONG WriteDisk(struct Args *);
-
- ULONG start(void)
- {
- ULONG ret = RETURN_FAIL;
- struct DosLibrary *dosbase;
-
- SysBase = (*((struct ExecBase **) 4));
- { /* test for WB and reply startup-message */
- struct Process *task;
- if(!(task = (struct Process *) FindTask(0))->pr_CLI)
- {
- WaitPort(&task->pr_MsgPort);
- Forbid();
- ReplyMsg(GetMsg(&task->pr_MsgPort));
- return RETURN_FAIL;
- }
- }
-
- if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
- {
- LONG err = 0;
- struct xadMasterBase *xadmasterbase;
-
- DOSBase = dosbase;
- if((xadmasterbase = (struct xadMasterBase *)
- OpenLibrary("xadmaster.library", 5)))
- {
- LONG def = 1;
- struct Args args;
- struct RDArgs *rda;
-
- memset(&args, 0 , sizeof(struct Args));
- args.entry = &def;
-
- xadMasterBase = xadmasterbase;
- if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
- {
- if(args.to || args.info)
- {
- struct xadArchiveInfo *ai;
-
- if(args.diskimage)
- {
- ret = 0;
- if(args.to[strlen(args.to)-1] == ':' && stricmp(args.to, "NIL:"))
- err = WriteDisk(&args);
- else
- Printf("Use copy command to copy disk images.\n");
- }
- else if((ai = (struct xadArchiveInfo *)
- xadAllocObjectA(XADOBJ_ARCHIVEINFO, 0)))
- {
- if(!(err = xadGetInfo(ai, XAD_INFILENAME, args.from,
- XAD_NOEXTERN, args.noextern, args.password ? XAD_PASSWORD :
- TAG_IGNORE, args.password, TAG_DONE)))
- {
- if(ai->xai_Flags & XADAIF_FILECORRUPT)
- Printf("!!! The archive file has some corrupt data. !!!\n");
- if(args.info)
- {
- struct xadDiskInfo *xdi;
- Printf("ArchiverName: %s\n", ai->xai_Client->xc_ArchiverName);
- #ifdef DEBUG
- Printf("Password: %s\n", ai->xai_Password ? ai->xai_Password : "<none>");
- Printf("InSize: %ld\n", ai->xai_InSize);
- Printf("InPos: %ld\n", ai->xai_InPos);
- #endif
-
- xdi = ai->xai_DiskInfo;
- while(xdi)
- {
- if(xdi->xdi_EntryNumber != 1 || xdi->xdi_Next)
- Printf("\nEntry: %ld\n", xdi->xdi_EntryNumber);
- Printf("EntryInfo: %s\n", xdi->xdi_EntryInfo ? xdi->xdi_EntryInfo : "<none>");
- #ifdef DEBUG
- Printf("Flags: ");
- if(xdi->xdi_Flags & XADDIF_CRYPTED)
- Printf("XADDIF_CRYPTED ");
- Printf(xdi->xdi_Flags ? "\n" : "<none>\n");
- #endif
- Printf("SectorSize: %ld\n", xdi->xdi_SectorSize);
- Printf("Sectors: %ld\n", xdi->xdi_TotalSectors);
- Printf("Cylinders: %ld\n", xdi->xdi_Cylinders);
- Printf("CylSectors: %ld\n", xdi->xdi_CylSectors);
- Printf("Heads: %ld\n", xdi->xdi_Heads);
- Printf("TrackSectors: %ld\n", xdi->xdi_TrackSectors);
- Printf("LowCyl: %ld\n", xdi->xdi_LowCyl);
- Printf("HighCyl: %ld\n", xdi->xdi_HighCyl);
- if(xdi->xdi_Flags & XADDIF_CRYPTED)
- Printf("The entry is encrypted\n");
- if(xdi->xdi_TextInfo)
- {
- STRPTR a;
- struct xadTextInfo *ti;
-
- for(ti = xdi->xdi_TextInfo; ti; ti = ti->xti_Next)
- {
- a = "TextInfo";
- if(ti->xti_Flags & XADTIF_BANNER)
- a = "Banner";
- else if(ti->xti_Flags & XADTIF_FILEDIZ)
- a = "DIZ-Text";
-
- if(ti->xti_Size && ti->xti_Text)
- Printf("There is a %s with size %ld.\n", a, ti->xti_Size);
- else if(ti->xti_Flags & XADTIF_CRYPTED)
- Printf("There is a crypted %s.\n", a);
- else
- Printf("There is an empty %s.\n", a);
- }
- if(args.showtexts)
- ShowTexts(xdi->xdi_TextInfo);
- if(args.savetexts)
- SaveTexts(xdi->xdi_TextInfo, args.savetexts);
- }
- xdi = xdi->xdi_Next;
- }
- ret = 0;
- }
- else
- {
- struct xadDeviceInfo *dvi = 0;
-
- if(args.to[strlen(args.to)-1] == ':' && stricmp(args.to, "NIL:"))
- {
- if((dvi = (struct xadDeviceInfo *)
- xadAllocObjectA(XADOBJ_DEVICEINFO, 0)))
- {
- args.to[strlen(args.to)-1] = 0; /* strip ':' */
- dvi->xdi_DOSName = args.to;
- }
- else
- err = XADERR_NOMEMORY;
- }
- if(args.showtexts || args.savetexts)
- {
- struct xadDiskInfo *xdi = ai->xai_DiskInfo;
-
- while(xdi && xdi->xdi_EntryNumber < *args.entry)
- xdi = xdi->xdi_Next;
- if(xdi && xdi->xdi_TextInfo)
- {
- if(args.showtexts)
- ShowTexts(xdi->xdi_TextInfo);
- if(args.savetexts)
- SaveTexts(xdi->xdi_TextInfo, args.savetexts);
- }
- }
- if(dvi)
- {
- UBYTE r;
- STRPTR b;
-
- for(b = args.to; *b; ++b)
- *b = toupper(*b);
-
- Printf("Insert disk into %s: and press <ENTER> (any other key to abort): ", dvi->xdi_DOSName);
- Flush(Output());
- SetMode(Input(), TRUE);
- r = FGetC(Input());
- SetMode(Input(), FALSE);
- if(r != '\r' && r != '\n')
- {
- Printf("\n");
- err = XADERR_BREAK;
- }
- }
- if(!err && !(err = xadDiskUnArc(ai, dvi ? XAD_OUTDEVICE :
- XAD_OUTFILENAME, dvi ? (ULONG) dvi : (ULONG) args.to,
- XAD_ENTRYNUMBER, *args.entry, args.lowcyl ?
- XAD_LOWCYLINDER : TAG_IGNORE, args.lowcyl ? *args.lowcyl :
- 0, args.highcyl ? XAD_HIGHCYLINDER : TAG_IGNORE,
- args.highcyl ? *args.highcyl : 0, XAD_OVERWRITE,
- args.overwrite, XAD_IGNOREGEOMETRY, args.ignoregeometry,
- XAD_FORMAT, args.format, XAD_VERIFY, TRUE, XAD_PROGRESSHOOK,
- &prhook, TAG_DONE)))
- ret = 0;
- if(dvi)
- xadFreeObjectA(dvi, 0);
- }
- xadFreeInfo(ai);
- } /* xadGetInfo */
- else if(err == XADERR_FILETYPE && args.to[strlen(args.to)-1] == ':' && stricmp(args.to, "NIL:"))
- {
- UBYTE r;
-
- ret = 0;
- Printf("Unknown type. Press <I> to write it to disks as image: ");
- Flush(Output());
- SetMode(Input(), TRUE);
- r = FGetC(Input());
- SetMode(Input(), FALSE);
- if(r == 'i' || r == 'I')
- err = WriteDisk(&args);
- else
- Printf("\n");
- }
-
- xadFreeObjectA(ai, 0);
- } /* xadAllocObject */
- }
- else
- SetIoErr(ERROR_REQUIRED_ARG_MISSING);
-
- FreeArgs(rda);
- } /* ReadArgs */
-
- if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
- SetIoErr(ERROR_BREAK);
-
- if(err)
- Printf("An error occured: %s\n", xadGetErrorText(err));
- else if(ret)
- PrintFault(IoErr(), 0);
-
- CloseLibrary((struct Library *) xadmasterbase);
- } /* OpenLibrary xadmaster */
- else
- Printf("Could not open xadmaster.library\n");
- CloseLibrary((struct Library *) dosbase);
- } /* OpenLibrary dos */
- return ret;
- }
-
- ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *hook),
- REG(a1, struct xadProgressInfo *pi))
- {
- ULONG ret = 0;
-
- switch(pi->xpi_Mode)
- {
- case XADPMODE_ASK:
- {
- UBYTE r;
- if(pi->xpi_Status & XADPIF_OVERWRITE)
- {
- Printf("File already exists, overwrite? (Y|S|\033[1mN\033[0m): ");
- Flush(Output());
- SetMode(Input(), TRUE);
- r = FGetC(Input());
- if(r == 'Y' || r == 'y')
- ret |= XADPIF_OVERWRITE;
- else if(r == 'S' || r == 's')
- ret |= XADPIF_SKIP;
- SetMode(Input(), FALSE);
- }
- if(pi->xpi_Status & XADPIF_IGNOREGEOMETRY)
- {
- Printf("\r\033[KDrive geometry not correct, ignore? (Y|S|\033[1mN\033[0m): ");
- Flush(Output());
- SetMode(Input(), TRUE);
- r = FGetC(Input());
- if(r == 'Y' || r == 'y')
- ret |= XADPIF_IGNOREGEOMETRY;
- else if(r == 'S' || r == 's')
- ret |= XADPIF_SKIP;
- SetMode(Input(), FALSE);
- }
- }
- break;
- case XADPMODE_PROGRESS:
- {
- if(pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS))
- {
- Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld sectors)",
- pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors*
- pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_CurrentSize/
- pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_DiskInfo->xdi_TotalSectors);
- }
- else
- {
- ULONG numcyl, fullsize, curcyl, i;
-
- i = pi->xpi_DiskInfo->xdi_CylSectors *
- pi->xpi_DiskInfo->xdi_SectorSize;
- numcyl = pi->xpi_HighCyl+1-pi->xpi_LowCyl;
- fullsize = numcyl * i;
- curcyl = pi->xpi_CurrentSize/i;
-
- Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld cylinders)",
- pi->xpi_CurrentSize, fullsize, curcyl, numcyl);
- }
- Flush(Output());
- }
- break;
- case XADPMODE_END:
- if(pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS))
- Printf("\r\033[KWrote %ld bytes (%ld sectors)\n",
- pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors);
- else
- Printf("\r\033[KWrote %ld bytes (%ld cylinders)\n",
- pi->xpi_CurrentSize, pi->xpi_HighCyl+1-pi->xpi_LowCyl);
- break;
- case XADPMODE_ERROR: Printf("\r\033[K");
- break;
- }
-
- if(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)) /* clear ok flag */
- ret |= XADPIF_OK;
-
- return ret;
- }
-
- void ShowTexts(struct xadTextInfo *ti)
- {
- ULONG i = 1, j;
- BPTR fh;
- STRPTR a;
-
- fh = Output();
-
- while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti)
- {
- if(ti->xti_Size && ti->xti_Text)
- {
- Printf("»»»» TEXTINFO %ld ««««\n", i);
- a = ti->xti_Text;
- for(j = 0; !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && j < ti->xti_Size; ++j)
- {
- if(isprint(*a) || *a == '\n' || *a == '\t' || *a == '\033')
- FPutC(fh, *a);
- else
- FPutC(fh, '.');
- ++a;
- }
- if(*(--a) != '\n')
- FPutC(fh, '\n');
- }
- ti = ti->xti_Next;
- ++i;
- }
- }
-
- void SaveTexts(struct xadTextInfo *ti, STRPTR name)
- {
- UBYTE namebuf[256];
- ULONG i = 1;
- BPTR fh;
- LONG err = 0;
-
- while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti && !err)
- {
- if(ti->xti_Size && ti->xti_Text)
- {
- sprintf(namebuf, "%s.%ld", name, i);
- if((fh = Open(namebuf, MODE_NEWFILE)))
- {
- if(Write(fh, ti->xti_Text, ti->xti_Size) != ti->xti_Size)
- ++err;
- Close(fh);
- }
- else
- ++err;
- }
- ti = ti->xti_Next;
- ++i;
- }
- if(err)
- Printf("Failed to save information texts.\n");
- }
-
- LONG WriteDisk(struct Args *args)
- {
- LONG err = XADERR_RESOURCE;
- struct DosList *dol;
-
- if((dol = LockDosList(LDF_READ|LDF_DEVICES)))
- {
- ULONG i;
-
- i = strlen(args->to)-1;
- args->to[i] = 0; /* remove ':' */
-
- if((dol = FindDosEntry(dol, args->to, LDF_DEVICES)))
- {
- struct MsgPort *port;
-
- args->to[i] = ':';
- if((port = CreateMsgPort()))
- {
- struct IOStdReq *ioreq;
-
- if((ioreq = (struct IOStdReq *) CreateIORequest(port, sizeof(struct IOStdReq))))
- {
- struct FileSysStartupMsg *fsm;
-
- fsm = (struct FileSysStartupMsg *) (dol->dol_misc.dol_handler.dol_Startup<<2);
-
- if(!OpenDevice((STRPTR)((fsm->fssm_Device<<2)+1), fsm->fssm_Unit, (struct IORequest *) ioreq, 0))
- {
- struct DosEnvec *de;
- STRPTR buf;
- ULONG size;
-
- de = (struct DosEnvec *) (fsm->fssm_Environ<<2);
- size = (de->de_SizeBlock<<2)*(de->de_BlocksPerTrack*de->de_Surfaces);
- if((buf = (STRPTR) AllocVec(size*2, MEMF_ANY)))
- {
- BPTR fh;
-
- if((fh = Open(args->from, MODE_OLDFILE)))
- {
- struct FileInfoBlock *fib;
- ULONG low, num;
-
- low = de->de_LowCyl*size;
- num = (de->de_HighCyl-de->de_LowCyl+1) * size;
- if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
- {
- if(ExamineFH(fh, fib))
- {
- struct UtilityBase *UtilityBase;
-
- if((UtilityBase = (struct UtilityBase *) OpenLibrary("utility.library", 37)))
- {
- struct xadProgressInfo *pi;
-
- if((pi = (struct xadProgressInfo *) xadAllocObjectA(XADOBJ_PROGRESSINFO, 0)))
- {
- struct xadDiskInfo *xdi;
- err = 0;
- if(num != fib->fib_Size && !args->ignoregeometry)
- {
- pi->xpi_Mode = XADPMODE_ASK;
- pi->xpi_Status = XADPIF_IGNOREGEOMETRY;
- if(!((i = CallHookPkt(&prhook, 0, pi)) & XADPIF_OK))
- err = XADERR_BREAK;
- else if(i & XADPIF_SKIP)
- err = XADERR_SKIP;
- else if(!(i & XADPIF_IGNOREGEOMETRY))
- err = XADERR_GEOMETRY;
- }
- if(!err)
- {
- UBYTE r;
- STRPTR b;
-
- for(b = args->to; *b; ++b)
- *b = toupper(*b);
-
- Printf("\r\033[KInsert disk into %s and press <ENTER> (any other key to abort): ", args->to);
- Flush(Output());
- SetMode(Input(), TRUE);
- r = FGetC(Input());
- SetMode(Input(), FALSE);
- if(r != '\r' && r != '\n')
- {
- Printf("\n");
- err = XADERR_BREAK;
- }
- }
- if(!err && (xdi = (struct xadDiskInfo *) xadAllocObjectA(XADOBJ_DISKINFO, 0)))
- {
- ULONG siz, p;
- STRPTR b;
- siz = fib->fib_Size;
-
- ioreq->io_Flags = 0;
- b = buf+size;
- p = 0;
- pi->xpi_DiskInfo = xdi;
- xdi->xdi_Flags = XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS;
- xdi->xdi_TotalSectors = (siz+511)>>9; /* divide by 512 */
- xdi->xdi_SectorSize = 512;
- Inhibit(args->to, DOSTRUE);
- while(siz && !err)
- {
- i = size > siz ? siz : size;
- if(p+i > num)
- {
- if(!(i = num-p)) /* do not exceed borders */
- {
- err = XADERR_OUTPUT; break;
- }
- }
- siz -= i;
-
- if(Read(fh, buf, i) != i)
- err = XADERR_INPUT;
- else
- {
- ioreq->io_Length = i;
- ioreq->io_Offset = low+p;
- ioreq->io_Command = args->format ? TD_FORMAT : CMD_WRITE;
- ioreq->io_Data = buf;
- p += i;
- if(DoIO(((struct IORequest *) ioreq)))
- err = XADERR_OUTPUT;
- else
- {
- ioreq->io_Command = CMD_READ;
- ioreq->io_Data = b;
- if(DoIO(((struct IORequest *) ioreq)))
- err = XADERR_OUTPUT;
- else
- {
- pi->xpi_Mode = XADPMODE_PROGRESS;
- pi->xpi_CurrentSize = p;
- if(!(CallHookPkt(&prhook, 0, pi)) & XADPIF_OK)
- err = XADERR_BREAK;
- else
- {
- while(i--)
- {
- if(buf[i] != b[i])
- {
- err = XADERR_OUTPUT;
- break;
- }
- }
- }
- }
- }
- }
- } /* while */
- Inhibit(args->to, DOSFALSE);
- pi->xpi_Mode = err ? XADPMODE_ERROR : XADPMODE_END;
- pi->xpi_CurrentSize = fib->fib_Size;
- pi->xpi_Status = err;
- CallHookPkt(&prhook, 0, pi);
- xadFreeObjectA(xdi, 0);
- }
- xadFreeObjectA(pi, 0);
- }
- else
- err = XADERR_NOMEMORY;
- CloseLibrary((struct Library *) UtilityBase);
- }
- }
- else
- err = XADERR_INPUT;
- FreeDosObject(DOS_FIB, fib);
- }
- else
- err = XADERR_NOMEMORY;
- Close(fh);
- }
- else
- err = XADERR_INPUT;
- FreeVec(buf);
- }
- else
- err = XADERR_NOMEMORY;
- CloseDevice((struct IORequest *) (ioreq));
- } /* OpenDevice */
- DeleteIORequest(ioreq);
- } /* CreatIORequest */
- DeleteMsgPort(port);
- } /* CreateMsgPort */
- } /* FindDosEntry */
- UnLockDosList(LDF_READ|LDF_DEVICES);
- } /* LockDosList */
-
- return err;
- }
-