home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Cruncher / ulib4271.lha / UnpackLib / For_Programmers_Only / Programmers_Tools / Examples / unpUnpack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-15  |  6.9 KB  |  255 lines

  1. /*************************************************************************
  2. *                               unpUnpack                                *
  3. *                                                                        *
  4. *              With this program you can unpack your files.              *
  5. *                                                                        *
  6. *************************************************************************/
  7.  
  8. // First we include a lot of things
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include <exec/types.h>
  15. #include <dos/rdargs.h>
  16. #include <dos/dosextens.h>
  17. #include <libraries/unpack.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21. #include <proto/unpack.h>
  22.  
  23.  
  24. // Global Variables
  25. struct  Library *UnpackBase;
  26. struct  UnpackInfo *cinfo=NULL;
  27. struct  RDArgs *rda=NULL;
  28. LONG    arguments[4] = {0,0,0,0};
  29. BPTR    oldlock;
  30. LONG    DecrunchLen;
  31.  
  32.  
  33. #ifdef LATTICE
  34. void __regargs _CXBRK(void)               // Catch CTRL-C Handling
  35. {
  36.   fprintf(stderr,"*** User breaked\n");   // Print out break message
  37.   CurrentDir(oldlock);                    // and clean up after us
  38.   upFreeCInfo(cinfo);
  39.   CloseLibrary(UnpackBase);
  40.   FreeArgs(rda);
  41.   exit(0);                                // then we exit our program.
  42. }
  43. #endif
  44.  
  45.  
  46. // Prototypes
  47. void ScanDir(struct UnpackInfo *ui, BPTR mylock);
  48. void UnpackFile(struct UnpackInfo *info, char *name);
  49. void PrintName(char *name);
  50. __asm void Saver(register __a1 ULONG userdata, register __a2 struct UnpackInfo *ui);
  51.  
  52. // Main program
  53. void main (void)
  54. {
  55. extern  struct ExecBase *SysBase;
  56. struct  Process *mytask;
  57. struct  FileInfoBlock fib;
  58.  
  59. BPTR    dirlock;
  60.  
  61. char   *name;
  62. int     i=0;
  63.  
  64.   if( ((struct Library*) DOSBase)->lib_Version < 37 )
  65.   {
  66.     fprintf(stderr,"unpUnpack requires at least Kickstart 2.04!\n");
  67.     exit(0);
  68.   }
  69.  
  70.   if (rda = ReadArgs("FILE=DIR/M,P=PATH/K,TO=DEST/K,PROTECT/S",arguments,NULL))
  71.   {
  72.     if (!((arguments[1] == NULL) && (arguments[2] == NULL)))
  73.     {
  74.       if (UnpackBase = OpenLibrary("unpack.library",42L))
  75.       {
  76.         if (cinfo = upAllocCInfo())
  77.         {
  78.           printf("unpUnpack 1.0 (5/10-1995) by Thomas Neumann\n\n");
  79.           mytask = (struct Process *)FindTask(NULL);
  80.           oldlock = mytask->pr_CurrentDir;
  81.  
  82.           cinfo->ui_Path = (char *)arguments[1]; // Setup path to archive unpackers
  83.           cinfo->ui_Jump = (void (*)(void *, void *))Saver;
  84.           cinfo->ui_Flag = UFN_NoA4;
  85.           if (arguments[3] != 0)
  86.             cinfo->ui_Flag |= UFN_Protect;
  87.  
  88.           if (arguments[0] == NULL) // If no files are given, scan
  89.           {                         // current directory.
  90.             dirlock = (oldlock);
  91.             ScanDir(cinfo, dirlock);
  92.           }
  93.           else
  94.           {
  95.             // It this complex or what? :)
  96.             while ((name = (char *)((LONG *)arguments[0])[i++]))
  97.             {
  98.               // Lock given name
  99.               if ((dirlock = Lock(name, ACCESS_READ)) != NULL)
  100.               {
  101.                 Examine(dirlock, &fib);
  102.                 if (fib.fib_DirEntryType > 0)
  103.                   ScanDir(cinfo, dirlock);    // It's a directory
  104.                 else
  105.                   UnpackFile(cinfo, name);    // It's a file
  106.                 UnLock(dirlock);
  107.               }
  108.               else
  109.                 UnpackFile(cinfo, name);      // Couldn't lock
  110.             }
  111.           }
  112.           upFreeCInfo(cinfo);
  113.         }
  114.         CloseLibrary(UnpackBase);
  115.       }
  116.       else
  117.         fprintf(stderr,"You need the unpack.library version 42 or higher\n");
  118.     }
  119.     else
  120.       fprintf(stderr,"You MUST use either the PATH or the TO/DEST keyword\n");
  121.  
  122.   FreeArgs(rda);
  123.   }
  124.   else
  125.     PrintFault(IoErr(),NULL);
  126. }
  127.  
  128.  
  129. void ScanDir (struct UnpackInfo *ui, BPTR mylock)
  130. {
  131. struct FileInfoBlock fib;
  132.  
  133.   oldlock = CurrentDir(mylock);         // Set current directory
  134.  
  135.   if (Examine(mylock, &fib))
  136.     while (ExNext(mylock, &fib))        // Test all files in directory
  137.     {
  138.       if (fib.fib_DirEntryType < 0)
  139.         UnpackFile(ui, fib.fib_FileName); // We got a file
  140.       else
  141.       {
  142.         PrintName(fib.fib_FileName);    // Print out directory name
  143.         printf(" (DIR)\n");
  144.       }
  145.     }
  146.  
  147.   CurrentDir(oldlock);                  // Set current directory back
  148. }
  149.  
  150.  
  151. void UnpackFile (struct UnpackInfo *info, char *name)
  152. {
  153. LONG CrunchLen;
  154. int j;
  155. BPTR winhd;
  156.  
  157.   winhd = Output();
  158.   PrintName(name);
  159.  
  160.   if (upDetermineFile(info,name))
  161.   {
  162.     CrunchLen=info->ui_CrunchLen;
  163.     if ((info->ui_CrunchType & 0x7f) == CRU_Track)
  164.       printf("Can't unpack track crunched files\n");
  165.     else
  166.     {
  167.       if ((info->ui_CrunchType & 0x7f) == CRU_Archive)
  168.         if (arguments[1] == NULL)
  169.         {
  170.           printf("No PATH argument given, can't unpack!!\n");
  171.           return;
  172.         }
  173.  
  174.       if (upUnpack(info) != 0)
  175.       {
  176.         printf("%s\n",info->ui_CruncherName);
  177.         for (j=0;j<30;j++)
  178.           Write(winhd," ",1);
  179.         printf("%6ld -> %6ld\n",CrunchLen,DecrunchLen);
  180.       }
  181.       else
  182.         printf("%s\n",info->ui_ErrorMsg);
  183.     }
  184.   }
  185.   else
  186.     printf("%s\n",info->ui_ErrorMsg);
  187. }
  188.  
  189.  
  190. void PrintName(char *name)
  191. {
  192. int j,k;
  193. BPTR winhd;
  194.  
  195.   winhd = Output();
  196.   k = strlen(name);
  197.  
  198.   Write(winhd,name,k);
  199.   if ((k = 30-k) < 0)
  200.     k=1;
  201.  
  202.   for (j=0;j<k;j++)
  203.     Write(winhd," ",1);
  204. }
  205.  
  206. __asm void Saver(register __a1 ULONG userdata, register __a2 struct UnpackInfo *ui)
  207. {
  208. char *filename;
  209. char realname[2*108];
  210. int  namelen;
  211. BPTR fh;
  212.  
  213.   // This if statement shouldn't you have if you make a virus scanner
  214.   // routine, because your function will be called for each file in an
  215.   // archive, so you just get the filename or whatever you want to
  216.   // scan the file. Note that the unpack library will read the file
  217.   // into memory, so you just have to look at UI_DecrunchAdr and
  218.   // UI_DecrunchLen to get the filedata.
  219.   if ((ui->ui_CrunchType & 0x7f) != CRU_Archive)  // Only Save if the
  220.   {                                               // file wasn't an archive.
  221.     /* The next lines is very important!!!!!
  222.        This demostrates how you will get the
  223.        right filename. You has to do this if
  224.        you want to handle recursive files,
  225.        like a powerpacked file in a lha archive. */
  226.  
  227.     filename = ui->ui_LoadNamePoi;
  228.     if (ui->ui_UseFilenamePointer == 0)
  229.     {
  230.       filename = realname;
  231.  
  232.       if (arguments[1] != NULL)   // Check to see if the user has the PATH keyword
  233.       {
  234.         namelen = stccpy(realname,(const char *)arguments[1],2*108) - 1;
  235.         if ((realname[namelen-1] != ':') && (realname[namelen-1] != '/'))
  236.         {
  237.           realname[namelen++] = '/';
  238.           realname[namelen] = NULL;
  239.         }
  240.         stccpy(realname+namelen,(const char *)FilePart((STRPTR)ui->ui_Filename),2*108-namelen);
  241.       }
  242.       else    // Well, the user has the DEST keyword, so we just copy the filename
  243.         stccpy(realname,(const char *)arguments[2],2*108) - 1;
  244.     }
  245.  
  246.   // Now we have to save the file.
  247.   if ((fh = Open(filename,MODE_NEWFILE)) != NULL)
  248.   {
  249.     Write(fh,ui->ui_DecrunchAdr,ui->ui_DecrunchLen);
  250.     Close(fh);
  251.     DecrunchLen=ui->ui_DecrunchLen;
  252.   }
  253.   }
  254. }
  255.