home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1035 / disk.c < prev    next >
C/C++ Source or Header  |  1990-12-28  |  8KB  |  286 lines

  1. /* TODO
  2.  *        Do not allow any changes to unit 0 if HD rooted.
  3.  *        if tried, give message stating that unit 0 is READONLY if HD rooted.
  4.  */
  5.  
  6. /*
  7. **    Disk Configuration utility for Microport Unix V/AT
  8. **
  9. **    THIS PROGRAM IS NOT COMPLETE
  10. **
  11. **    It WILL NOT work (or compile) AS-IS.
  12. **
  13. **    Replaces fdisk, divvy, and showbad
  14. **    Adds "addbad" and "printconfiguration" utilities
  15. **
  16. **    Author: John Plocher        April 1988
  17. **
  18. **    Last modified by $Author: plocher$ on $Date: 88/04/12 04:29:04 $
  19. **
  20. **    Locked by $Locker: plocher$
  21. **              $Revision: 1.0 $
  22. **
  23. **  Source is found in $Source$
  24. **
  25. **
  26. **    Modification Log
  27. **  ----------------
  28. **  $Log$
  29. */
  30.  
  31. #ifndef lint
  32.     static char rcsid[] =
  33.     "$Header$";
  34. #endif
  35.  
  36. #include <stdio.h>
  37.  
  38. #include "localdisk.h"
  39.  
  40. #include "mbb.h"
  41. #include "pbb.h"
  42. #include "per.h"
  43. #include "btt.h"
  44.  
  45. #define NEEDED    0x00        /* Status states for various buffers */
  46. #define INCORE    0x01
  47. #define INVALID    0x02
  48. #define BADGEO    0x04
  49. #define DIRTY    0x08
  50.  
  51.         /* NEEDED - needs to be read in */
  52.         /* INCORE - we have a copy - See INVALID bit for "goodness" */
  53.         /* INCORE + BADGEO means that the geometry info in this thing */
  54.         /*              is out of date and needs to be updated to match */
  55.         /*              the PER geometry */
  56.         /* INCORE + INVALID - bad copy on disk - need to regenerate */
  57.         /* INCORE + DIRTY - need to update disk copy */
  58.  
  59. #define CYL(x)        x    /* For clarification of code */
  60. #define HEAD(x)        x
  61. #define SECTOR(x)    x
  62.  
  63.  
  64. int HDRooted;        /* "true" if booted off of hard disk */
  65.  
  66. mbb_t mbb;        /* structure to contain the Master boot Block */
  67. pbb_t pbb;        /* Partition Boot Block */
  68. per_t per;        /* Partition End Record */
  69. btt_t btt;        /* Bad Track Table */
  70.  
  71. int GEOstatus = NEEDED;
  72.                         /* NEEDED = not found yet */
  73.                         /* DIRTY  = PBB and PER is out of date */
  74.                         /* BADGEO = out of bounds for HD Driver */
  75. int MBBstatus = NEEDED;
  76.                         /* INVALID= No MBB found on disk */
  77.                         /* depends on /etc/master.bblock, and PT */
  78. int PTstatus  = NEEDED;
  79.                         /* DIRTY  = PT changed */
  80.                         /* INVALID= bad numbers in it */
  81. int PBBstatus = NEEDED;
  82.                         /* DIRTY  = needs to be written to disk */
  83.                         /* INVALID= No PBB found on disk */
  84.                         /* depends on GEO and /etc/boot.hd */
  85. int PERstatus = NEEDED;
  86.                         /* DIRTY  = needs to be written to disk */
  87.                         /* INVALID= no PER found on disk */
  88.                         /* depends on GEO & SLICE */
  89. int SLICEstatus = NEEDED;
  90.                         /* DIRTY  = modified */
  91. int BTTstatus = NEEDED;
  92.                         /* DIRTY  = in core copy differs from disk copy */
  93.                         /* INVALID= blocks conflict with MBB/PBB/PER/BTT */
  94. int CMOSstatus= NEEDED;
  95.                         /* DIRTY  = in core copy differs from CMOS RAM */
  96.                         /* INVALID= Bad Checksum - MUST RUN SETUP */
  97.  
  98. main( argc, argv )
  99. int argc;
  100. char *argv[];
  101. {
  102.  
  103.     int unit      = 0;
  104.     int pbbcyl, pbbhead, pbbsec;
  105.     int percyl, perhead, persec;
  106.     partition_t *activepartition;
  107.  
  108.     /*
  109.      *    For each of MBB PBB PER try reading and validating before assuming
  110.      *  it is invalid.  This allows the user to screw up the partition table,
  111.      *    restore it, and not lose too much sleep (or info).
  112.      */
  113.  
  114.     /*
  115.          We look in the MBB, the PBB, the CMOS, and lastly in the user's brain
  116.         for the drive geometry.  When we find it, we will put it into the PBB
  117.         if it is new/changed.  NOTE that this will not work with PRE 2.3 
  118.         systems that expect the drive info to be found in the MBB!  We do
  119.         NOT write the geometry to the MBB because other OSs may be using
  120.         the space... (not mentioning names, but some DOS programs are really
  121.         not very well behaved!)
  122.      */
  123.  
  124.         CMOSstatus = getCMOS( &cmos );
  125.         if (CMOSstatus != INCORE || !CMOSdriveEnabled( unit, &cmos )) {
  126.             fprintf(stderr,
  127. "Error: You must use the setup program to tell the machine that you have\n");
  128.             fprintf(stderr,
  129. "a hard disk drive attached.  If you don't have a ROM type which matches\n");
  130.             fprintf(stderr,
  131. "your drive exactly, pick a type with the same number of heads and the\n");
  132.             fprintf(stderr,
  133. "closest number of cylinders.  If in doubt, be generous with the cylinders.\n");
  134.             exit( -1 );
  135.         }
  136.  
  137.         while (1) {
  138.             if (MBBstatus == NEEDED)  {
  139.                 if ((MBBstatus = getMBB(unit, &mbb)) == INCORE) {
  140.                     if ((GEOstatus & INCORE) != INCORE) {
  141. !                        if (MBBGeometryIsValid( &mbb )) {
  142. !                            GEOstatus = MBBgeoToPERgeo(mbb.geometry, geometry);
  143.                         }
  144.                     }
  145.                 }
  146.             }
  147.             
  148.             if ((MBBstatus & INCORE) == INCORE)
  149. !                activepartition = GetActive( &mbb );
  150.             else activepartition = NULL;
  151.  
  152.             if (activepartition == NULL) {
  153.                 PTstatus = INCORE + INVALID;
  154.             } else {
  155.  
  156.                 pbbcyl = CYL_BOOT( activepartition );
  157.                 pbbhead= HEAD_BOOT(activepartition );
  158.                 pbbsec = SEC_BOOT( activepartition );
  159.  
  160.                 if (PBBstatus == NEEDED) {
  161.                     if ((PBBstatus= getPBB(unit, pbbcyl, pbbhead, pbbsec, &pbb))
  162.                                  == INCORE) {
  163.  
  164.                         /* Try reading a 2.3+ geometry specification */
  165.  
  166.                         if ((GEOstatus & INCORE) != INCORE) {
  167.                             /* by definition - if a PBB is valid, it */
  168.                             /* has a valid geometry table */
  169. !                            GEOstatus = PBBgeoToPERgeo(pbb.geometry, geometry);
  170.                         }
  171.                     }
  172.                 }
  173.  
  174.                 /*
  175.                     At this point, if we don't have valid drive geometry info,
  176.                     we need to grab it from the CMOS ... 
  177.                  */
  178.     
  179.                 if ((GEOstatus & INCORE) != INCORE) {
  180. !                    GEOstatus=CMOSgeoToPERgeo(&cmos,unit,geometry);
  181.                     if ((GEOstatus & INCORE) != INCORE) {
  182.                         reinitialize drive
  183.                     }
  184.                 }
  185.  
  186.                 /* now snarf up the PER ... */
  187.  
  188.                 percyl = CYL_END( activepartition );
  189.                 perhead= HEAD_END(activepartition );
  190.                 persec = SEC_END( activepartition );
  191.  
  192.                 if (PERstatus == NEEDED)
  193.                     PERstatus=read_sector(unit,&per,percyl,perhead,persec);
  194.  
  195.                 SLICEstatus = ValidSliceTable( unit, &per );
  196.  
  197.                 if (BTTstatus == NEEDED)
  198.                     BTTstatus=read_sector(unit,&btt,percyl,perhead,persec - 1);
  199.             }
  200.  
  201.         DISPLAY
  202.             GEO,    if any are NEEDED or INVALID, label as such, else
  203.             PT,        show contents on the screen
  204.             PER,
  205.             BTT, and
  206.             SLICE    (also note if valid superblock found there)
  207.  
  208.         Select one of GEO PT BTT SLICE to modify
  209.             /* GEO */
  210.             if ((GEOstatus & INCORE) != INCORE) { /* virgin disk! */
  211. !                while ((GEOstatus = GetGEOfromUser(geometry)) != INCORE)
  212.                     ; /* wait till the user gets it right */
  213.                 GEOstatus |= DIRTY;
  214.             }
  215.             if changed GEO, reinit drive & set MBB,PBB,PER,&BTT to NEEDED
  216.         
  217.             if changed PT, re-read PBB, PER, and BTT & set MBB |= DIRTY
  218.               if not valid, mark on screen and dont allow update till fixed
  219.         
  220.             if changed BTT - check for conflicts with the MBB, PBB, BTT, and PER
  221.               if conflicts, complain and allow user to modify PT to bypass these
  222.         
  223.             if changed SLICE, set SLICEstatus |= DIRTY
  224.             /* at this point check over the NEEDED/INVALID bits */
  225.             /* if any of PT, GEO, BTT, or SLICE are still set, tell what */
  226.             /* is needed and go back to the loop */
  227.             /* if all is kosher, quit... (OK if MBB, PBB, or PER invalid) */
  228.         }
  229.         /* ... to here where we must figure out what needs updating */
  230.         /* if MBB is INVALID then read in boot code */
  231.         /* if PBB is INVALID then read in boot code */
  232.         /* if CMOS is BADGEO then need to update with GEO */
  233.         /* if GEO dirty, need to update PBB, PER & set dirty, unset GEO dirty */
  234.         /* if PT dirty, update & set MBB dirty, unset PT dirty */
  235.         /* if SLICE dirty, update & set PER dirty */
  236.  
  237.         /* if MBB dirty, write & unset */
  238.         /* if PBB dirty ... */
  239.         /* if PER dirty ... */
  240.         /* if BTT dirty ... */
  241.  
  242.         /* if SLICE dirty then need to do smartMKFSing remembering that */
  243.         /* changes to 0s0 if HD rooted are not allowed */
  244. }
  245.  
  246. getMBB( unit, mbbp )
  247. int unit;
  248. mbb_t *mbbp;
  249. {
  250.     int cc;
  251.  
  252.     if ( read_sector( unit, mbbp, CYL(0), HEAD(0), SECTOR(1)) == ERROR ) {
  253.         fprintf(stderr, "Error reading MBB from HD unit %d",unit);
  254.         return INVALID;
  255.     }
  256.     if ( mbbp->signature == PT_SIG )
  257.         return INCORE;
  258.     else
  259.         return INVALID;
  260. }
  261.  
  262.  
  263. getPBB( unit, pbbcyl, pbbhead, pbbsec, pbbp )
  264. int unit;
  265. int pbbcyl, pbbhead, pbbsec;
  266. pbb_t *pbbp;
  267. {
  268.     int cc;
  269.  
  270.     if ( read_sector( unit, pbbp, pbbcyl, pbbhead, pbbsec) == ERROR ) {
  271.         fprintf(stderr, "Error reading PBB from HD unit %d",unit);
  272.         return INVALID;
  273.     }
  274.     if ( VALID_PBB( pbbp ) )
  275.         return INCORE;
  276.     else
  277.         return INVALID;
  278. }
  279.  
  280.                 /* forcibly update CMOS */
  281.                 CMOSstatus = PERgeoToCMOSgeo(&cmos, unit, geometry);
  282.                 if ((CMOSstatus & DIRTY) == DIRTY) {
  283.                     writeCMOS( &cmos );
  284.                     CMOSstatus &= ~DIRTY;
  285.                 }
  286.