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 >
Text File  |  1991-08-04  |  5KB  |  232 lines

  1. /*
  2.  * Initialize a MSDOS diskette.  Read the boot block for disk layout
  3.  * and switch to the proper floppy disk device to match the format
  4.  * of the disk.  Sets a bunch of global variables.  Returns 0 on success,
  5.  * or 1 on failure.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <signal.h>
  11. #include <modes.h>
  12. #include <errno.h>
  13. #include <sgstat.h>
  14. #include "devices.h"
  15. #include "msdos.h"
  16.  
  17. #define DUP_FAT /* update of the second FAT */
  18.  
  19. extern int fd, dir_len, dir_start, clus_size, fat_len, num_clus;
  20. extern unsigned char *fatbuf;
  21. extern char *mcwd;
  22.  
  23. /* The available drivers */
  24. extern struct device fd_devices[];
  25.  
  26. /* The bootblock */
  27. union bootblock bb ;
  28.  
  29. short is_tos0 = 0;
  30.  
  31. int
  32. init(mode)
  33. int mode;
  34. {
  35.   struct sgbuf tos0opts;
  36.   int code, buflen, intr();
  37.   void perror(), exit(), move(), reset_dir();
  38.   char *getenv(), *fixmcwd(), *malloc(), *dummy;
  39.   long lseek();
  40.   struct device *try;
  41.   int ncyl = 0, nsect = 0, ntrack =0 ;
  42.   char *floppy = getenv("FLOPPY");
  43.  
  44.   /*
  45.    * Let the user set the geometry in the environment
  46.    * It is possible for this to be the only way out of the catch-22
  47.    * wherein the geometry needs to be read from the first block
  48.    * which cannot be read until the geometry is set!
  49.    */
  50.  
  51.   fd = -1 ;
  52.  
  53.   if (!floppy) {
  54.         floppy = "/tos0@";
  55.         is_tos0 = 1;
  56.         system("ex diskcache -d /d0");
  57.   }
  58.   mode = (mode == 0) ? S_IREAD : S_IREAD|S_IWRITE;
  59.   if ( (fd = open(floppy, mode)) > 0 ) {
  60.         if(read_boot()) {
  61.           close(fd) ;
  62.           fd = -1;
  63.         } else {
  64.           (void) fprintf(stderr,"ok\n") ;
  65.           fflush(stderr) ;
  66.       }
  67.   }
  68.  
  69.   if ( fd < 0 ) {
  70.     (void) fprintf(stderr,"All known devices failed.\nSorry.\n") ;
  71.     exit(errno) ;
  72.   }
  73.   if ((mode & S_IWRITE) && _gs_opt(fd, &tos0opts) >= 0) {
  74.           tos0opts.sg_verify = 1;
  75.           _ss_opt(fd, &tos0opts);
  76.   }
  77.         
  78.   dir_start = DIROFF(bb.sb) ;
  79.   dir_len = DIRLEN(bb.sb);
  80.   clus_size = CLSIZ(bb.sb);
  81.   fat_len = FATLEN(bb.sb);
  82.   num_clus = NCLUST(bb.sb);
  83.  
  84.   /* Set the parameters if needed */
  85.   if (NSECT(bb.sb) != 9) {
  86.       fprintf(stderr, "Cannot handle other than 9 sectors yet\n");
  87.           exit(1);
  88.   }
  89.  
  90.   buflen = fat_len * MSECSIZ;
  91.   fatbuf = (unsigned char *) malloc((unsigned int) buflen);
  92.  
  93.   /* read the FAT sectors */
  94.   move(FATOFF(bb.sb));
  95.   if (read(fd, fatbuf, buflen) != buflen) {
  96.     (void) fprintf(stderr,"Could not read the FAT table\n");
  97.     perror("init: read");
  98.     exit(1) ;
  99.   }
  100.  
  101.   /* set dir_chain to root directory */
  102.   reset_dir();
  103.   /* get Current Working Directory */
  104.   mcwd = fixmcwd(getenv("MCWD"));
  105.   /* test it out.. */
  106.   if (subdir("")) {
  107.     (void) fprintf(stderr, "Environment variable MCWD needs updating\n");
  108.     exit(1);
  109.   }
  110.   return(0);
  111. }
  112.  
  113. /*
  114.  * Set the logical sector.  Non brain-dead drivers don't move the
  115.  * head until we ask for data,  so computing relative seeks is overkill.
  116.  */
  117.  
  118. void
  119. move(sector)
  120. int sector;
  121. {
  122.   long lseek();
  123.   void exit(), perror();
  124.  
  125.   if (lseek(fd, (long)sector*MSECSIZ, 0) < 0) {
  126.     perror("move: lseek");
  127.     exit(1);
  128.   }
  129. }
  130.  
  131. /*
  132.  * Fix MCWD to be a proper directory name.  Always has a leading separator.
  133.  * Never has a trailing separator (unless it is the path itself).
  134.  */
  135.  
  136. char *
  137. fixmcwd(dirname)
  138. char *dirname;
  139. {
  140.   char *s, *ans, *malloc(), *strcpy(), *strcat();
  141.  
  142.   if (dirname == NULL)
  143.     return("/");
  144.  
  145.   ans = malloc((unsigned int) strlen(dirname)+2);
  146.   /* add a leading separator */
  147.   if (*dirname != '/' && *dirname != '\\') {
  148.     strcpy(ans, "/");
  149.     strcat(ans, dirname);
  150.   }
  151.   else
  152.     strcpy(ans, dirname);
  153.   /* translate to upper case */
  154.   for (s = ans; *s; ++s) {
  155.     if (islower(*s))
  156.       *s = toupper(*s);
  157.   }
  158.   /* if separator alone */
  159.   if (strlen(ans) == 1)
  160.     return(ans);
  161.   /* zap the trailing separator */
  162.   s--;
  163.   if (*s == '/' || *s == '\\')
  164.     *s = '\0';
  165.   return(ans);
  166. }
  167.  
  168. /*
  169.  * Do a graceful exit if the program is interupted.  This will reduce
  170.  * (but not eliminate) the risk of generating a corrupted disk on
  171.  * a user abort.
  172.  */
  173.  
  174. int
  175. intr()
  176. {
  177.   void writefat();
  178.  
  179.   writefat();
  180.   close(fd);
  181.   exit(1);
  182. }
  183.  
  184. /*
  185.  * Write the FAT table to the disk.  Up to now the FAT manipulation has
  186.  * been done in memory.  All errors are fatal.  (Might not be too smart
  187.  * to wait till the end of the program to write the table.  Oh well...)
  188.  */
  189.  
  190. void
  191. writefat()
  192. {
  193.   int buflen;
  194.   void move();
  195.  
  196.   move(FATOFF(bb.sb)) ;
  197.   buflen = fat_len * MSECSIZ;
  198.   if (write(fd, (char *) fatbuf, buflen) != buflen) {
  199.     perror("writefat: write");
  200.     exit(1);
  201.   }
  202. #ifdef DUP_FAT
  203.   /* the duplicate FAT table */
  204.   if (write(fd, (char *) fatbuf, buflen) != buflen) {
  205.     perror("writefat: write");
  206.     exit(1);
  207.   }
  208. #endif                          /* DUP_FAT */
  209.   return;
  210. }
  211.  
  212. read_boot()
  213. {
  214.   unsigned char buf[MSECSIZ];
  215.   static unsigned char ans;
  216.  
  217.   move(0);
  218.      
  219.   if (read(fd, &bb, MSECSIZ) != MSECSIZ ) {
  220.     return(1) ;
  221.   }
  222.   
  223.   /* Do not know how to deal with non 512 byte blocks! */
  224.   if ( SECSIZ(bb.sb) != MSECSIZ ) {
  225.     fprintf(stderr,"File system block size of %d bytes is not valid\n",
  226.             SECSIZ(bb.sb));
  227.     exit(1) ;
  228.   }
  229.  
  230.   return(0) ;
  231. }
  232.