/*************************************************************************/ /* WBLink V1.10 */ /* */ /* WBLink is Copyright 1991 by Dave Schreiber. All Rights Reserved */ /* */ /* WBLink puts an AppIcon on the Workbench. When a file is dropped onto */ /* the icon, a link to that file is generated. */ /*************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "WBLink.h" /* Function prototypes*/ void _main(); BOOL GetLinkFilename(char *src,char *dest); void MakeName(char *src,char *dest,int c); void FindOrig(char *src,char *dest); void cleanup(UWORD err); void parseArgs(void); #pragma libcall UtilityBase Strnicmp a8 09803 /* Global variables */ struct Library *WorkbenchBase=NULL; struct Library *IconBase=NULL; struct Library *IntuitionBase=NULL; struct Library *UtilityBase=NULL; struct Port *port=NULL; struct AppIcon *appIcon=NULL; extern struct WBStartup *WBenchMsg; /*The version string*/ char *version="$VER: WBLink V1.10 (8.2.92)"; void _main() { struct AppMessage *mesg; char dest[256],src[256],temp[256]; BPTR oldDir,fileLock; struct DiskObject *diskObj; BOOL abort=FALSE; BOOL status; BOOL isDir=FALSE; UBYTE c; /* Open libraries */ WorkbenchBase=OpenLibrary("workbench.library",37L); if(WorkbenchBase==NULL) cleanup(50); IconBase=OpenLibrary("icon.library",37L); if(IconBase==NULL) cleanup(75); IntuitionBase=OpenLibrary("intuition.library",37L); if(IntuitionBase==NULL) cleanup(85); UtilityBase=OpenLibrary("utility.library",37L); if(UtilityBase==NULL) cleanup(95); /* Get any user arguments */ parseArgs(); /* Create a port for Workbench to use to communicate with us */ port=CreatePort("",0); if(port==NULL) cleanup(100); /* Create the application icon */ appIcon = AddAppIcon(1,1,"WBLink",port,NULL,&iconObj,TAG_DONE,NULL); if(appIcon==NULL) cleanup(300); /* Loop until the user asks to quit */ while(!abort) { /* Wait for a message from Workbench */ WaitPort(port); /* Get the message */ mesg=(struct AppMessage *)GetMsg(port); /* If am_NumArgs != 0, it means one or more icons were dropped on */ /* the AppIcon */ if(mesg->am_NumArgs!=0) { /* Loop for each file */ for(c=0;cam_NumArgs;c++) { /* Check to see if this is a drawer */ if(mesg->am_ArgList[c].wa_Name[0]==0 && mesg->am_ArgList[c].wa_Lock != NULL) { isDir=TRUE; /* If it is a drawer, we didn't get the name from Workbench*/ /* So we need to get the name from the lock instead*/ if(!NameFromLock(mesg->am_ArgList[c].wa_Lock,temp,255)) continue; /* The name we get is the full path name. This function*/ /* call will leave us with just the directory name*/ strcpy(src,FilePart(temp)); } else { /* If it is a file, just copy the filename */ strcpy(src,mesg->am_ArgList[c].wa_Name); isDir=FALSE; } /* Move to the file's directory*/ if(isDir) /* If we got a drawer, the lock is to the directory */ /* itself. To get the directory that the drawer is in, */ /* we need to use ParentDir() */ oldDir=CurrentDir(ParentDir(mesg->am_ArgList[c].wa_Lock)); else oldDir=CurrentDir(mesg->am_ArgList[c].wa_Lock); /* Get the destination filename (i.e. foo -> Link_to_foo ) */ if(GetLinkFilename(src,dest)) { /* Get a lock on the file that was given */ if(isDir) fileLock=mesg->am_ArgList[c].wa_Lock; else fileLock=Lock(src,SHARED_LOCK); /* If we got the lock, make the link */ if(fileLock!=NULL) { status=MakeLink(dest,fileLock,FALSE); if(!isDir) UnLock(fileLock); /* If we managed to make the link, copy (NOT link) the */ /* source's icon */ if(status) { /* Get the source file's icon */ diskObj=GetDiskObjectNew(src); if(diskObj!=NULL) { /* Reset the icon's position*/ diskObj->do_CurrentY=NO_ICON_POSITION; diskObj->do_CurrentX=NO_ICON_POSITION; /* Store the icon as the destination's icon */ PutDiskObject(dest,diskObj); /* Free the disk object's memory */ FreeDiskObject(diskObj); } } else EasyRequest(NULL,&erError2,NULL, "Couldn't create the link",dest); } else EasyRequest(NULL,&erError3,NULL,"Couldn't open", src,"for linking"); } else EasyRequest(NULL,&erError2,NULL,"Couldn't create", "a filename for the link"); /* Restore the old directory */ CurrentDir(oldDir); } } else /* If am_NumArgs==0, the user double clicked on the icon */ /* So put up the About... requestor, and quit if the user */ /* clicks on the "Quit WBLink" button */ abort=(EasyRequestArgs(NULL,&erAboutWBLink,NULL,"")==1); /* Reply to the message */ ReplyMsg((struct Message *)mesg); } /* We're done, so exit */ cleanup(0); } /* Create a link filename (i.e. foo -> Link_to_foo ) */ BOOL GetLinkFilename(char *src,char *dest) { UWORD c; BPTR lock=1; char realSrc[256]; /* Strip away the link portion of the filename, leaving the original */ /* filename */ FindOrig(src,realSrc); /* Loop until we get a unused filename slot */ for(c=1;c<1000 && lock!=NULL;c++) { /* Create a filename (e.g. Link_22_to_HelloWorld) */ MakeName(realSrc,dest,c); /* See if it exists */ lock=Lock(dest,SHARED_LOCK); /* If the lock was successful, unlock the file */ if(lock!=NULL) UnLock(lock); } /* Return TRUE if the destination file name is <26 characters ( so */ /* that the filename + .info won't exceed the Amiga's 30 character */ /* filename limit) and if c<1000 (1000 is the upper limit on the */ /* number of files that will be created; it's in place as a safe- */ /* guard, to keep the above loop from becoming infinite) */ return((strlen(dest)<=25) && !(c==1000)); } /* Add the link prefix to the given filename */ void MakeName(char *src,char *dest,int c) { /* For c==1, don't use a number (e.g. foo -> Link_to_foo) */ if(c==1) { strcpy(dest,"Link_to_"); strcat(dest,src); } /* For all others, include the given number (e.g. for c==2, foo -> */ /* Link_2_to_foo */ else { strcpy(dest,"Link_"); stci_d(&dest[5],c); strcat(dest,"_to_"); strcat(dest,src); } } /* Strip the link information from the filename (i.e. convert */ /* Link_22_to_foobar into foobar) to make the 'original' filename */ void FindOrig(char *src,char *dest) { UBYTE c,numUS; if((Strnicmp(src,"link_",5))==0) if((Strnicmp(src,"link_to_",8))==0) /* This handles Link_to_ */ strcpy(dest,&src[8]); else { /* This handles Link__to_ */ /* Move past two underscores (there are two after the ) */ for(c=5,numUS=0;c<30;c++) { if(src[c]=='_') numUS++; if(numUS==2) { /* Whatever is left is the original filename */ strcpy(dest,&src[c+1]); return; } } /*If we couldn't find two underscores, just copy the whole thing*/ strcpy(dest,src); } else /*This is just a regular filename, so copy the whole thing */ strcpy(dest,src); } /* This frees allocated resources */ void cleanup(UWORD err) { /* The AppIcon */ if(appIcon!=NULL) RemoveAppIcon(appIcon); /* The port */ if(port!=NULL) DeletePort(port); /* The libraries */ if(WorkbenchBase!=NULL) CloseLibrary(WorkbenchBase); if(IconBase!=NULL) CloseLibrary(IconBase); if(IntuitionBase!=NULL) CloseLibrary(IntuitionBase); if(UtilityBase!=NULL) CloseLibrary(UtilityBase); /* Exit the program, using the specified error code */ exit(err); } /* Parse the user's arguments */ void parseArgs(void) { char *str; struct DiskObject *diskObj; if(WBenchMsg!=NULL) { /* Get the icon for this program */ diskObj=GetDiskObject(WBenchMsg->sm_ArgList[0].wa_Name); if(diskObj==NULL) return; /* Get the X coordinate, if given */ str=FindToolType(diskObj->do_ToolTypes,"ICONX"); if(str!=NULL) StrToLong(str,&iconObj.do_CurrentX); /* Get the Y coordinate, if given */ str=FindToolType(diskObj->do_ToolTypes,"ICONY"); if(str!=NULL) StrToLong(str,&iconObj.do_CurrentY); /* Free the memory used by the disk object */ FreeDiskObject(diskObj); } else { LONG args[2]; struct RDArgs *ra; args[0]=args[1]=NULL; /* Read the command-line arguments */ ra=ReadArgs("ICONX/N,ICONY/N",args,NULL); /* Get the X coordinate, if given */ if(args[0]!=NULL) iconObj.do_CurrentX=*(ULONG *)args[0]; /* Get the Y coordinate, if given */ if(args[1]!=NULL) iconObj.do_CurrentY=*(ULONG *)args[1]; FreeArgs(ra); } return; }