home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / dsksl096.zip / dsl.c < prev    next >
C/C++ Source or Header  |  1997-11-08  |  17KB  |  773 lines

  1. /*
  2.  * $Source: E:/source/driver/sleep/RCS/dsl.c,v $
  3.  * $Revision: 1.7 $
  4.  * $Date: 1997/09/03 01:29:11 $
  5.  * $Author: vitus $
  6.  *
  7.  * Displays and/or modifies device sleeping timers.  Sample
  8.  * application.
  9.  * Compile with...
  10.  * IBM CSet++ 2.1    - icc -Q -W2all -O [-Gd] dsl.c
  11.  * IBM VAC++ 3.00    - icc -Q -W2all -O [-Gd] dsl.c
  12.  * GNU C 2.7.*        - gcc -Wall -O3 [-Zcrtdll] dsl.c
  13.  * WatCom C/C++ 10.5    - wcl386 -zq -bt=os2v2 -3s -wx -oax dsl.c
  14.  *
  15.  * $Log: dsl.c,v $
  16.  * Revision 1.7  1997/09/03 01:29:11  vitus
  17.  * added -l parameter
  18.  * added DisplayLaststatus (if -l)
  19.  *
  20.  * Revision 1.6  1997/06/03 23:28:24  vitus
  21.  * - expanded '-?' output
  22.  *
  23.  * Revision 1.5  1997/05/07 23:53:27  vitus
  24.  * Tests both forms of version query
  25.  * Calls READ_MSGS to get size of required buffer
  26.  *
  27.  * Revision 1.4  1997/04/07 03:35:03  vitus
  28.  * Changed program options
  29.  * Added possibility to change/display timeout counter
  30.  *
  31.  * Revision 1.3  1997/04/05 01:50:24  vitus
  32.  * DisplayVersion shows registered-flag
  33.  * Test: display datasize before/after call
  34.  *
  35.  * Revision 1.2  1997/03/05 21:58:26  vitus
  36.  * Changed for new timeout in seconds
  37.  * Added mode to display saved messages
  38.  *
  39.  * Revision 1.1  1997/02/06 01:25:42  vitus
  40.  * Initial revision
  41.  */
  42. static char const id[]="$Id: dsl.c,v 1.7 1997/09/03 01:29:11 vitus Exp $";
  43.  
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47.  
  48. #define INCL_DOS
  49. #include <os2.h>
  50.  
  51. #include "dskslpub.h"
  52.  
  53.  
  54.  
  55.  
  56. #define DEVICENAME    "dsleeps$"        /* DSKSLEEP.FLT is actual... */
  57.  
  58. #define MODE_DISPLAY    0
  59. #define MODE_CHANGE    1
  60. #define MODE_MESSAGE    2
  61. #define MODE_QUERY    3
  62. #define MODE_IMMEDIATE    4
  63. #define MODE_LASTSTATUS    5
  64.  
  65.  
  66. /*
  67.  * Global variables
  68.  */
  69. char    szPrgName[_MAX_PATH];
  70. char    fVerbose = 0;
  71. char    fMode = MODE_DISPLAY;
  72.  
  73.  
  74. void
  75. usage(void)
  76. {
  77.     printf("usage: %s [-?] [-m | -l | -q | {-c|-i} a1,d1,t1 [a2,d2,t2 ...]]\n", szPrgName);
  78. }
  79. void
  80. help(void)
  81. {
  82.     usage();
  83.     printf("\nDisplays and/or changes sleeping times/timers\n"
  84.        " -m\tdisplay saved messages\n"
  85.        " -l\tdisplay last status\n" 
  86.        " -c\tpermanent change of disk timeout (minutes)\n"
  87.        " -q\tdisplay *seconds* left until disk stops\n"
  88.        " -i\tchange *seconds* left until disk stops\n"
  89.        " -?\tthis text\n\n"
  90.        " a,d,t\ta value ('t' minutes or seconds) for disk 'd' on adapter 'a'\n"
  91.        "Examples:\n"
  92.        " 'dsl'\t\t\tdisplay current timeout values\n"
  93.        " 'dsl -c 1,0,10'\tchange timeout for first disk on second adapter\n\t\t\tto 10 minutes\n"
  94.        " 'dsl -c 0,0,0'\t\tchange timeout for first disk on first adapter\n\t\t\tto 0 minutes (never stop that disk)\n"
  95.        " 'dsl -i 1,1,0'\t\tset timer for second disk on second adapter\n\t\t\tto 0 seconds (immediately stop that disk)\n"
  96.        "\nRemember that any access to a disk will reset it's timer value.  So '-i'\nmight not work for you.\n");
  97. }
  98.  
  99.  
  100.  
  101.  
  102. void
  103. DumpBuffer(PUCHAR buf,size_t siz)
  104. {
  105.     for(; siz; --siz, ++buf )
  106.     printf(" %02x", *buf);
  107. }
  108.  
  109.  
  110.  
  111.  
  112. /*#
  113.  * NAME
  114.  *    DisplayVersion
  115.  * CALL
  116.  *    DisplayVersion(hd)
  117.  * PARAMETER
  118.  *    hd        handle to open device
  119.  * RETURNS
  120.  *    OS error code
  121.  * GLOBAL
  122.  *    none
  123.  * DESPRIPTION
  124.  *    Displays driver version.
  125.  * REMARKS
  126.  */
  127. int
  128. DisplayVersion(HFILE hd)
  129. {
  130.     APIRET        rc;
  131.     DSKSL_VER_DATA    data;
  132.     ULONG        datasize;
  133.  
  134.  
  135.     /* Issue IOCtl in two fashions
  136.      * - 16bit data: only version
  137.      * - DSKSL_VER_DATA: registered info, too */
  138.  
  139.     do
  140.     {
  141.     datasize = sizeof(data.version);
  142.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_VERSION,
  143.              NULL, 0, NULL, &data.version, datasize, &datasize);
  144.     if( rc )
  145.     {
  146.         fprintf(stderr, "DSKSL_QUERY_VERSION - error %lu\n", rc);
  147.         break;
  148.     }
  149.     printf("Installed: DSKSLEEP.FLT %u.%02u\n",
  150.            HIBYTE(data.version), LOBYTE(data.version));
  151.  
  152.     datasize = sizeof(data);
  153.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_VERSION,
  154.              NULL, 0, NULL, &data, datasize, &datasize);
  155.     if( rc )
  156.     {
  157.         fprintf(stderr, "DSKSL_QUERY_VERSION - error %lu\n", rc);
  158.         break;
  159.     }
  160.  
  161.     printf("Installed: DSKSLEEP.FLT %u.%02u (%s)\n",
  162.            HIBYTE(data.version), LOBYTE(data.version),
  163.            (data.flags&0x01 ? "registered" : "unregistered"));
  164.     }
  165.     while( 0 );
  166.  
  167.     return (int)rc;
  168. }
  169.  
  170.  
  171.  
  172.  
  173. /*#
  174.  * NAME
  175.  *    DisplayMessages
  176.  * CALL
  177.  *    DisplayMessages(hd)
  178.  * PARAMETER
  179.  *    hd        handle to open device
  180.  * RETURNS
  181.  *    OS error code
  182.  * GLOBAL
  183.  *    none
  184.  * DESPRIPTION
  185.  *    Displays messages saved during driver startup.
  186.  * REMARKS
  187.  */
  188. int
  189. DisplayMessages(HFILE hd)
  190. {
  191.     APIRET    rc;
  192.     USHORT    cb = 0;                /* keep compiler happy */
  193.     unsigned    i;
  194.     ULONG    datasize;
  195.     DSKSL_MSGS_DATA * data = NULL;
  196.  
  197.     do
  198.     {
  199.     /* First: read size of stored messages */
  200.  
  201.     datasize = sizeof(cb);
  202.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_READ_MSGS,
  203.              NULL, 0, NULL, &cb, datasize, &datasize);
  204.     if( rc )
  205.     {
  206.         fprintf(stderr, "DSKSL_READ_MSGS - error %lu\n", rc);
  207.         break;
  208.     }
  209.  
  210.     /* Second: allocate buffer big enough to hold
  211.        those messages (but no single byte more) */
  212.  
  213.     datasize = FIELDOFFSET(DSKSL_MSGS_DATA,msg) + (ULONG)cb;
  214.     data = malloc(datasize);
  215.     if( data == NULL )
  216.     {
  217.         fprintf(stderr, "out of memory\n");
  218.         rc = (APIRET)-3;
  219.         break;
  220.     }
  221.  
  222.     /* Third: read and display messages */
  223.  
  224.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_READ_MSGS,
  225.              NULL, 0, NULL, data, datasize, &datasize);
  226.     if( rc )
  227.     {
  228.         fprintf(stderr, "DSKSL_READ_MSGS - error %lu\n", rc);
  229.         break;
  230.     }
  231.  
  232.     printf("------------------------------"
  233.            "------------------------------\n");
  234.     for( i = 0;
  235.         i < data->cb - FIELDOFFSET(DSKSL_MSGS_DATA,msg);
  236.         i += strlen(&data->msg[i])+1 )
  237.     {
  238.         printf("%s\n", &data->msg[i]);
  239.     }
  240.     printf("------------------------------"
  241.            "------------------------------\n");
  242.     }
  243.     while( 0 );
  244.  
  245.     if( data != NULL )
  246.     free(data);
  247.     return (int)rc;
  248. }
  249.  
  250.  
  251.  
  252.  
  253. /*#
  254.  * NAME
  255.  * CALL
  256.  * PARAMETER
  257.  * RETURNS
  258.  * GLOBAL
  259.  * DESPRIPTION
  260.  * REMARKS
  261.  */
  262. int
  263. DisplayLaststatus(HFILE hd,UCHAR a,UCHAR d)
  264. {
  265.     APIRET    rc;
  266.     ULONG        parmsize = sizeof(DSKSL_DEVSTATE_PARM);
  267.     DSKSL_DEVSTATE_PARM    parm;
  268.     ULONG        datasize = sizeof(DSKSL_STATUS_DATA);
  269.     DSKSL_STATUS_DATA    data;
  270.  
  271.     unsigned    i;
  272.     static char    * iotab[] = {"device allocation",
  273.                  "device deallocation",
  274.                  "start",
  275.                  "stop",
  276.                  "verify",
  277.                  "test unit ready"};
  278.  
  279.     parm.adapter = a;
  280.     parm.unit = d;
  281.  
  282.     if( fVerbose )
  283.     {
  284.     printf("parmsize(in) %lu\n", parmsize);
  285.     printf("datasize(in) %lu\n", datasize);
  286.     }
  287.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_GET_LASTSTATUS,
  288.              &parm, parmsize, &parmsize, &data, datasize, &datasize);
  289.     if( fVerbose )
  290.     {
  291.     printf("parmsize(in) %lu\n", parmsize);
  292.     printf("datasize(out) %lu\n", datasize);
  293.     }
  294.  
  295.     if( rc )
  296.     fprintf(stderr, "DSKSL_GET_LASTSTATUS - error %lu\n", rc);
  297.     else
  298.     {
  299.     printf("Last Status refers to %s\n",
  300.            (data.iotype > sizeof(iotab) / sizeof(iotab[0])
  301.         ? "unknown" : iotab[data.iotype]));
  302.     printf("Status %#x, Error %#x\nStatusblock:", data.status, data.error);
  303.     DumpBuffer(data.statusblock, sizeof(data.statusblock));
  304.     printf("\nSensedata:");
  305.     DumpBuffer(data.sensedata, sizeof(data.sensedata));
  306.     printf("\n");
  307.     }
  308.  
  309.     return (int)rc;
  310. }
  311.  
  312.  
  313.  
  314.  
  315. /*#
  316.  * NAME
  317.  *    DisplaySettings
  318.  * CALL
  319.  *    DisplaySettings(hd)
  320.  * PARAMETER
  321.  *    hd        handle to open device
  322.  * RETURNS
  323.  *    OS error code
  324.  * GLOBAL
  325.  *    none
  326.  * DESPRIPTION
  327.  *    Displays all devices and timeout values.
  328.  * REMARKS
  329.  */
  330. int
  331. DisplaySettings(HFILE hd)
  332. {
  333.     APIRET        rc;
  334.     ULONG        datasize = 4 + 40 * sizeof(DEVICE_TIMEOUT);
  335.     PDSKSL_QL_DATA  data = malloc( datasize );
  336.     unsigned        i;
  337.  
  338.     if( data == NULL )
  339.     {
  340.     fprintf(stderr, "out of memory\n");
  341.     return -3;
  342.     }
  343.  
  344.     if( fVerbose )
  345.     printf("datasize(in) %lu\n", datasize);
  346.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_TIMEOUT,
  347.              NULL, 0, NULL, data, datasize, &datasize);
  348.     if( fVerbose )
  349.     printf("datasize(out) %lu\n", datasize);
  350.  
  351.     if( rc )
  352.     fprintf(stderr, "DSKSL_QUERY_TIMEOUT - error %lu\n", rc);
  353.     else
  354.     {
  355.     /* Calculate number of entries. */
  356.  
  357.     unsigned cnt = ((data->cb > datasize ?
  358.             datasize : data->cb)
  359.             - FIELDOFFSET(DSKSL_QL_DATA,list))
  360.              / sizeof(data->list[0]);
  361.  
  362.     /* Display nice table */
  363.  
  364.     printf(" Adapter Unit\tMinutes\n");
  365.     for( i = 0; i < cnt; ++i )
  366.         printf(" %3u\t %3u\t %4lu\n",
  367.            data->list[i].adapter, data->list[i].unit,
  368.            data->list[i].seconds / 60UL );
  369.     }
  370.  
  371.     free( data );
  372.     return (int)rc;
  373. }
  374.  
  375.  
  376.          
  377.  
  378. /*#
  379.  * NAME
  380.  *    ChangeSetting
  381.  * CALL
  382.  *    ChangeSetting(hd,a,d,m)
  383.  * PARAMETER
  384.  *    a        adapter index
  385.  *    d        unit index
  386.  *    m        minutes before sleep (0: never)
  387.  * RETURNS
  388.  *    OS error code
  389.  * GLOBAL
  390.  *    none
  391.  * DESPRIPTION
  392.  *    Changes the timeout value for a single device.
  393.  * REMARKS
  394.  */
  395. int
  396. ChangeSetting(HFILE hd,UCHAR a,UCHAR d,ULONG m)
  397. {
  398.     APIRET        rc;
  399.     ULONG        parmsize = sizeof(DSKSL_SETTO_PARM);
  400.     DSKSL_SETTO_PARM    parm;
  401.  
  402.     if( fVerbose )
  403.     printf("--- new: %u %u %lu\n", a, d, m);
  404.  
  405.     parm.cb = (USHORT)parmsize;
  406.     parm.reserved[0] = parm.reserved[1] = 0;
  407.     parm.list[0].adapter = a;
  408.     parm.list[0].unit = d;
  409.     parm.list[0].seconds = m * 60UL;
  410.     parm.list[0].reserved[0] = parm.list[0].reserved[1] = 0;
  411.  
  412.     if( fVerbose )
  413.     printf("parmsize(in) %lu\n", parmsize);
  414.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_SET_TIMEOUT,
  415.              &parm, parmsize, &parmsize, NULL, 0, NULL);
  416.     if( fVerbose )
  417.     printf("parmsize(out) %lu\n", parmsize);
  418.  
  419.     if( rc )
  420.     fprintf(stderr, "DSKSL_SET_TIMEOUT - error %lu\n", rc);
  421.     return (int)rc;
  422. }
  423.  
  424.  
  425.  
  426.  
  427. /*#
  428.  * NAME
  429.  *    DisplayCurrent
  430.  * CALL
  431.  *    DisplayCurrent(hd)
  432.  * PARAMETER
  433.  *    hd        handle to open device
  434.  * RETURNS
  435.  *    OS error code
  436.  * GLOBAL
  437.  *    none
  438.  * DESPRIPTION
  439.  *    Displays all device timers.
  440.  * REMARKS
  441.  */
  442. int
  443. DisplayCurrent(HFILE hd)
  444. {
  445.     APIRET    rc;
  446.     ULONG    parmsize;
  447.     ULONG    datasize = 4 + 40 * sizeof(DEVICE_TIMEOUT);
  448.     PDSKSL_QL_DATA  data = malloc( datasize );
  449.     unsigned    devcnt;
  450.     unsigned    i;
  451.  
  452.     if( data == NULL )
  453.     {
  454.     fprintf(stderr, "out of memory\n");
  455.     return -3;
  456.     }
  457.  
  458.     do
  459.     {
  460.     if( fVerbose )
  461.         printf("datasize(in) %lu\n", datasize);
  462.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_TIMEOUT,
  463.              NULL, 0, NULL, data, datasize, &datasize);
  464.     if( fVerbose )
  465.         printf("datasize(out) %lu\n", datasize);
  466.  
  467.     if( rc )
  468.     {
  469.         fprintf(stderr, "DSKSL_QUERY_TIMEOUT - error %lu\n", rc);
  470.         break;
  471.     }
  472.  
  473.     /* Calculate number of entries. */
  474.  
  475.     devcnt = ((data->cb > datasize ?
  476.            datasize : data->cb)
  477.           - FIELDOFFSET(DSKSL_QL_DATA,list))
  478.         / sizeof(data->list[0]);
  479.  
  480.     /* Display nice table */
  481.  
  482.     printf(" Adapter Unit\tSeconds\n");
  483.     for( i = 0; i < devcnt; ++i )
  484.     {
  485.         DSKSL_DEVSTATE_PARM    coord;
  486.         DSKSL_DEVSTATE_DATA    current;
  487.  
  488.         coord.adapter = data->list[i].adapter;
  489.         coord.unit = data->list[i].unit;
  490.  
  491.         parmsize = sizeof(coord);
  492.         datasize = sizeof(current);
  493.         if( fVerbose )
  494.         printf("datasize(in) %lu\n", datasize);
  495.         rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_DEVSTATE,
  496.                  &coord, parmsize, &parmsize,
  497.                  ¤t, datasize, &datasize);
  498.         if( fVerbose )
  499.         printf("datasize(out) %lu\n", datasize);
  500.  
  501.         if( rc )
  502.         {
  503.         fprintf(stderr, "DSKSL_QUERY_DEVSTATE - error %lu\n", rc);
  504.         break;
  505.         }
  506.  
  507.         printf(" %3u\t %3u\t %4lu\n",
  508.            coord.adapter, coord.unit, current.seconds);
  509.     }
  510.     }
  511.     while( 0 );
  512.  
  513.     free( data );
  514.     return (int)rc;
  515. }
  516.  
  517.  
  518.  
  519.  
  520. /*#
  521.  * NAME
  522.  *    ChangeCurrent
  523.  * CALL
  524.  *    ChangeCurrent(hd,a,d,s)
  525.  * PARAMETER
  526.  *    a        adapter index
  527.  *    d        unit index
  528.  *    s        seconds before sleep (0: immediate)
  529.  * RETURNS
  530.  *    OS error code
  531.  * GLOBAL
  532.  *    none
  533.  * DESPRIPTION
  534.  *    Changes the current counter for a single device.
  535.  * REMARKS
  536.  */
  537. int
  538. ChangeCurrent(HFILE hd,UCHAR a,UCHAR d,ULONG s)
  539. {
  540.     APIRET        rc;
  541.     ULONG        parmsize = sizeof(DSKSL_DEVSTATE_PARM);
  542.     DSKSL_DEVSTATE_PARM    parm;
  543.     ULONG        datasize = sizeof(DSKSL_DEVSTATE_DATA);
  544.     DSKSL_DEVSTATE_DATA    data;
  545.  
  546.     if( fVerbose )
  547.     printf("--- new: %u %u %lu\n", a, d, s);
  548.  
  549.     parm.adapter = a;
  550.     parm.unit = d;
  551.     data.seconds = s;
  552.  
  553.     if( fVerbose )
  554.     {
  555.     printf("parmsize(in) %lu\n", parmsize);
  556.     printf("datasize(in) %lu\n", datasize);
  557.     }
  558.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_SET_DEVSTATE,
  559.              &parm, parmsize, &parmsize,
  560.              &data, datasize, &datasize);
  561.     if( fVerbose )
  562.     {
  563.     printf("parmsize(in) %lu\n", parmsize);
  564.     printf("datasize(in) %lu\n", datasize);
  565.     }
  566.  
  567.     if( rc )
  568.     fprintf(stderr, "DSKSL_SET_DEVSTATE - error %lu\n", rc);
  569.     return (int)rc;
  570. }
  571.  
  572.  
  573.  
  574.  
  575. /*#
  576.  * NAME
  577.  *    main
  578.  * CALL
  579.  *    main(argc,argv)
  580.  * PARAMETER
  581.  *    argc,argv    as usual
  582.  * RETURNS
  583.  *    0        OK
  584.  *    /0        some error
  585.  * GLOBAL
  586.  *    szPrgName, fVerbose
  587.  * DESPRIPTION
  588.  *    Main routine, parses parameter and calls requested
  589.  *    subfunctions.
  590.  * REMARKS
  591.  */
  592. int
  593. main(int argc,char *argv[])
  594. {
  595.     HFILE    hd = 0;
  596.     ULONG    action_taken;
  597.     APIRET    rc;
  598.     int        result;
  599.  
  600.     strcpy( szPrgName, argv[0] );
  601.     while( argc > 1  &&  argv[1][0] == '-' )
  602.     {
  603.     switch( argv[1][1] )
  604.     {
  605.       case '?':
  606.         help();
  607.         return 0;
  608.  
  609.       case 'v':
  610.         fVerbose = 1;
  611.         break;
  612.  
  613.       case 'm':
  614.         fMode = MODE_MESSAGE;
  615.         break;
  616.  
  617.       case 'l':
  618.         fMode = MODE_LASTSTATUS;
  619.         break;
  620.  
  621.       case 'c':
  622.         fMode = MODE_CHANGE;
  623.         break;
  624.  
  625.       case 'q':
  626.         fMode = MODE_QUERY;
  627.         break;
  628.  
  629.       case 'i':
  630.         fMode = MODE_IMMEDIATE;
  631.         break;
  632.  
  633.       default:
  634.         fprintf(stderr, "%s: unknown arg \"%s\"\n", szPrgName, argv[1]);
  635.         return -1;
  636.     }
  637.     --argc;
  638.     ++argv;
  639.     }
  640.  
  641.     /* Open device driver, no special settings.  Use DENYNONE
  642.      * so other processes (daemon?) may open concurrently. */
  643.  
  644.     rc = DosOpen( DEVICENAME, &hd, &action_taken,
  645.          0, 0,
  646.          OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS,
  647.          OPEN_SHARE_DENYNONE|OPEN_ACCESS_READWRITE,
  648.          NULL );
  649.     if( rc )
  650.     {
  651.     fprintf(stderr, "DosOpen(%s) - error %lu\n", DEVICENAME, rc);
  652.     return (int)rc;
  653.     }
  654.  
  655.     DisplayVersion(hd);                /* always display version */
  656.     switch( fMode )
  657.     {
  658.       case MODE_MESSAGE:
  659.     if( argc != 1 )
  660.     {
  661.         fprintf(stderr, "argument count error\n");
  662.         result = -1;
  663.     }
  664.     else
  665.         result = DisplayMessages(hd);
  666.     break;
  667.  
  668.       case MODE_LASTSTATUS:
  669.     if( argc <= 1 )                /* at least one double */
  670.     {
  671.         fprintf(stderr, "missing device coordinates\n");
  672.         result = -1;
  673.     }
  674.     else
  675.     {
  676.         for(; argc > 1; --argc,++argv )
  677.         {
  678.         unsigned a = 0xFF, d = 0xFF;    /* dsksleep won't find them... */
  679.  
  680.         /* Parse argument (spaces important!) and
  681.          * call ChangeSetting(). */
  682.  
  683.         sscanf(argv[1], "%u ,%u", &a, &d);
  684.         result = DisplayLaststatus(hd, a, d);
  685.         }
  686.     }
  687.     break;
  688.  
  689.       case MODE_DISPLAY:
  690.     if( argc != 1 )
  691.     {
  692.         fprintf(stderr, "argument count error\n");
  693.         result = -1;
  694.     }
  695.     else
  696.     {
  697.         printf("Current settings:\n");
  698.         result = DisplaySettings(hd);
  699.     }
  700.     break;
  701.  
  702.       case MODE_CHANGE:
  703.     printf("Current settings:\n");
  704.     result = DisplaySettings(hd);
  705.     if( result != 0 )
  706.         break;                /* don't change */
  707.     if( argc <= 1 )                /* at least one triple */
  708.     {
  709.         fprintf(stderr, "missing device timeout\n");
  710.         result = -1;
  711.     }
  712.     else
  713.     {
  714.         for(; argc > 1; --argc,++argv )
  715.         {
  716.         unsigned a = 0xFF, d = 0xFF;    /* dsksleep won't find them... */
  717.         ULONG     m = 0;
  718.  
  719.         /* Parse argument (spaces important!) and
  720.          * call ChangeSetting(). */
  721.  
  722.         sscanf(argv[1], "%u ,%u ,%lu", &a, &d, &m);
  723.         result = ChangeSetting(hd, (UCHAR)a, (UCHAR)d, m);
  724.         }
  725.         printf("After changing:\n");
  726.         DisplaySettings(hd);        /* ignore errors */
  727.     }
  728.     break;
  729.  
  730.       case MODE_QUERY:
  731.     if( argc != 1 )
  732.     {
  733.         fprintf(stderr, "argument count error\n");
  734.         result = -1;
  735.     }
  736.     else
  737.         result = DisplayCurrent(hd);
  738.     break;
  739.  
  740.       case MODE_IMMEDIATE:
  741.     if( argc <= 1 )                /* at least one triple */
  742.     {
  743.         fprintf(stderr, "missing device timeout\n");
  744.         result = -1;
  745.     }
  746.     else
  747.     {
  748.         for(; argc > 1; --argc,++argv )
  749.         {
  750.         unsigned a = 0xFF, d = 0xFF;    /* dsksleep won't find them... */
  751.         ULONG     m = 0xFFFFFF;
  752.  
  753.         /* Parse argument (spaces important!) and
  754.          * call ChangeCurrent(). */
  755.  
  756.         sscanf(argv[1], "%u ,%u ,%lu", &a, &d, &m);
  757.         result = ChangeCurrent(hd, (UCHAR)a, (UCHAR)d, m);
  758.         }
  759.         printf("After changing:\n");
  760.         DisplayCurrent(hd);            /* ignore errors */
  761.     }
  762.     break;
  763.  
  764.       default:
  765.     result = -1;
  766.     break;
  767.     }
  768.  
  769.     DosClose( hd );                /* be a nice guy */
  770.  
  771.     return result;
  772. }
  773.