home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / INTERNET / UPC2S1.ZIP / NDIR.C < prev    next >
C/C++ Source or Header  |  1993-08-22  |  7KB  |  217 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    n d i r . c                                                     */
  3. /*                                                                    */
  4. /*    Berkeley-style directory reading routine on MS-DOS by Samuel    */
  5. /*    Lam <skl@van-bc.UUCP>, June/87                                  */
  6. /*                                                                    */
  7. /*    Changes Copyright (c) 1990, 1991 by Andrew H. Derbyshire        */
  8. /*--------------------------------------------------------------------*/
  9.  
  10. /*--------------------------------------------------------------------*/
  11. /*                   Standard library include files                   */
  12. /*--------------------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <dos.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20.  
  21. /*--------------------------------------------------------------------*/
  22. /*                    UUPC/extended include files                     */
  23. /*--------------------------------------------------------------------*/
  24.  
  25. #include "lib.h"
  26. #include "uundir.h"
  27. #include "getdta.h"
  28.  
  29. #include "dos2unix.h"
  30.  
  31. #ifndef __TURBOC__
  32. #include "getdta.h"           /* Custom versions of Disk Xfer Addr
  33.                                  functions for MS environment only   */
  34. #endif
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /*                          Global variables                          */
  38. /*--------------------------------------------------------------------*/
  39.  
  40. currentfile();
  41.  
  42. static DIR *thisDirP = NULL;
  43. static DIR *lastDirP = NULL;
  44. static openForBusiness = FALSE;
  45.  
  46. /*--------------------------------------------------------------------*/
  47. /*    o p e n d i r x                                                 */
  48. /*                                                                    */
  49. /*    Open a directory                                                */
  50. /*--------------------------------------------------------------------*/
  51.  
  52. extern DIR *opendirx( const char *dirname, char *pattern)
  53. {
  54.    union REGS inregs, outregs;
  55.    struct SREGS segregs;
  56.    char pathname[FILENAME_MAX];
  57.    DTA far *dtasave;
  58.    DTA far *dtaptr;
  59.    char far *pathptr;
  60.  
  61. /*--------------------------------------------------------------------*/
  62. /*                    Build pathname to be scanned                    */
  63. /*--------------------------------------------------------------------*/
  64.  
  65.    strcpy(pathname, dirname);
  66.    if ((*pattern != '/') || (dirname[ strlen(dirname) - 1] != '/'))
  67.       strcat(pathname,"/");
  68.    strcat(pathname, pattern);
  69.  
  70.    /* allocate control block */
  71.    thisDirP = malloc(sizeof(DIR));
  72.  
  73. /*--------------------------------------------------------------------*/
  74. /*                     Set disk transfer address                      */
  75. /*--------------------------------------------------------------------*/
  76.  
  77.    dtasave = (DTA far *)getdta();
  78.    dtaptr = (DTA far *)&(thisDirP->dirdta);
  79.    setdta((char far *)dtaptr);
  80.  
  81. /*--------------------------------------------------------------------*/
  82. /*                      look for the first file                       */
  83. /*--------------------------------------------------------------------*/
  84.  
  85.    inregs.h.ah = 0x4e;
  86.    pathptr = (char far *)pathname;
  87.    segregs.ds = FP_SEG(pathptr);
  88.    inregs.x.dx = FP_OFF(pathptr);
  89.    inregs.x.cx = 0;   /* attribute */
  90.    intdosx(&inregs, &outregs, &segregs);
  91.  
  92.    /* bad directory name? */
  93.    if (outregs.x.cflag && (outregs.x.ax == 2 || outregs.x.ax == 3)) {
  94.       free(thisDirP);
  95.       return NULL;
  96.    }
  97.  
  98.    thisDirP->dirfirst = outregs.x.cflag ? outregs.x.ax : 0;
  99.  
  100.    setdta((char far *)dtasave);
  101.    strcpy(thisDirP->dirid, "DIR");
  102.  
  103.    printmsg(2,"opendir: Address is %p", thisDirP );
  104.    openForBusiness = TRUE;
  105.    return thisDirP;
  106.  
  107. } /*opendir*/
  108.  
  109.  
  110. /*--------------------------------------------------------------------*/
  111. /*    r e a d d i r                                                   */
  112. /*                                                                    */
  113. /*    Get next entry in a directory                                   */
  114. /*--------------------------------------------------------------------*/
  115.  
  116. struct direct *readdir(DIR *dirp)
  117. {
  118.    int errcode;
  119.  
  120. /*--------------------------------------------------------------------*/
  121. /*    Debugging code for failures when running on Novell networks     */
  122. /*--------------------------------------------------------------------*/
  123.  
  124.    if ( dirp == NULL )
  125.    {
  126.       flushall();
  127.       printmsg(0,"readdir: INTERNAL ERROR: dirp pointer is NULL");
  128.       printmsg(0,"readdir: Snuffles debug code: %s %p %p %p",
  129.                   openForBusiness ? "Open" : "Closed",
  130.                   lastDirP,
  131.                   thisDirP );
  132.       flushall();
  133.       panic();
  134.    }
  135.  
  136.    if (!equal(dirp->dirid, "DIR"))
  137.    {
  138.       flushall();
  139.       printmsg(0,"readdir: INTERNAL ERROR: No search in progress");
  140.       printmsg(0,"readdir: Snuffles debug code: %s %p %p %p %s",
  141.                   openForBusiness ? "Open" : "Closed",
  142.                   lastDirP,
  143.                   thisDirP,
  144.                   dirp,
  145.                   dirp->dirid );
  146.       flushall();
  147.       panic();
  148.    }
  149.  
  150.    if (dirp->dirfirst == -1) {
  151.       union REGS inregs, outregs;
  152.       struct SREGS segregs;
  153.       DTA far *dtaptr;
  154.       DTA far *dtasave;
  155.  
  156.      /* set DTA address to our buffer each time we're called */
  157.       dtasave = (DTA far *)getdta();
  158.       dtaptr = (DTA far *)&(dirp->dirdta);
  159.       setdta((char far *)dtaptr);
  160.  
  161.       inregs.h.ah = 0x4f;
  162.       segregs.ds = FP_SEG(dtaptr);
  163.       inregs.x.dx = FP_OFF(dtaptr);
  164.       intdosx(&inregs, &outregs, &segregs);
  165.       errcode = outregs.x.cflag ? outregs.x.ax : 0;
  166.  
  167.       setdta((char far *)dtasave);  /* Restore DTA address     */
  168.  
  169.    } else {
  170.  
  171.       errcode = dirp->dirfirst;
  172.       dirp->dirfirst = -1;
  173.  
  174.    };
  175.  
  176.    /* no more files in directory? */
  177.    if (errcode == 18)
  178.       return NULL;
  179.  
  180.    if ( errcode != 0)
  181.    {
  182.       errno = errcode;
  183.       printerr( "readdir" );
  184.       panic();
  185.    }
  186.  
  187.    dirp->dirent.d_ino = -1;   /* no inode information */
  188.    strlwr(strcpy(dirp->dirent.d_name, dirp->dirdta.filename));
  189.    dirp->dirent.d_namlen = strlen(dirp->dirent.d_name);
  190.    dirp->dirent.d_reclen = sizeof(struct direct) - (MAXNAMLEN + 1) +
  191.       ((((dirp->dirent.d_namlen + 1) + 3) / 4) * 4);
  192.  
  193.    dirp->dirent.d_modified = dos2unix( dirp->dirdta.filedate,
  194.                                         dirp->dirdta.filetime );
  195.    dirp->dirent.d_size     = dirp->dirdta.filesize;
  196.  
  197.    return &(dirp->dirent);
  198.  
  199. } /*readdir*/
  200.  
  201. /*--------------------------------------------------------------------*/
  202. /*    c l o s e d i r                                                 */
  203. /*                                                                    */
  204. /*    Close a directory                                               */
  205. /*--------------------------------------------------------------------*/
  206.  
  207. void closedir(DIR *dirp)
  208. {
  209.  
  210.    strcpy(dirp->dirid, "CLO");
  211.    lastDirP = dirp;
  212.    openForBusiness = FALSE;
  213.    printmsg(2,"closedir: Freeing dirp at %p", dirp );
  214.    free(dirp);
  215.  
  216. } /*closedir*/
  217.