home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************/
- /* Program Id. Cdir.C. */
- /* Author. Stan Milam. */
- /* Installation. Mountain View College */
- /* Date Written. 09/06/87. */
- /* Compiler. Turbo C V1.00, */
- /* Microsoft C V5.00, */
- /* Mix Power C V1.00. */
- /* Comments: This program was written to demonstrate the */
- /* use of software interrupts, both DOS & BIOS. The */
- /* functions performed are to get a directory listing by */
- /* making DOS interrupt calls and to display the directory*/
- /* on the screen with a window managed by ROM BIOS. Also */
- /* the bit masking & shifting capabilities of C are */
- /* demonstrated. */
- /* WARNING! Do not try to redirect the output to the */
- /* printer since some of the line feeds will be performed */
- /* by ROM BIOS. */
- /**********************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <dos.h>
- #include <conio.h>
- #include <pcwproto.h>
-
- #define TRUE 1
- #define FALSE 0
-
- int pause = FALSE; /* A flag to signal pause */
-
- struct dta_type { /* Defines Disk Transfer Area */
- char reserved[21]; /* Reserved by DOS */
- char fattrib; /* File attribute */
- /************************************/
- /* The next 3 fields are bit fields */
- /************************************/
- unsigned int fsec:5; /* Second file was created */
- unsigned int fmin:6; /* Minute file was created */
- unsigned int fhour:5; /* Hour file was created */
- unsigned int fdate; /* Date the file was created */
- long fsize; /* Size of the file in bytes */
- char fname[13]; /* File name */
- };
-
- /***********************************************************/
- /* SET_DTA */
- /* This function (procedure) will establish a new Disk */
- /* Transfer Area. The new DTA will be a structure that */
- /* will mirror the information DOS will return to us when */
- /* we call the firstfile and nextfile functions. */
- /***********************************************************/
-
- void set_dta(dta)
- struct dta_type *dta; {
-
- struct SREGS sregs;
- union REGS regs;
-
- segread(&sregs); /* Get segment registers' values */
- regs.x.ax = 0x1A00; /* DOS function Set Disk Transfer Area */
- regs.x.dx = (unsigned int) dta; /* Address of our DTA */
- int86x(0x21,®s,®s,&sregs); /* Call DOS to set up new DTA */
- }
-
- /***********************************************************/
- /* INITIALIZE */
- /* This function will initialize the program. Mainly it */
- /* will clear the screen, print some headings and invoke */
- /* the function to set up a new DTA for the program. */
- /***********************************************************/
-
- void initialize(dta)
- struct dta_type *dta; { /* Pointer to DTA */
- vcls(); /* Clear the screen */
- set_dta(dta); /* Establish Disk Transfer Area */
- printf("\n\n\n");
- printf(" File Name Size Date Time Attribute\n");
- printf(" ------------ ------ -------- -------- -------------\n");
- }
-
- /**********************************************************/
- /* FIRSTFILE */
- /* This function will find the first file that matches */
- /* search argument. First a call is made to DOS to set */
- /* up a Disk Transfer Area in a structure dta. Next the */
- /* call is made to find the first file. When the file is*/
- /* found DOS will pass information about the file back to*/
- /* us in the Disk Transfer area that we set up. */
- /**********************************************************/
-
- int firstfile(s_arg)
- char *s_arg; { /* Pointer to the search argument */
-
- union REGS regs;
- struct SREGS sregs;
-
- segread(&sregs); /* Get segment registers */
- regs.x.ax = 0x4e00; /* DOS function Find First File */
- regs.x.dx = (unsigned int) s_arg; /* Offset of search argument */
- regs.x.cx = 0x003f; /* File Attribute = ALL */
- int86x(0x21,®s,®s,&sregs); /* Call DOS to find first file */
-
- if (regs.x.ax == 0) /* if no error occured then */
- return(TRUE); /* return a true condition */
- else
- return(FALSE); /* otherwise .... */
- }
-
- /***********************************************************/
- /* NEXTFILE */
- /* This function is much like the last except it gets the */
- /* next file which matchs our search argument. It passes */
- /* back a flag = FALSE when no more files are found */
- /***********************************************************/
-
- int nextfile(void) {
-
- union REGS regs;
-
- regs.x.ax = 0x4f00; /* DOS function for nextfile */
- int86(0x21,®s,®s); /* Call DOS */
- if (regs.x.ax == 0) /* Check for an error or no more */
- return(TRUE); /* files. */
- else
- return(FALSE);
- }
-
- /***********************************************************/
- /* PFILE */
- /* This function will print all the pertinate information */
- /* about the file retrieved such as its name, time & date */
- /* created, and its attribute (read-only, hidden, system */
- /* etc...). */
- /***********************************************************/
-
- void pfile(dta,fcount)
- struct dta_type *dta;
- int fcount; {
-
- int hour,min,sec,year,day,month; /* variables to get from dta */
- char attribute[16]; /* pointer to attribute description */
- long size; /* size of file */
- int dattr; /* debug only */
- char *pr1, *pr2; /* print strings */
- char name[9], extention[4]; /* File Name & Extention */
- char *wrk;
-
- pr1 = " %-8s %-3s %6ld %02d/%02d/%02d %02d:%02d:%02d %s\n";
- pr2 = " %-8s %-3s %6ld %02d/%02d/%02d %02d:%02d:%02d %s";
-
- attribute[0] = '\0';
-
- size = dta->fsize;
- hour = dta->fhour; /* Hour from bit field */
- min = dta->fmin; /* Minute from bit field */
- sec = dta->fsec * 2; /* Seconds * 2 from bit field */
- year = (dta->fdate & 0xfe00) >> 9; /* mask & shift to get year */
- month =(dta->fdate & 0x01e0) >> 5; /* mask & shift to get month */
- day = (dta->fdate & 0x001f); /* just mask to get day */
- year += 80; /* year + 1980 */
-
- if ((wrk = strchr(dta->fname,'.')) == NULL) { /* Find Extention */
- strcpy(name, dta->fname);
- strcpy(extention, " ");
- }
- else {
- if (strcmp(dta->fname, wrk) != 0) { /* Is it ".." or "." */
- *wrk = '\0'; /* No - delimit name & ext */
- strcpy(name, dta->fname); /* Copy file name */
- strcpy(extention, ++wrk); /* Copy extention */
- }
- else {
- strcpy(name, dta->fname); /* Copy ".." or "." */
- strcpy(extention, " "); /* Put spaces into ext. */
- }
- }
-
- if ((dta -> fattrib & 0x01) == 0x01)
- strcat(attribute,"R "); /* Read Only */
- else
- strcat(attribute,". ");
- if ((dta -> fattrib & 0x02) == 0x02)
- strcat(attribute,"H "); /* Hidden */
- else
- strcat(attribute,". ");
- if ((dta -> fattrib & 0x04) == 0x04)
- strcat(attribute,"S "); /* System */
- else
- strcat(attribute,". ");
- if ((dta -> fattrib & 0x08) == 0x08)
- strcat(attribute,"V "); /* Volume Label */
- else
- strcat(attribute,". ");
- if ((dta -> fattrib & 0x10) == 0x10)
- strcat(attribute,"D "); /* Directory */
- else
- strcat(attribute,". ");
- if ((dta -> fattrib & 0x20) == 0x20)
- strcat(attribute,"Arc"); /* Archive */
- else
- strcat(attribute,"...");
-
-
- if (fcount % 12 == 0 && pause){ /* If pause then stop */
- while(!kbhit()); /* and wait for a key */
- getch();
- }
-
- if (fcount >= 13) {
- printf(pr2,
- name,extention,size,month,day,year,hour,min,sec,attribute);
- scroll(6,2,18,79,7,0,-1);
- set_cursor_pos(18,1);
- }
- else
- printf(pr1,
- name,extention,size,month,day,year,hour,min,sec,attribute);
- }
-
- /**********************************************************/
- /* FREE_SPACE */
- /* This function will print the total number of files */
- /* listed along with the total disk space, total disk */
- /* space used, total disk space available, and percent of */
- /* free disk space. We are going to use the DOS function */
- /* Get Free Disk Space (Int 0x21 function 0x36) to do all */
- /* of this fancy stuff. Upon return from the DOS call */
- /* the registers will reflect the following: */
- /* AX = sectors per cluster. */
- /* BX = number of available clusters. */
- /* CX = bytes per sector. */
- /* DX = total number of clusters. */
- /**********************************************************/
-
- void free_space(fcount,drive)
- int fcount; int drive; {
-
- union REGS regs; /* Set up registers of course */
- unsigned long total,avail,used; /* Need longs for big numbers */
- int percent; /* Nuff said? */
-
- regs.x.ax = 0x3600; /* DOS function Free Space */
- regs.x.dx = drive; /* Set for specified drive */
- int86(0x21,®s,®s); /* Call DOS */
-
- if (regs.x.ax == 0xffff) { /* If an error then print a */
- puts("*** Invalid Drive Specification ***"); /* nasty message */
- exit(16); /* and return home */
- }
- total = (long) regs.x.dx * regs.x.cx * regs.x.ax; /* Total bytes on disk */
- avail = (long) regs.x.ax * regs.x.bx * regs.x.cx; /* Available bytes */
- used = total - avail; /* Total used */
- percent = (avail * 100) / total; /* % of free space */
-
- puts(" ");
- printf(" %3d file(s) %8ld total disk space\n",fcount, total);
- printf(" %8ld total disk space available\n",avail);
- printf(" %8ld total disk space used\n",used);
- printf(" %8d percent free disk space\n",percent);
- }
-
- /**********************************************************/
- /* PARSER */
- /* This function will parse the command line for a drive */
- /* specification. If it is present then the drive spec */
- /* will be used when we call free_space so that we use the*/
- /* correct disk drive. Default drive = 0, A drive = 1, */
- /* B drive = 2, etc.... */
- /* Changed code to append "*.*" if no file spec was */
- /* entered. Example: */
- /* cdir a: will turn into cdir a:*.* */
- /* cdir \dos\ will turn into cdir \dos\*.* */
- /**********************************************************/
-
- int parser(arg)
- char arg[]; {
-
- int retval = 0; /* Assume Defualt Drive */
- char *wrk; /* Character Work Pointer */
-
- if (arg[1] == ':') { /* If second char is ':' then return */
- retval = toupper(arg[0]) - 64; /* Covert to numeric */
- if (arg[2] == '\0') /* Char after ':' a null? */
- strcat(arg, "*.*"); /* Yes! - concatenate wildcard */
- }
- if ((wrk = strrchr(arg, '\\')) != NULL) {
- if (*(wrk + 1) == NULL) {
- strcat(arg, "*.*");
- }
- }
- return(retval);
- }
-
- /***********************************************************/
- /* PARSE_COMMAND */
- /* */
- /* This function does two things: Takes all command line */
- /* arguments and converts the alpha characters to upper */
- /* case. Secondly, it searches the arguments for "/P" and */
- /* returns TRUE indicating that the user wants to pause */
- /* after one full page of output. */
- /***********************************************************/
-
- int parse_command(argc, argv)
- int argc;
- char *argv [];
-
- {
- int i;
- char *wrk;
-
- for (i = 1; i < argc; i++) { /* Change all alpha chars */
- wrk = argv[i]; /* In command line args to*/
- while(*wrk) { /* Upper Case */
- *wrk = toupper(*wrk);
- wrk++;
- }
- }
-
- for (i = 1; i < argc; i++) { /* Now search for the */
- wrk = argv[i]; /* "/P" in one of the */
- if (strcmp(wrk, "/P") == 0) /* Arguments */
- return(TRUE);
- }
- return(FALSE);
- }
-
-
- /******************************/
- /* MAIN */
- /******************************/
- int main(argc,argv)
- int argc;
- char *argv[]; {
-
- struct dta_type dta;
- int fcount = 0, drive =0;
- char *arg;
-
- set_int24();
- pause = parse_command(argc, argv);
-
- if (pause && argc > 2) {
- arg = argv[1];
- drive = parser(arg);
- }
- else
- if (pause && argc > 1)
- arg = "*.*";
- else
- if (argc > 1) {
- arg = argv[1];
- drive = parser(arg);
- }
- else
- arg = "*.*";
-
- initialize(&dta); /* Initialize the program */
- if (firstfile(arg)) { /* Is there a first file? */
- do {
- fcount += 1; /* Yes - print file name until */
- pfile(&dta,fcount); /* no more matches */
- }
- while (nextfile());
- free_space(fcount,drive); /* And then print info about */
- } /* the disk */
- else {
- puts("*** No matching files ***");
- free_space(fcount,drive);
- return(16);
- }
- return (0);
- }