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