/*************************************************************************/ /* WBLink V1.00 */ /* */ /* 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 "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); /* Global variables */ struct Library *WorkbenchBase=NULL; struct Library *IconBase=NULL; struct Library *IntuitionBase=NULL; struct Port *port=NULL; struct AppIcon *appIcon=NULL; /*The version string*/ char *version="$VER: WBLink V1.00 (4.9.91)"; void _main() { struct AppMessage *mesg; char dest[40],*src,temp[140]; BPTR oldDir,fileLock; struct DiskObject *diskObj; BOOL abort=FALSE; BOOL status; BOOL isDir=FALSE; UBYTE c; /* Open libraries */ WorkbenchBase=OpenLibrary("workbench.library",0L); if(WorkbenchBase==NULL) cleanup(50); IconBase=OpenLibrary("icon.library",0L); if(IconBase==NULL) cleanup(75); IntuitionBase=OpenLibrary("intuition.library",0L); if(IntuitionBase==NULL) cleanup(85); /* 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,139)) continue; /* The name we get is the full path name. This function*/ /* call will leave us with just the directory*/ 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=GetDiskObject(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,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[40]; /* 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); /* Exit the program, using the specified error code */ exit(err); }