home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
SRC
/
msdos_diskaccess.lzh
/
MS_DISK_ACCESS
/
init.c
< prev
next >
Wrap
Text File
|
1991-08-04
|
5KB
|
232 lines
/*
* Initialize a MSDOS diskette. Read the boot block for disk layout
* and switch to the proper floppy disk device to match the format
* of the disk. Sets a bunch of global variables. Returns 0 on success,
* or 1 on failure.
*/
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <modes.h>
#include <errno.h>
#include <sgstat.h>
#include "devices.h"
#include "msdos.h"
#define DUP_FAT /* update of the second FAT */
extern int fd, dir_len, dir_start, clus_size, fat_len, num_clus;
extern unsigned char *fatbuf;
extern char *mcwd;
/* The available drivers */
extern struct device fd_devices[];
/* The bootblock */
union bootblock bb ;
short is_tos0 = 0;
int
init(mode)
int mode;
{
struct sgbuf tos0opts;
int code, buflen, intr();
void perror(), exit(), move(), reset_dir();
char *getenv(), *fixmcwd(), *malloc(), *dummy;
long lseek();
struct device *try;
int ncyl = 0, nsect = 0, ntrack =0 ;
char *floppy = getenv("FLOPPY");
/*
* Let the user set the geometry in the environment
* It is possible for this to be the only way out of the catch-22
* wherein the geometry needs to be read from the first block
* which cannot be read until the geometry is set!
*/
fd = -1 ;
if (!floppy) {
floppy = "/tos0@";
is_tos0 = 1;
system("ex diskcache -d /d0");
}
mode = (mode == 0) ? S_IREAD : S_IREAD|S_IWRITE;
if ( (fd = open(floppy, mode)) > 0 ) {
if(read_boot()) {
close(fd) ;
fd = -1;
} else {
(void) fprintf(stderr,"ok\n") ;
fflush(stderr) ;
}
}
if ( fd < 0 ) {
(void) fprintf(stderr,"All known devices failed.\nSorry.\n") ;
exit(errno) ;
}
if ((mode & S_IWRITE) && _gs_opt(fd, &tos0opts) >= 0) {
tos0opts.sg_verify = 1;
_ss_opt(fd, &tos0opts);
}
dir_start = DIROFF(bb.sb) ;
dir_len = DIRLEN(bb.sb);
clus_size = CLSIZ(bb.sb);
fat_len = FATLEN(bb.sb);
num_clus = NCLUST(bb.sb);
/* Set the parameters if needed */
if (NSECT(bb.sb) != 9) {
fprintf(stderr, "Cannot handle other than 9 sectors yet\n");
exit(1);
}
buflen = fat_len * MSECSIZ;
fatbuf = (unsigned char *) malloc((unsigned int) buflen);
/* read the FAT sectors */
move(FATOFF(bb.sb));
if (read(fd, fatbuf, buflen) != buflen) {
(void) fprintf(stderr,"Could not read the FAT table\n");
perror("init: read");
exit(1) ;
}
/* set dir_chain to root directory */
reset_dir();
/* get Current Working Directory */
mcwd = fixmcwd(getenv("MCWD"));
/* test it out.. */
if (subdir("")) {
(void) fprintf(stderr, "Environment variable MCWD needs updating\n");
exit(1);
}
return(0);
}
/*
* Set the logical sector. Non brain-dead drivers don't move the
* head until we ask for data, so computing relative seeks is overkill.
*/
void
move(sector)
int sector;
{
long lseek();
void exit(), perror();
if (lseek(fd, (long)sector*MSECSIZ, 0) < 0) {
perror("move: lseek");
exit(1);
}
}
/*
* Fix MCWD to be a proper directory name. Always has a leading separator.
* Never has a trailing separator (unless it is the path itself).
*/
char *
fixmcwd(dirname)
char *dirname;
{
char *s, *ans, *malloc(), *strcpy(), *strcat();
if (dirname == NULL)
return("/");
ans = malloc((unsigned int) strlen(dirname)+2);
/* add a leading separator */
if (*dirname != '/' && *dirname != '\\') {
strcpy(ans, "/");
strcat(ans, dirname);
}
else
strcpy(ans, dirname);
/* translate to upper case */
for (s = ans; *s; ++s) {
if (islower(*s))
*s = toupper(*s);
}
/* if separator alone */
if (strlen(ans) == 1)
return(ans);
/* zap the trailing separator */
s--;
if (*s == '/' || *s == '\\')
*s = '\0';
return(ans);
}
/*
* Do a graceful exit if the program is interupted. This will reduce
* (but not eliminate) the risk of generating a corrupted disk on
* a user abort.
*/
int
intr()
{
void writefat();
writefat();
close(fd);
exit(1);
}
/*
* Write the FAT table to the disk. Up to now the FAT manipulation has
* been done in memory. All errors are fatal. (Might not be too smart
* to wait till the end of the program to write the table. Oh well...)
*/
void
writefat()
{
int buflen;
void move();
move(FATOFF(bb.sb)) ;
buflen = fat_len * MSECSIZ;
if (write(fd, (char *) fatbuf, buflen) != buflen) {
perror("writefat: write");
exit(1);
}
#ifdef DUP_FAT
/* the duplicate FAT table */
if (write(fd, (char *) fatbuf, buflen) != buflen) {
perror("writefat: write");
exit(1);
}
#endif /* DUP_FAT */
return;
}
read_boot()
{
unsigned char buf[MSECSIZ];
static unsigned char ans;
move(0);
if (read(fd, &bb, MSECSIZ) != MSECSIZ ) {
return(1) ;
}
/* Do not know how to deal with non 512 byte blocks! */
if ( SECSIZ(bb.sb) != MSECSIZ ) {
fprintf(stderr,"File system block size of %d bytes is not valid\n",
SECSIZ(bb.sb));
exit(1) ;
}
return(0) ;
}