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