home *** CD-ROM | disk | FTP | other *** search
-
- ==========
- amiga/programs #367, from talin, 9715 chars, Sun Feb 7 07:56:54 1988
- Comment to 366.
- ----------
- /***********************************************************************
- * bootback.c - copies boot blocks to file, or files to boot blocks *
- * By Talin, otherwise known as David Joiner *
- * Note comments are only mostly serious *
- ***********************************************************************/
- /* compiled like this:
- cc +l bootback
- ln bootback.o -lc32
- */
-
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "libraries/dosextens.h" /* my DOS is bigger than your DOS */
- #include "libraries/filehandler.h"
- #include "devices/trackdisk.h" /* But does it make a good frisbee? */
-
- #include "arp/arpbase.h"
- #include "arp/arpfunctions.h"
-
- #define SCAT goto exit_pgm
- #define MAX_FILENAME 32
-
- struct ArpBase *ArpBase; /* Mama! */
- void *OpenLibrary(), /* Daddy! */
- *AllocMem(); /* Cheetah! */
-
- /* This is the stuff mother never told you about */
-
- struct DevEnviron {
- ULONG TableSize, SizeBlock, SecOrg, NumHeads,
- SecsPerBlock, BlocksPerTrack, ReservedBlocks, Preface,
- Interleave, LowCylinder, UpperCylinder, NumBuffers,
- MemBufType;
- } *environ;
-
- ULONG blocksize;
-
- struct MsgPort *diskport, *CreatePort();
- struct IOExtTD *diskreq, *CreateExtIO();
-
- #define ADDR(a) (void *)( (int)a << 2) /* I don't like the standard macro */
-
- /* This is a rather EVIL way to do this, but I can think of nothing
- else that will work in a reasonable fashion.
- Essentially what this does is take a name of a device or volume
- and returns the DeviceNode entry for that device, buy brute force
- searching through the AmigaDOS device list. For a volume, the
- search has to be done twice, and is rather kludgey.
- Works like a charm. I wish it worked like software instead.
- Once this is done, the caller can easily determine the device
- driver name for exec-level IO. (see main below).
- */
-
- struct DeviceNode *get_device(name) char *name;
- { struct DeviceNode *dlist = NULL;
- char device_name[MAX_FILENAME+2];
- short length;
-
- while (dlist = (struct DeviceNode *)GetDevInfo(dlist))
- { length = BtoCStr(device_name,dlist->dn_Name,33);
- device_name[length++] = ':'; /* Appendix a Colon on the end */
- device_name[length] = '\0'; /* and that other thing */
-
- /* try to find a match with name */
- if (Strcmp(name,device_name)==0)
- { if (dlist->dn_Type == DLT_DEVICE) return dlist;
- if (dlist->dn_Type == DLT_VOLUME)
- { struct Task *dev_task;
- char *task_name, *colon_name;
- struct MsgPort *proc; /* actually a Process, but those */
- /* makes no sense anyway */
- proc = (struct MsgPort *)dlist->dn_Task;
- /* Oooh, I remembered 'mp_SigTask' without looking it
- up...that's Scary. */
-
- dev_task = proc->mp_SigTask; /* not very kosher */
- colon_name = device_name; /* copy device name to here */
- task_name = dev_task->tc_Node.ln_Name; /* BAD Talin! BAD! */
- while (*task_name) *colon_name++ = *task_name++; /* copy */
- *colon_name++ = ':'; /* put a colon on it, bud. */
- *colon_name++ = '\0'; /* and stop it from bleeding */
- return get_device(device_name); /* recursive but only once */
- }
- return NULL; /* return NULL for assigns: */
- }
- }
- return NULL; /* Negative, Will Robinson */
- }
-
- extern struct WBStartup *WBenchMsg;
-
- wb_parse(); /* stub */
-
- main(argc, argv) LONG argc; UBYTE **argv;
- { char driver_name[MAX_FILENAME+2];
- ULONG error, /* open device error */
- arg_device, /* which arg was the device */
- arg_file; /* and which was the file? */
- struct FileSysStartupMsg *fssm; /* filesys startup message */
- struct DeviceNode *d1, /* Device node entries for */
- *d2, /* arg1, arg2 and */
- *dvc; /* whichever one we open */
- struct FILE *save_file=NULL, *Open();
- APTR buff=NULL; /* buffer for loaded blocks */
- UBYTE device_open=0; /* flag is device was open */
-
- diskport = NULL; diskreq = NULL;
-
- if (WBenchMsg) exit(0); /* HELL NO, WE WON'T GO! */
-
- if (!(ArpBase = OpenLibrary("arp.library",0))) /* open up there, arp! */
- { Write(Output(),"Can't find arp.library\n",23); /* You Varmit! */
- exit(20);
- }
-
- if (argc != 3) /* check to make sure correct # of arguments */
- { Printf("BootBack - Saves and restores custom boot blocks\n");
- Printf("Usage:\n\n");
- Printf("To save boot block: BootBack <device> <file>\n");
- Printf("To restore boot block: BootBack <file> <device>\n");
- SCAT; /* Take a powder */
- }
-
- d1 = get_device(argv[1]);
- d2 = get_device(argv[2]);
-
- if (d1 && d2) { Printf("They can't BOTH be devices!\n"); SCAT; }
- if (!d1 && !d2) { Printf("Neither of those is a device, silly!\n"); SCAT; }
-
- if (d1) { dvc = d1; arg_device = 1; arg_file = 2; }
- if (d2) { dvc = d2; arg_device = 2; arg_file = 1; }
-
- fssm = ADDR(dvc->dn_Startup);
- if (!fssm)
- { Printf("Can't find device driver for <%s>.\n",argv[arg_device]); SCAT; }
-
- BtoCStr(driver_name,fssm->fssm_Device,33);
- environ = ADDR(fssm->fssm_Environ);
- blocksize = environ->SizeBlock * sizeof (LONG); /* BCPL foolishness */
-
- if (arg_file == 1) save_file = Open(argv[arg_file],MODE_OLDFILE);
- else save_file = Open(argv[arg_file],MODE_NEWFILE);
-
- if (!save_file)
- { Printf("Can't open save file <%s>.\n",argv[arg_file]); SCAT; }
-
- /* Ah pity the foo don't have enough memory to run this program! */
- buff = AllocMem(2 * blocksize,MEMF_CHIP);
- if (!buff) { Printf("Not enough memory.\n"); SCAT; } /* TILT! */
-
- if (!(diskport = CreatePort(0,0)) ||
- !(diskreq = CreateExtIO(diskport,sizeof (struct IOExtTD))) ||
- (error = OpenDevice(driver_name,fssm->fssm_Unit,
- diskreq,fssm->fssm_Flags)) )
- { Printf("Problems opening disk device...!\n");
- if (error) Printf("Error = %d.\n",error);
- SCAT; /* get outta here, ya nut! */
- }
- device_open = TRUE;
- Printf("%s opened.\n",driver_name); /* chatty but educational */
-
- if (arg_file == 2) /* if filename was 2nd arg */
- { if (load_track_range(0,2,buff)) /* 2 lumps please */
- { Printf("Problem reading device...\n"); SCAT; } /* TOAST */
- Write(save_file,"BOOTBLOC",8); /* id check for safety's sake */
- Write(save_file,buff,2*blocksize); /* Doit Toit */
- }
- else
- { char file_id[9]; /* id string */
- Read(save_file,file_id,8); /* read id */
- file_id[8] = 0; /* null terminate */
- if (Strcmp(file_id,"BOOTBLOC"))
- { Printf("This file is NOT a saved boot block!\n"); SCAT; }
- Read(save_file,buff,2 * blocksize);
- if (save_track_range(0,2,buff)) /* Thou art Healed! A Miracle! */
- { Printf("Problem writing device...\n"); SCAT; } /* Well, Almost */
- }
-
- Printf("Done!\n");
- exit_pgm:
- if (device_open) { motor_off(); CloseDevice(diskreq); }
- if (diskreq) DeleteExtIO(diskreq,sizeof (struct IOExtTD));
- if (diskport) DeletePort(diskport);
- if (buff) FreeMem(buff,2 * blocksize);
- if (save_file) Close(save_file);
- if (ArpBase) CloseLibrary(ArpBase);
- }
-
- save_track_range(first_block,block_count,buffer)
- short first_block, block_count; char *buffer;
- { diskreq->iotd_Req.io_Length = (block_count * blocksize);
- diskreq->iotd_Req.io_Data = (APTR)buffer;
- diskreq->iotd_Req.io_Command = CMD_WRITE;
- diskreq->iotd_Req.io_Offset = (first_block * blocksize);
- DoIO(diskreq);
- return diskreq->iotd_Req.io_Error;
- }
-
- load_track_range(first_block,block_count,buffer)
- short first_block, block_count; char *buffer;
- { diskreq->iotd_Req.io_Length = (block_count * blocksize);
- diskreq->iotd_Req.io_Data = (APTR)buffer;
- diskreq->iotd_Req.io_Command = CMD_READ;
- diskreq->iotd_Req.io_Offset = (first_block * blocksize);
- DoIO(diskreq);
- return diskreq->iotd_Req.io_Error;
- }
-
- motor_off()
- { diskreq->iotd_Req.io_Length = 0;
- diskreq->iotd_Req.io_Command = TD_MOTOR;
- DoIO(diskreq);
- }
-
- #asm
- cseg
- include "arp/arpbase.i"
-
- public _ArpBase
-
- public _Printf
- _Printf move.l 4(sp),a0
- lea 8(sp),a1
- move.l _ArpBase,a6
- jmp _LVOPrintf(a6)
-
- public _Strcmp
- _Strcmp move.l 4(sp),a0
- move.l 8(sp),a1
- move.l _ArpBase,a6
- jmp _LVOStrcmp(a6)
-
- public _GetDevInfo
- _GetDevInfo move.l 4(sp),a2
- move.l _ArpBase,a6
- jmp _LVOGetDevInfo(a6)
-
- public _BtoCStr
- _BtoCStr move.l 4(sp),a0
- move.l 8(sp),d0
- move.l 12(sp),d1
- move.l _ArpBase,a6
- jmp _LVOBtoCStr(a6)
-
- #endasm
-
- /* That's all, folks! */
- No more unread
- Hit <RETURN> for next
- R: