home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / v2 / wblink.lzh / WBLink / Source / WBLink.c next >
Encoding:
C/C++ Source or Header  |  1992-02-09  |  9.2 KB  |  370 lines

  1.  
  2. /*************************************************************************/
  3. /*                 WBLink V1.10                 */
  4. /*                                     */
  5. /* WBLink is Copyright 1991 by Dave Schreiber.    All Rights Reserved     */
  6. /*                                     */
  7. /* WBLink puts an AppIcon on the Workbench.  When a file is dropped onto */
  8. /* the icon, a link to that file is generated.                 */
  9. /*************************************************************************/
  10.  
  11.  
  12. #include <exec/types.h>
  13. #include <exec/exec.h>
  14. #include <intuition/intuition.h>
  15. #include <workbench/startup.h>
  16. #include <workbench/workbench.h>
  17. #include <workbench/startup.h>
  18. #include <dos/dos.h>
  19.  
  20. #include <proto/wb.h>
  21. #include <proto/intuition.h>
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/icon.h>
  25.  
  26. #include "WBLink.h"
  27.  
  28. /* Function prototypes*/
  29. void _main();
  30. BOOL GetLinkFilename(char *src,char *dest);
  31. void MakeName(char *src,char *dest,int c);
  32. void FindOrig(char *src,char *dest);
  33. void cleanup(UWORD err);
  34. void parseArgs(void);
  35.  
  36. #pragma libcall UtilityBase Strnicmp a8 09803
  37.  
  38. /* Global variables */
  39. struct Library *WorkbenchBase=NULL;
  40. struct Library *IconBase=NULL;
  41. struct Library *IntuitionBase=NULL;
  42. struct Library *UtilityBase=NULL;
  43. struct Port *port=NULL;
  44. struct AppIcon *appIcon=NULL;
  45. extern struct WBStartup *WBenchMsg;
  46.  
  47.  
  48. /*The version string*/
  49. char *version="$VER: WBLink V1.10 (8.2.92)";
  50.  
  51. void _main()
  52. {
  53.    struct AppMessage *mesg;
  54.    char dest[256],src[256],temp[256];
  55.    BPTR oldDir,fileLock;
  56.    struct DiskObject *diskObj;
  57.  
  58.    BOOL abort=FALSE;
  59.    BOOL status;
  60.    BOOL isDir=FALSE;
  61.    UBYTE c;
  62.  
  63.    /* Open libraries */
  64.    WorkbenchBase=OpenLibrary("workbench.library",37L);
  65.    if(WorkbenchBase==NULL)
  66.       cleanup(50);
  67.  
  68.    IconBase=OpenLibrary("icon.library",37L);
  69.    if(IconBase==NULL)
  70.       cleanup(75);
  71.  
  72.    IntuitionBase=OpenLibrary("intuition.library",37L);
  73.    if(IntuitionBase==NULL)
  74.       cleanup(85);
  75.  
  76.    UtilityBase=OpenLibrary("utility.library",37L);
  77.    if(UtilityBase==NULL)
  78.       cleanup(95);
  79.  
  80.    /* Get any user arguments */
  81.    parseArgs();
  82.  
  83.    /* Create a port for Workbench to use to communicate with us */
  84.    port=CreatePort("",0);
  85.    if(port==NULL)
  86.       cleanup(100);
  87.  
  88.    /* Create the application icon */
  89.    appIcon = AddAppIcon(1,1,"WBLink",port,NULL,&iconObj,TAG_DONE,NULL);
  90.  
  91.    if(appIcon==NULL)
  92.       cleanup(300);
  93.  
  94.    /* Loop until the user asks to quit */
  95.    while(!abort)
  96.    {
  97.       /* Wait for a message from Workbench */
  98.       WaitPort(port);
  99.  
  100.       /* Get the message */
  101.       mesg=(struct AppMessage *)GetMsg(port);
  102.  
  103.       /* If am_NumArgs != 0, it means one or more icons were dropped on */
  104.       /* the AppIcon */
  105.       if(mesg->am_NumArgs!=0)
  106.       {
  107.      /* Loop for each file */
  108.      for(c=0;c<mesg->am_NumArgs;c++)
  109.      {
  110.         /* Check to see if this is a drawer */
  111.         if(mesg->am_ArgList[c].wa_Name[0]==0 &&
  112.           mesg->am_ArgList[c].wa_Lock != NULL)
  113.         {
  114.            isDir=TRUE;
  115.  
  116.            /* If it is a drawer, we didn't get the name from Workbench*/
  117.            /* So we need to get the name from the lock instead*/
  118.            if(!NameFromLock(mesg->am_ArgList[c].wa_Lock,temp,255))
  119.           continue;
  120.  
  121.            /* The name we get is the full path name.  This function*/
  122.            /* call will leave us with just the directory name*/
  123.            strcpy(src,FilePart(temp));
  124.         }
  125.         else
  126.         {
  127.            /* If it is a file, just copy the filename */
  128.            strcpy(src,mesg->am_ArgList[c].wa_Name);
  129.            isDir=FALSE;
  130.         }
  131.  
  132.         /* Move to the file's directory*/
  133.         if(isDir)
  134.            /* If we got a drawer, the lock is to the directory */
  135.            /* itself.  To get the directory that the drawer is in, */
  136.            /* we need to use ParentDir() */
  137.            oldDir=CurrentDir(ParentDir(mesg->am_ArgList[c].wa_Lock));
  138.         else
  139.            oldDir=CurrentDir(mesg->am_ArgList[c].wa_Lock);
  140.  
  141.         /* Get the destination filename (i.e. foo -> Link_to_foo ) */
  142.         if(GetLinkFilename(src,dest))
  143.         {
  144.            /* Get a lock on the file that was given */
  145.            if(isDir)
  146.           fileLock=mesg->am_ArgList[c].wa_Lock;
  147.            else
  148.           fileLock=Lock(src,SHARED_LOCK);
  149.  
  150.            /* If we got the lock, make the link */
  151.            if(fileLock!=NULL)
  152.            {
  153.           status=MakeLink(dest,fileLock,FALSE);
  154.           if(!isDir)
  155.              UnLock(fileLock);
  156.  
  157.           /* If we managed to make the link, copy (NOT link) the */
  158.           /* source's icon */
  159.           if(status)
  160.           {
  161.              /* Get the source file's icon */
  162.              diskObj=GetDiskObjectNew(src);
  163.  
  164.              if(diskObj!=NULL)
  165.              {
  166.             /* Reset the icon's position*/
  167.             diskObj->do_CurrentY=NO_ICON_POSITION;
  168.             diskObj->do_CurrentX=NO_ICON_POSITION;
  169.  
  170.             /* Store the icon as the destination's icon */
  171.             PutDiskObject(dest,diskObj);
  172.  
  173.             /* Free the disk object's memory */
  174.             FreeDiskObject(diskObj);
  175.              }
  176.           }
  177.           else
  178.              EasyRequest(NULL,&erError2,NULL,
  179.                  "Couldn't create the link",dest);
  180.            }
  181.            else
  182.           EasyRequest(NULL,&erError3,NULL,"Couldn't open",
  183.                   src,"for linking");
  184.         }
  185.         else
  186.            EasyRequest(NULL,&erError2,NULL,"Couldn't create",
  187.                "a filename for the link");
  188.         /* Restore the old directory */
  189.         CurrentDir(oldDir);
  190.      }
  191.       }
  192.       else  /* If am_NumArgs==0, the user double clicked on the icon */
  193.         /* So put up the About... requestor, and quit if the user */
  194.         /* clicks on the "Quit WBLink" button  */
  195.      abort=(EasyRequestArgs(NULL,&erAboutWBLink,NULL,"")==1);
  196.  
  197.       /* Reply to the message */
  198.       ReplyMsg((struct Message *)mesg);
  199.    }
  200.  
  201.    /* We're done, so exit */
  202.    cleanup(0);
  203. }
  204.  
  205.  
  206. /* Create a link filename (i.e. foo -> Link_to_foo ) */
  207. BOOL GetLinkFilename(char *src,char *dest)
  208. {
  209.    UWORD c;
  210.    BPTR lock=1;
  211.    char realSrc[256];
  212.  
  213.    /* Strip away the link portion of the filename, leaving the original */
  214.    /* filename */
  215.    FindOrig(src,realSrc);
  216.  
  217.    /* Loop until we get a unused filename slot */
  218.    for(c=1;c<1000 && lock!=NULL;c++)
  219.    {
  220.       /* Create a filename (e.g. Link_22_to_HelloWorld) */
  221.       MakeName(realSrc,dest,c);
  222.  
  223.       /* See if it exists */
  224.       lock=Lock(dest,SHARED_LOCK);
  225.  
  226.       /* If the lock was successful, unlock the file */
  227.       if(lock!=NULL)
  228.      UnLock(lock);
  229.    }
  230.  
  231.    /* Return TRUE if the destination file name is <26 characters ( so */
  232.    /* that the filename + .info won't exceed the Amiga's 30 character */
  233.    /* filename limit) and if c<1000 (1000 is the upper limit on the   */
  234.    /* number of files that will be created; it's in place as a safe-  */
  235.    /* guard, to keep the above loop from becoming infinite)          */
  236.    return((strlen(dest)<=25) && !(c==1000));
  237. }
  238.  
  239. /* Add the link prefix to the given filename */
  240. void MakeName(char *src,char *dest,int c)
  241. {
  242.    /* For c==1, don't use a number (e.g. foo -> Link_to_foo) */
  243.    if(c==1)
  244.    {
  245.       strcpy(dest,"Link_to_");
  246.       strcat(dest,src);
  247.    }
  248.    /* For all others, include the given number (e.g. for c==2, foo -> */
  249.    /* Link_2_to_foo */
  250.    else
  251.    {
  252.       strcpy(dest,"Link_");
  253.       stci_d(&dest[5],c);
  254.       strcat(dest,"_to_");
  255.       strcat(dest,src);
  256.    }
  257. }
  258.  
  259.  
  260. /* Strip the link information from the filename (i.e. convert */
  261. /* Link_22_to_foobar into foobar) to make the 'original' filename */
  262. void FindOrig(char *src,char *dest)
  263. {
  264.    UBYTE c,numUS;
  265.  
  266.    if((Strnicmp(src,"link_",5))==0)
  267.       if((Strnicmp(src,"link_to_",8))==0)
  268.      /* This handles Link_to_<filename> */
  269.      strcpy(dest,&src[8]);
  270.       else
  271.       {
  272.      /* This handles Link_<number>_to_<filename> */
  273.      /* Move past two underscores (there are two after the <number>) */
  274.      for(c=5,numUS=0;c<30;c++)
  275.      {
  276.         if(src[c]=='_')
  277.            numUS++;
  278.         if(numUS==2)
  279.         {
  280.            /* Whatever is left is the original filename */
  281.            strcpy(dest,&src[c+1]);
  282.            return;
  283.         }
  284.      }
  285.      /*If we couldn't find two underscores, just copy the whole thing*/
  286.      strcpy(dest,src);
  287.       }
  288.    else  /*This is just a regular filename, so copy the whole thing */
  289.       strcpy(dest,src);
  290. }
  291.  
  292. /* This frees allocated resources */
  293. void cleanup(UWORD err)
  294. {
  295.    /* The AppIcon */
  296.    if(appIcon!=NULL)
  297.       RemoveAppIcon(appIcon);
  298.  
  299.    /* The port */
  300.    if(port!=NULL)
  301.       DeletePort(port);
  302.  
  303.    /* The libraries */
  304.    if(WorkbenchBase!=NULL)
  305.       CloseLibrary(WorkbenchBase);
  306.  
  307.    if(IconBase!=NULL)
  308.       CloseLibrary(IconBase);
  309.  
  310.    if(IntuitionBase!=NULL)
  311.       CloseLibrary(IntuitionBase);
  312.  
  313.    if(UtilityBase!=NULL)
  314.       CloseLibrary(UtilityBase);
  315.  
  316.    /* Exit the program, using the specified error code */
  317.    exit(err);
  318. }
  319.  
  320. /* Parse the user's arguments */
  321. void parseArgs(void)
  322. {
  323.    char *str;
  324.    struct DiskObject *diskObj;
  325.  
  326.    if(WBenchMsg!=NULL)
  327.    {
  328.       /* Get the icon for this program */
  329.       diskObj=GetDiskObject(WBenchMsg->sm_ArgList[0].wa_Name);
  330.       if(diskObj==NULL)
  331.      return;
  332.  
  333.       /* Get the X coordinate, if given */
  334.       str=FindToolType(diskObj->do_ToolTypes,"ICONX");
  335.       if(str!=NULL)
  336.      StrToLong(str,&iconObj.do_CurrentX);
  337.  
  338.       /* Get the Y coordinate, if given */
  339.       str=FindToolType(diskObj->do_ToolTypes,"ICONY");
  340.       if(str!=NULL)
  341.      StrToLong(str,&iconObj.do_CurrentY);
  342.  
  343.       /* Free the memory used by the disk object */
  344.       FreeDiskObject(diskObj);
  345.    }
  346.    else
  347.    {
  348.       LONG args[2];
  349.       struct RDArgs *ra;
  350.  
  351.       args[0]=args[1]=NULL;
  352.  
  353.       /* Read the command-line arguments */
  354.       ra=ReadArgs("ICONX/N,ICONY/N",args,NULL);
  355.  
  356.       /* Get the X coordinate, if given */
  357.       if(args[0]!=NULL)
  358.      iconObj.do_CurrentX=*(ULONG *)args[0];
  359.  
  360.       /* Get the Y coordinate, if given */
  361.       if(args[1]!=NULL)
  362.      iconObj.do_CurrentY=*(ULONG *)args[1];
  363.  
  364.       FreeArgs(ra);
  365.    }
  366.  
  367.    return;
  368. }
  369.  
  370.