home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / forum7.lzh / C / DINFO / dinfo.c < prev    next >
Text File  |  1988-11-10  |  11KB  |  374 lines

  1. /**************************************/
  2. /*              DInfo                 */
  3. /*------------------------------------*/
  4. /*      Advanced version of the       */
  5. /*    Standard OS9 "free" utility     */
  6. /*====================================*/
  7. /*     (c) 1988 by Lukas Zeller       */
  8. /*         Hofenstrasse 12            */
  9. /*       CH-8708 Maennedorf           */
  10. /*   email: zeller@strati.ethz.ch     */
  11. /*            DEC-Mail                */
  12. /*   PSI%4991108411::STRATI::ZELLER   */
  13. /*        OS9-BBS: LZELLER            */
  14. /**************************************/
  15.  
  16. /* This program is public domain and may be used and distributed freely
  17.    as long as the following conditions are met:
  18.  
  19.    1. This Program may only be used for peaceful applications. I do NOT
  20.       ALLOW using this program for anything that has to do with development,
  21.       testing or manufacturing of weapons of any type.
  22.  
  23.    2. This text as well as all copyright messages must be retained.
  24. */
  25.  
  26. /* Edition History
  27.    ---------------
  28.    001 : 88-11-01 : created
  29. */
  30.  
  31. #include <stdio.h>
  32. #include <ctype.h>
  33. #include <sgstat.h>
  34. #include <modes.h>
  35.  
  36. /* Sector 0 constant definitions */
  37. #define S0BYTS 96   /* number of interesting bytes in sector 0 */
  38. #define DD_TOT 0
  39. #define DD_TKS 3
  40. #define DD_MAP 4
  41. #define DD_BIT 6
  42. #define DD_DIR 8
  43. #define DD_OWN 0xB
  44. #define DD_ATT 0xD
  45. #define DD_DSK 0xE
  46. #define DD_FMT 0x10
  47. #define DD_SPT 0x11
  48. #define DD_RES 0x13
  49. #define DD_BT 0x15
  50. #define DD_BSZ 0x18
  51. #define DD_DAT 0x1A
  52. #define DD_NAM 0x1F
  53. #define DD_OPT 0x3F
  54. #define PD_TYP 3
  55.  
  56. /* Constants */
  57. /* --------- */
  58.  
  59. #define MINBUF 2048   /* minimum buffer size for allocation map */
  60.  
  61.  
  62. /* type definitions */
  63. /* ---------------- */
  64.  
  65. typedef struct {
  66.           int tot_sect;  /* total number of sectors on media */
  67.           int sect_p_tk; /* sectors per track */
  68.           int map_size;  /* size of allocation map in bytes */
  69.           int clu_siz;   /* cluster size (sectors/per) */
  70.           int group;     /* owner's group ID */
  71.           int user;      /* owner's user ID */
  72.           int boot;      /* boot LSN */
  73.           char attrs;    /* disk attributes */
  74.           char fmt;      /* format flags */
  75.           char dnam[32];  /* disk name */
  76.           char credat[5]; /* creation date */
  77.           char typ;      /* disk type */
  78.         } dinfo_typ;
  79.  
  80. typedef struct {
  81.           int free_bits;  /* number of free bits (clusters) */
  82.           int largest;    /* size of largest contiguous block */
  83.         } minfo_typ;
  84.  
  85. /* global variables */
  86. /* ---------------- */
  87.  
  88. int nargc;  /* number of non-option (and non argv[0]) arguments  */
  89. int bufsiz=MINBUF; /* buffer size for allocation map checker */
  90.  
  91. /* option flags */
  92. int extended=0;   /* show extedned information */
  93.  
  94. /* routines */
  95. char *malloc();
  96.  
  97.  
  98. /* copy <count> bytes from *b2++ to *b1++ */
  99. bytncpy(b1,b2,count)
  100.  
  101. char *b1, *b2;
  102. int count;
  103.  
  104. {
  105.    for (;(count--)>0;*b1++=*b2++);
  106. }
  107.  
  108.  
  109. /* get sector 0 information and write it into a "dinfo_typ" struct
  110.    Input  : disk_info = pointer to struct of type dinfo_typ
  111.             path      = pathnumber of open raw device
  112.    Output : fields in *disk_info updated
  113. */
  114. sector0_info(path,disk_info)
  115.  
  116. int path;
  117. dinfo_typ *disk_info;
  118.  
  119. {
  120.    char sector0[S0BYTS];  /* room to store interesting sector 0 bytes */
  121.  
  122.    /* - first get the interesting bytes from sector 0 */
  123.    lseek(path,0,0);  /* "rewind" to first sector */
  124.    read(path,sector0,S0BYTS);
  125.    /* - total # of sectors on disk */
  126.    disk_info->tot_sect=0;
  127.    bytncpy(((char *) &(disk_info->tot_sect))+1,sector0+DD_TOT,3);
  128.    /* - boot file LSN */
  129.    disk_info->boot=0;
  130.    bytncpy(((char *) &(disk_info->boot))+1,sector0+DD_BT,3);
  131.    /* - sectors per track */
  132.    disk_info->sect_p_tk=0;
  133.    bytncpy(((char *) &(disk_info->sect_p_tk))+2,sector0+DD_SPT,2);
  134.    /* - bitmap size */
  135.    disk_info->map_size=0;
  136.    bytncpy(((char *) &(disk_info->map_size))+2,sector0+DD_MAP,2);
  137.    /* - cluster size */
  138.    disk_info->clu_siz=0;
  139.    bytncpy(((char *) &(disk_info->clu_siz))+2,sector0+DD_BIT,2);
  140.    /* - owner's group.user ID number */
  141.    disk_info->group=sector0[DD_OWN];
  142.    disk_info->user=sector0[DD_OWN+1];
  143.    /* - disk attributes/format flags */
  144.    disk_info->attrs=sector0[DD_ATT];
  145.    disk_info->fmt=sector0[DD_FMT];
  146.    disk_info->typ=sector0[DD_OPT+PD_TYP];
  147.    /* - creation date */
  148.    bytncpy(disk_info->credat,sector0+DD_DAT,5);
  149.    /* - volume name */
  150.    strhcpy(disk_info->dnam,sector0+DD_NAM);
  151. } /* sector0_info */
  152.  
  153.  
  154. /* read bitmap from path and calculate # of free bits / largest block
  155.    Input  : disk_info = valid sector 0 information
  156.             bufsiz = size of buffer to be used for bitmap processing
  157.    Output : map_info = number of free blocks and size of largest block
  158. */
  159.  
  160. bitmap_info(path,disk_info,map_info,bufsz)
  161.  
  162. dinfo_typ *disk_info;
  163. minfo_typ *map_info;
  164. int bufsz;
  165.  
  166. {
  167.    char by, *buffer, *scanner;
  168.    int mbytes,sbytes,thisblock,bitcnt;
  169.  
  170.    /* allocate buffer for bitmap reading */
  171.    if ((buffer=malloc(bufsz))==NULL)
  172.       exit(_errmsg(1,"Can't get requested buffer memory\n"));
  173.    mbytes=disk_info->map_size;
  174.    /* init map_info fields */
  175.    map_info->free_bits=0;
  176.    map_info->largest=0;
  177.    thisblock=0;
  178.    lseek(path,0x100,0); /* begin reading at the beginning of the bitmap */
  179.    /* read loop */
  180.    for (mbytes=disk_info->map_size;mbytes>0;mbytes-=bufsz) {
  181.       sbytes=(mbytes>bufsz?bufsz:mbytes); /* calc number of bytes to read */
  182.       if (read(path,buffer,sbytes)<0)
  183.          exit(_errmsg(errno,"Error reading allocation map. "));
  184.       /* byte examination loop */
  185.       for(scanner=buffer;by=*(scanner++),(sbytes--)>0;) {
  186.          /* bit examination loop */
  187.          for (bitcnt=8;(bitcnt--)>0;by<<=1) {
  188.             if ((by&0x80)!=0) {
  189.                /* cluster allocated */
  190.                if (thisblock>map_info->largest) map_info->largest=thisblock;
  191.                thisblock=0;
  192.             }
  193.             else {
  194.                /* cluster free */
  195.                thisblock++;
  196.                (map_info->free_bits)++;
  197.             }
  198.          } /* bitloop */
  199.       } /* byteloop */
  200.    } /* read loop */
  201.    if (thisblock>map_info->largest) map_info->largest=thisblock;
  202.    /* return the bitmap buffer */
  203.    free(buffer);
  204. } /* end of bitmap_info */
  205.  
  206.  
  207. /* get and display info about one single RBF device
  208.    Input  : devname=&<device name string>
  209.             global bufsiz and option flags valid
  210.    Output : info displayed
  211. */
  212. one_dinfo(devname)
  213.  
  214. char *devname;
  215.  
  216. {
  217.     char accname[33];
  218.     char sc,a,att[9];
  219.     dinfo_typ disk_info;
  220.     minfo_typ map_info;
  221.     int path;
  222.     struct sgbuf optbuf;
  223.     int i,clsz;
  224.  
  225.     /* - construct raw device name */
  226.     strcpy(accname,devname);
  227.     strcat(accname,"@");
  228.     /* - open raw device path */
  229.     if ((path=open(accname,S_IREAD))<0)
  230.        exit(_errmsg(errno,"Can't open device \"%s\". \n",devname));
  231.     /* - check if it is RBF decice */
  232.     _gs_opt(path,&optbuf);
  233.     if (optbuf.sg_class!=1)
  234.        exit(_errmsg(1,"\"%s\" is no an RBF device\n",devname));
  235.     /* - get disk information */
  236.     sector0_info(path,&disk_info);
  237.     bitmap_info(path,&disk_info,&map_info,bufsiz);
  238.     /* - display device and disk name */
  239.     printf("Device name   : %s\n",devname);
  240.     printf("Volume name   : \"%s\"\n",disk_info.dnam);
  241.     /* - display creation date */
  242.     printf("Creation date : %4d-%d-%d %d:%d\n",
  243.             disk_info.credat[0]+1900,
  244.             disk_info.credat[1],disk_info.credat[2],
  245.             disk_info.credat[3],disk_info.credat[4]);
  246.     /* - display cluster size (extended only) */
  247.     if ((clsz=disk_info.clu_siz)!=1) sc='s'; else sc=' ';
  248.     if (extended) printf("Cluster size  : %d sector%c\n",clsz,sc);
  249.     /* - display capacity/used/free info */
  250.     printf("Capacity      : %d KBytes (%d sectors)\n",
  251.             disk_info.tot_sect/4,disk_info.tot_sect);
  252.     printf("Free          : %d KBytes (%d sectors)\n",
  253.             map_info.free_bits*clsz/4,map_info.free_bits*clsz);
  254.     printf("Largest block : %d KBytes (%d sectors)\n",
  255.             map_info.largest*clsz/4,map_info.largest*clsz);
  256.     /* - show additional info about disk (extended only) */
  257.     if (extended) {
  258.        printf("Owner         : %d.%d\n",
  259.                disk_info.group,disk_info.user);
  260.        /* show attributes */
  261.        strcpy(att,"dsewrewr");
  262.        a=disk_info.attrs;
  263.        for(i=7;(i--)>=0;a>>=1) {
  264.           if ((a&1)==0) att[i]='-';
  265.        }
  266.        printf("Attributes    : %s\n",att);
  267.        /* - information about disk type */
  268.        printf("Disk type     : ");
  269.        if ((disk_info.typ&0x80)!=0) {
  270.           printf ("harddisk\n");
  271.        }
  272.        else {
  273.           if ((disk_info.typ&0x20)!=0) printf ("non-standard, ");
  274.           printf ("%s\" floppy disk\n",(disk_info.typ&1?"8":"3.5\" or 5.25"));
  275.           printf("Format        : ");
  276.           if ((disk_info.fmt&0x1)==0) printf("single"); else printf("double");
  277.           printf(" sided, ");
  278.           if ((disk_info.fmt&0x2)==0) printf("single"); else printf("double");
  279.           printf(" density, ");
  280.           if ((disk_info.fmt&0x4)==0) printf("48"); else printf("96");
  281.           printf(" TPI\n");
  282.        }
  283.        /* - information about bootfile */
  284.        printf("Bootfile      : ");
  285.        if ((disk_info.boot==0)||(disk_info.boot>disk_info.tot_sect)) {
  286.           printf ("none (disk not bootable)\n");
  287.        }
  288.        else {
  289.           printf ("starting at LSN $%X\n",disk_info.boot);
  290.        }
  291.     } /* extended */
  292.     close(path);
  293. } /* one_dinfo */
  294.  
  295.  
  296. /* main program */
  297. main (argc,argv)
  298.  
  299. int argc;
  300. char *argv[];
  301.  
  302. {
  303.    char **argp;
  304.    char *dev;
  305.    char devnam[32];
  306.    int path;
  307.  
  308.    /* --- entry point */
  309.    options(argc,argv);
  310.    argp=&argv[1];
  311.    if (nargc==0) {
  312.       /* get current dir's device name */
  313.       if ((path=open(".",S_IFDIR+S_IREAD))<0)
  314.          exit(_errmsg(errno,"Can't open current device. "));
  315.       devnam[0]='/';
  316.       _gs_devn(path,devnam+1);
  317.       close(path);
  318.       one_dinfo(devnam);
  319.    }
  320.    else {
  321.       /* get device name(s) from command line */
  322.       while ((nargc--)>0) {
  323.          while (*(dev=*(argp++))=='-'); /* get next non-option argument */
  324.          one_dinfo(dev);
  325.       }
  326.    }
  327. } /* main */
  328.  
  329.  
  330. /**** display program usage */
  331. usage (pname)
  332. char *pname;
  333. {
  334.   printf("Syntax:   %s [<opts>] {<device name> [<opts>]}\n",pname);
  335.   printf("Function: Show information about a RBF Disk Device\n");
  336.   printf("          (Substitute for OS9 \"free\" utility)\n");
  337.   printf("Options:  -e          : Extended display\n");
  338.   printf("          -b[=]<size> : set buffer size\n");
  339.   printf("(c) 1988 by L.Zeller\n");
  340. } /* usage */
  341.  
  342.  
  343. /**** analyze command line options */
  344. options (argc,argv)
  345. int argc;
  346. char *argv[];
  347. {
  348.   int count, nextarg;
  349.   char *sc;
  350.  
  351.   for (count=nargc=0;++count<argc;) {
  352.     if (*(sc=argv[count])=='-') {
  353.       /* this argument is an option (begins with a hyphen) */
  354.       nextarg=0;
  355.       while ((*(++sc)!=NULL)&&!nextarg) {
  356.         switch (tolower(*sc)) {
  357.           case '?' : usage(argv[0]); exit(0);
  358.           case 'e' : extended=1; break;
  359.           case 'b' : if (*(++sc)=='=') sc++;
  360.                      bufsiz=atoi(sc);
  361.                      if (bufsiz<MINBUF) bufsiz=MINBUF;
  362.                      nextarg=1;
  363.                      break;
  364.           default  : usage(argv[0]); exit(_errmsg(1,"unknown option '%c'\n",*sc));
  365.           /* options with arguments may set nextarg to stop processing
  366.              of this argument. Otherwise, *sc must be the last char processed */
  367.         } /* switch */
  368.       } /* while */
  369.     } /* if hyphen */
  370.     else nargc++;
  371.   } /* for */
  372. } /* options */
  373.  
  374.