home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / System / XADmaster / xad_dev / Sources / tools / xadUnDisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-04-01  |  13.6 KB  |  489 lines

  1. #define NAME         "xadUnDisk"
  2. #define DISTRIBUTION "(Freeware) "
  3. #define REVISION     "11"
  4. #define DATE         "11.11.2000"
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        xadUnDisk
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    dearchives disk archives
  12.     Compileropts:    -
  13.     Linkeropts:    -gsi -l amiga
  14.  
  15.  1.0   18.11.98 : first version
  16.  1.1   23.12.98 : added support for FILEDESCRIPT
  17.  1.2   04.02.99 : added file corrupt message, new InfoText system and SAVETEXTS
  18.  1.3   16.02.99 : bug fix in report hook
  19.  1.4   28.02.99 : little bug fix in chunk hook
  20.  1.5   15.09.99 : added insert disk question
  21.  1.6   20.02.00 : added FORMAT keyword and ADF to disk
  22.  1.7   19.03.00 : bug fix
  23.  1.8   12.04.00 : image question only, if XADERR_FILETYPE
  24.  1.9   07.07.00 : added NOASKINSERT keyword
  25.  1.10  21.08.00 : now uses xadGetHookAccess instead of own image copy
  26.  1.11  11.11.00 : fixed Enforcer hit, added USESECTORLABELS
  27. */
  28.  
  29. #include <proto/xadmaster.h>
  30. #include <proto/exec.h>
  31. #include <proto/dos.h>
  32. #include <proto/utility.h>
  33. #include <exec/memory.h>
  34. #include <devices/trackdisk.h>
  35. #include <dos/dosasl.h>
  36. #include <dos/filehandler.h>
  37. #include <utility/hooks.h>
  38. #include "SDI_version.h"
  39. #include "SDI_compiler.h"
  40. #define SDI_TO_ANSI
  41. #include "SDI_ASM_STD_protos.h"
  42.  
  43. struct xadMasterBase *   xadMasterBase = 0;
  44. struct DosLibrary *     DOSBase = 0;
  45. struct ExecBase *     SysBase  = 0;
  46.  
  47. #define PARAM    "FROM/A,TO,LOWCYL/N,HIGHCYL/N,ENTRY/N,PASSWORD,SAVETEXTS/K," \
  48.         "NE=NOEXTERN/S,INFO=LIST/S,SHOWTEXTS/S,OW=OVERWRITE/S,"    \
  49.         "IG=IGNOREGEOMETRY/S,FORMAT/S,DIMG=DISKIMAGE/S,NAI=NOASKINSERT/S," \
  50.         "USL=USESECTORLABELS/S"
  51.  
  52. struct Args {
  53.   STRPTR from;
  54.   STRPTR to;
  55.   LONG * lowcyl;
  56.   LONG * highcyl;
  57.   LONG * entry;
  58.   STRPTR password;
  59.   STRPTR savetexts;
  60.   ULONG  noextern;
  61.   ULONG  info;
  62.   ULONG  showtexts;
  63.   ULONG  overwrite;
  64.   ULONG  ignoregeometry;
  65.   ULONG  format;
  66.   ULONG  diskimage;
  67.   ULONG  noaskinsert;
  68.   ULONG  usesectorlabels;
  69. };
  70.  
  71. ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *),
  72.   REG(a1, struct xadProgressInfo *));
  73. struct Hook prhook = {{0,0},(ULONG (*)()) progrhook, 0, 0};
  74. void ShowTexts(struct xadTextInfo *ti);
  75. void SaveTexts(struct xadTextInfo *ti, STRPTR name);
  76. LONG WriteDisk(struct Args *);
  77. LONG AskInsertDisk(STRPTR);
  78.  
  79. ULONG start(void)
  80. {
  81.   ULONG ret = RETURN_FAIL;
  82.   struct DosLibrary *dosbase;
  83.  
  84.   SysBase = (*((struct ExecBase **) 4));
  85.   { /* test for WB and reply startup-message */
  86.     struct Process *task;
  87.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  88.     {
  89.       WaitPort(&task->pr_MsgPort);
  90.       Forbid();
  91.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  92.       return RETURN_FAIL;
  93.     }
  94.   }
  95.  
  96.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  97.   {
  98.     LONG err = 0;
  99.     struct xadMasterBase *xadmasterbase;
  100.  
  101.     DOSBase = dosbase;
  102.     if((xadmasterbase = (struct xadMasterBase *) OpenLibrary("xadmaster.library", 9)))
  103.     {
  104.       LONG def = 1;
  105.       struct Args args;
  106.       struct RDArgs *rda;
  107.       
  108.       memset(&args, 0 , sizeof(struct Args));
  109.       args.entry = &def;
  110.  
  111.       xadMasterBase = xadmasterbase;
  112.       if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  113.       {
  114.     if(args.to || args.info)
  115.     {
  116.       struct xadArchiveInfo *ai;
  117.     
  118.       if(args.diskimage)
  119.       {
  120.         ret = 0;
  121.             err = WriteDisk(&args);
  122.       }
  123.       else if((ai = (struct xadArchiveInfo *)
  124.       xadAllocObjectA(XADOBJ_ARCHIVEINFO, 0)))
  125.       {
  126.         if(!(err = xadGetInfo(ai, XAD_INFILENAME, args.from,
  127.         XAD_NOEXTERN, args.noextern, args.password ? XAD_PASSWORD :
  128.         TAG_IGNORE, args.password, TAG_DONE)))
  129.         {
  130.           if(ai->xai_Flags & XADAIF_FILECORRUPT)
  131.             Printf("!!! The archive file has some corrupt data. !!!\n");
  132.           if(args.info)
  133.           {
  134.             struct xadDiskInfo *xdi;
  135.             Printf("ArchiverName:   %s\n", ai->xai_Client->xc_ArchiverName);
  136.  
  137.             xdi = ai->xai_DiskInfo;
  138.             while(xdi)
  139.             {
  140.               LONG a;
  141.  
  142.           if(xdi->xdi_EntryNumber != 1 || xdi->xdi_Next)
  143.                 Printf("\nEntry:          %ld\n", xdi->xdi_EntryNumber);
  144.               Printf("EntryInfo:      %s\n", xdi->xdi_EntryInfo ? xdi->xdi_EntryInfo : "<none>");
  145.               Printf("SectorSize:     %ld\n", xdi->xdi_SectorSize);
  146.               Printf("Sectors:        %ld\n", xdi->xdi_TotalSectors);
  147.               Printf("Cylinders:      %ld\n", xdi->xdi_Cylinders);
  148.               Printf("CylSectors:     %ld\n", xdi->xdi_CylSectors);
  149.               Printf("Heads:          %ld\n", xdi->xdi_Heads);
  150.               Printf("TrackSectors:   %ld\n", xdi->xdi_TrackSectors);
  151.               Printf("LowCyl:         %ld\n", xdi->xdi_LowCyl);
  152.               Printf("HighCyl:        %ld\n", xdi->xdi_HighCyl);
  153.               a = xdi->xdi_Flags & (XADDIF_CRYPTED|XADDIF_SECTORLABELS);
  154.               if(a)
  155.               {
  156.                 Printf("Flags:          ");
  157.                 if(a & XADDIF_CRYPTED)
  158.                 {
  159.                   a ^= XADDIF_CRYPTED;
  160.                   Printf("encrypted%s", a ? ", " : "\n");
  161.                 }
  162.                 if(a & XADDIF_SECTORLABELS)
  163.                 {
  164.                   a ^= XADDIF_SECTORLABELS;
  165.                   Printf("has SectorLabels%s", a ? ", " : "\n");
  166.                 }
  167.               }
  168.               if(xdi->xdi_TextInfo)
  169.               {
  170.                 STRPTR a;
  171.                 struct xadTextInfo *ti;
  172.  
  173.                 for(ti = xdi->xdi_TextInfo; ti; ti = ti->xti_Next)
  174.                 {
  175.               a = "TextInfo";
  176.               if(ti->xti_Flags & XADTIF_BANNER)
  177.                 a = "Banner";
  178.               else if(ti->xti_Flags & XADTIF_FILEDIZ)
  179.                 a = "DIZ-Text";
  180.  
  181.               if(ti->xti_Size && ti->xti_Text)
  182.                     Printf("There is a %s with size %ld.\n", a, ti->xti_Size);
  183.                   else if(ti->xti_Flags & XADTIF_CRYPTED)
  184.                     Printf("There is a crypted %s.\n", a);
  185.                   else
  186.                     Printf("There is an empty %s.\n", a);
  187.                 }
  188.                 if(args.showtexts)
  189.                   ShowTexts(xdi->xdi_TextInfo);
  190.                 if(args.savetexts)
  191.                   SaveTexts(xdi->xdi_TextInfo, args.savetexts);
  192.               }
  193.               xdi = xdi->xdi_Next;
  194.             }
  195.             ret = 0;
  196.           }
  197.           else
  198.           {
  199.         struct xadDeviceInfo *dvi = 0;
  200.  
  201.             if(args.to[strlen(args.to)-1] == ':' && stricmp(args.to, "NIL:"))
  202.             {
  203.               if((dvi = (struct xadDeviceInfo *)
  204.               xadAllocObjectA(XADOBJ_DEVICEINFO, 0)))
  205.               {
  206.                 args.to[strlen(args.to)-1] = 0; /* strip ':' */
  207.                 dvi->xdi_DOSName = args.to;
  208.               }
  209.               else
  210.                 err = XADERR_NOMEMORY;
  211.             }
  212.             if(args.showtexts || args.savetexts)
  213.             {
  214.               struct xadDiskInfo *xdi = ai->xai_DiskInfo;
  215.  
  216.               while(xdi && xdi->xdi_EntryNumber < *args.entry)
  217.                 xdi = xdi->xdi_Next;
  218.               if(xdi && xdi->xdi_TextInfo)
  219.               {
  220.                 if(args.showtexts)
  221.                   ShowTexts(xdi->xdi_TextInfo);
  222.                 if(args.savetexts)
  223.                   SaveTexts(xdi->xdi_TextInfo, args.savetexts);
  224.               }
  225.             }
  226.         if(dvi && !args.noaskinsert)
  227.           err = AskInsertDisk(args.to);
  228.  
  229.             if(!err && !(err = xadDiskUnArc(ai, dvi ? XAD_OUTDEVICE :
  230.             XAD_OUTFILENAME, dvi ? (ULONG) dvi : (ULONG) args.to,
  231.             XAD_ENTRYNUMBER, *args.entry, args.lowcyl ?
  232.             XAD_LOWCYLINDER : TAG_IGNORE, args.lowcyl ? *args.lowcyl :
  233.             0, args.highcyl ? XAD_HIGHCYLINDER : TAG_IGNORE,
  234.             args.highcyl ? *args.highcyl : 0, XAD_OVERWRITE,
  235.             args.overwrite, XAD_IGNOREGEOMETRY, args.ignoregeometry,
  236.             XAD_FORMAT, args.format, XAD_VERIFY, TRUE, XAD_USESECTORLABELS,
  237.             args.usesectorlabels, XAD_PROGRESSHOOK, &prhook, TAG_DONE)))
  238.               ret = 0;
  239.             if(dvi)
  240.               xadFreeObjectA(dvi, 0);
  241.           }
  242.           xadFreeInfo(ai);
  243.         } /* xadGetInfo */
  244.         else if(err == XADERR_FILETYPE)
  245.         {
  246.           UBYTE r;
  247.  
  248.           ret = 0;
  249.               Printf("Unknown type. Press <I> to write it to disks as image: ");
  250.               Flush(Output());
  251.               SetMode(Input(), TRUE);
  252.               r = FGetC(Input());
  253.               SetMode(Input(), FALSE);
  254.               if(r == 'i' || r == 'I')
  255.             err = WriteDisk(&args);
  256.           else
  257.                 Printf("\n");
  258.         }
  259.  
  260.         xadFreeObjectA(ai, 0);
  261.           } /* xadAllocObject */
  262.         }
  263.         else
  264.           SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  265.  
  266.         FreeArgs(rda);
  267.       } /* ReadArgs */
  268.  
  269.       if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  270.         SetIoErr(ERROR_BREAK);
  271.  
  272.       if(err)
  273.     Printf("An error occured: %s\n", xadGetErrorText(err));
  274.       else if(ret)
  275.         PrintFault(IoErr(), 0);
  276.  
  277.       CloseLibrary((struct Library *) xadmasterbase);
  278.     } /* OpenLibrary xadmaster */
  279.     else
  280.       Printf("Could not open xadmaster.library\n");
  281.     CloseLibrary((struct Library *) dosbase);
  282.   } /* OpenLibrary dos */
  283.   return ret;
  284. }
  285.  
  286. ASM(ULONG) SAVEDS progrhook(REG(a0, struct Hook *hook),
  287. REG(a1, struct xadProgressInfo *pi))
  288. {
  289.   ULONG ret = 0;
  290.  
  291.   switch(pi->xpi_Mode)
  292.   {
  293.   case XADPMODE_ASK:
  294.     {
  295.       UBYTE r;
  296.       if(pi->xpi_Status & XADPIF_OVERWRITE)
  297.       {
  298.         Printf("File already exists, overwrite? (Y|S|\033[1mN\033[0m): ");
  299.         Flush(Output());
  300.         SetMode(Input(), TRUE);
  301.         r = FGetC(Input());
  302.         if(r == 'Y' || r == 'y')
  303.           ret |= XADPIF_OVERWRITE;
  304.         else if(r == 'S' || r == 's')
  305.           ret |= XADPIF_SKIP;
  306.         SetMode(Input(), FALSE);
  307.       }
  308.       if(pi->xpi_Status & XADPIF_IGNOREGEOMETRY)
  309.       {
  310.         Printf("\r\033[KDrive geometry not correct, ignore? (Y|S|\033[1mN\033[0m): ");
  311.         Flush(Output());
  312.         SetMode(Input(), TRUE);
  313.         r = FGetC(Input());
  314.         if(r == 'Y' || r == 'y')
  315.           ret |= XADPIF_IGNOREGEOMETRY;
  316.         else if(r == 'S' || r == 's')
  317.           ret |= XADPIF_SKIP;
  318.         SetMode(Input(), FALSE);
  319.       }
  320.     }
  321.     break;
  322.   case XADPMODE_PROGRESS:
  323.     {
  324.       if(!pi->xpi_DiskInfo)
  325.         Printf("\r\033[KWrote %ld bytes", pi->xpi_CurrentSize);
  326.       else if(pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS))
  327.       {
  328.         Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld sectors)",
  329.         pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors*
  330.         pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_CurrentSize/
  331.         pi->xpi_DiskInfo->xdi_SectorSize, pi->xpi_DiskInfo->xdi_TotalSectors);
  332.       }
  333.       else
  334.       {
  335.         ULONG numcyl, fullsize, curcyl, i;
  336.  
  337.         i = pi->xpi_DiskInfo->xdi_CylSectors *
  338.             pi->xpi_DiskInfo->xdi_SectorSize;
  339.         numcyl = pi->xpi_HighCyl+1-pi->xpi_LowCyl;
  340.         fullsize = numcyl * i;
  341.         curcyl = pi->xpi_CurrentSize/i;
  342.  
  343.         Printf("\r\033[KWrote %ld of %ld bytes (%ld/%ld cylinders)",
  344.         pi->xpi_CurrentSize, fullsize, curcyl, numcyl);
  345.       }
  346.       Flush(Output());
  347.     }
  348.     break;
  349.   case XADPMODE_END: 
  350.     if(pi->xpi_DiskInfo && (pi->xpi_DiskInfo->xdi_Flags & (XADDIF_NOCYLINDERS|XADDIF_NOCYLSECTORS)))
  351.       Printf("\r\033[KWrote %ld bytes (%ld sectors)\n",
  352.       pi->xpi_CurrentSize, pi->xpi_DiskInfo->xdi_TotalSectors);
  353.     else
  354.       Printf("\r\033[KWrote %ld bytes (%ld cylinders)\n",
  355.       pi->xpi_CurrentSize, pi->xpi_HighCyl+1-pi->xpi_LowCyl);
  356.     break;
  357.   case XADPMODE_ERROR: Printf("\r\033[K");
  358.     break;
  359.   }
  360.  
  361.   if(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)) /* clear ok flag */
  362.     ret |= XADPIF_OK;
  363.  
  364.   return ret;
  365. }
  366.  
  367. void ShowTexts(struct xadTextInfo *ti)
  368. {
  369.   ULONG i = 1, j;
  370.   BPTR fh;
  371.   STRPTR a;
  372.  
  373.   fh = Output();
  374.  
  375.   while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti)
  376.   {
  377.     if(ti->xti_Size && ti->xti_Text)
  378.     {
  379.       Printf("»»»» TEXTINFO %ld ««««\n", i);
  380.       a = ti->xti_Text;
  381.       for(j = 0; !(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && j < ti->xti_Size; ++j)
  382.       {
  383.         if(isprint(*a) || *a == '\n' || *a == '\t' || *a == '\033')
  384.           FPutC(fh, *a);
  385.         else
  386.           FPutC(fh, '.');
  387.         ++a;
  388.       }
  389.       if(*(--a) != '\n')
  390.         FPutC(fh, '\n');
  391.     }
  392.     ti = ti->xti_Next;
  393.     ++i;
  394.   }
  395. }
  396.  
  397. void SaveTexts(struct xadTextInfo *ti, STRPTR name)
  398. {
  399.   UBYTE namebuf[256];
  400.   ULONG i = 1;
  401.   BPTR fh;
  402.   LONG err = 0;
  403.  
  404.   while(!(SetSignal(0L,0L) & SIGBREAKF_CTRL_C) && ti && !err)
  405.   {
  406.     if(ti->xti_Size && ti->xti_Text)
  407.     {
  408.       sprintf(namebuf, "%s.%ld", name, i);
  409.       if((fh = Open(namebuf, MODE_NEWFILE)))
  410.       {
  411.         if(Write(fh, ti->xti_Text, ti->xti_Size) != ti->xti_Size)
  412.           ++err;
  413.         Close(fh);
  414.       }
  415.       else
  416.         ++err;
  417.     }
  418.     ti = ti->xti_Next;
  419.     ++i;
  420.   }
  421.   if(err)
  422.     Printf("Failed to save information texts.\n");
  423. }
  424.  
  425. LONG WriteDisk(struct Args *args)
  426. {
  427.   LONG err = 0;
  428.   struct xadArchiveInfo *ai;
  429.   struct xadDeviceInfo *dvi = 0;
  430.  
  431.   if((ai = (struct xadArchiveInfo *) xadAllocObjectA(XADOBJ_ARCHIVEINFO, 0)))
  432.   {
  433.     if(args->to[strlen(args->to)-1] == ':' && stricmp(args->to, "NIL:"))
  434.     {
  435.       if((dvi = (struct xadDeviceInfo *) xadAllocObjectA(XADOBJ_DEVICEINFO, 0)))
  436.       {
  437.         args->to[strlen(args->to)-1] = 0; /* strip ':' */
  438.         dvi->xdi_DOSName = args->to;
  439.       }
  440.       else
  441.         err = XADERR_NOMEMORY;
  442.     }
  443.  
  444.     if(dvi && !args->noaskinsert)
  445.       err = AskInsertDisk(args->to);
  446.  
  447.     if(!err)
  448.     {
  449.       if(!(err = xadGetHookAccess(ai, XAD_INFILENAME, args->from, dvi ? XAD_OUTDEVICE :
  450.       XAD_OUTFILENAME, dvi ? (ULONG) dvi : (ULONG) args->to, XAD_OVERWRITE, args->overwrite,
  451.       XAD_IGNOREGEOMETRY, args->ignoregeometry, XAD_FORMAT, args->format, XAD_VERIFY,
  452.       TRUE, XAD_PROGRESSHOOK, &prhook, TAG_DONE)))
  453.       {
  454.         err = xadHookAccess(XADAC_COPY, ai->xai_InSize, 0, ai);
  455.         xadFreeHookAccess(ai, err ? XAD_WASERROR : TAG_DONE, err, TAG_DONE);
  456.       }
  457.       xadFreeObjectA(dvi, 0);
  458.     }
  459.     else
  460.       err = XADERR_NOMEMORY;
  461.     xadFreeObjectA(ai,0);
  462.   }
  463.   else
  464.     err = XADERR_NOMEMORY;
  465.  
  466.   return err;
  467. }
  468.  
  469. LONG AskInsertDisk(STRPTR name)
  470. {
  471.   UBYTE r;
  472.   STRPTR b;
  473.           
  474.   for(b = name; *b; ++b)
  475.     *b = toupper(*b);
  476.  
  477.   Printf("\r\033[KInsert disk into %s: and press <ENTER> (any other key to abort): ", name);
  478.   Flush(Output());
  479.   SetMode(Input(), TRUE);
  480.   r = FGetC(Input());
  481.   SetMode(Input(), FALSE);
  482.   if(r != '\r' && r != '\n')
  483.   {
  484.     Printf("\n");
  485.     return XADERR_BREAK;
  486.   }
  487.   return 0;
  488. }
  489.