home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX302.ST / HDX.BAK < prev    next >
Encoding:
Text File  |  2001-02-09  |  37.8 KB  |  1,617 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  *
  48.  */
  49.  
  50. #include "obdefs.h"
  51. #include "gemdefs.h"
  52. #include "osbind.h"
  53. #include "mydefs.h"
  54. #include "part.h"
  55. #include "bsl.h"
  56. #include "hdx.h"
  57. #include "ipart.h"
  58. #include "addr.h"
  59. #include "error.h"
  60.  
  61. #define MFM 17
  62.  
  63. extern char sbuf[];
  64. extern int rebootp;
  65. extern long gbslsiz();
  66. extern long get3bytes();
  67. extern long bslsiz;
  68. extern BYTE *bsl;
  69. extern int uplim;            /* the number of partitions */
  70. extern long sptrk;
  71. extern long spcyl;
  72. extern int ibmpart;
  73. extern int yesscan;
  74. extern long disksiz;
  75. extern long ratio;
  76. extern int typedev;
  77. extern int typedrv;
  78. extern int prevnpart;
  79.  
  80. /* Globals */
  81. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  82. int tformat;            /* TRUE: just formatted disk */
  83. int running;        /* 1: continue evnt_multi() loop */
  84. char sbuf[512];        /* error message buffer */
  85. long extsiz;        /* the size of extened partition */
  86. long ostack;                /* old stack pointer */
  87. int toibm;            /* the flag of partition to ibm format */
  88. int ibm2st;            /* the flag for IBM partition to ST */
  89. long bps;            /* bytes per sector */
  90. int npart;            /* number of partition */
  91. int ext;            /* the index of extended partition */
  92. int extend;            /* the index of end extended partition */
  93. int showmany;        /* the flag that show the too much device alert box */
  94. char ttscsi;        /* SCSI hard disk drive */
  95. int needscan;        /* TRUE: if info in the LOGMAP update */
  96. int noinfo;            /* 1: no informations in the wincap */
  97.  
  98. /*  Logical-to-dev+partition mapping table. */
  99. extern int nlogdevs;        /* #logical devs found */
  100. extern LOGMAP logmap[];        /* logical dev map */
  101. extern int livedevs[];        /* live physical dev flag */
  102. char cachexst;        /* 0: no cache. 1: with cache */
  103.  
  104. /* Partition related variables */
  105. long mxpsiz = MAXPSIZ;
  106.  
  107. /* AES (windows and messages) related variables */
  108. int gl_hchar;        /* height of system font (pixels) */
  109. int gl_wchar;        /* width of system font (pixels) */
  110. int gl_wbox;        /* width of box able to hold system font */
  111. int gl_hbox;        /* height of box able to hold system font */
  112.  
  113. int phys_handle;    /* physical workstation handle */
  114. int handle;        /* virtual workstation handle */
  115. int wi_handle;        /* window handle */
  116.  
  117. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  118. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  119. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  120.  
  121. int msgbuff[8];        /* event message buffer */
  122. int keycode;        /* keycode returned by event-keyboard */
  123. int mx, my;        /* mouse x and y pos. */
  124. int butdown;        /* button state tested for, UP/DOWN */
  125. int ret;        /* dummy return variable */
  126. int pnf;        /* 1: partition or format; 0: zero or markbad */
  127. int hidden;        /* current state of cursor */
  128. int contrl[12];
  129. int intin[128];
  130. int ptsin[128];
  131. int intout[128];
  132. int ptsout[128];    /* storage wasted for idiotic bindings */
  133. int work_in[11];    /* Input to GSX parameter array */
  134. int work_out[57];    /* Output from GSX parameter array */
  135. int pxyarray[10];    /* input point array */
  136.  
  137. /*
  138.  * Top level;
  139.  * we get control from the desktop.
  140.  */
  141. main()
  142. {
  143.     running = TRUE;
  144.     pnf = 0;        /* set the flag to it isn't partition yet */
  145.     appl_init();
  146.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  147.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  148.     open_vwork();
  149.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  150.  
  151.     hidden = FALSE;
  152.     butdown = TRUE;
  153.  
  154.     /* doing a checking see if the cache in the system */
  155.     cachexst = (char) chkcache();
  156.  
  157.     if (!rsrc_load(RESOURCEFILE)) {
  158.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  159.     goto punt;
  160.     }
  161.  
  162.     
  163.     /* Get all addresses of dialogues from resource file */
  164.     if (getalladdr() != OK) {
  165.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  166.     goto punt;
  167.     }
  168.  
  169.  
  170.     /*
  171.      * Get maximum partition size from
  172.      * wincap "@@" entry.
  173.      */
  174.     /*
  175.     if (wgetent("Parameters", "@@") == OK) {
  176.     if (wgetnum("ms", &mxpsiz) != OK)
  177.         mxpsiz = MAXPSIZ;
  178.     } else {
  179.         goto punt;
  180.     }
  181.     */
  182.  
  183.     ARROW_MOUSE;
  184.  
  185.     /* display menu bar */
  186.     menu_bar(menuobj, 1);
  187.  
  188.     needscan = TRUE;
  189.     while (running) {
  190.         domulti();
  191.     }
  192.  
  193.     /*
  194.      * If nothing has been done to the hard disks
  195.      * then just get out, back to the desktop.
  196.      * Otherwise reboot the system.
  197.      */
  198.     menu_bar(menuobj, 0);        /* erase menu bar */
  199.  
  200. punt:
  201.     /*
  202.      * If we have to reboot,
  203.      * tell the user and then do it.
  204.      *
  205.      */
  206.     if (rebootp) {
  207.     err(autoboot);
  208.     reboot();
  209.     }
  210.  
  211.     wind_delete(wi_handle);
  212.     v_clsvwk(handle);
  213.     appl_exit();
  214. }
  215.  
  216.  
  217. /*
  218.  * Get a single event, process it, and return.
  219.  *
  220.  */
  221. domulti(){
  222.     int event;
  223.     
  224.     event = evnt_multi(MU_MESAG,
  225.             1,1,butdown,
  226.             0,0,0,0,0,
  227.             0,0,0,0,0,
  228.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  229.  
  230.     if (event & MU_MESAG) {
  231.         wind_update(TRUE);
  232.     switch (msgbuff[0]) {
  233.         case WM_REDRAW:
  234.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  235.         break;
  236.  
  237.         case MN_SELECTED:
  238.             BEE_MOUSE;
  239.         switch(msgbuff[3]) {
  240.             case MNDISK:
  241.             switch (msgbuff[4]) {
  242.                 case DIFORM:
  243.                     if ((needscan) && (rescan(0,0) == ERROR))    {
  244.                         break;    /* don't report medium changed */
  245.                     }
  246.                     tformat = TRUE;
  247.                     needscan = FALSE;
  248.                     dodiform();
  249.                     tformat = FALSE;
  250.                     break;
  251.                 case DIPART:
  252.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  253.                         break;    /* don't report medium changed */
  254.                     }
  255.                     needscan = FALSE;
  256.                     dodipart(-1, NULL, NULL);
  257.                     break;
  258.                 case DIZERO:
  259.                     if (pnf)    {
  260.                         err(needboot);
  261.                     } else {
  262.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  263.                             break;    /* don't report medium changed */
  264.                         }
  265.                         needscan = FALSE;
  266.                         dodizero();
  267.                     }
  268.                     break;
  269.                 case DIMARK:
  270.                     if (pnf)    {
  271.                         err(needboot);
  272.                     } else {
  273.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  274.                             break;    /* don't report medium changed */
  275.                         }
  276.                         needscan = FALSE;
  277.                         dodimark();
  278.                     }
  279.                     break;
  280.                 case DISHIP:
  281.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  282.                         break;    /* don't report medium changed */
  283.                     }
  284.                     needscan = FALSE;
  285.                     dodiship();
  286.                     break;
  287.                 default:        break;
  288.             }
  289.             break;
  290.  
  291.             case MNFILE:
  292.             switch (msgbuff[4]) {
  293.                 case FIQUIT:
  294.                 running = 0;
  295.                 break;
  296.  
  297.                 default:
  298.                 break;
  299.             }
  300.             break;
  301.             
  302.             case MNDESK:
  303.             if(msgbuff[4] == DEABOUT) {
  304.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 3.02");
  305.                 abtdial[ABOK].ob_state = NORMAL;
  306.                 execform(abtdial);
  307.             }
  308.             break;        /* "cannot happen" */
  309.         }
  310.  
  311.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  312.             ARROW_MOUSE;
  313.         break;
  314.         
  315.         case WM_NEWTOP:
  316.         case WM_TOPPED:
  317.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  318.         break;
  319.  
  320.         case WM_CLOSED:
  321.         running = FALSE;
  322.         break;
  323.  
  324.         default:
  325.         break;
  326.     }
  327.     wind_update(FALSE);
  328.     }
  329. }
  330.  
  331.  
  332. /*
  333.  * Default partition name (no "pt" entry).
  334.  */
  335. #define    DEF_PARTNAME    "4-6-10"
  336.  
  337.  
  338. /*
  339.  * Map from button in format dial.
  340.  */
  341. int pfmt[] = {
  342.     PFMT0, PFMT1, PFMT2, PFMT3,
  343.     PFMT4, PFMT5, PFMT6, PFMT7,
  344.     PFMT8, PFMT9, PFMT10, PFMT11,
  345.     PFMT12, PFMT13, PFMT14, PFMT15
  346. };
  347.  
  348.  
  349. /*
  350.  * Handle [FORMAT] item.
  351.  *
  352.  */
  353. dodiform()
  354. {
  355.   extern char bootstop;
  356.   extern char bootend;
  357.   int dev, v, i, br;
  358.   int modesel;            /* flag for mode select */
  359.   long cnt, hdsiz;
  360.   char *s, *d, *wgetstr();
  361.   char bs[512], sendata[32];
  362.   char pnam[128];
  363.   char *seldev = "X", *id = "XXXXX";
  364.   HINFO hinfo;
  365.   char devnames[NAMSIZ];    /* device type name buffer */
  366.   long nbad;
  367.   extern long gbslsiz(), nument(), dsmarkbad();
  368.   long pattern, temp;
  369.   long longrandom();
  370.   char pr_id[10];    /* partition scheme id */
  371.   int mask = 0x0001;
  372.   int set, scsidrv, bsiz, other = 0;
  373.   
  374.   /*
  375.    * Throw up generic formatting/partition warning,
  376.    * then get physical dev they want to clobber.
  377.    */
  378.   yesscan = 0;
  379.   noinfo = 0;
  380.   for (i = 0; i < NAMSIZ; i++)
  381.       devnames[i] = "\0";
  382.   fwarning[FWARNCN].ob_state = NORMAL;
  383.   fwarning[FWARNOK].ob_state = NORMAL;
  384.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  385.  
  386.   if ((dev = gphysdev()) < 0) {
  387.       return BAILOUT;
  388.   }
  389.   strcpy(id, "mn");
  390.   br = 0;
  391.  
  392.   /* display doing SCSI massage */
  393.  
  394.   if (ttscsi)  {
  395.       noinfo = 1;
  396.       goto stfm;
  397.   }
  398.   
  399.   inqfmt:
  400.   /* Get all available disk types from wincap 'mn' entries */  
  401.   wallents(devnames, id);
  402.   if (!*devnames)     {
  403.       noinfo = 1;
  404.       goto stfm;
  405.   }
  406.   
  407.   /* Shove format name text into buttons */
  408.   for (i = 0, s = devnames; i < 14 && *s; ++i) {
  409.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  410.       dsknames[pfmt[i]].ob_spec = (long)s;
  411.       dsknames[pfmt[i]].ob_state = NORMAL;
  412.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  413.       while (*s++)
  414.     ;
  415.   }
  416.   other = i;                            /* the other button */
  417.   dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  418.   dsknames[pfmt[i]].ob_spec = "OTHER";
  419.   dsknames[pfmt[i]].ob_state = NORMAL;
  420.   dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  421.   i++;
  422.  
  423.   /* rest of buttons are invisible and untouchable */
  424.   for (; i < 16; ++i) {
  425.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  426.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  427.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  428.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  429.   }
  430.   
  431.   /* clean up rest of the form and throw it up */
  432.   dsknames[PFOK].ob_state = NORMAL;
  433.   dsknames[PFCN].ob_state = NORMAL;
  434.   if (execform(dsknames) != PFOK)
  435.     return BAILOUT;
  436.   
  437.   /* search for format they picked */
  438.   for (i = 0; i < 16; ++i)
  439.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  440.       break;
  441.   if (i >= 16) {        /* nothing picked */
  442.       return BAILOUT;
  443.   } else if (other == i)    {  /* the OTHER button was selected */
  444.         noinfo = 1;
  445.       goto stfm;
  446.   }
  447.   
  448.     if ((!br) && (!ttscsi))        {
  449.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  450.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  451.             nofmt[NOSCHFMT].ob_state = NORMAL;
  452.             execform(nofmt, 0);
  453.             return ERROR;
  454.         }
  455.         if ((s = wgetstr("br")) != NULL)    {
  456.             strcpy(id, s);
  457.             br = 1;            /* processing the branch */
  458.             goto inqfmt;    /* start over */
  459.         }
  460.     }
  461.  
  462. stfm:
  463.     modesel = 1;
  464.   if (gfparm(dev, noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) {
  465.       return ERROR;
  466.   }
  467.   
  468.   /* get data pattern to test the disk */
  469.   if (wgetnum("dp", &pattern) != OK) {
  470.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  471.   } else {
  472.       temp = pattern;
  473.       pattern <<= 16;    /* shift pattern to hi word */
  474.       pattern |= temp;
  475.   }
  476.  
  477.  
  478.   /*
  479.    * One last chance to bail out.
  480.    */
  481.   *seldev = dev + '0';
  482.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  483.   fmtfnl[FMTYES].ob_state = NORMAL;
  484.   fmtfnl[FMTNO].ob_state = NORMAL;
  485.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  486.  
  487.   /* For REAL !! */  
  488.   dsplymsg(fmtmsg);
  489.  
  490.   bsl = 0L;
  491.   
  492.   /* Get size of Bad Sector List */
  493.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  494.       /* Allocate memory for existing BSL */
  495.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  496.           ret = err(nomemory);
  497.           goto formend;
  498.       }
  499.       
  500.       /* Read in BSL */
  501.       if ((ret = rdbsl(dev)) != OK) {
  502.           /* Create a new BSL if current one is unusable */
  503.           if (creabsl(dev, NEW, 0L) != OK) {
  504.               ret = ERROR;
  505.               goto formend;
  506.           }
  507.       } else {
  508.             /* Remove USER BSL */
  509.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  510.                 ret = ERROR;
  511.                 goto formend;
  512.             }
  513.       }
  514.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  515.       if (creabsl(dev, NEW, 0L) != OK) {
  516.           ret = ERROR;
  517.           goto formend;
  518.       }
  519.   } else {    /* bslsiz == MDMERR; medium changed error */
  520.       ret = ERROR;
  521.       goto formend;
  522.   }
  523.   
  524.   /*
  525.    * In supervisor mode
  526.    * set disk format parameters
  527.    * and format the disk.
  528.    */
  529.   ostack = Super(NULL);
  530.   v = OK;                    /* assume everything is OK */
  531.   if (modesel)    {            /* normal mode select ? */
  532.       v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  533.         /* Find formatted capacity of drive */
  534.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  535.   }    else {                    /* No, do special mode set */
  536.       set = typedev & (mask << dev);
  537.     scsidrv = typedrv & (mask << dev);
  538.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  539.     for (i = 0; i < bsiz; i++)
  540.         sendata[i] = 0;
  541.       if ((v = mdsense(dev, 0, 0, bsiz, sendata)) == OK)        {
  542.           for (i = 0; i < bsiz; i++)
  543.               if (sendata[i])
  544.                 break;
  545.           if (i == bsiz)    { /* no infomations returned */
  546.             ret = 111;        
  547.             delay();
  548.               Super(ostack);
  549.             goto formend;
  550.           }
  551.         hdsiz = get3bytes(sendata+5);
  552.           delay();                    /* kludge delay */
  553.         v = sqms(dev, sendata);
  554.     }
  555.   }
  556.   disksiz = hdsiz;
  557.   delay();                    /* kludge delay */
  558.   if (v == OK)
  559.   v = format(dev, (UWORD)hinfo.hi_in);  /* format */
  560.   delay();                    /* kludge delay */
  561.   Super(ostack);
  562.   
  563.   if (v != 0) {
  564.       ret = errcode(dev);
  565.       if (tsterr(ret) != OK)
  566.           formaterr(dev);
  567.       ret = ERROR;
  568.       goto formend;
  569.   }
  570.   
  571.   ret = OK;
  572.   rebootp = 1;
  573. formend:
  574.   erasemsg();    /* Erase formatting box */
  575.   if (ret == 111)        /* HDX may not support this drive */
  576.           ret = err(needinfo);
  577.   if (ret < 0) {
  578.       if (bsl > 0) free(bsl);
  579.       return ERROR;
  580.   }
  581.   
  582.   /*------------------------------------------*
  583.    * Markbad the device destructively.          *
  584.    * Bad Sectors found are added to the BSL.  *
  585.    * Write BSL to device.              *
  586.    *------------------------------------------*/
  587.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  588.       free(bsl);
  589.       return ERROR;
  590.   }
  591.   if (wrbsl(dev) != OK) {
  592.       free(bsl);
  593.       return ERROR;
  594.   }
  595.   free(bsl);
  596.  
  597.     
  598.   /*
  599.    * Install boot-stopper in sector image;
  600.    * write root sector to device.
  601.    * 6-13-88  Setting of soft format parameters in root sector sets
  602.    *        the hard disk size only.
  603.    */
  604.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  605.   sbslparm(bs);            /* set BSL parameters */
  606.   if (modesel)    {
  607.       sfmtparm(bs, &hinfo);
  608.   } else {
  609.       sdisksiz(bs, disksiz);
  610.   }
  611.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  612.     *d++ = *s++;
  613.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  614.   
  615.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  616.       if (tsterr(ret) != OK)
  617.           err(rootwrit);
  618.       return ERROR;
  619.   }
  620.  
  621.   /*
  622.    * Make a copy of the default partition name.
  623.    * Figure out the partition scheme id.
  624.    */
  625.   if (!noinfo)    {
  626.       s = wgetstr("pt");
  627.       strcpy(pnam, s);
  628.   }
  629.   /* ??
  630.   figprid(disksiz, pr_id);
  631.   */
  632.   dodipart(dev, pnam, disksiz);
  633.   return OK;
  634. }
  635.  
  636.  
  637.  
  638. /*
  639.  * Handle [PARTITION] item;
  640.  * if `xdev' is -1, throw up dialog boxes;
  641.  * if `xdev' >= 0, just partition the dev,
  642.  * using `pnam' as the partition type, 
  643.  * and `pr_id' to search for the type.
  644.  *
  645.  */
  646. dodipart(xdev, pnam, hsize)
  647. int xdev;
  648. char *pnam;
  649. long hsize;
  650. {
  651.     int dev, i, ret =OK, fine;
  652.     int choice;
  653.     char *seldev = "X";
  654.     char *s;
  655.     char bs[512];
  656.     PART *pinfo;
  657.     int tem1, tem2;
  658.     long disksiz;
  659.     extern long getdsiz();
  660.  
  661.     if (xdev < 0) {
  662.     /*
  663.      * Throw up warning saying that partition is dangerous;
  664.      * then get physical dev they want to clobber.
  665.      */
  666.     pwarning[PWARNCN].ob_state = NORMAL;
  667.     pwarning[PWARNOK].ob_state = NORMAL;
  668.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  669.     tformat = FALSE;
  670.     if ((dev = gphysdev()) < 0) {
  671.         return BAILOUT;
  672.     }
  673.     /*
  674.      * Let the user edit/pick partitions.
  675.      */
  676.     fine = 0;
  677.     while (!fine) {
  678.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  679.             if (pinfo > 0)    Mfree(pinfo);
  680.             return BAILOUT;
  681.         }
  682.         if ((ret = chkpart(dev, pinfo)) != OK) {
  683.             if (ret < 0)    {    /* size too big */
  684.                 err(nexsmem);
  685.             } else {    /* some other errors  */
  686.                 if (pinfo > 0)    Mfree(pinfo);
  687.                 return BAILOUT;
  688.             }
  689.         } else {
  690.             fine = 1;
  691.         }
  692.     }
  693.  
  694.     /* Last chance to bail out */
  695.     *seldev = dev + '0';
  696.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  697.     partfnl[PARTYES].ob_state = NORMAL;
  698.     partfnl[PARTNO].ob_state = NORMAL;
  699.     if (execform(partfnl) != PARTYES)    {
  700.         if (pinfo > 0)    Mfree(pinfo);
  701.         return BAILOUT;
  702.     }
  703.  
  704.     } else {
  705.         /* ??
  706.         if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) {
  707.             nopart[NOSCHPOK].ob_state = NORMAL;
  708.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  709.             execform(nopart);
  710.             return ERROR;
  711.         }
  712.         */
  713.         npart = 4;
  714.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  715.         dev = xdev;
  716.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  717.             err(nomemory);
  718.             if (pinfo > 0)    Mfree(pinfo);
  719.             return ERROR;
  720.         }
  721.         inipart(pinfo, npart);
  722.         npart = 0;
  723.         setpart(pinfo, pnam, hsize);
  724.         /* ??
  725.         if (ttscsi)        {     SCSI bus drive 
  726.             setpart(pinfo, hsize);
  727.         } else {             regular drvie 
  728.             for (i = 0; i < 4; ++i)
  729.                 fillpart(i, &pinfo[i]);
  730.         }
  731.         */
  732.     }
  733.  
  734.     /* For REAL!! */
  735.     dsplymsg(partmsg);
  736.     
  737.     bsl = 0L;
  738.     
  739.     /* Get size of BSL */
  740.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  741.         /* Allocate memory for existing BSL */
  742.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  743.             ret = err(nomemory);
  744.             goto partend;
  745.         }
  746.             
  747.         /* Read in BSL */
  748.         if ((ret = rdbsl(dev)) != OK) {
  749.             if (ret == INVALID)
  750.                 err(cruptbsl);
  751.             ret = ERROR;
  752.             goto partend;
  753.         }
  754.     } else if (bslsiz == 0) {
  755.         ret = err(oldfmt);
  756.         goto partend;
  757.     } else if (bslsiz == ERROR) {
  758.         ret = err(rootread);
  759.         goto partend;
  760.     } else {
  761.         ret = ERROR;
  762.         goto partend;
  763.     }
  764.  
  765.     
  766.     /* Lay out partition headers */
  767.     if (spheader(dev, &pinfo[0]) != OK) {
  768.         ret = ERROR;
  769.         goto partend;
  770.     }
  771.     
  772.     if (wrbsl(dev) != OK) {        /* write BSL */
  773.         ret = ERROR;
  774.         goto partend;
  775.     }
  776.  
  777.     /* check and change the structure's id after 'spheader()' */
  778.     changeid(pinfo);
  779.  
  780.     /* Shove partition parms into root sector */
  781.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  782.         if (tsterr(ret) != OK)
  783.             err(rootread);
  784.         ret = ERROR;
  785.         goto partend;
  786.     }
  787.  
  788.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  789.         goto partend;
  790.     }
  791.     tem1 = npart;            /* save the number of partitions */
  792.     tem2 = ext;                /* save the index of extended partition */
  793.     if (rescan(1,0)) {        /* has to be here because map changed    */
  794.         ret = ERROR;        /* after partitions are moved around,    */
  795.         goto partend;        /* report medium change error.        */
  796.     }
  797.     npart = tem1;
  798.     ext = tem2;
  799.     /* Partition the device with parameters given in pinfo */
  800.     if (stlaybs(dev, &pinfo[0]) != OK)
  801.         ret = ERROR;
  802.     else
  803.         ret = OK;
  804.         
  805.     rebootp = 1;
  806.     pnf = 1;        /* set the flag to just doing the partition */
  807. partend:
  808.     if (bsl > 0) free(bsl);
  809.     inipart(pinfo, npart);
  810.     if (pinfo > 0)    Mfree(pinfo);
  811.     erasemsg();
  812.     return (ret);
  813. }
  814.  
  815.  
  816. /*
  817.  * get root sector informations and write them into that sector 
  818.  */
  819.  
  820. stlayroot(bs, dev, part)
  821. char *bs;
  822. int dev;
  823. PART *part;
  824. {
  825.     int i;
  826.     UWORD sum = 0x1234;
  827.     long cnt, disksiz, prvst;
  828.     char *d, *s;
  829.     extern char bootstop;
  830.     extern char bootend;
  831.  
  832.     /* do the prime partition */
  833.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  834.     /*
  835.       sfmtparm(bs, &hinfo);
  836.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  837.         *d++ = *s++;
  838.     */
  839.     sbslparm(bs);                /* set bsl parameters */
  840.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  841.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  842.         if (tsterr(ret) != OK)
  843.             err(rootwrit);
  844.         return(ERROR);
  845.     }
  846.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  847.     /* do the extended partitions */
  848.     extsiz = part[ext].p_siz;
  849.     for (i = 4; i < npart; i++)    {
  850.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  851.             return OK;
  852.         }
  853.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  854.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  855.             if (tsterr(ret) != OK)
  856.                 err(rootwrit);
  857.             return(ERROR);
  858.         }
  859.     }
  860.     return OK;
  861. }
  862.  
  863.  
  864.  
  865.  
  866. /*
  867.  * Put information into the root structure
  868.  */
  869.  
  870. spart(image, pinfo, pnm, prvst)
  871.  
  872. char *image;            /* root sector buffer */
  873. register PART *pinfo;    /* partition information */
  874. int pnm;                /* partition number */
  875. long *prvst;            /* The previous partition start sector */
  876.  
  877. {
  878.     PART *rpart;
  879.     long numcyl;
  880.     int i, j;
  881.  
  882.     if (pnm)     {
  883.         fillbuf(image, 512L, 0L);
  884.     }
  885.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  886.     if (pnm < 4)    {
  887.         for (i = 0; i < NPARTS; i++, rpart++)    {
  888.             if (pinfo->p_flg & P_EXISTS)    {
  889.                 rpart->p_flg = P_EXISTS;
  890.                 for (j = 0; j < 3; j++)
  891.                     rpart->p_id[j] = pinfo->p_id[j];
  892.                 rpart->p_st = pinfo->p_st;
  893.                 rpart->p_siz = pinfo->p_siz;
  894.             } else {
  895.                 rpart->p_flg = 0;
  896.                 for (j = 0; j < 3; j++)
  897.                     rpart->p_id[j] = 0;
  898.                 rpart->p_st = 0L;
  899.                 rpart->p_siz = 0L;
  900.             }
  901.             pinfo++;
  902.         }
  903.  
  904.     } else {    /* pnm => 4 */
  905.         rpart->p_flg = pinfo[pnm].p_flg;
  906.         for (j = 0; j < 3; j++)
  907.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  908.         rpart->p_st = ROOTSECT;
  909.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  910.         rpart++;
  911.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  912.             /* need extened partition */
  913.             rpart->p_flg = P_EXISTS;
  914.             rpart->p_id[0] = 'X';
  915.             rpart->p_id[1] = 'G';
  916.             rpart->p_id[2] = 'M';
  917.             rpart->p_siz = pinfo[pnm+1].p_siz;
  918.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  919.                                     (pinfo[pnm].p_siz + *prvst);
  920.             *prvst = rpart->p_st;
  921.         }
  922.  
  923.     }
  924. }
  925.  
  926.  
  927.  
  928. /*
  929.  * Setup partitions on the disk;
  930.  * write boot sectors and zero FATs and root directories.
  931.  *
  932.  */
  933. stlaybs(physdev, pinfo)
  934. int physdev;
  935. register PART *pinfo;
  936. {
  937.     int i, ldev, ret;
  938.     int kindfat;
  939.     SECTOR data, nsect;
  940.     char *devno="X";
  941.     long ndirs;
  942.     UWORD fatsiz;
  943.     BOOT *bs;
  944.     long serialno;
  945.     extern long longrandom();
  946.     extern long cell();
  947.     char *buf;
  948.     long size;
  949.  
  950.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  951.         if (bslsiz == ERROR)
  952.             err(rootread);
  953.         return ERROR;
  954.     }
  955.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  956.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  957.  
  958.     for (i = 0; i < npart; ++i, ++pinfo) {
  959.         
  960.         /* don't care if partition does not exist */
  961.         if (!(pinfo->p_flg & P_EXISTS)) {
  962.             return OK;
  963.         }
  964.  
  965.  
  966.     /*
  967.      * Compute boot sector parameters.
  968.      */
  969.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  970.             *devno = i + '0';
  971.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  972.             part2big[BGPARTOK].ob_state = NORMAL;
  973.             execform(part2big);
  974.             return ERROR;
  975.         }
  976.  
  977.     /* estimat the bps */
  978.     /* MAXSECT = 16MB - 8 */
  979.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  980.  
  981.     /* the real bps */
  982.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  983.     ratio = bps / BPS;
  984.     nsect = pinfo->p_siz / ratio;
  985.  
  986.     size = (long)BPS * ratio;
  987.     if ((buf = (char *)Malloc(size)) <= 0)    {
  988.         err(nomemory);
  989.         if (buf > 0) Mfree((long)buf);
  990.         return ERROR;
  991.     }
  992.  
  993.     /*
  994.      * Install entries in boot sector image;
  995.      * force sector checksum to zero (non-executable);
  996.      * write boot sector to media.
  997.      *
  998.       *    512 bytes/sector
  999.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  1000.      *    1 reserved sector (for boot)
  1001.      *    2 FATs
  1002.      *    ... dir slots
  1003.      *    ... # sectors
  1004.      *    F8 means media is a hard disk
  1005.      *    ... FAT size
  1006.      *
  1007.      */
  1008.      
  1009.     /* Make a clean boot sector */
  1010.     fillbuf(buf, bps, 0L);
  1011.     bs = (BOOT *)buf;
  1012.         
  1013.  
  1014.     /* bytes per sector */
  1015.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  1016.     
  1017.     /* sectors per cluster */
  1018.     bs->b_spc = SPC;
  1019.         
  1020.     /* number of reserved sectors */
  1021.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  1022.     
  1023.     /* number of FATs */
  1024.     bs->b_nfats = 2;
  1025.     
  1026.  
  1027.     /*
  1028.      * Compute root directory size
  1029.      * 256 entries, plus fudge on devs > 10Mb
  1030.      */
  1031.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  1032.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  1033.     /* round to nearest sector */
  1034.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  1035.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  1036.     
  1037.     /* number of sectors on media (partition) */
  1038.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  1039.  
  1040.     /* media descriptor */
  1041.     bs->b_media = 0xf8;
  1042.  
  1043.     /*--------------------------------------------------------------*
  1044.      * Compute FAT size                        *
  1045.      *                                *
  1046.      * Num entries to map the entire partition            *
  1047.      *    = partition's size in clusters                *
  1048.      *    = partition's size in sectors / spc            *
  1049.      *                                *
  1050.      * Num entries in FAT                        *
  1051.      *    = Num entries to map partition + reserved entries    *
  1052.      *    = (partition's size in sectors / spc) + 2        *
  1053.      *                                *
  1054.      * Num sectors FAT occupies                    *
  1055.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1056.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  1057.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  1058.      *                        <+1 to round up>    *
  1059.      *--------------------------------------------------------------*/
  1060.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  1061.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  1062.  
  1063.     /* write the serial number to the bs */ 
  1064.     Protobt(bs, 0x01000000, -1, -1);
  1065.  
  1066.     /*
  1067.      * Write partition's boot sector
  1068.      */
  1069.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1070.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1071.         if (tsterr(ret) != OK)
  1072.             err(bootwrit);
  1073.         return ERROR;
  1074.     }
  1075.  
  1076.     /*
  1077.      * Zero the partition
  1078.      */
  1079.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1080.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1081.         if (tsterr(ret) != OK)
  1082.             err(hdrwrite);
  1083.         return ERROR;
  1084.     }
  1085.              
  1086.     /*
  1087.      * Make first 2 entries in FATs more IBM-like.
  1088.      */
  1089.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1090.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1091.         if (tsterr(ret) != OK)
  1092.             err(fatread);
  1093.         return ERROR;
  1094.     }
  1095.     *(UWORD *)&buf[0] = 0xf8ff;
  1096.     *(UWORD *)&buf[2] = 0xffff;
  1097.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1098.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1099.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1100.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1101.         != 0) {
  1102.         if (tsterr(ret) != OK)
  1103.             err(fatwrite);
  1104.         return ERROR;
  1105.     }
  1106.  
  1107.     /*
  1108.      * Mark bad sectors recorded in the BSL into the FATs.
  1109.      * Calculating parameters:
  1110.      *    ldev - from physdev and i.
  1111.      *    fat0 - always equals 1.
  1112.      *    fatsiz - calculated above.
  1113.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1114.      */
  1115.  
  1116.         if (bslsiz > 0) {
  1117.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1118.                 return parterr(physdev);
  1119.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1120.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1121.                                                 data*ratio, MEDIA);
  1122.         }
  1123.         if (buf > 0) Mfree((long)buf);
  1124.     }
  1125.     return OK;
  1126. }
  1127.  
  1128.  
  1129.  
  1130.  
  1131. /*
  1132.  * Handle [ZERO] item.
  1133.  *
  1134.  */
  1135. dodizero()
  1136. {
  1137.     int ldev, ret;
  1138.     char *seldev = "X";
  1139.     int i; 
  1140.  
  1141.     zwarning[ZWOK].ob_state = NORMAL;
  1142.     zwarning[ZWCN].ob_state = NORMAL;
  1143.     if (execform(zwarning) != ZWOK)
  1144.     return BAILOUT;
  1145.     if (showmany)    err(manyldev);
  1146.  
  1147.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1148.  
  1149.     /* Find out if logical device has assumed parameters */
  1150.     if (chkparm(ldev) != OK) {
  1151.         wronparm[WRONOK].ob_state = NORMAL;
  1152.     execform(wronparm);
  1153.     return ERROR;
  1154.     }
  1155.         
  1156.     *seldev = ldev;
  1157.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1158.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1159.     zerofnl[ZYES].ob_state = NORMAL;
  1160.     zerofnl[ZNO].ob_state = NORMAL;
  1161.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1162.  
  1163.     dsplymsg(zeromsg);
  1164.     if (zero(ldev) == OK) {
  1165.     if (!rebootp) {
  1166.         for (i = 0; i < 10; i++) {
  1167.         if (!mediach(ldev-'A')) break;
  1168.         }
  1169.         if (i == 10) {
  1170.             rebootp = 1;
  1171.         err(mdach);
  1172.             }
  1173.     }
  1174.     }
  1175.     erasemsg();
  1176. }
  1177.  
  1178.  
  1179. /*
  1180.  * Handle [MARKBAD] item.
  1181.  *
  1182.  */
  1183. dodimark()
  1184. {
  1185.     int ldev, ret;
  1186.     int i;
  1187.  
  1188.     mwarning[MWARNOK].ob_state = NORMAL;
  1189.     mwarning[MWARNCN].ob_state = NORMAL;
  1190.     if (execform(mwarning) == MWARNCN)
  1191.         return BAILOUT;
  1192.     if (showmany)    err(manyldev);
  1193.  
  1194.     if ((ldev = glogdev()) < 0)
  1195.         return BAILOUT;
  1196.         
  1197.     /* Find out if logical device has assumed parameters */
  1198.     if (chkparm(ldev) != OK) {
  1199.         wronparm[WRONOK].ob_state = NORMAL;
  1200.     execform(wronparm);
  1201.     return ERROR;
  1202.     }
  1203.          
  1204.     dsplymsg(lmrkmsg);
  1205.     if (markbad(ldev) != OK) {
  1206.         erasemsg();
  1207.     } else {
  1208.         if (!rebootp) {
  1209.         for (i = 0; i < 10; i++) {
  1210.         if (!mediach(ldev-'A')) break;
  1211.         }
  1212.         if (i == 10) {
  1213.             rebootp = 1;
  1214.         err(mdach);
  1215.             }
  1216.         }
  1217.     }
  1218. }
  1219.  
  1220.  
  1221. /*
  1222.  * Map from button in ship dial.
  1223.  */
  1224. int sdev[] = {
  1225.     SDEV0, SDEV1, SDEV2, SDEV3,
  1226.     SDEV4, SDEV5, SDEV6, SDEV7
  1227. };
  1228.  
  1229. /*
  1230.  * Ship selected devices.
  1231.  */
  1232. dodiship()
  1233. {
  1234.   int i, seldev[16], selected=0;
  1235.   int j, endup, index, doscsi;
  1236.   
  1237.     /* Set up the dialog box for SCSI or ACSI driver selection */
  1238.     typedial[TYPEOK].ob_state = NORMAL;
  1239.     typedial[TYPECN].ob_state = NORMAL;
  1240.     typedial[SCSIYES].ob_state = NORMAL;
  1241.     typedial[ACSIYES].ob_state = NORMAL;
  1242.     if (execform(typedial) != TYPEOK)
  1243.         return ERROR;
  1244.     /* check which type of unit was selected */
  1245.     if (typedial[SCSIYES].ob_state & SELECTED)    {
  1246.         doscsi = 1;
  1247.         index = 8;
  1248.     } else if (typedial[ACSIYES].ob_state & SELECTED)    {
  1249.         doscsi = 0;
  1250.         index = 0;
  1251.     } else {
  1252.         return ERROR;
  1253.     }
  1254.     
  1255.   /* Throw up generic shipping warning. */
  1256.   shipdial[SWARNCN].ob_state = NORMAL;
  1257.   shipdial[SWARNOK].ob_state = NORMAL;
  1258.   if (execform(shipdial) != SWARNOK) return BAILOUT;
  1259.   
  1260.   /* Device(s) selected? */
  1261.   shipdev[SDEVOK].ob_state = NORMAL;
  1262.   shipdev[SDEVCN].ob_state = NORMAL;
  1263.   for(i = 0; i < 8; i++)     /* indicate what's alive */
  1264.         shipdev[sdev[i]].ob_state = DISABLED;
  1265.   endup = index + 8;
  1266.   for(i = index, j = 0; i < endup; i++, j++)     /* indicate what's alive */
  1267.         if (livedevs[i])
  1268.             shipdev[sdev[j]].ob_state = NORMAL | SHADOWED;
  1269.   
  1270.   if (execform(shipdev) != SDEVOK)
  1271.       return BAILOUT;
  1272.       
  1273.   for(i = 0; i < 8; i++) {    /* search for selected unit */
  1274.       if (shipdev[sdev[i]].ob_state & SELECTED) {
  1275.           seldev[i+index] = 1;
  1276.           selected++;
  1277.       } else {
  1278.             seldev[i+index] = 0;
  1279.       }
  1280.   }
  1281.   
  1282.   if (!selected) return BAILOUT;    /* nothing is selected */
  1283.   
  1284.   /* Throw up final shipping warning. */
  1285.   shipfnl[SFNLCN].ob_state = NORMAL;
  1286.   shipfnl[SFNLOK].ob_state = NORMAL;
  1287.   if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1288.   
  1289.   /* For REAL!!! */
  1290.   /* Ship selected devices */
  1291.   for (i = 0; i < MAXPHYSDEV; i++) {
  1292.       if (seldev[i])
  1293.           ship(i);
  1294.   }
  1295.   
  1296.   /* Put out final message about turning off hard disks */
  1297.   scommand[TRNOFFOK].ob_state = NORMAL;
  1298.   execform(scommand);
  1299. }
  1300.  
  1301.  
  1302.  
  1303. /*
  1304.  * Translate unit number to tree index.
  1305.  *
  1306.  */
  1307. static int physxlat[] = {
  1308.     UNIT0, UNIT1, UNIT2, UNIT3,
  1309.     UNIT4, UNIT5, UNIT6, UNIT7
  1310. };
  1311.  
  1312.  
  1313. /*
  1314.  * Get physical device#,
  1315.  * return devno or -1.
  1316.  *
  1317.  */
  1318. gphysdev()
  1319. {
  1320.     int i, j, endup, start, index, doscsi;
  1321.  
  1322.     /* Set up the dialog box for SCSI or ACSI driver selection */
  1323. redoghy:
  1324.     typedial[TYPEOK].ob_state = NORMAL;
  1325.     typedial[TYPECN].ob_state = NORMAL;
  1326.     typedial[SCSIYES].ob_state = NORMAL;
  1327.     typedial[ACSIYES].ob_state = NORMAL;
  1328.     if (execform(typedial) != TYPEOK)
  1329.         return ERROR;
  1330.     /* check which type of unit was selected */
  1331.     if (typedial[SCSIYES].ob_state & SELECTED)    {
  1332.         doscsi = 1;
  1333.         index = 8;
  1334.     } else if (typedial[ACSIYES].ob_state & SELECTED)    {
  1335.         doscsi = 0;
  1336.         index = 0;
  1337.     } else {
  1338.         return ERROR;
  1339.     }
  1340.     /*
  1341.      * Clean up and exec object;
  1342.      * shadow devs we KNOW are there.
  1343.      */
  1344.     physdial[PHYSOK].ob_state = NORMAL;
  1345.     physdial[PHYSCN].ob_state = NORMAL;
  1346.     
  1347.     if (tformat == TRUE) {
  1348.         start = 1;        /* start initializing at unit 0 */
  1349.         physdial[physxlat[0]].ob_state = NORMAL;
  1350.     } else {
  1351.         start = 0;        /* start initializing at unit 1 */
  1352.     }
  1353.     
  1354.     for (i = start; i < 8; ++i)
  1355.         physdial[physxlat[i]].ob_state = DISABLED;
  1356.     /*
  1357.     if (ttscsi)             the hard drive is a SCSI drive 
  1358.         physdial[physxlat[8]].ob_state = NORMAL;
  1359.     */
  1360.     endup = index + 8;
  1361.     for (i = index, j = 0; i < endup; ++i, j++)
  1362.         if (livedevs[i])
  1363.             physdial[physxlat[j]].ob_state = NORMAL | SHADOWED;
  1364.  
  1365.     if (execform(physdial) != PHYSOK)
  1366.         return ERROR;
  1367.      
  1368.     /* search for the selected unit */
  1369.     for (i = 0; i < 8; ++i)
  1370.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1371.             if (livedevs[index+i])
  1372.                 return(index+i);
  1373.             else    {    
  1374.                 form_alart(1, nodev);
  1375.                 goto redogphy;
  1376.             }
  1377.         }
  1378.  
  1379.  
  1380.     return ERROR;            /* if no object selected */
  1381. }
  1382.  
  1383.  
  1384. /*
  1385.  * Translate from logical device number
  1386.  * to object number in logical device
  1387.  * dialouge box.
  1388.  */
  1389. int logxlat[] = {
  1390.     CCOLON, DCOLON, ECOLON, FCOLON,
  1391.     GCOLON, HCOLON, ICOLON, JCOLON,
  1392.     KCOLON, LCOLON, MCOLON, NCOLON,
  1393.     OCOLON, PCOLON
  1394. };
  1395.  
  1396.  
  1397. /*
  1398.  * Get logical device,
  1399.  * return 'C'...'P'
  1400.  * or -1.
  1401.  *
  1402.  */
  1403. glogdev()
  1404. {
  1405.     int i, flg;
  1406.  
  1407.     /*
  1408.      * Setup tree; selectively enable drive buttons
  1409.      * and so on.
  1410.      */
  1411.     logdial[LOGOK].ob_state = NORMAL;
  1412.     logdial[LOGCN].ob_state = NORMAL;
  1413.     for (i = 0; i < MAXLOGDEVS; ++i) {
  1414.     if (logmap[i].lm_physdev < 0)
  1415.         flg = DISABLED;
  1416.         else flg = NORMAL;
  1417.     logdial[logxlat[i]].ob_state = flg;
  1418.     }
  1419.  
  1420.     if (execform(logdial) != LOGOK) return -1;
  1421.  
  1422.     for (i = 0; i < MAXLOGDEVS; ++i)
  1423.     if (logdial[logxlat[i]].ob_state & SELECTED)
  1424.         return i + 'C';
  1425.  
  1426.     return -1;
  1427. }
  1428.  
  1429.  
  1430. /*
  1431.  * Open virtual workstation.
  1432.  *
  1433.  */
  1434. open_vwork()
  1435. {
  1436.     int i;
  1437.  
  1438.     for (i = 0; i < 10;)
  1439.     work_in[i++] = 1;
  1440.     work_in[10] = 2;
  1441.     handle = phys_handle;
  1442.     v_opnvwk(work_in, &handle, work_out);
  1443. }
  1444.  
  1445.  
  1446. /*
  1447.  * Find and redraw all clipping rectangles
  1448.  *
  1449.  */
  1450. do_redraw(xc, yc, wc, hc)
  1451. int xc, yc, wc, hc;
  1452. {
  1453.     GRECT t1, t2;
  1454.     int temp[4];
  1455.  
  1456.     hide_mouse();
  1457.     t2.g_x=xc;
  1458.     t2.g_y=yc;
  1459.     t2.g_w=wc;
  1460.     t2.g_h=hc;
  1461.     vsf_interior(handle, 1);
  1462.     vsf_color(handle, 0);
  1463.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1464.     while (t1.g_w && t1.g_h) {
  1465.     if (rc_intersect(&t2, &t1)) {
  1466.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  1467.         temp[0] = xwork;
  1468.         temp[1] = ywork;
  1469.         temp[2] = xwork + wwork - 1;
  1470.         temp[3] = ywork + hwork - 1;
  1471.         v_bar(handle, temp);
  1472.     }
  1473.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1474.     }
  1475.  
  1476.     show_mouse();
  1477. }
  1478.  
  1479.  
  1480. /*
  1481.  * Hide the mouse.
  1482.  *
  1483.  */
  1484. hide_mouse()
  1485. {
  1486.     if (!hidden) {
  1487.     graf_mouse(M_OFF, 0L);
  1488.     hidden = TRUE;
  1489.     }
  1490. }
  1491.  
  1492.  
  1493. /*
  1494.  * Show the mouse.
  1495.  *
  1496.  */
  1497. show_mouse() 
  1498. {
  1499.     if (hidden) {
  1500.     graf_mouse(M_ON, 0L);
  1501.     hidden = FALSE;
  1502.     }
  1503. }
  1504.  
  1505.  
  1506. /*
  1507.  * Set clipping rectangle.
  1508.  *
  1509.  */
  1510. set_clip(x, y, w, h)
  1511. int x, y, w, h;
  1512. {
  1513.     int clip[4];
  1514.  
  1515.     clip[0] = x;
  1516.     clip[1] = y;
  1517.     clip[2] = x + w;
  1518.     clip[3] = y + h;
  1519.     vs_clip(handle, 1, clip);
  1520. }
  1521.  
  1522.  
  1523. /*
  1524.  * "Execute" form,
  1525.  * return thingy that caused the exit.
  1526.  *
  1527.  */
  1528. execform(tree)
  1529. OBJECT tree[];
  1530. {
  1531.     int thingy;
  1532.  
  1533.     ARROW_MOUSE;
  1534.     dsplymsg(tree);
  1535.     thingy = form_do(tree, 0);
  1536.     erasemsg();
  1537.     BEE_MOUSE;
  1538.     return thingy;
  1539. }
  1540.  
  1541.  
  1542. /*
  1543.  *  Display a dialogue box on the screen.
  1544.  *    Input:
  1545.  *        tree - object tree for dialogue box to be displayed.
  1546.  *    Output:
  1547.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1548.  */
  1549. dsplymsg(tree)
  1550. OBJECT *tree;
  1551. {
  1552.     form_center(tree,&lx, &ly, &formw, &formh);
  1553.  
  1554.     /*
  1555.     sx = lx + formw / 2;
  1556.     sy = ly + formh / 2;
  1557.     */
  1558.     
  1559.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1560.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1561. }
  1562.  
  1563.  
  1564. /*
  1565.  *  Erase a dialogue box from the screen.
  1566.  *    Input:
  1567.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1568.  */
  1569. erasemsg()
  1570. {
  1571.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1572. }
  1573.  
  1574.  
  1575.  
  1576. /*
  1577.  *  Make a long (4-byte) random.
  1578.  */ 
  1579. long
  1580. longrandom()
  1581. {
  1582.     long pattern;
  1583.     
  1584.     pattern = Random();
  1585.     pattern <<= 16;
  1586.     pattern ^= Random();
  1587.     
  1588.     return (pattern);
  1589. }
  1590.  
  1591. changeid(part)
  1592. PART *part;
  1593. {
  1594.     int i;
  1595.     long psiz;
  1596.  
  1597.     for(i = 0; i < npart; i++)    {
  1598.         if (i == ext)    continue;
  1599.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  1600.         if (i > 3)    {
  1601.             psiz = part[i].p_siz - ROOTSECT;
  1602.         } else {
  1603.             psiz = part[i].p_siz;
  1604.         }
  1605.         if (psiz < MB16)    {
  1606.             part[i].p_id[0] = 'G';
  1607.             part[i].p_id[1] = 'E';
  1608.             part[i].p_id[2] = 'M';
  1609.         } else {
  1610.             part[i].p_id[0] = 'B';
  1611.             part[i].p_id[1] = 'G';
  1612.             part[i].p_id[2] = 'M';
  1613.         }
  1614.     }
  1615. }
  1616.  
  1617.