home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / utilities / misc / iconmonger.lha / source.lha / Monger.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-11  |  18.3 KB  |  736 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <workbench/workbench.h>
  4. #include <workbench/icon.h>
  5. #include <clib/macros.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. // #include <functions.h>
  12.  
  13. #include <proto/dos.h>
  14. #include <proto/wb.h>
  15. #include <proto/icon.h>
  16. #include <proto/exec.h>
  17. #include <proto/graphics.h>
  18. #include <proto/intuition.h>
  19. #include <clib/alib_protos.h>
  20.  
  21. // #include "PatMatch.h"
  22. #include "Monger.h"
  23.  
  24. #define MAXCHARS 120
  25.  
  26. char file_pat_parsed[      MAXCHARS * 2 ];
  27. char old_tool_pat_parsed[ MAXCHARS * 2 ];
  28. char tmp_oldimagename[      MAXCHARS     ];
  29. char tmp_newimagename[      MAXCHARS     ];
  30.  
  31. struct DiskObject *newicon  = NULL;
  32. struct DiskObject *oldimage = NULL;
  33. struct DiskObject *newimage = NULL;
  34.  
  35. /**********************************************************************/
  36. /*******   Interrupt Control Section    *******************************/
  37.  
  38. BOOL control_c_hit = FALSE;
  39.  
  40. void __regargs _CXBRK( void );
  41.  
  42. void __regargs _CXBRK( void )
  43.   {
  44.     control_c_hit = TRUE;
  45.   }
  46.  
  47. int stop_check( void )
  48.   {
  49.     chkabort();
  50.     return control_c_hit;
  51.   }
  52.  
  53.  
  54. /**********************************************************************/
  55. /*******   Image Recoloring Section    *******************************/
  56.  
  57. typedef struct FixImage_
  58.   {
  59.     struct Image     new_image;
  60.     struct Image    *org_image;
  61.     struct BitMap    bm;
  62.     struct RastPort  rp;
  63.   } FixImage_t;
  64.  
  65. static void free_fix_image( FixImage_t *fi )
  66.   {
  67.     if ( fi->bm.Planes[0] )
  68.       FreeMem( fi->bm.Planes[0], RASSIZE(fi->new_image.Width,fi->new_image.Height * fi->new_image.Depth) );
  69.     FreeMem( fi, sizeof(*fi) );
  70.   }
  71.  
  72. static FixImage_t *fix_image_pens( struct Image *i )
  73. {
  74.    FixImage_t          *fi;
  75.    struct Image       *old_NextImage;
  76.    WORD            old_LeftEdge;
  77.    WORD            old_TopEdge;
  78.    LONG            j,k,l;
  79.  
  80.    if ( (!i) || (i->Depth < 2) ) return NULL;
  81.  
  82.    if ( (fi = AllocMem( sizeof( FixImage_t ), MEMF_ANY | MEMF_CLEAR )) )
  83.      {
  84.        fi->org_image = i;
  85.  
  86.        InitBitMap  ( &fi->bm, MIN(i->Depth,8), i->Width, i->Height );
  87.        InitRastPort( &fi->rp );
  88.        fi->rp.BitMap = &fi->bm;
  89.  
  90.        fi->bm.Planes[0] = (PLANEPTR)AllocRaster( i->Width, MIN(i->Depth,8)*i->Height);
  91.        if ( fi->bm.Planes[0] == NULL )
  92.      {
  93.        free_fix_image( fi );
  94.        return NULL;
  95.      }
  96.  
  97.        fi->new_image.LeftEdge    = i->LeftEdge;
  98.        fi->new_image.TopEdge    = i->TopEdge;
  99.        fi->new_image.Width    = i->Width;
  100.        fi->new_image.Height    = i->Height;
  101.        fi->new_image.Depth    = MIN(i->Depth,8);
  102.        fi->new_image.ImageData    = (UWORD *)fi->bm.Planes[0];
  103.        fi->new_image.PlanePick    = (UBYTE)((~(0x0ff << MIN(i->Depth,8)))&(0xff));
  104.        fi->new_image.PlaneOnOff = 0;
  105.        fi->new_image.NextImage    = NULL;
  106.  
  107.        for (j=1; j<MIN(i->Depth,8); j++ )
  108.         fi->bm.Planes[j] = &(fi->bm.Planes[0][(j*RASSIZE(i->Width,i->Height))]);
  109.  
  110.        old_NextImage= i->NextImage;
  111.        old_LeftEdge = i->LeftEdge;
  112.        old_TopEdge  = i->TopEdge;
  113.  
  114.        i->NextImage = NULL;
  115.        i->LeftEdge  = 0;
  116.        i->TopEdge   = 0;
  117.  
  118.        DrawImage(&fi->rp,i,0,0);
  119.  
  120.        i->NextImage = old_NextImage;
  121.        i->LeftEdge  = old_LeftEdge;
  122.        i->TopEdge   = old_TopEdge;
  123.  
  124.        for (j=0; j<i->Width; j++)
  125.      for (k=0; k<i->Height; k++)
  126.        {
  127.          l = ReadPixel(&fi->rp,j,k);
  128.          SetAPen( &fi->rp, l==1?2:l==2?1:l );
  129.          WritePixel( &fi->rp,j,k);
  130.        }
  131.      }
  132.    return fi;
  133. }
  134.  
  135. static FixImage_t *fi0 = NULL;
  136. static FixImage_t *fi1 = NULL;
  137.  
  138. void recolor( struct DiskObject *DO )
  139.   {
  140.      fi0 = fix_image_pens( DO->do_Gadget.GadgetRender );
  141.      fi1 = fix_image_pens( DO->do_Gadget.SelectRender );
  142.      if ( fi0 )
  143.      DO->do_Gadget.GadgetRender = (APTR)&fi0->new_image;
  144.      if ( fi1 )
  145.      DO->do_Gadget.SelectRender = (APTR)&fi1->new_image;
  146.   }
  147.  
  148. void decolor( struct DiskObject *DO )
  149.   {
  150.      if ( fi0 )
  151.        {
  152.      DO->do_Gadget.GadgetRender = (APTR)fi0->org_image;
  153.      free_fix_image( fi0 );
  154.      fi0 = NULL;
  155.        }
  156.      if ( fi1 )
  157.        {
  158.      DO->do_Gadget.SelectRender = (APTR)fi1->org_image;
  159.      free_fix_image( fi1 );
  160.      fi1 = NULL;
  161.        }
  162.   }
  163.  
  164. /**********************************************************************/
  165. /**********************************************************************/
  166.  
  167.  
  168. BOOL scan_setup( void )
  169.   {
  170.     BOOL retcode = TRUE;
  171.  
  172.      if ( parms.new_icon && ( parms.disks      || parms.drawers    ||
  173.                   parms.tools      || parms.projects   ||
  174.                   parms.garbage    || parms.unsnapshot ||
  175.                   parms.recolor    || parms.new_image  ||
  176.                   parms.new_tool   || parms.new_stack    ) )
  177.        {
  178.      printf("Error: NEWICON not allowed with DISKS, DRAWERS, "
  179.         "PROJECTS, TOOLS, GARBAGE, UNSNAPSHOT, "
  180.         "RECOLOR, NEWIMAGE, NEWTOOL, or NEWSTACK.\n");
  181.      retcode = FALSE;
  182.        }
  183.  
  184.      if ( parms.new_stack && ( *parms.new_stack < 400 ) )
  185.        {
  186.      printf("Error: NEWSTACK is too small (%d<400).\n", *parms.new_stack );
  187.      retcode = FALSE;
  188.        }
  189.  
  190.      if ( parms.new_image && parms.recolor )
  191.        {
  192.      printf("Error: Can't RECOLOR a NEWIMAGE.\n");
  193.      retcode = FALSE;
  194.        }
  195.  
  196.      if ( parms.new_tool || parms.old_tool_pat )
  197.        {
  198.      if ( parms.disks || parms.drawers || parms.tools || parms.garbage )
  199.        {
  200.          printf("Error: OLDTOOL and NEWTOOL not allowed with DISKS, DRAWERS, TOOLS, or GARBAGE.\n");
  201.          retcode = FALSE;
  202.        }
  203.        }
  204.  
  205.      if ( parms.old_stack || parms.new_stack )
  206.        {
  207.      if ( parms.disks || parms.drawers || parms.garbage )
  208.        {
  209.          printf("Error: OLDSTACK and NEWSTACK not allowed with DISKS, DRAWERS, or GARBAGE.\n");
  210.          retcode = FALSE;
  211.        }
  212.        }
  213.  
  214.      if ( parms.old_tool_pat )
  215.        {
  216.      if ( -1==ParsePatternNoCase( parms.old_tool_pat, old_tool_pat_parsed,MAXCHARS ) )
  217.        {
  218.          printf("Error: bad OLDTOOL pattern \"%s\".\n", parms.old_tool_pat );
  219.          retcode = FALSE;
  220.        }
  221.        }
  222.  
  223.      if ( parms.file_pat )
  224.        {
  225.      if ( -1==ParsePatternNoCase( parms.file_pat, file_pat_parsed, MAXCHARS ) )
  226.        {
  227.          printf("Error: bad FILEPAT \"%s\".\n", parms.file_pat );
  228.          retcode = FALSE;
  229.        }
  230.        }
  231.  
  232.      /***
  233.        At this point, we have done all the parameter checking we can do
  234.        without hitting the disk.
  235.      ***/
  236.  
  237.      if ( parms.new_icon )
  238.        {
  239.       newicon = GetDiskObject( parms.new_icon );
  240.       if ( ! newicon )
  241.         {
  242.           printf("Error: couldn't get NEWICON \"%s\".\n", parms.new_icon );
  243.           retcode = FALSE;
  244.         }
  245.        }
  246.  
  247.      if ( parms.old_tool_pat || parms.new_tool )
  248.      parms.projects = TRUE;
  249.  
  250.      if ( (parms.old_stack || parms.new_stack) &&
  251.      !(parms.projects  || parms.tools    )    )
  252.        {
  253.      parms.projects = TRUE;
  254.      parms.tools    = TRUE;
  255.        }
  256.  
  257.      if ( ! (parms.disks || parms.drawers || parms.projects || parms.tools || parms.garbage ) )
  258.      parms.disks      =
  259.      parms.drawers      =
  260.      parms.projects   =
  261.      parms.tools      =
  262.      parms.garbage      = TRUE;
  263.  
  264.      if ( parms.new_image )
  265.        {
  266.       strcpy( tmp_newimagename, parms.new_image );
  267.       get_volume_name      ( tmp_newimagename );
  268.       newimage = GetDiskObject( tmp_newimagename );
  269.       if ( ! newimage )
  270.         {
  271.           printf("Error: couldn't get NEWIMAGE \"%s\".\n", tmp_newimagename );
  272.           retcode = FALSE;
  273.         }
  274.        }
  275.  
  276.      if ( parms.old_image )
  277.        {
  278.       strcpy( tmp_oldimagename, parms.old_image );
  279.       get_volume_name      ( tmp_oldimagename );
  280.       oldimage = GetDiskObject( tmp_oldimagename );
  281.       if ( ! oldimage )
  282.         {
  283.           printf("Error: couldn't get OLDIMAGE \"%s\".\n", tmp_oldimagename );
  284.           retcode = FALSE;
  285.         }
  286.        }
  287.  
  288.      if ( ! (parms.unsnapshot || parms.recolor  || parms.new_icon ||
  289.          parms.new_image  || parms.new_tool || (ULONG)parms.new_stack ) )
  290.        {
  291.      printf("Error: No actions specified.\n");
  292.      retcode = FALSE;
  293.        }
  294.  
  295.      if ( retcode == FALSE )
  296.        scan_cleanup();
  297.  
  298.      return retcode;
  299.   }
  300.  
  301. void scan_cleanup( void )
  302.   {
  303.      if ( oldimage )
  304.        {
  305.      FreeDiskObject( oldimage );
  306.      oldimage = NULL;
  307.        }
  308.      if ( newimage )
  309.        {
  310.      FreeDiskObject( newimage );
  311.      newimage = NULL;
  312.        }
  313.      if ( newicon )
  314.        {
  315.      FreeDiskObject( newicon );
  316.      newicon = NULL;
  317.        }
  318.   }
  319.  
  320. static struct DiskObject tmp_DiskObject;
  321.  
  322. BOOL mangle_diskobject( struct DiskObject *DO, char *filename )
  323.   {
  324.     BOOL retcode = TRUE;
  325.  
  326.     if ( parms.new_icon )
  327.     tmp_DiskObject = *newicon;
  328.       else
  329.     tmp_DiskObject = *DO;
  330.  
  331.     if ( parms.new_stack )
  332.     tmp_DiskObject.do_StackSize   = *parms.new_stack;
  333.  
  334.     if ( parms.new_tool )
  335.     tmp_DiskObject.do_DefaultTool = parms.new_tool;
  336.  
  337.     if ( parms.new_image )
  338.     tmp_DiskObject.do_Gadget      = newimage->do_Gadget;
  339.  
  340.     if ( parms.unsnapshot )
  341.       {
  342.     tmp_DiskObject.do_CurrentX =
  343.     tmp_DiskObject.do_CurrentY = NO_ICON_POSITION;
  344.       }
  345.     if ( parms.recolor )
  346.       {
  347.     recolor( &tmp_DiskObject );
  348.       }
  349.  
  350.     if ( ! parms.quiet && !parms.verbose) printf("%s",filename);
  351.     if ( ! parms.test )
  352.     {
  353.       if (!PutDiskObject( filename, &tmp_DiskObject ))
  354.         {
  355.           if ( ! parms.quiet ) printf(" <------- CHANGE FAILED!");
  356.           retcode = FALSE;
  357.         }
  358.     }
  359.     if ( !parms.quiet || parms.verbose) printf("\n");
  360.  
  361.     if ( parms.recolor )
  362.       {
  363.     decolor( &tmp_DiskObject );
  364.       }
  365.  
  366.     return retcode;
  367.   }
  368.  
  369. BOOL cmp_images( struct Image *im0, struct Image *im1 )
  370.   {
  371.     SHORT  x,y,z,dy,x1;
  372.     UWORD  w0,    w1;
  373.     UWORD *b0, *b1;
  374.     UWORD  mask;
  375.     UBYTE  planepick0, planeonoff0, planepick1, planeonoff1;
  376.  
  377.     if ( im0->Width  != im1->Width  ||
  378.      im0->Height != im1->Height ||
  379.      im0->Depth  != im1->Depth     )
  380.        {
  381.      return FALSE;
  382.        }
  383.  
  384.     planepick0    = im0->PlanePick;
  385.     planepick1    = im1->PlanePick;
  386.     planeonoff0 = im0->PlaneOnOff;
  387.     planeonoff1 = im1->PlaneOnOff;
  388.     b0        = im0->ImageData;
  389.     b1        = im1->ImageData;
  390.     dy           = (im0->Width+15)/16;
  391.     mask       =~(0x0ffff>>(im0->Width%16));
  392.     x1           = (im0->Width+15)/16;
  393.  
  394.     for (    z=0; z< im0->Depth;  z++ )
  395.      {
  396.       for(   y=0; y< im0->Height; y++ )
  397.     for (x=0; x<x1;           x++ )
  398.       {
  399.         if ( planepick0 & (1<<z) )
  400.             w0 = b0[x+dy*y];
  401.            else if ( planeonoff0 & (1<<z) )
  402.                 w0 = (USHORT)~0;
  403.                else w0 =      0;
  404.         if ( planepick1 & (1<<z) )
  405.             w1 = b1[x+dy*y];
  406.            else if ( planeonoff1 & (1<<z) )
  407.                 w1 = (USHORT)~0;
  408.                else w1 =      0;
  409.         if ( x == x1-1 )
  410.           {
  411.         w0 &= mask;
  412.         w1 &= mask;
  413.           }
  414.         if ( w0 != w1 )
  415.           {
  416.         return FALSE;
  417.           }
  418.       }
  419.       if ( planepick0 & (1<<z) )
  420.      b0 += dy * im0->Height;
  421.       if ( planepick1 & (1<<z) )
  422.      b1 += dy * im1->Height;
  423.      }
  424.     return TRUE;
  425.   }
  426.  
  427. BOOL test_diskobject( struct DiskObject *DO, char *filename )
  428.   {
  429.     char *tmp_old_tool;
  430.  
  431.     if ( parms.verbose ) printf("Testing %s:", filename );
  432.     // Check for all the selection criteria:
  433.     //     NAME, <type>, OLDSTACK, OLDTOOL, and OLDIMAGE
  434.  
  435.     // We already know that the name matches, so let's go on
  436.     // and check the do_Type field.
  437.  
  438.     if ( newicon )  /* Only replace icons of the same type. */
  439.     {
  440.       if (newicon->do_Type != DO->do_Type )
  441.         {
  442.           if ( parms.verbose )
  443.         printf(" wrong TYPE (was %s, needs %s).\n",
  444.                do_TypeStr( DO->do_Type     ),
  445.                do_TypeStr( newicon->do_Type) );
  446.            return FALSE;
  447.         }
  448.     }
  449.       else
  450.     {
  451.       switch ( DO->do_Type )
  452.         {
  453.           case WBDISK    : if ( ! parms.disks   )
  454.                  {
  455.                    if ( parms.verbose ) printf(" wrong TYPE (DISK).\n");
  456.                    return FALSE;
  457.                  }
  458.                    break;
  459.           case WBDRAWER  : if ( ! parms.drawers )
  460.                  {
  461.                    if ( parms.verbose ) printf(" wrong TYPE (DRAWER).\n" );
  462.                    return FALSE;
  463.                  }
  464.                    break;
  465.           case WBPROJECT : if ( ! parms.projects)
  466.                  {
  467.                    if ( parms.verbose ) printf(" wrong TYPE (PROJECT)\n");
  468.                    return FALSE;
  469.                  }
  470.                    break;
  471.           case WBTOOL    : if ( ! parms.tools   )
  472.                  {
  473.                    if ( parms.verbose ) printf(" wrong TYPE (TOOL)\n");
  474.                    return FALSE;
  475.                  }
  476.                  break;
  477.           case WBGARBAGE : if ( ! parms.garbage   )
  478.                  {
  479.                    if ( parms.verbose ) printf(" wrong TYPE (GARBAGE)\n");
  480.                    return FALSE;
  481.                  }
  482.                  break;
  483.           default         : if ( ! parms.quiet ) printf(" unknown TYPE.\n");
  484.                    return FALSE;
  485.         }
  486.     }
  487.  
  488.     if ( parms.old_stack ) // We already think it is a project or a tool.
  489.       {
  490.      if ( (DO->do_Type != WBTOOL) && (DO->do_Type != WBPROJECT) )
  491.        {
  492.          printf("Error (internal): shouldn't be checking stack of a %s.\n", do_TypeStr(DO->do_Type) );
  493.          return FALSE;
  494.        }
  495.      switch ( parms.old_stack_op )
  496.        {
  497.          case  1 :
  498.                if ( DO->do_StackSize > parms.old_stack_val )
  499.              {
  500.                if ( parms.verbose ) printf(" stack (%d) too high.\n",DO->do_StackSize );
  501.                return FALSE;
  502.              }
  503.                break;
  504.          case  0 :
  505.                if ( DO->do_StackSize != parms.old_stack_val )
  506.              {
  507.                if ( parms.verbose ) printf(" stack %d NE %d.\n",DO->do_StackSize,parms.old_stack_val );
  508.                return FALSE;
  509.              }
  510.                break;
  511.          case -1 :
  512.                if ( DO->do_StackSize < parms.old_stack_val )
  513.              {
  514.                if ( parms.verbose ) printf(" stack (%d) too low.\n",DO->do_StackSize );
  515.                return FALSE;
  516.              }
  517.                break;
  518.          default :
  519.                if ( parms.verbose ) printf("Error: Internal error wrt OLDSTACK.\n");
  520.                return FALSE;
  521.                break;
  522.        }
  523.       }
  524.  
  525.     // Next we see if the old_tool_pat matches.
  526.     if ( parms.old_tool_pat )
  527.        {
  528.      if ( DO->do_DefaultTool )
  529.          tmp_old_tool = DO->do_DefaultTool;
  530.        else
  531.          tmp_old_tool = "";
  532.  
  533.      if (DO->do_Type != WBPROJECT )
  534.        {
  535.          if ( parms.verbose ) printf("Not a PROJECT.\n" );
  536.          return FALSE;  // Old tool only checked for Projects.
  537.        }
  538.  
  539.      if ( !MatchPatternNoCase( old_tool_pat_parsed, tmp_old_tool ) )
  540.        {
  541.          if ( parms.verbose ) printf(" DEFAULT TOOL (%s) doesn't match OLDTOOL pattern.\n", tmp_old_tool );
  542.          return FALSE;  // Old tool only checked for Projects.
  543.        }
  544.        }
  545.  
  546.     // So far so good. Now we compare the images.
  547.     if ( oldimage )
  548.       {
  549.     if ( ! cmp_images( (struct Image *)DO      ->do_Gadget.GadgetRender,
  550.                (struct Image *)oldimage->do_Gadget.GadgetRender  ) )
  551.        {
  552.          if ( parms.verbose ) printf(" OLDIMAGE doesn't match.\n");
  553.          return FALSE;
  554.        }
  555.       }
  556.  
  557.     // If we got this far, then the icon is ripe for changing.
  558.  
  559.     if ( parms.verbose ) printf(" selected.");
  560.     return TRUE;
  561.   }
  562.  
  563. BOOL is_a_dot_info( char *fn )
  564.   {
  565.     short i,j;
  566.  
  567.     i=strlen( fn );
  568.     if ( i < 6 ) return FALSE;
  569.     for (j=0; j<5; j++)
  570.       if ( ".info"[j] != tolower( fn[i-5+j] ) ) return FALSE;
  571.     fn[i-5] = '\0';
  572.     return TRUE;
  573.   }
  574.  
  575. int scan_directory( char *dirname )
  576.   {
  577.     struct FileLock     *lock;
  578.     struct FileInfoBlock *fib;
  579.     char         *filename;
  580.     long          retcode;
  581.     struct DiskObject     *diskobj;
  582.  
  583.     filename = AllocMem( MAXCHARS, MEMF_CLEAR );
  584.     if (filename == NULL) {
  585.        retcode = ALLOCATE_FAILURE;
  586.        goto SD_DIE1;
  587.        }
  588.  
  589.     fib = AllocMem( sizeof(struct FileInfoBlock), MEMF_CLEAR);
  590.     if (fib == NULL) {
  591.        retcode = ALLOCATE_FAILURE;
  592.        goto SD_DIE2;
  593.        }
  594.  
  595.     lock = (struct FileLock *) Lock(dirname,ACCESS_READ);
  596.     if (lock == NULL) {
  597.        retcode = BAD_FILE_NAME;
  598.        goto SD_DIE3;
  599.        }
  600.  
  601.     retcode = Examine( (BPTR)lock, fib );
  602.     if (retcode == 0) {
  603.        retcode = BAD_FILE_NAME;
  604.        goto SD_DIE4;
  605.        }
  606.  
  607.     if (fib->fib_DirEntryType < 0) {      /* it's a file */
  608.        retcode = INVALID_DIR_NAME;
  609.        goto SD_DIE5;
  610.        }
  611.  
  612.     /*!!! We have to do the ExNext once outside of the while loop
  613.       and the rest inside the loop but before we mangle the
  614.       diskobj so when we do the PutDiskObject() it will replace
  615.       the file we examined before--NOT the one the current fib
  616.       references.  Whew!  What a joy to figure this one out.
  617.       !!!*/
  618.  
  619.     retcode = ExNext((BPTR)lock, fib );
  620.  
  621.     while ( retcode && !stop_check())
  622.      {
  623.        strcpy(filename,dirname);
  624.        if ( strlen(filename) > 0 && filename[ strlen(filename)-1 ] != ':' )
  625.      strcat(filename,"/");
  626.        strcat( filename,         fib->fib_FileName );
  627.  
  628.        if (fib->fib_DirEntryType > 0 && parms.all && !stop_check())  /* it's a directory */
  629.      {
  630.        scan_directory( filename );
  631.      }
  632.  
  633.        /* Gotta get the next files fib so the PutDiskObject() doesn't
  634.       yank the file we are examining out from under us.
  635.     */
  636.  
  637.        retcode = ExNext((BPTR)lock, fib );
  638.  
  639.        /* Now we've ExNext()ed the next file, but we can still play
  640.     * with the last one's icon without messing up our NEXT ExNext().
  641.     */
  642.  
  643.        if ( is_a_dot_info( filename ) )  /* chops off ".info" and returns TRUE */
  644.      {                 /* ELSE return FALSE if it didn't end w/ ".info" */
  645.        if ( !parms.file_pat ||
  646.          MatchPatternNoCase( file_pat_parsed, FilePart(filename)  ) )
  647.          {
  648.  
  649.            if ( (diskobj = GetDiskObject( filename )) )
  650.          {
  651.             if (test_diskobject( diskobj, filename ) )
  652.               mangle_diskobject( diskobj, filename );
  653.             FreeDiskObject( diskobj );
  654.          }
  655.          }
  656.      }
  657.      } /* end of while (ExNext())... */
  658.  
  659.     retcode = OK;
  660.     SD_DIE5: ;
  661.     SD_DIE4: UnLock((BPTR)lock);
  662.     SD_DIE3: FreeMem( fib, sizeof(struct FileInfoBlock) );
  663.     SD_DIE2: FreeMem( filename, MAXCHARS );
  664.     SD_DIE1: return( retcode );
  665.     }
  666.  
  667. int get_volume_name( char *dirname )
  668.   { /* expands the string <dirname> to the full path name. */
  669.     struct FileLock     *lock, *tmplock;
  670.     struct FileInfoBlock *fib;
  671.     char         *volname;
  672.     long          retcode;
  673.  
  674.     volname = AllocMem( MAXCHARS, MEMF_CLEAR );
  675.     if (volname == NULL) {
  676.        retcode = ALLOCATE_FAILURE;
  677.        goto GVN_DIE1;
  678.        }
  679.  
  680.     fib = AllocMem( sizeof(struct FileInfoBlock), MEMF_CLEAR);
  681.     if (fib == NULL) {
  682.        retcode = ALLOCATE_FAILURE;
  683.        goto GVN_DIE2;
  684.        }
  685.  
  686.     lock = (struct FileLock *) Lock(dirname,ACCESS_READ);
  687.     if (lock == NULL) {
  688.        retcode = BAD_FILE_NAME;
  689.        goto GVN_DIE3;
  690.        }
  691.  
  692.     retcode = Examine( (BPTR)lock, fib );
  693.     if (retcode == 0) {
  694.        retcode = BAD_FILE_NAME;
  695.        goto GVN_DIE4;
  696.        }
  697.  
  698.     // if (fib->fib_DirEntryType < 0) {      /* it's a file */
  699.     //      retcode = INVALID_DIR_NAME;
  700.     //      goto GVN_DIE5;
  701.     //      }
  702.  
  703.     strcpy(volname,fib->fib_FileName);
  704.     dirname[0] = '\0';
  705.  
  706.     while ( tmplock = (struct FileLock *)ParentDir( (BPTR)lock) ) {
  707.       UnLock((BPTR)lock);
  708.       lock = tmplock;
  709.       retcode = Examine( (BPTR)lock, fib );
  710.       if (retcode == 0) {
  711.          retcode = BAD_FILE_NAME;
  712.          goto GVN_DIE4;
  713.          }
  714.       if (dirname[0]) {
  715.          strcat(volname,"/");
  716.          strcat(volname,dirname);
  717.          }
  718.       strcpy(dirname,volname);
  719.       strcpy(volname,fib->fib_FileName );
  720.       }
  721.  
  722.     strcat(volname,":");
  723.     strcat(volname,dirname);
  724.     strcpy(dirname,volname);
  725.  
  726.     if ( ! parms.quiet ) printf("Examining \"%s\".\n",volname);
  727.  
  728.     retcode = OK;
  729.     GVN_DIE5: ;
  730.     GVN_DIE4: UnLock((BPTR)lock);
  731.     GVN_DIE3: FreeMem( fib, sizeof(struct FileInfoBlock) );
  732.     GVN_DIE2: FreeMem( volname, MAXCHARS );
  733.     GVN_DIE1: return( retcode );
  734.     }
  735.  
  736.