/****************************************************************************
* 
* A S S I G N D E V . C
*
*   Duplicate a device in place--Allowing multiple names to a device.
*
*   Phillip Lindsay (c) 1987 Commodore-Amiga, Inc.
*   Unlimited use granted as long as copyright remains intact.
****************************************************************************/

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>


#ifdef AZTEC_C
#include <functions.h>
#include <stdio.h>
#else
#include <lattice/stdio.h>
#endif

extern  struct  DosLibrary      *DOSBase;


/*
 * external functions found in "misc.c"
 */
extern  BSTR    ctob();
extern  char    *allocstr(),
                *btoc(),
                *strupper();
extern  BOOL    ourdevnode();
extern  BOOL    finddosnode();
extern  VOID    freedev(),
                dupdev(),
                adddosnode(),
                trunc(),
                memfill(),
                memcpy();
                

main(argc,argv)
int argc;
char **argv;
{
    struct              RootNode    *rnode;     /* root node pointer        */
    struct              DosInfo     *dinfo;     /* DOS info pointer         */
    register    struct  DeviceNode  *dnode;     /* device entry pointer     */
    register    struct  DeviceNode  *lastdnode; /* last device pointer      */
    char                            *bname,     /* tmp. ptr to bstr         */
                                    name[32],   /* tmp. for device name     */
                                    *oldname,   /* existing device name     */
                                    *newname;   /* new device name          */
    LONG                            error = 1;  /* flag error - 1 initially */
                                    

    if(argc == 3)       /* duplicate given device  */
    {
        newname = argv[1];
        trunc(strupper(newname),':');
        
        if( finddosnode(newname) )
        {
            printf("Error: Device %s: already exists.\n",newname);
            exit(0);
        }
        
        oldname = argv[2];
        trunc(strupper(oldname),':');

    }
    else if(argc == 2)  /* try and remove specified device */
    {
        oldname = argv[1];
        trunc(strupper(oldname),':');
        newname = NULL;
    }                                        
    else                /* ??? give them usage info */ 
    {
        printf("Usage: %s [new device] [old device]\n",argv[0]);
        printf("       %s [old device]\n",argv[0]);
        exit(0);
    }        
    
   
    rnode   = (struct RootNode *)  DOSBase->dl_Root;        /* find root node */
    dinfo   = (struct DosInfo  *)  BADDR(rnode->rn_Info);   /* now dos info   */

/*
 * Here we search for the given device name and once found we will duplicate
 * the entire device data structure.  Then we add a new device node with
 * the supplied name to the device list. If no "newname" is specified the
 * given device is removed from the device list and free memory for the device
 * node and device name. (normally you only delete nodes you created...I do 
 * take precautions to NOT delete existing system devices...I add a key to
 * the end of the device name to flag the device node as being created by
 * ASSIGNDEV. 
 */
    lastdnode = NULL;
    
    if(!newname) 
        printf("Removing Device %s:\n",oldname);
    else
        printf("Duplicating Device %s: -> %s:\n",oldname,newname);
        
    Forbid();          /* protect ourselves */
    
    for(dnode = (struct DeviceNode *) BADDR(dinfo->di_DevInfo); ( dnode );
      dnode = (struct DeviceNode *) BADDR(dnode->dn_Next))
    {
        if( dnode->dn_Type == DLT_DEVICE )  /* Are dealing with a device? */
        {
            bname = (char *) BADDR(dnode->dn_Name);
            memcpy(bname, name, (ULONG)( bname[0] + 1 ) );
            if( !( strcmp( oldname, strupper(btoc(name)) ) ) )
            {
                error = FALSE;
                if( newname )
                    dupdev(dnode,newname);
                else if( lastdnode )
                {
                    if( ourdevnode(dnode) )
                    {
                        lastdnode->dn_Next = dnode->dn_Next;
                        freedev(dnode);
                    }
                    else
                        error = 2;
                        
                }
                else  
                {
                    if( ourdevnode(dnode) )
                    {
                        dinfo->di_DevInfo = dnode->dn_Next;
                        freedev(dnode);
                    }
                    else
                        error = 2;
                }
                
                break;
            }   
        }
        
        lastdnode = dnode;
    }
 
    Permit(); 

if(error == 1) 
    puts("Error: Device not found.");
else if(error == 2)
    puts("Error: Cannot remove device."); 
     
exit(0);

}

/* eof */


