/* * Assign Command - C Language Equivalent. * * This command looks and feels like the original AmigaDOS Assign command * except that it is written in C and thus available for "forking." Also * since it is written in C it is a somewhat larger than it's BCPL counterpart * although a good assembly hack could probably fix that. * * (c) Copyright 1986 Charles McManis, All rights reserved. * This code may be copied for private use only. It may not be * included as part of any commercial package in whole or in * part without the express written permission of the Author. * */ #include #include #include #include #include extern struct DosLibrary *DOSBase; #define PATHSIZE 128 /* This is max numbers in a path (Arbitrary) */ struct DosInfo *di; struct FileInfoBlock *fi; /* Our file info (on directory assigns) */ char *pathstr, *tmpstr; /* * Function - MyExit(ConditionCode) * This is the final exit routine, if we can't find something we need * like memory we go here and free up what we have. Exit code is 'cc'. */ void MyExit(cc) int cc; { if (fi != NULL) FreeMem(fi,sizeof(struct FileInfoBlock)); if (pathstr != NULL) FreeMem(pathstr,PATHSIZE); if (tmpstr != NULL) FreeMem(tmpstr,PATHSIZE); exit(cc); } /* * Function - CvtBstr(str) * This function takes a BPTR to a BSTR and returns a pointer to an * equivalent C string that may be printed or copied. */ #define STRSIZE 81 char * CvtBstr(bstr) char *bstr; { int i,mx; char *foo; static char tmpstr[STRSIZE]; /* Maximum size */ foo = (char *)(BADDR(bstr)); mx = (foo[0] < STRSIZE) ? foo[0] : STRSIZE; /* Safety net */ for (i=0; idi_DevInfo); found = -1; while (thisdev != NULL) { if (thisdev->dl_Type == DLT_DIRECTORY) { str = CvtBstr(thisdev->dl_Name); if (stricmp(str,nm) == 0) { found = 0; if (prevdev == NULL) { /* If first device */ Forbid(); /* Turn off tasking */ di->di_DevInfo = thisdev->dl_Next; /* Delete from list */ Permit(); /* Turn tasking back on */ } else { Forbid(); /* Turn off tasking */ prevdev->dl_Next = thisdev->dl_Next; /* Delete from list */ Permit(); /* Back to multitasking */ } /* Now free the Lock, the String, and the DevList structure */ UnLock(thisdev->dl_Lock); /* free the lock */ str = (char *)(BADDR(thisdev->dl_Name)); /* easier to read */ i = str[0]; FreeMem(str,i); /* Free the string */ FreeMem(thisdev,sizeof(struct DeviceList)); /* Free struct */ break; /* Exit the while loop */ } /* if matched devices */ } /* if it was a directory entry */ prevdev = thisdev; /* If not found, walk the list */ thisdev = (struct DeviceList *)BADDR(thisdev->dl_Next); } /* While */ return(found); } /* * Main code, options of the Assign command are name, directory, or List. * the default is to list the current assignments, Volumes, and devices. * */ void main(argc,argv) int argc; /* Number of arguments (max 3) */ char *argv[]; /* Text of the arguments */ { /* The pointers here make it easier later */ struct RootNode *rn; struct DeviceList *dl, *curdev, *xl; struct DeviceNode *dn; struct FileLock *fl; BPTR plock, thislock, tb; char Name[41],Path[81],*sptr; int i,listem; /* Get some memory for various buffers */ fi = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0); if (fi == NULL) MyExit(RETURN_FAIL); pathstr = (char *)AllocMem(PATHSIZE,0); if (pathstr == NULL) MyExit(RETURN_FAIL); tmpstr = (char *)AllocMem(PATHSIZE,0); if (tmpstr == NULL) MyExit(RETURN_FAIL); printf("Assign command substitute v1.0\n"); /* Then we track down the head of the Device list from the Root Node */ rn = (struct RootNode *)DOSBase->dl_Root; di = (struct DosInfo *)BADDR(rn->rn_Info); /* dl becomes the anchor point that we always start from */ dl = (struct DeviceList *)BADDR(di->di_DevInfo); listem = FALSE; /* Initially no list output */ Name[0] = '\0'; /* No name parameter */ Path[0] = '\0'; /* And no path specifier */ /************************************************************************* * Process the arguments passed. To be 100% compatible with the AmigaDOS * * assign command. * *************************************************************************/ if (argc > 4) { printf("Too many arguments, usage is Assign [Name:] [Dir:] [List]\n"); MyExit(RETURN_WARN); } for (i=1; i 1) { if ((sptr = (char *)strchr(Name,':')) == NULL) { printf("Improper device name format.\n"); MyExit(RETURN_WARN); } *sptr = '\0'; /* Eliminate the trailing colon */ } /* Ok, now we have the parameters they work like this, if a name was * supplied but no path then it is a deassign operation, if both are * supplied it is an assign operation, if both are missing it is a * list operation */ if ((Name[0] != '\0') && (Path[0] == '\0')) /* DEASSIGN 'Name' */ if (DeleteDevice(Name) != 0) { printf("Device %s: Not found.\n"); MyExit(RETURN_WARN); } if ((Name[0] != '\0') && (Path[0] != '\0')) { /* ASSIGN 'Name' */ (void) DeleteDevice(Name); /* Delete in case it exists */ if ((thislock = Lock(Path,ACCESS_READ)) != 0) { dl = (struct DeviceList *)AllocMem(sizeof(struct DeviceList),0); sptr = (char *)AllocMem(strlen(Name)+1,0); strcpy(sptr+1,Name); /* Create BSTR out of Name */ *sptr = strlen(Name); dl->dl_Name = (BSTR *)(((long)sptr) >> 2); /* Convert to BSTR ptr */ dl->dl_Lock = thislock; /* Put the BPTR value into Lock */ dl->dl_Type = DLT_DIRECTORY; /* The type is Directory */ fl = (struct FileLock *)(BADDR(thislock)); /* for convience */ dl->dl_Task = fl->fl_Task; /* Copy the message port task ptr */ tb = (BPTR)(((long)dl) >> 2); /* Make a BPTR out of our pointer */ Forbid(); /* Disable multitasking */ dl->dl_Next = di->di_DevInfo; /* Insert it at the head */ di->di_DevInfo = tb; /* Put a pointer to us in DevInfo */ Permit(); /* Start up Multitasking again */ } /* if we got the lock */ else { printf("Couldn't get a Lock on %s\n",Path); MyExit(RETURN_WARN); } } /* ASSIGN operation */ if (((Name[0] != '\0') || (Path[0] != '\0')) && ! listem) MyExit(RETURN_OK); /* The remainder of the code lists out the current assignments, if * no arguments, or the argument "List" is included it will run this * section. * * Pass 1: Print out all of the known volumes, if they have a handler * task present then they are mounted in a physical device */ curdev = dl; printf("Volumes:\n"); while (curdev != NULL) { if (curdev->dl_Type == DLT_VOLUME) { printf("%s ",CvtBstr(curdev->dl_Name)); if (curdev->dl_Task != NULL) printf("[Mounted]"); printf("\n"); } curdev = (struct DeviceList *)BADDR(curdev -> dl_Next); } printf("\n"); /* Pass 2 : Scan for directory redirections. If the volume that the * directory is redirected to is not mounted then we just * print out the volume name. If it is mounted we print * out the full path. If we have been redirected to a device * like 'RAM' then we just print the device name. */ curdev = dl; printf("Directories:\n"); while (curdev != NULL) { if (curdev->dl_Type == DLT_DIRECTORY) { strcpy(tmpstr,CvtBstr(curdev->dl_Name)); printf("%s ",tmpstr); if (strlen(tmpstr) < 8) printf(" "); fl = (struct FileLock *)(BADDR(curdev->dl_Lock)); xl = (struct DeviceList *)(BADDR(fl->fl_Volume)); if (xl->dl_Type == DLT_DEVICE) { dn = (struct DeviceNode *) xl; printf("%s:",CvtBstr(dn->dn_Name)); } else { if (xl->dl_Task == NULL) /* Not Mounted if Task == NULL */ printf("Volume: %s",CvtBstr(xl->dl_Name)); else { /* This code tracks down the full path */ printf("%s:",CvtBstr(xl->dl_Name)); pathstr[0] = '\0'; /* initialize it to the null string */ thislock = curdev->dl_Lock; plock = ParentDir(thislock); while (plock != 0) { if (Examine(thislock,fi)) { if (strlen(pathstr) == 0) strcpy(pathstr,fi->fib_FileName); else { strins(pathstr,"/"); /* insert directory separator */ strins(pathstr,fi->fib_FileName); /* insert parent dir name */ } } else printf("\nBad Lock!\n"); /* This should never print! */ thislock = plock; plock = ParentDir(thislock); } /* while we haven't got to the top */ printf("%s",pathstr); } } /* else it was a directory rather than a device */ printf("\n"); } /* If it was a directory redirection at all */ curdev = (struct DeviceList *)BADDR(curdev -> dl_Next); } printf("\n"); /* Pass 3 : Print out all of the devices, like the original we pretty much * assume device names are three characters long. (They can be more * though.) */ printf("Devices:"); i = 0; curdev = dl; while (curdev != NULL) { if (curdev->dl_Type == DLT_DEVICE) { if ((i%5) == 0) printf("\n"); /* Every 5 devices print a newline */ i++; dn = (struct DeviceNode *) curdev; printf("%s ",CvtBstr(dn->dn_Name)); } curdev = (struct DeviceList *)BADDR(curdev -> dl_Next); } /* While */ printf("\n"); MyExit(RETURN_OK); /* Exit with a status of zero */ }