home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_01_02 / clune.exe / DOS_FUNC.C < prev    next >
C/C++ Source or Header  |  1990-06-08  |  14KB  |  481 lines

  1.  
  2. /* count_files() added 11/89 by T Clune for R Webb.  count_files() */
  3. /* accepts a filespec template and returns the number of matching files */
  4.  
  5. /* fget_time_date() added 10/89 by T Clune, to construct a string */
  6. /* that identifies a file's time and date of creation.  Added by */
  7. /* T Clune for F Van de Velde */
  8.  
  9. /* get_dir() modified to accept pointers instead of character arrays */
  10. /* for the returned names.  Now get_dir() is compatible with menu() in */
  11. /* menu.c, and dir_menu() in that file has been eliminated.  Changed */
  12. /* 12/88 by T Clune */
  13.  
  14. /* del_fines() and parse_filename() deleted 12/88 by T Clune.  Use */
  15. /* del_fhandle() for all file deletions */
  16.  
  17. /* dos_func.c was created 11/88 by T Clune to incorporate the various */
  18. /* DOS software interrupt functions that were spread over a variety of */
  19. /* applications into one file.  Copyright (c) 1988, Eye Research Institute */
  20. /* All Rights Reserved. */
  21.  
  22.  
  23. #include "dos_func.h" /* this file's typedefs and declarations */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <dos.h>
  28. #include <malloc.h>
  29.  
  30.     /* support functions for del_fhandle() and get_dir() */
  31. static unsigned int get_first_match();
  32. static unsigned int get_next_match();
  33. static unsigned long get_dta();
  34. static void set_dta();
  35.  
  36.  
  37.  
  38.  
  39.  
  40. /* count_files() looks in the directory in filespec for the file(s) specified */
  41. /* by filespec (same format as DOS dir command for filespec).  The function */
  42. /* returns the number of matching files found.  */
  43. /* added 11/89 by T Clune */
  44.  
  45. int count_files(filespec)
  46. char filespec[];
  47. {
  48.     int i=0;    /* the number of matching files counter */
  49.     unsigned int cflag; /* the carry flag returned by get_first_match() */
  50.             /* and get_next_match() function calls */
  51.     unsigned long int fnameptr;  /* flespec cast as an unsigned long int */
  52.     dta dir_struct;  /* the file dta */
  53.     unsigned long psp_dta;  /* the dta pointer on entry to get_dir() */
  54.  
  55.  
  56.     psp_dta=get_dta();
  57.     set_dta((unsigned long)&dir_struct);
  58.  
  59.     /* get first filename */
  60.     fnameptr=(unsigned long int)filespec;
  61.     cflag=get_first_match(fnameptr,0);
  62.  
  63.     while(!cflag)
  64.     {
  65.     cflag=get_next_match(fnameptr,0);
  66.     i++;    /* increment match-count */
  67.     }
  68.  
  69.     /* restore original dta before exiting */
  70.     set_dta(psp_dta);
  71.  
  72.     return i;  /* return number of matches found */
  73.  
  74. }
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. /* del_fhandle() was modified 12/88 by T. Clune to support wildcards. */
  82. /* del_fhandle() deletes all files specified by FILESPEC.  The advantage */
  83. /* of del_fhandle() over del_files() is that you can specify a path instead */
  84. /* of having to use the default path. Returns 0 if successful, 1 if not. */
  85. /* See Programmers Problem Solver, p. 272-275 for details of function 0x41. */
  86.  
  87. int del_fhandle(filespec)
  88. char filespec[];
  89. {
  90.      /* the first block of declarations is for getting the filenames */
  91.     dta dir_struct;  /* the file dta */
  92.     unsigned long psp_dta;  /* the dta pointer on entry to get_dir() */
  93.     unsigned long int fnameptr; /* filespec cast as a number */
  94.     unsigned int cflag; /* the carry flag returned by get_first_match() */
  95.         /* and get_next_match() */
  96.     char *ptr;
  97.     char pathname[40];
  98.     char fullname[80];
  99.  
  100.     /* this block of declarations is for doing the deletions */
  101.     address_union address;
  102.     union REGS inregs, outregs;
  103.     struct SREGS segregs;
  104.  
  105.     /* get path name of filespec */
  106.     strcpy(pathname, filespec);
  107.     ptr=strrchr(pathname, '\\');
  108.     if(!ptr)
  109.     ptr=strrchr(pathname,':');
  110.     if(ptr)
  111.     {
  112.     ptr++;
  113.     *ptr ='\0';
  114.     }
  115.     else
  116.     pathname[0]='\0';
  117.  
  118.     psp_dta=get_dta();
  119.     set_dta((unsigned long)&dir_struct);
  120.  
  121.     /* get first filename */
  122.     fnameptr=(unsigned long int)filespec;
  123.     cflag=get_first_match(fnameptr,0);
  124.  
  125.     /* set up the delete-file software interrupt */
  126.     address.pointer=(unsigned long int)fullname;
  127.     segregs.ds=address.s.segment;
  128.     inregs.x.dx=address.s.offset;
  129.     inregs.h.ah=0x41;   /* the erase filespec function in DOS */
  130.  
  131.     while(!cflag)
  132.     {
  133.         /* construct name of matching file (including path) to delete */
  134.     strcpy(fullname, pathname);
  135.     strcat(fullname, dir_struct.name);
  136.     intdosx(&inregs, &outregs, &segregs);  /* delete the file */
  137.     if(outregs.x.cflag) /* abort on failure to delete */
  138.         break;
  139.     cflag=get_next_match(fnameptr,0);
  140.     }
  141.  
  142.     /* restore original dta before exiting */
  143.     set_dta(psp_dta);
  144.  
  145.     return outregs.x.cflag;
  146.  
  147. }
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154. /* disk_space() returns the number of bytes available on a disk */
  155. /* you specify the disk in the call (0 = default drive, 1=A, etc.) */
  156. /* and it returns a LONG INT with the size of the available space */
  157. /* any DOS programming guide will explain the routine, but two that */
  158. /* did a good job are _Programmer's Guide to MS DOS_ by Dennis Jump */
  159. /* p. 95-96 and my old stand-by _Programmer's Problem Solver_ by Robert */
  160. /* Jourdain, p.247. */
  161.  
  162. long disk_space(drive)
  163. int drive;  /* drive choice. 0=default, 1=A, 2=B, etc. */
  164. {
  165.     long bytes_free;    /* return value in bytes for disk specified */
  166.     union REGS inregs, outregs;     /* as per dos.h */
  167.  
  168.     inregs.h.ah = 0x36;    /* function call specifies get disk space */
  169.     inregs.h.dl = drive;   /* which drive? */
  170.  
  171.     intdos(&inregs, &outregs); /* call the interrupt */
  172.  
  173.             /* calculate bytes free */
  174.     bytes_free = (long) outregs.x.ax*outregs.x.bx*outregs.x.cx;
  175.  
  176.     return bytes_free;
  177.  
  178. }
  179.  
  180.  
  181.  
  182.  
  183. /* fget_time_date() gets the time and date of creation of the file FILESPEC */
  184. /* and writes the data as a string into TIMEDATE, in the format; */
  185. /* MM-DD-YY HH:MM.SS  where MM is month, DD is day, YY is year, HH is HOUR, and */
  186. /* MM is minutes, and SS is seconds.  The TIMEDATE string length is */
  187. /* <= 18 chars, including terminating null. Added 10/89 by T Clune. */
  188.  
  189. void fget_time_date(filespec,timedate)
  190. char filespec[], timedate[];
  191. {
  192.     dta dir_struct;  /* the file dta */
  193.     address_union address;
  194.     unsigned long psp_dta; /* the dta on entry to fname_unused() */
  195.     union REGS regs;
  196.     struct SREGS segregs;
  197.     filestamp td;
  198.     int i;
  199.     char string[10];
  200.  
  201.     if(fname_unused(filespec))
  202.     {
  203.     strcpy(timedate, "00-00-00 0:00.00");
  204.     return;
  205.     }
  206.  
  207.     psp_dta=get_dta();
  208.     set_dta((unsigned long)&dir_struct);
  209.  
  210.     /* get first filename */
  211.     address.pointer=(unsigned long int)&filespec[0];
  212.     segregs.ds=address.s.segment;
  213.     regs.x.dx=address.s.offset;
  214.     regs.x.cx=0;  /* no funny attributes in file */
  215.     regs.h.ah=0x4E;   /* first file match function number of int 0x21 */
  216.     intdosx(®s, ®s, &segregs);
  217.     /* the 0x21 function 0x57 is the "official" time/date interrupt */
  218.     /* function, but anything that gets a file using the file handle */
  219.     /* method will initialize the dta for you. */
  220.  
  221.     /* restore original dta before exiting */
  222.     set_dta(psp_dta);
  223.     td.w.time=dir_struct.time;
  224.     td.w.date=dir_struct.date;
  225.     i=td.b.mon;
  226.     itoa(i,string,10);
  227.     strcpy(timedate, string);
  228.     strcat(timedate,"-");
  229.     i=td.b.day;
  230.     itoa(i,string,10);
  231.     strcat(timedate, string);
  232.     strcat(timedate,"-");
  233.     i=td.b.yr;
  234.     i +=80;
  235.     itoa(i,string,10);
  236.     strcat(timedate, string);
  237.     strcat(timedate," ");
  238.     i=td.b.hrs;
  239.     itoa(i,string,10);
  240.     strcat(timedate, string);
  241.     strcat(timedate,":");
  242.     i=td.b.mins;
  243.     if(i<10)
  244.     strcat(timedate,"0");
  245.     itoa(i,string,10);
  246.     strcat(timedate, string);
  247.     strcat(timedate,".");
  248.     i=td.b.secs;
  249.     if(i<10)
  250.     strcat(timedate,"0");
  251.     itoa(i,string,10);
  252.     strcat(timedate, string);
  253.  
  254. }
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261. /* fname_unused() checks the directory in filespec for the file(s) specified */
  262. /* by filespec to see whether the name has been used already.   Returns 0 if */
  263. /* name is already used, 1 otherwise */
  264.  
  265. int fname_unused(filespec)
  266. char filespec[];
  267. {
  268.     dta dir_struct;  /* the file dta */
  269.     address_union address;
  270.     unsigned long psp_dta; /* the dta on entry to fname_unused() */
  271.     union REGS inregs, outregs;
  272.     struct SREGS segregs;
  273.  
  274.     psp_dta=get_dta();
  275.     set_dta((unsigned long)&dir_struct);
  276.  
  277.     /* get first filename */
  278.     address.pointer=(unsigned long int)&filespec[0];
  279.     segregs.ds=address.s.segment;
  280.     inregs.x.dx=address.s.offset;
  281.     inregs.x.cx=0;  /* no funny attributes in file */
  282.     inregs.h.ah=0x4E;   /* first file match function number of int 0x21 */
  283.     intdosx(&inregs, &outregs, &segregs);
  284.  
  285.     /* restore original dta before exiting */
  286.     set_dta(psp_dta);
  287.  
  288.     return outregs.x.cflag;
  289.  
  290. }
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297. /* get_dir() looks in the directory in filespec for the file(s) specified */
  298. /* by filespec (same format as DOS dir command for filespec)  The matching */
  299. /* files are written into fnames.  The function returns the number of */
  300. /* matching files found, or MAX_FILES+1 if too many matches for the array  */
  301.  
  302. int get_dir(filespec,fnames,max_files)
  303. char filespec[], *fnames[];
  304. int max_files;  /* the size of fnames array */
  305. {
  306.     int i=0;    /* the number of matching files counter */
  307.     int name_size;  /* strlen(filename) */
  308.     unsigned int cflag; /* the carry flag returned by get_first_match() */
  309.             /* and get_next_match() function calls */
  310.     unsigned long int fnameptr;  /* flespec cast as an unsigned long int */
  311.     dta dir_struct;  /* the file dta */
  312.     unsigned long psp_dta;  /* the dta pointer on entry to get_dir() */
  313.  
  314.  
  315.     psp_dta=get_dta();
  316.     set_dta((unsigned long)&dir_struct);
  317.  
  318.     /* get first filename */
  319.     fnameptr=(unsigned long int)filespec;
  320.     cflag=get_first_match(fnameptr,0);
  321.  
  322.     while((!cflag) && i<max_files)
  323.     {
  324.     name_size=strlen(dir_struct.name);
  325.     fnames[i]=malloc(name_size+1);
  326.     if(fnames[i]==NULL)
  327.     {
  328.         printf("Error allocating file names buffer space.  Program aborting.\n");
  329.         exit(-1);
  330.     }
  331.     strcpy(fnames[i], dir_struct.name); /* write matching filename into */
  332.                     /* the fnames array */
  333.     cflag=get_next_match(fnameptr,0);
  334.     i++;    /* increment match-count */
  335.     }
  336.     if((i == max_files) && (!cflag))
  337.     i++;
  338.  
  339.     /* restore original dta before exiting */
  340.     set_dta(psp_dta);
  341.  
  342.     return i;  /* return number of matches found */
  343.  
  344. }
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351. /* volume_label() added 6/90 by T Clune. It finds and returns the */
  352. /* volume label for a disk, or the null string if no label. You pass */
  353. /* the function the diskette and *.*, i.e., to read the c: volume label, */
  354. /* you would call: string=volume_label("c:\\*.*"); */
  355.  
  356. char *volume_label(filespec)
  357. char *filespec;
  358. {
  359.     unsigned int cflag; /* the carry flag returned by get_first_match() */
  360.             /* and get_next_match() function calls */
  361.     unsigned long int fnameptr;  /* flespec cast as an unsigned long int */
  362.     dta dir_struct;  /* the file dta */
  363.     unsigned long psp_dta;  /* the dta pointer on entry to get_dir() */
  364.  
  365.  
  366.     psp_dta=get_dta();
  367.     set_dta((unsigned long)&dir_struct);
  368.  
  369.     /* get first filename */
  370.     fnameptr=(unsigned long int)filespec;
  371.     cflag=get_first_match(fnameptr,_A_VOLID);
  372.     if(cflag)
  373.     dir_struct.name[0]='\0';
  374.     /* restore original dta before exiting */
  375.     set_dta(psp_dta);
  376.  
  377.     return dir_struct.name;
  378.  
  379. }
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386. /* get_dta() returns the address of the current dta, as an unsigned long int */
  387.  
  388. static unsigned long get_dta()
  389. {
  390.     address_union address;
  391.     union REGS inregs, outregs;
  392.     struct SREGS segregs;
  393.  
  394.     inregs.h.ah=0x2f;
  395.     intdosx(&inregs, &outregs, &segregs);
  396.  
  397.     address.s.segment=segregs.es;
  398.     address.s.offset=outregs.x.bx;
  399.  
  400.     return address.pointer;
  401.  
  402. }
  403.  
  404.  
  405. /* get_first_match() gets the first match of the filespec and returns 0 */
  406. /* if a match was found, non-zero otherwise.  The name is in the current dta */
  407.  
  408. static unsigned int get_first_match(fnameptr, flag)
  409. unsigned long int fnameptr;
  410. unsigned int flag;
  411. {
  412.     address_union address;  /* address conversion union */
  413.     union REGS inregs, outregs;
  414.     struct SREGS segregs;
  415.  
  416.  
  417.     /* get first filename */
  418.     address.pointer=fnameptr;
  419.     segregs.ds=address.s.segment;
  420.     inregs.x.dx=address.s.offset;
  421.     inregs.x.cx=flag;
  422.     inregs.h.ah=0x4E;   /* first file match function number of int 0x21 */
  423.     intdosx(&inregs, &outregs, &segregs);
  424.  
  425.     return outregs.x.cflag;
  426.  
  427. }
  428.  
  429.  
  430. /* get_next_match() gets a match after the get_first_match() call, */
  431. /* and returns 0 if a match was found, nonzero otherwise.  The name is in the */
  432. /* current dta */
  433.  
  434. static unsigned int get_next_match(fnameptr, flag)
  435. unsigned long int fnameptr;
  436. unsigned int flag;
  437. {
  438.     address_union address;  /* address conversion union */
  439.     union REGS inregs, outregs;
  440.     struct SREGS segregs;
  441.  
  442.  
  443.     /* get first filename */
  444.     address.pointer=fnameptr;
  445.     segregs.ds=address.s.segment;
  446.     inregs.x.dx=address.s.offset;
  447.     inregs.x.cx=flag;
  448.     inregs.h.ah=0x4F;  /* set function number for continuing search */
  449.     intdosx(&inregs, &outregs, &segregs);
  450.  
  451.     return outregs.x.cflag;
  452.  
  453. }
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461. /* set_dta() sets the address for the start of the new dta */
  462.  
  463. static void set_dta(pointer)
  464. unsigned long pointer;
  465. {
  466.     address_union address;
  467.     union REGS inregs, outregs;
  468.     struct SREGS segregs;
  469.  
  470.         /* set up the dta */
  471.     address.pointer=pointer;
  472.     segregs.ds=address.s.segment;
  473.     inregs.x.dx=address.s.offset;
  474.     inregs.h.ah=0x1A;   /* the function that tells DOS that POINTER is a dta */
  475.     intdosx(&inregs, &outregs, &segregs);
  476.  
  477. }
  478.  
  479.  
  480.  
  481.