home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol2 / ii-43 / part.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  8KB  |  272 lines

  1. ;/* Part.c - AmigaMail File/Path separator example.  Compiled with SAS/C 6.56.
  2. sc NMINC STRMERGE NOSTKCHK NODEBUG DATA=FAR IGNORE=73 Part.c
  3. slink from Part.o to Part lib lib:amiga.lib ; if you don't have pragmas
  4. quit
  5.  */
  6. /*
  7. Copyright (c) 1991 Commodore-Amiga, Inc.
  8.  
  9. This example is provided in electronic form by Commodore-Amiga,
  10. Inc. for use with the Amiga Mail Volume II technical publication.
  11. Amiga Mail Volume II contains additional information on the correct
  12. usage of the techniques and operating system functions presented in
  13. these examples.  The source and executable code of these examples may
  14. only be distributed in free electronic form, via bulletin board or
  15. as part of a fully non-commercial and freely redistributable
  16. diskette.  Both the source and executable code (including comments)
  17. must be included, without modification, in any copy.  This example
  18. may not be published in printed form or distributed with any
  19. commercial product. However, the programming techniques and support
  20. routines set forth in these examples may be used in the development
  21. of original executable software products for Commodore Amiga
  22. computers.
  23.  
  24. All other rights reserved.
  25.  
  26. This example is provided "as-is" and is subject to change; no
  27. warranties are made.  All use is at your own risk. No liability or
  28. responsibility is assumed.
  29. */
  30.  
  31. #include <exec/types.h>
  32. #include <exec/memory.h>
  33. #include <dos/dos.h>
  34. #include <dos/dosextens.h>
  35. #include <dos/rdargs.h>
  36.  
  37. #include <clib/exec_protos.h>
  38. #include <clib/dos_protos.h>
  39.  
  40. /* def PRAGMAS if you have them */
  41. /* #define PRAGMAS */
  42. #ifdef PRAGMAS
  43. #include <pragmas/exec_pragmas.h>
  44. #include <pragmas/dos_pragmas.h>
  45. #else
  46. struct ExecBase *SysBase;
  47. struct Library *DOSBase;
  48.  
  49. #endif
  50.  
  51. VOID            main(VOID);
  52. LONG            GetPath(UBYTE * path, UBYTE * buffer, LONG buffersize);
  53. UBYTE          *ItsWild(UBYTE * string);
  54.  
  55. VOID main(VOID)
  56. {
  57. #ifdef PRAGMAS
  58.     struct Library *DOSBase;
  59.  
  60. #endif
  61.     struct RDArgs  *readargs;
  62.     LONG            rargs[2];
  63.     LONG            vargs[8];
  64.     UBYTE          *path, *filename;
  65.     UBYTE          *buffer;
  66.     UBYTE          *filepart, *pathpart;
  67.     struct Process *process;
  68.     BPTR            lock;
  69.     APTR            wptr;
  70.     BOOL            error;
  71.  
  72. #ifndef PRAGMAS
  73.     /* set up SysBase */
  74.     SysBase = (*((struct Library **) 4));
  75. #endif
  76.  
  77.     /* Fail silently if < 37 */
  78.     if (DOSBase = OpenLibrary("dos.library", 37))
  79.     {
  80.  
  81.         /*
  82.          * Use a generous 256 byte buffer. Should suffice for everything but
  83.          * extreme cases.
  84.          */
  85.         if (buffer = AllocMem(256, MEMF_CLEAR))
  86.         {
  87.  
  88.             if (readargs = ReadArgs("PATH/A,FILENAME/A", rargs, NULL))
  89.             {
  90.                 path = (UBYTE *) (rargs[0]);
  91.                 filename = (UBYTE *) (rargs[1]);
  92.  
  93.                 error = GetPath(path, buffer, 255);
  94.                 if (error)
  95.                     PrintFault(error, NULL);
  96.  
  97.                 filepart = FilePart(path);
  98.                 pathpart = PathPart(path);
  99.  
  100.                 vargs[0] = (LONG) path;
  101.                 vargs[1] = (LONG) filepart;
  102.                 vargs[2] = (LONG) pathpart;
  103.                 vargs[3] = (LONG) buffer;
  104.                 VFPrintf(Output(),
  105.                          "Filename: %s\nFilepart: %s\nPathpart: %s\nPath: %s\n",
  106.                          vargs);
  107.  
  108.                 /* No requesters */
  109.                 process = (struct Process *) FindTask(NULL);
  110.                 wptr = process->pr_WindowPtr;
  111.                 process->pr_WindowPtr = (APTR) - 1L;
  112.  
  113.                 /*
  114.                  * Make sure this name is for real. This will weed out names
  115.                  * like "dh0:/" and non-existent directories. (and also
  116.                  * complain about non-mounted volumes.) It is tempting to look
  117.                  * for trailing slashes and remove them but you shouldn't. You
  118.                  * might misinterpret the users intention. Better to generate a
  119.                  * warning and prompt for new input.
  120.                  */
  121.                 if (lock = Lock(buffer, SHARED_LOCK))
  122.                     UnLock(lock);
  123.                 else
  124.                     PrintFault(IoErr(), buffer);
  125.  
  126.                 /* Reset windowpointer */
  127.                 process->pr_WindowPtr = wptr;
  128.  
  129.                 /*
  130.                  * Normally we should respect the test for an invalid path. To
  131.                  * show the results however, we blunder along...
  132.                  *
  133.                  * Add the filename to the path.
  134.                  */
  135.                 if (AddPart(buffer, filename, 255))
  136.                     vargs[0] = (LONG) buffer;
  137.                 else
  138.                     vargs[0] = (LONG) "OVERFLOW";
  139.  
  140.                 VFPrintf(Output(), "\nNew path: %s\n", vargs);
  141.  
  142.                 FreeArgs(readargs);
  143.             }
  144.             else
  145.                 PrintFault(IoErr(), NULL);
  146.             FreeMem(buffer, 256);
  147.         }
  148.         CloseLibrary(DOSBase);
  149.     }
  150. }
  151.  
  152. /*
  153.  * Standalone function to isolate a path and copy it into a supplied buffer.
  154.  * Does not test if the path is valid. Returns an error in case of buffer
  155.  * overflow.
  156.  */
  157. LONG
  158. GetPath(UBYTE * path, UBYTE * buffer, LONG buffersize)
  159. {
  160.     UBYTE          *pathpart, *filepart;
  161.     UBYTE          *tmp1, *tmp2;
  162.     BPTR            lock;
  163.     struct FileInfoBlock *fib;
  164.     LONG            error = 0;
  165.  
  166.     /* Open own copy of dos.library if pragmas are used so it's standalone */
  167. #ifdef PRAGMAS
  168.     struct Library *DOSBase;
  169.  
  170.     if (!(DOSBase = OpenLibrary("dos.library", 36)))
  171.         return (1);
  172. #endif
  173.  
  174.     /*
  175.      * If there seems to be no path, the pathpart will point to the filepart
  176.      * too, so we need to check for that.
  177.      */
  178.     filepart = FilePart(path);
  179.     pathpart = PathPart(path);
  180.  
  181.     /*
  182.      * This also handles cases where there is only a volume/device name, only a
  183.      * directory name or a combo of those.
  184.      */
  185.     if (pathpart == path)
  186.     {
  187.  
  188.         /*
  189.          * There seems to be only one component. Copy it if it is not wild.
  190.          * Caller will have to check whether if it exists and if it is a file
  191.          * or directory.
  192.          */
  193.         if (!(ItsWild(pathpart)))
  194.             pathpart = NULL;
  195.     }
  196.  
  197.     if (pathpart != path)
  198.     {
  199.  
  200.         /*
  201.          * If pathpart equals filepart (pointer wise) then there is only one
  202.          * component (possible preceeded by a volume name).
  203.          */
  204.         if (pathpart == filepart)
  205.         {
  206.             if (!(ItsWild(pathpart)))
  207.                 pathpart = NULL;
  208.         }
  209.         else
  210.         {
  211.  
  212.             /*
  213.              * Try to lock it to determine if the last component is a
  214.              * directory.
  215.              */
  216.             if (lock = Lock(path, SHARED_LOCK))
  217.             {
  218.                 if (fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR))
  219.                 {
  220.                     if ((Examine(lock, fib)) == DOSTRUE)
  221.                     {
  222.                         /* Hey it's a directory after all */
  223.                         if (fib->fib_DirEntryType > 0)
  224.                             pathpart = NULL;
  225.                     }
  226.                     FreeMem(fib, sizeof(struct FileInfoBlock));
  227.                 }
  228.                 UnLock(lock);
  229.             }           /* else treat it as a filename */
  230.         }
  231.  
  232.         /* Copy the pathpart in the buffer */
  233.         tmp1 = buffer;
  234.         tmp2 = path;
  235.         while ((*tmp1++ = *tmp2++) && (tmp2 != pathpart))
  236.         {
  237.             if (tmp1 == (buffer + buffersize))
  238.             {
  239.                 error = ERROR_NO_FREE_STORE;
  240.                 break;
  241.             }
  242.         }
  243.         *tmp1 = '\0';  /* NULL terminate. */
  244.     }
  245.  
  246. #ifdef PRAGMAS
  247.     CloseLibrary(DOSBase);
  248. #endif
  249.     return (error);
  250. }
  251.  
  252. /* Simple test whether a filename contains wildcards or not */
  253. UBYTE          *
  254. ItsWild(UBYTE * string)
  255. {
  256.     static UBYTE   *special = "#?*%([|";
  257.     UBYTE          *tmp = string;
  258.     COUNT           i;
  259.  
  260.     do
  261.     {
  262.         for (i = 0; special[i] != '\0'; i++)
  263.         {
  264.             if (*tmp == special[i])
  265.                 return (tmp);
  266.         }
  267.         tmp++;
  268.     } while (*tmp);
  269.  
  270.     return (NULL);
  271. }
  272.