home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ue312os2.zip / src / mswfile.c < prev    next >
C/C++ Source or Header  |  1994-08-26  |  19KB  |  654 lines

  1. /* The routines in this file provide support for file access under the
  2.    Microsoft Windows environment on an IBM-PC or compatible computer.
  3.  
  4.    Must be compiled with Borland C++ 2.0 or MSC 6.0 or later versions
  5.  
  6.    It should not be compiled if the WINDOW_MSWIN symbol is not set */
  7.  
  8. #include    "estruct.h"
  9. #include    <stdio.h>
  10. #include    "eproto.h"
  11. #include    "edef.h"
  12.  
  13. #if WINNT
  14. #define FNAMELEN NFILEN
  15. #else
  16. #define FNAMELEN 13
  17. #endif
  18.  
  19. #if  TURBO
  20. #include    <dir.h>
  21.  
  22. struct ffblk fileblock;    /* structure for directory searches */
  23. #endif
  24. #if    MSC | ZTC | IC
  25. #include <dos.h>
  26.  
  27. #if WINDOW_MSWIN32
  28. WIN32_FIND_DATA fileblock;
  29. HANDLE  filehandle;
  30. #else
  31. struct find_t fileblock;    /* structure for directory searches */
  32. #endif
  33. #endif
  34. #if     MSC
  35. #include <direct.h>
  36. #define getcwd _getcwd
  37. #endif
  38.  
  39. #include    "mswin.h"
  40.  
  41. /* macros */
  42. #define ATTR_DIR    (0x4010 | 0x8000)   /* attributes for dir listbox */
  43. #define ATTR_FIL    (0x0021)            /* attributes for file listbox */
  44.  
  45. /* structures */
  46. typedef struct PARAMS {     /* parameters between filenamedlg and
  47.                    FileDlgProc (pointed by Par) */
  48.     char    Name [FNAMELEN];    /* file name */
  49.     char    *Prompt;            /* prompt text for the caption */
  50. } PARAMS;
  51.  
  52. /* static variables */
  53. static  char    Path [NFILEN] = "";    /* directory path */
  54. static  char    StarName [FNAMELEN] = "*.*";    /* starname */
  55. static  PARAMS  *Par;
  56.  
  57. /* function prototypes */
  58. int EXPORT FAR PASCAL FileDlgProc (HWND hDlg, UINT wMsg, UINT wParam,
  59.                                    LONG lParam);
  60. static void    CompletePath (char *s, char *FileName);
  61. static void    UpdateAll (HWND hDlg, char *s);
  62.  
  63. /* ChangeWorkingDir:    sets the working dir to match the supplied path */
  64. /* ================                                                     */
  65.  
  66. static int ChangeWorkingDir (char * FilePath)
  67.  
  68. /* returns 0 if successful, -1 otherwise */
  69. {
  70.     char    *WorkPath;
  71.     char    *Backslash; /* will find the last backslash in the path */
  72.     char    Crushed;
  73.     int     Result;
  74.  
  75.     WorkPath = FilePath;
  76.     if (*WorkPath == '\0') return 0;    /* empty path! */
  77.     if (WorkPath[1] == ':') {   /* drive specification */
  78.         int     disk;
  79.  
  80.     _chdrive(disk = (lowerc(*WorkPath) - 'a') + 1);
  81.     if (disk != _getdrive ()) return -1;
  82.     WorkPath += 2;  /* skip that drive spec */
  83.     }
  84.     
  85.     for (Backslash = WorkPath; *Backslash != '\0'; Backslash++) ;
  86.     while (*Backslash != '\\') {
  87.         if (Backslash == WorkPath) break;
  88.     --Backslash;
  89.     }
  90.     /* Backslash now points at the last backslash in the file path. That
  91.        is the end of the directory path */
  92.     if ((Backslash == WorkPath) && (*Backslash == '\\')) ++Backslash;
  93.     Crushed = *Backslash;
  94.     *Backslash = '\0';      /* temporarily terminate the path there */
  95.     if (*WorkPath == '\0') Result = TRUE;
  96.     else Result = chdir (WorkPath);
  97.     *Backslash = Crushed;   /* restore the file path before returning */
  98.     return Result;
  99. } /* ChangeWorkingDir */
  100.  
  101. /* SetWorkingDir:   sets the working dir to the current window's path */
  102. /* =============                                                      */
  103.  
  104. int FAR PASCAL SetWorkingDir (void)
  105.  
  106. /* returns 0 if successful, -1 otherwise */
  107. /* this function also sets the text of the Path displayed in the FILE
  108.    dialog */
  109. {
  110.     int     Result;
  111.  
  112.     Result = ChangeWorkingDir (curbp->b_fname);
  113.     if (Result == 0) getcwd (Path, NFILEN);
  114.     return Result;
  115. } /* SetWorkingDir */
  116.  
  117. /* fullpathname:    fully qualifies the given pathname */
  118. /* ============                                        */
  119.  
  120. char * PASCAL   fullpathname (char *PathName, int Nbuf)
  121.  
  122. /* the PathName argument is assumed to be at least Nbuf characters
  123.    long. It is modified to contain the corresponding full pathname. The
  124.    returned address is the PathName argument. */
  125. {
  126.     char    FullName [_MAX_PATH];
  127.  
  128.     if (_fullpath(FullName, PathName, Nbuf) != NULL) {
  129.         strcpy (PathName, FullName);
  130.     }
  131.     return PathName;
  132. } /* fullpathname */
  133.  
  134. /* filenamedlg: equivalent of mlreply, but specifically to get a filename */
  135. /* ===========                                                            */
  136.  
  137. PASCAL  filenamedlg (char *prompt, char *buf, int nbuf, int fullpath)
  138. {
  139.     PARAMS  Parameters;
  140.     FARPROC ProcInstance;
  141.     BOOL    Result;
  142.  
  143.     SetWorkingDir ();
  144.     if (clexec || (kbdmode != STOP)) {  /* not interactive */
  145.         Result = mlreply (prompt, buf, nbuf);
  146.         if (Result == TRUE) {
  147.         if (fullpath) fullpathname (buf, nbuf);
  148.         }
  149.         return Result;
  150.     }
  151.     Parameters.Prompt = prompt;
  152.     Par = &Parameters;
  153.     ProcInstance = MakeProcInstance ((FARPROC)FileDlgProc, hEmacsInstance);
  154.     if (Result = (DialogBox (hEmacsInstance, "FILE", hFrameWnd,
  155.                              ProcInstance) >= 0)) {
  156.         CompletePath (buf, Parameters.Name);
  157.     }
  158.     FreeProcInstance (ProcInstance);
  159.     SetWorkingDir ();
  160.     return Result;
  161. } /* filenamedlg */
  162.  
  163. /* FileDlgOK:   process OK in File Dialog */
  164. /* =========                              */
  165.  
  166. static BOOL PASCAL FileDlgOK (HWND hDlg)
  167.  
  168. /* this is a service function for FileDlgProc. It processes the OK case.
  169.    The returned value is TRUE if the dialog box is ending, FALSE
  170.    otherwise */
  171. {
  172.     char    s [NFILEN];
  173.  
  174.     GetDlgItemText (hDlg, ID_FILENAME, s, NFILEN);
  175.     if (*s == 0) return FALSE;  /* empty name, ignore it! */
  176.     if (strchr (s, '*') || strchr (s, '?')) {
  177.     /* there is a starname here! */
  178.     UpdateAll (hDlg, s);
  179.     }
  180.     else {
  181.     int     l;
  182.     char    *n;
  183.  
  184.     l = strlen (s);
  185.     n = &s[l - 1];
  186.     if ((*n == '\\') || (*n == ':')) {
  187.         /* it is a directory or drive */
  188.         if (l < NFILEN - 1 - strlen(StarName)) {
  189.         strcat (s, StarName);
  190.         UpdateAll (hDlg, s);
  191.         }
  192.     }
  193.     else {
  194.         /* it looks like a bonafide file name ! */
  195.         int     nl = 1;
  196.  
  197.         /* first, we extract the filename portion...*/
  198.         do {
  199.         if (n-- == &s[0]) goto ExtractedOK;
  200.         if ((*n == ':') || (*n == '\\')) goto ExtractedOK;
  201.         } while (++nl < FNAMELEN);
  202.         return FALSE;
  203. ExtractedOK:
  204.         strcpy (Par->Name, ++n);
  205.         if (n - &s[0] < NFILEN - 1 - strlen(StarName)) {
  206.         strcpy (n, StarName);
  207.         /* now, we use DlgDirList to generate the full directory
  208.            path */
  209.         if (DlgDirList (hDlg, s, NULL, ID_PATH, ATTR_FIL)) {
  210.             getcwd (Path, NFILEN);
  211.             EndDialog (hDlg, 0);
  212.             return TRUE;
  213.         }
  214.         }
  215.     }
  216.     }
  217.     return FALSE;
  218. } /* FileDlgOK */
  219.  
  220. /* FileNameCompletion:  process filename edit box for name completion */
  221. /* ==================                                                 */
  222.  
  223. /* scrolls the file list box to bring the first match into view and
  224.    attempt filename completion if a space is placed at the end of the
  225.    edit field. Returns TRUE if filename completion was attempted and
  226.    successful, FALSE otherwise. */
  227. static BOOL PASCAL FileNameCompletion (HWND hDlg)
  228. {
  229.     char    s [NFILEN];
  230.     int     i;
  231.     BOOL    PleaseComplete = FALSE;
  232.  
  233.     i = GetDlgItemText (hDlg, ID_FILENAME, s, NFILEN);
  234.     while ((i > 0) && (s[--i] == ' ')) {
  235.     PleaseComplete = TRUE;
  236.     s[i] = '\0';
  237.     }
  238.     if (PleaseComplete) {
  239.     DWORD   LastSel;
  240.  
  241.     LastSel = SendDlgItemMessage (hDlg, ID_FILENAME, EM_GETSEL, 0, 0L);
  242.         SetDlgItemText (hDlg, ID_FILENAME, s);  /* remove the spaces */
  243. #if WINDOW_MSWIN32
  244.         SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL,
  245.                             (UINT)LOWORD(LastSel), (DWORD)HIWORD(LastSel));
  246. #else
  247.         SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0, LastSel);
  248. #endif
  249.     }
  250.     if (strchr (s, '\\') || strchr (s, ':') || strchr (s, '[')) {
  251.         return FALSE;   /* contains more than a plain file name. The
  252.                file list box will not be appropriate for
  253.                completion so we do not attempt anything */
  254.     }
  255.     i = SendDlgItemMessage (hDlg, ID_FILES, LB_SELECTSTRING,
  256.                             -1, (DWORD)(LPSTR)&s[0]);
  257.     if (i == LB_ERR) {
  258.         /* no match, give up! */
  259.         return FALSE;
  260.     }
  261.     if (GetFocus () != GetDlgItem (hDlg, ID_FILES)) {
  262.         SendDlgItemMessage (hDlg, ID_FILES, LB_SETTOPINDEX, i, 0L);
  263.     }
  264.     if (PleaseComplete) {
  265.         if (i != SendDlgItemMessage (hDlg, ID_FILES, LB_FINDSTRING,
  266.                                      i, (DWORD)(LPSTR)&s[0])) {
  267.             return FALSE;   /* not unique ==> completion fails */
  268.         }
  269.         else {
  270.             SendDlgItemMessage (hDlg, ID_FILES, LB_GETTEXT,
  271.                                 i, (DWORD)(LPSTR)&s[0]);
  272.             SetDlgItemText (hDlg, ID_FILENAME, s);
  273.             return TRUE;
  274.         }
  275.     }
  276.     return FALSE;
  277. } /* FileNameCompletion */
  278.  
  279. /* FileDlgProc: Open file dialog function */
  280. /* ===========                            */
  281. int EXPORT FAR PASCAL  FileDlgProc (HWND hDlg, UINT wMsg, UINT wParam,
  282.                                     LONG lParam)
  283. {
  284.     char    s [NFILEN];    /* all purpose */
  285.     int     i;
  286.     
  287.     switch (wMsg) {
  288.         
  289.     case WM_INITDIALOG:
  290.     {   /* let's build the caption */
  291.         char    DlgTitle [sizeof(PROGNAME) + 3 + 30];
  292.  
  293.         strcpy (DlgTitle, ProgName);
  294.         strcat (DlgTitle, " - ");
  295.         strcat (DlgTitle, Par->Prompt); /* hopefully, the prompt is
  296.                            under 30 char! */
  297.         i = strlen (DlgTitle) - 1;
  298.         while (DlgTitle[i] == ' ') i--;
  299.         if (DlgTitle[i] == ':') DlgTitle[i] = 0;
  300.             /* we remove the colon+spaces at the end of the prompt */
  301.         SetWindowText (hDlg, DlgTitle);
  302.     }
  303.     SetFocus (GetDlgItem (hDlg, ID_FILENAME));
  304.         CompletePath (s, StarName);
  305.         UpdateAll (hDlg, s);
  306.         i = 0;
  307.         while (in_check()) {
  308.             /* we need to send to the dialog box the characters stored
  309.            into the in_put() buffer. For instance, if the user typed
  310.            ^X^F while the startup script was running (to specify the
  311.            first file to read in) and quickly followed this by
  312.            typing a file name. The Find file dialog box would not
  313.            receive those characters which would already have been
  314.            absorbed into the in_put() pipe and would later end up
  315.            inserted at the beginning of the buffer! */
  316.         int     c;
  317.  
  318.         c = in_get();
  319.         switch (c) {
  320.         case 0: /* escape sequence, discard it... */
  321.             if (in_get() & (MOUS >> 8)) {
  322.                 in_get();
  323.                 in_get();
  324.             }
  325.             in_get();
  326.             break;
  327.         case '\b':  /* backspace */
  328.         if (i > 0) i--;
  329.         break;
  330.         case '\r':  /* Enter */
  331.         s[i] = '\0';
  332.         SetDlgItemText (hDlg, ID_FILENAME, s);
  333.         if (FileDlgOK (hDlg)) goto NoMoreTypeAhead;
  334.         i = 0;
  335.         break;
  336.         case 0x1B:  /* Escape */
  337.             EndDialog (hDlg, -1);
  338.         goto NoMoreTypeAhead;
  339.         default:
  340.             if ((c > 0x1F) && (c < 0x7F)) {
  341.                 /* regular ASCII char, stuff it into the filename */
  342.                 s[i++] = c;
  343.             }
  344.             /* else, discard it */
  345.             break;
  346.         }
  347.     }
  348.         if (i > 0) {
  349.             s[i] = '\0';
  350.         SetDlgItemText (hDlg, ID_FILENAME, s);
  351.     }
  352. #if WINDOW_MSWIN32
  353.     SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, i, -1);
  354. #else
  355.     SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL,
  356.                         0, MAKELONG(i, -1));
  357. #endif
  358.     if (FileNameCompletion (hDlg)) FileDlgOK (hDlg);
  359. NoMoreTypeAhead:
  360.     return FALSE;
  361.     
  362.     case WM_COMMAND:
  363.     switch (LOWORD(wParam)) {
  364.  
  365.     case ID_FILENAME:
  366.         if (NOTIFICATION_CODE == EN_CHANGE) {
  367.             if (FileNameCompletion (hDlg)) FileDlgOK (hDlg);
  368.         }
  369.         break;
  370.         
  371.     case ID_DIRECTORIES:
  372.         switch (NOTIFICATION_CODE) {
  373.         case LBN_SELCHANGE:
  374. #if WINDOW_MSWIN32
  375.         DlgDirSelectEx (hDlg, s, NFILEN -1 - strlen (StarName),
  376.                                 ID_DIRECTORIES);
  377. #else
  378.         DlgDirSelect (hDlg, s, ID_DIRECTORIES);
  379. #endif
  380.         strcat (s, StarName);
  381.         SetDlgItemText (hDlg, ID_FILENAME, s);
  382.         break;
  383.         case LBN_DBLCLK:
  384.         FileDlgOK (hDlg);   /* same as OK */
  385.         }
  386.         break;
  387.         
  388.     case ID_FILES:
  389.         switch (NOTIFICATION_CODE) {
  390.         case LBN_SELCHANGE:
  391. #if WINDOW_MSWIN32
  392.         DlgDirSelectEx (hDlg, s, NFILEN -1, ID_FILES);
  393. #else
  394.         DlgDirSelect (hDlg, s, ID_FILES);
  395. #endif
  396.         i = strlen (s) - 1;
  397.         if (s[i] == '.') s[i] = 0;  /* zap dot at end of file
  398.                            name */
  399.             SetDlgItemText (hDlg, ID_FILENAME, s);
  400.         break;
  401.         case LBN_DBLCLK:
  402.         FileDlgOK (hDlg);   /* same as OK */
  403.         }
  404.         break;
  405.         
  406.     case IDOK:
  407.             FileDlgOK (hDlg);
  408.         break;
  409.         
  410.     case IDCANCEL:
  411.         EndDialog (hDlg, -1);
  412.         break;
  413.     }
  414.     break;
  415.     
  416.     default:
  417.     return FALSE;
  418.     }
  419.     return FALSE;
  420. } /* FileDlgProc */
  421.  
  422. /* CompletePath:  prepend Path to the FileName, result in s */
  423. /* ============                                             */
  424.  
  425. static void    CompletePath (char *s, char *FileName)
  426.  
  427. /* s must be at least NFILEN characters long, while the length of Path +
  428.    the length of FileName must be < NFILEN */
  429. {
  430.     strcpy (s, Path);
  431.     if ((*s != 0) && (s[strlen (s) - 1] != '\\')) strcat (s, "\\");
  432.     strcat (s, FileName);
  433. } /* CompletePath */
  434.  
  435. /* UpdateAll:   updates all the controls from the path in s */
  436. /* =========                                                */
  437.  
  438. static void    UpdateAll (HWND hDlg, char *s)
  439.  
  440. /* this function also keeps the static variables Path and StarName up to
  441.    date */
  442. {
  443.     if (DlgDirList (hDlg, s, ID_DIRECTORIES, ID_PATH, ATTR_DIR)) {
  444.         getcwd (Path, NFILEN);
  445.         strcpy (StarName, s);
  446.     DlgDirList (hDlg, s, ID_FILES, NULL, ATTR_FIL);
  447.         SetDlgItemText (hDlg, ID_FILENAME, StarName);
  448. #if WINDOW_MSWIN32
  449.     SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0, -1);
  450. #else
  451.     SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0, MAKELONG(0, -1));
  452. #endif
  453.     }
  454. } /* UpdateAll */
  455.  
  456. #if    TURBO | IC
  457. /*    FILE Directory routines        */
  458. /* all borrowed from MSDOS.C */
  459.  
  460. char path[NFILEN];    /* path of file to find */
  461. char rbuf[NFILEN];    /* return file buffer */
  462.  
  463. /*    do a wild card directory search (for file name completion) */
  464.  
  465. char *PASCAL getffile(fspec)
  466.  
  467. char *fspec;    /* pattern to match */
  468.  
  469. {
  470.     register int index;        /* index into various strings */
  471.     register int point;        /* index into other strings */
  472.     register int extflag;        /* does the file have an extention? */
  473.     char fname[NFILEN];        /* file/path for DOS call */
  474.  
  475.     /* first parse the file path off the file spec */
  476.     strcpy(path, fspec);
  477.     index = strlen(path) - 1;
  478.     while (index >= 0 && (path[index] != '/' &&
  479.                 path[index] != '\\' && path[index] != ':'))
  480.         --index;
  481.     path[index+1] = 0;
  482.  
  483.     /* check for an extension */
  484.     point = strlen(fspec) - 1;
  485.     extflag = FALSE;
  486.     while (point > index) {
  487.         if (fspec[point] == '.') {
  488.             extflag = TRUE;
  489.             break;
  490.         }
  491.         point--;
  492.     }
  493.  
  494.     /* construct the composite wild card spec */
  495.     strcpy(fname, path);
  496.     strcat(fname, &fspec[index+1]);
  497.     strcat(fname, "*");
  498.     if (extflag == FALSE)
  499.         strcat(fname, ".*");
  500.  
  501.     /* and call for the first file */
  502.     if (findfirst(fname, &fileblock, FA_DIREC) == -1)
  503.         return(NULL);
  504.  
  505.     /* return the first file name! */
  506.     strcpy(rbuf, path);
  507.     strcat(rbuf, fileblock.ff_name);
  508.     mklower(rbuf);
  509.     if (fileblock.ff_attrib == 16)
  510.         strcat(rbuf, DIRSEPSTR);
  511.     return(rbuf);
  512. }
  513.  
  514. char *PASCAL getnfile()
  515.  
  516. {
  517.     register int index;        /* index into various strings */
  518.     register int point;        /* index into other strings */
  519.     register int extflag;        /* does the file have an extention? */
  520.     char fname[NFILEN];        /* file/path for DOS call */
  521.  
  522.     /* and call for the first file */
  523.     if (findnext(&fileblock) == -1)
  524.         return(NULL);
  525.  
  526.     /* return the first file name! */
  527.     strcpy(rbuf, path);
  528.     strcat(rbuf, fileblock.ff_name);
  529.     mklower(rbuf);
  530.     if (fileblock.ff_attrib == 16)
  531.         strcat(rbuf, DIRSEPSTR);
  532.     return(rbuf);
  533. }
  534. #else
  535. #if    (MSC || ZTC)
  536. /*    FILE Directory routines        */
  537.  
  538. char path[NFILEN];    /* path of file to find */
  539. char rbuf[NFILEN];    /* return file buffer */
  540.  
  541. /*    do a wild card directory search (for file name completion) */
  542.  
  543. char *PASCAL getffile(fspec)
  544.  
  545. char *fspec;    /* pattern to match */
  546.  
  547. {
  548.     register int index;        /* index into various strings */
  549.     register int point;        /* index into other strings */
  550.     register int extflag;        /* does the file have an extention? */
  551.     char fname[NFILEN];        /* file/path for DOS call */
  552.  
  553.     /* first parse the file path off the file spec */
  554.     strcpy(path, fspec);
  555.     index = strlen(path) - 1;
  556.     while (index >= 0 && (path[index] != '/' &&
  557.                 path[index] != '\\' && path[index] != ':'))
  558.         --index;
  559.     path[index+1] = 0;
  560.  
  561.     /* check for an extension */
  562.     point = strlen(fspec) - 1;
  563.     extflag = FALSE;
  564.     while (point > index) {
  565.         if (fspec[point] == '.') {
  566.             extflag = TRUE;
  567.             break;
  568.         }
  569.         point--;
  570.     }
  571.  
  572.     /* construct the composite wild card spec */
  573.     strcpy(fname, path);
  574.     strcat(fname, &fspec[index+1]);
  575.     strcat(fname, "*");
  576.     if (extflag == FALSE)
  577.         strcat(fname, ".*");
  578.  
  579.     /* and call for the first file */
  580. #if WINDOW_MSWIN32
  581.         if ((filehandle = FindFirstFile (fname, &fileblock)) ==
  582.             INVALID_HANDLE_VALUE)
  583. #else
  584.     if (_dos_findfirst(fname, _A_NORMAL|_A_SUBDIR, &fileblock) != 0)
  585. #endif
  586.         return(NULL);
  587.  
  588.     /* return the first file name! */
  589.     strcpy(rbuf, path);
  590. #if WINDOW_MSWIN32
  591.         strcat(rbuf, fileblock.cFileName);
  592.         mklower(rbuf);
  593.         if (fileblock.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  594. #else
  595.     strcat(rbuf, fileblock.name);
  596.     mklower(rbuf);
  597.     if (fileblock.attrib == 16)
  598. #endif
  599.         strcat(rbuf, DIRSEPSTR);
  600.     return(rbuf);
  601. }
  602.  
  603. char *PASCAL getnfile()
  604.  
  605. {
  606.     register int index;        /* index into various strings */
  607.     register int point;        /* index into other strings */
  608.     register int extflag;        /* does the file have an extention? */
  609.     char fname[NFILEN];        /* file/path for DOS call */
  610.  
  611.     /* and call for the next file */
  612. #if WINDOW_MSWIN32
  613.         if (!FindNextFile (filehandle, &fileblock)) {
  614.             FindClose(filehandle);
  615.             return (NULL);
  616.         }
  617. #else
  618.     if (_dos_findnext(&fileblock) != 0)
  619.         return(NULL);
  620. #endif
  621.  
  622.     /* return the first file name! */
  623.     strcpy(rbuf, path);
  624. #if WINDOW_MSWIN32
  625.         strcat(rbuf, fileblock.cFileName);
  626.         mklower(rbuf);
  627.         if (fileblock.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  628. #else
  629.     strcat(rbuf, fileblock.name);
  630.     mklower(rbuf);
  631.     if (fileblock.attrib == 16)
  632. #endif
  633.         strcat(rbuf, DIRSEPSTR);
  634.     return(rbuf);
  635. }
  636. #else
  637. char *PASCAL getffile(fspec)
  638.  
  639. char *fspec;    /* file to match */
  640.  
  641. {
  642.     return(NULL);
  643. }
  644.  
  645. char *PASCAL getnfile()
  646.  
  647. {
  648.     return(NULL);
  649. }
  650. #endif
  651. #endif
  652.  
  653.  
  654.