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 >
Wrap
Text File
|
1988-11-10
|
11KB
|
374 lines
/**************************************/
/* DInfo */
/*------------------------------------*/
/* Advanced version of the */
/* Standard OS9 "free" utility */
/*====================================*/
/* (c) 1988 by Lukas Zeller */
/* Hofenstrasse 12 */
/* CH-8708 Maennedorf */
/* email: zeller@strati.ethz.ch */
/* DEC-Mail */
/* PSI%4991108411::STRATI::ZELLER */
/* OS9-BBS: LZELLER */
/**************************************/
/* This program is public domain and may be used and distributed freely
as long as the following conditions are met:
1. This Program may only be used for peaceful applications. I do NOT
ALLOW using this program for anything that has to do with development,
testing or manufacturing of weapons of any type.
2. This text as well as all copyright messages must be retained.
*/
/* Edition History
---------------
001 : 88-11-01 : created
*/
#include <stdio.h>
#include <ctype.h>
#include <sgstat.h>
#include <modes.h>
/* Sector 0 constant definitions */
#define S0BYTS 96 /* number of interesting bytes in sector 0 */
#define DD_TOT 0
#define DD_TKS 3
#define DD_MAP 4
#define DD_BIT 6
#define DD_DIR 8
#define DD_OWN 0xB
#define DD_ATT 0xD
#define DD_DSK 0xE
#define DD_FMT 0x10
#define DD_SPT 0x11
#define DD_RES 0x13
#define DD_BT 0x15
#define DD_BSZ 0x18
#define DD_DAT 0x1A
#define DD_NAM 0x1F
#define DD_OPT 0x3F
#define PD_TYP 3
/* Constants */
/* --------- */
#define MINBUF 2048 /* minimum buffer size for allocation map */
/* type definitions */
/* ---------------- */
typedef struct {
int tot_sect; /* total number of sectors on media */
int sect_p_tk; /* sectors per track */
int map_size; /* size of allocation map in bytes */
int clu_siz; /* cluster size (sectors/per) */
int group; /* owner's group ID */
int user; /* owner's user ID */
int boot; /* boot LSN */
char attrs; /* disk attributes */
char fmt; /* format flags */
char dnam[32]; /* disk name */
char credat[5]; /* creation date */
char typ; /* disk type */
} dinfo_typ;
typedef struct {
int free_bits; /* number of free bits (clusters) */
int largest; /* size of largest contiguous block */
} minfo_typ;
/* global variables */
/* ---------------- */
int nargc; /* number of non-option (and non argv[0]) arguments */
int bufsiz=MINBUF; /* buffer size for allocation map checker */
/* option flags */
int extended=0; /* show extedned information */
/* routines */
char *malloc();
/* copy <count> bytes from *b2++ to *b1++ */
bytncpy(b1,b2,count)
char *b1, *b2;
int count;
{
for (;(count--)>0;*b1++=*b2++);
}
/* get sector 0 information and write it into a "dinfo_typ" struct
Input : disk_info = pointer to struct of type dinfo_typ
path = pathnumber of open raw device
Output : fields in *disk_info updated
*/
sector0_info(path,disk_info)
int path;
dinfo_typ *disk_info;
{
char sector0[S0BYTS]; /* room to store interesting sector 0 bytes */
/* - first get the interesting bytes from sector 0 */
lseek(path,0,0); /* "rewind" to first sector */
read(path,sector0,S0BYTS);
/* - total # of sectors on disk */
disk_info->tot_sect=0;
bytncpy(((char *) &(disk_info->tot_sect))+1,sector0+DD_TOT,3);
/* - boot file LSN */
disk_info->boot=0;
bytncpy(((char *) &(disk_info->boot))+1,sector0+DD_BT,3);
/* - sectors per track */
disk_info->sect_p_tk=0;
bytncpy(((char *) &(disk_info->sect_p_tk))+2,sector0+DD_SPT,2);
/* - bitmap size */
disk_info->map_size=0;
bytncpy(((char *) &(disk_info->map_size))+2,sector0+DD_MAP,2);
/* - cluster size */
disk_info->clu_siz=0;
bytncpy(((char *) &(disk_info->clu_siz))+2,sector0+DD_BIT,2);
/* - owner's group.user ID number */
disk_info->group=sector0[DD_OWN];
disk_info->user=sector0[DD_OWN+1];
/* - disk attributes/format flags */
disk_info->attrs=sector0[DD_ATT];
disk_info->fmt=sector0[DD_FMT];
disk_info->typ=sector0[DD_OPT+PD_TYP];
/* - creation date */
bytncpy(disk_info->credat,sector0+DD_DAT,5);
/* - volume name */
strhcpy(disk_info->dnam,sector0+DD_NAM);
} /* sector0_info */
/* read bitmap from path and calculate # of free bits / largest block
Input : disk_info = valid sector 0 information
bufsiz = size of buffer to be used for bitmap processing
Output : map_info = number of free blocks and size of largest block
*/
bitmap_info(path,disk_info,map_info,bufsz)
dinfo_typ *disk_info;
minfo_typ *map_info;
int bufsz;
{
char by, *buffer, *scanner;
int mbytes,sbytes,thisblock,bitcnt;
/* allocate buffer for bitmap reading */
if ((buffer=malloc(bufsz))==NULL)
exit(_errmsg(1,"Can't get requested buffer memory\n"));
mbytes=disk_info->map_size;
/* init map_info fields */
map_info->free_bits=0;
map_info->largest=0;
thisblock=0;
lseek(path,0x100,0); /* begin reading at the beginning of the bitmap */
/* read loop */
for (mbytes=disk_info->map_size;mbytes>0;mbytes-=bufsz) {
sbytes=(mbytes>bufsz?bufsz:mbytes); /* calc number of bytes to read */
if (read(path,buffer,sbytes)<0)
exit(_errmsg(errno,"Error reading allocation map. "));
/* byte examination loop */
for(scanner=buffer;by=*(scanner++),(sbytes--)>0;) {
/* bit examination loop */
for (bitcnt=8;(bitcnt--)>0;by<<=1) {
if ((by&0x80)!=0) {
/* cluster allocated */
if (thisblock>map_info->largest) map_info->largest=thisblock;
thisblock=0;
}
else {
/* cluster free */
thisblock++;
(map_info->free_bits)++;
}
} /* bitloop */
} /* byteloop */
} /* read loop */
if (thisblock>map_info->largest) map_info->largest=thisblock;
/* return the bitmap buffer */
free(buffer);
} /* end of bitmap_info */
/* get and display info about one single RBF device
Input : devname=&<device name string>
global bufsiz and option flags valid
Output : info displayed
*/
one_dinfo(devname)
char *devname;
{
char accname[33];
char sc,a,att[9];
dinfo_typ disk_info;
minfo_typ map_info;
int path;
struct sgbuf optbuf;
int i,clsz;
/* - construct raw device name */
strcpy(accname,devname);
strcat(accname,"@");
/* - open raw device path */
if ((path=open(accname,S_IREAD))<0)
exit(_errmsg(errno,"Can't open device \"%s\". \n",devname));
/* - check if it is RBF decice */
_gs_opt(path,&optbuf);
if (optbuf.sg_class!=1)
exit(_errmsg(1,"\"%s\" is no an RBF device\n",devname));
/* - get disk information */
sector0_info(path,&disk_info);
bitmap_info(path,&disk_info,&map_info,bufsiz);
/* - display device and disk name */
printf("Device name : %s\n",devname);
printf("Volume name : \"%s\"\n",disk_info.dnam);
/* - display creation date */
printf("Creation date : %4d-%d-%d %d:%d\n",
disk_info.credat[0]+1900,
disk_info.credat[1],disk_info.credat[2],
disk_info.credat[3],disk_info.credat[4]);
/* - display cluster size (extended only) */
if ((clsz=disk_info.clu_siz)!=1) sc='s'; else sc=' ';
if (extended) printf("Cluster size : %d sector%c\n",clsz,sc);
/* - display capacity/used/free info */
printf("Capacity : %d KBytes (%d sectors)\n",
disk_info.tot_sect/4,disk_info.tot_sect);
printf("Free : %d KBytes (%d sectors)\n",
map_info.free_bits*clsz/4,map_info.free_bits*clsz);
printf("Largest block : %d KBytes (%d sectors)\n",
map_info.largest*clsz/4,map_info.largest*clsz);
/* - show additional info about disk (extended only) */
if (extended) {
printf("Owner : %d.%d\n",
disk_info.group,disk_info.user);
/* show attributes */
strcpy(att,"dsewrewr");
a=disk_info.attrs;
for(i=7;(i--)>=0;a>>=1) {
if ((a&1)==0) att[i]='-';
}
printf("Attributes : %s\n",att);
/* - information about disk type */
printf("Disk type : ");
if ((disk_info.typ&0x80)!=0) {
printf ("harddisk\n");
}
else {
if ((disk_info.typ&0x20)!=0) printf ("non-standard, ");
printf ("%s\" floppy disk\n",(disk_info.typ&1?"8":"3.5\" or 5.25"));
printf("Format : ");
if ((disk_info.fmt&0x1)==0) printf("single"); else printf("double");
printf(" sided, ");
if ((disk_info.fmt&0x2)==0) printf("single"); else printf("double");
printf(" density, ");
if ((disk_info.fmt&0x4)==0) printf("48"); else printf("96");
printf(" TPI\n");
}
/* - information about bootfile */
printf("Bootfile : ");
if ((disk_info.boot==0)||(disk_info.boot>disk_info.tot_sect)) {
printf ("none (disk not bootable)\n");
}
else {
printf ("starting at LSN $%X\n",disk_info.boot);
}
} /* extended */
close(path);
} /* one_dinfo */
/* main program */
main (argc,argv)
int argc;
char *argv[];
{
char **argp;
char *dev;
char devnam[32];
int path;
/* --- entry point */
options(argc,argv);
argp=&argv[1];
if (nargc==0) {
/* get current dir's device name */
if ((path=open(".",S_IFDIR+S_IREAD))<0)
exit(_errmsg(errno,"Can't open current device. "));
devnam[0]='/';
_gs_devn(path,devnam+1);
close(path);
one_dinfo(devnam);
}
else {
/* get device name(s) from command line */
while ((nargc--)>0) {
while (*(dev=*(argp++))=='-'); /* get next non-option argument */
one_dinfo(dev);
}
}
} /* main */
/**** display program usage */
usage (pname)
char *pname;
{
printf("Syntax: %s [<opts>] {<device name> [<opts>]}\n",pname);
printf("Function: Show information about a RBF Disk Device\n");
printf(" (Substitute for OS9 \"free\" utility)\n");
printf("Options: -e : Extended display\n");
printf(" -b[=]<size> : set buffer size\n");
printf("(c) 1988 by L.Zeller\n");
} /* usage */
/**** analyze command line options */
options (argc,argv)
int argc;
char *argv[];
{
int count, nextarg;
char *sc;
for (count=nargc=0;++count<argc;) {
if (*(sc=argv[count])=='-') {
/* this argument is an option (begins with a hyphen) */
nextarg=0;
while ((*(++sc)!=NULL)&&!nextarg) {
switch (tolower(*sc)) {
case '?' : usage(argv[0]); exit(0);
case 'e' : extended=1; break;
case 'b' : if (*(++sc)=='=') sc++;
bufsiz=atoi(sc);
if (bufsiz<MINBUF) bufsiz=MINBUF;
nextarg=1;
break;
default : usage(argv[0]); exit(_errmsg(1,"unknown option '%c'\n",*sc));
/* options with arguments may set nextarg to stop processing
of this argument. Otherwise, *sc must be the last char processed */
} /* switch */
} /* while */
} /* if hyphen */
else nargc++;
} /* for */
} /* options */