home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / ntcode / lkbackup / ntdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  6.6 KB  |  332 lines

  1. // pulled this out of gnu tar port for NT. The writer pulled it out of NT Perl.
  2. // It's really getting around...
  3.  
  4. /* $Log: ntdir.c,v $
  5.  * Revision 1.3  1993/09/16  01:10:14  ESullivan
  6.  * Added an $Id $ section.
  7.  *
  8.  * Revision 1.2  1993/09/07  02:09:30  ESullivan
  9.  * added a $Log area.
  10.  *
  11.  * Revision 1.1  1993/09/05  04:59:21  ESullivan
  12.  * Initial revision
  13.  * */
  14.  
  15. /*
  16.  *  Copyright (c) 1993, Intergraph Corporation
  17.  *
  18.  *  You may distribute under the terms of either the GNU General Public
  19.  *  License or the Artistic License, as specified in the perl README file.
  20.  *
  21.  *  Various Unix compatibility functions and NT specific functions.
  22.  *
  23.  *  Some of this code was derived from the MSDOS port(s) and the OS/2 port.
  24.  *
  25.  *  I pulled this out of the PERL NT port (the memory functions came
  26.  *  from PERL itself (v 4.036).  Clark Williams of Intergraph wrote
  27.  *  the original of this, and I apologize to him in advance for hacking
  28.  *  it all up.  :-)
  29.  *
  30.  */
  31. char ntdirver[] = "$Id: ntdir.c,v 1.3 1993/09/16 01:10:14 ESullivan Exp ESullivan $";
  32. #if 0
  33. #include "EXTERN.h"
  34. #include "perl.h"
  35. #endif /* 0 */
  36. #include <fcntl.h>
  37. #include <process.h>
  38. #include <sys/stat.h>
  39. #include <assert.h>
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <malloc.h>
  44.  
  45. #include "nt.h"
  46.  
  47. //
  48. // These exist elsewhere in the PERL for NT code, but I have to
  49. // redo them because I don't have the original.
  50. //
  51. #define index   strchr
  52.  
  53. static void fatal( char * );
  54. static char nomem[] = "Out of memory!\n";
  55. static short nomemok = FALSE;
  56.  
  57.  
  58. //
  59. // UNIX compatible directory access functions for NT
  60. //
  61.  
  62. //
  63. // File names are converted to lowercase if the
  64. // CONVERT_TO_LOWER_CASE variable is defined.
  65. //
  66.  
  67. #define CONVERT_TO_LOWER_CASE
  68.  
  69. #define PATHLEN 1024
  70.  
  71. //
  72. // The idea here is to read all the directory names into a string table
  73. // (separated by nulls) and when one of the other dir functions is called
  74. // return the pointer to the current file name. 
  75. //
  76.  
  77. DIR *
  78. opendir(char *filename)
  79. {
  80.     DIR            *p;
  81.     long            len;
  82.     long            idx;
  83.     char            scannamespc[PATHLEN];
  84.     char       *scanname = scannamespc;
  85.     struct stat        sbuf;
  86.     WIN32_FIND_DATA FindData;
  87.     HANDLE          fh;
  88.  
  89.     //
  90.     // check to see if we\'ve got a directory
  91.     //
  92.  
  93.     if (stat (filename, &sbuf) < 0 ||
  94.     sbuf.st_mode & _S_IFDIR == 0) {
  95.     return NULL;
  96.     }
  97.  
  98.     //
  99.     // Get us a DIR structure
  100.     //
  101.  
  102.     Newz (1501, p, 1, DIR);
  103.     if (p == NULL)
  104.     return NULL;
  105.     
  106.     //
  107.     // Create the search pattern
  108.     //
  109.  
  110.     strcpy(scanname, filename);
  111.  
  112.     if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
  113.     strcat(scanname, "/*");
  114.     else
  115.     strcat(scanname, "*");
  116.  
  117.     //
  118.     // do the FindFirstFile call
  119.     //
  120.  
  121.     fh = FindFirstFile (scanname, &FindData);
  122.     if (fh == INVALID_HANDLE_VALUE) {
  123.     return NULL;
  124.     }
  125.  
  126.     //
  127.     // now allocate the first part of the string table for the
  128.     // filenames that we find.
  129.     //
  130.  
  131.     idx = strlen(FindData.cFileName)+1;
  132.     New (1502, p->start, idx, char);
  133.     if (p->start == NULL) {
  134.     fatal ("opendir: malloc failed!\n");
  135.     }
  136.     strcpy (p->start, FindData.cFileName);
  137.     p->nfiles++;
  138.     
  139.     //
  140.     // loop finding all the files that match the wildcard
  141.     // (which should be all of them in this directory!).
  142.     // the variable idx should point one past the null terminator
  143.     // of the previous string found.
  144.     //
  145.     while (FindNextFile(fh, &FindData)) {
  146.     len = strlen (FindData.cFileName);
  147.  
  148.     //
  149.     // bump the string table size by enough for the
  150.     // new name and it's null terminator 
  151.     //
  152.  
  153.     Renew (p->start, idx+len+1, char);
  154.     if (p->start == NULL) {
  155.         fatal ("opendir: malloc failed!\n");
  156.     }
  157.     strcpy(&p->start[idx], FindData.cFileName);
  158.     p->nfiles++;
  159.     idx += len+1;
  160.     }
  161.     FindClose(fh);
  162.     p->size = idx;
  163.     p->curr = p->start;
  164.     return p;
  165. }
  166.  
  167.  
  168. //
  169. // Readdir just returns the current string pointer and bumps the
  170. // string pointer to the next entry.
  171. //
  172.  
  173. struct direct  *
  174. readdir(DIR *dirp)
  175. {
  176.     int         len;
  177.     static int  dummy = 0;
  178.  
  179.     if (dirp->curr) {
  180.  
  181.     //
  182.     // first set up the structure to return
  183.     //
  184.  
  185.     len = strlen(dirp->curr);
  186.     strcpy(dirp->dirstr.d_name, dirp->curr);
  187.     dirp->dirstr.d_namlen = len;
  188.  
  189.     //
  190.     // Fake inode
  191.     //
  192.     dirp->dirstr.d_ino = dummy++;
  193.  
  194.     //
  195.     // Now set up for the next call to readdir
  196.     //
  197.  
  198.     dirp->curr += len + 1;
  199.     if (dirp->curr >= (dirp->start + dirp->size)) {
  200.         dirp->curr = NULL;
  201.     }
  202.  
  203.     return &(dirp->dirstr);
  204.  
  205.     } else
  206.     return NULL;
  207. }
  208.  
  209. //
  210. // Telldir returns the current string pointer position
  211. //
  212.  
  213. long
  214. telldir(DIR *dirp)
  215. {
  216.     return (long) dirp->curr;    /* ouch! pointer to long cast */
  217. }
  218.  
  219. //
  220. // Seekdir moves the string pointer to a previously saved position
  221. // (Saved by telldir).
  222.  
  223. void
  224. seekdir(DIR *dirp, long loc)
  225. {
  226.     dirp->curr = (char *) loc;    /* ouch! long to pointer cast */
  227. }
  228.  
  229. //
  230. // Rewinddir resets the string pointer to the start
  231. //
  232.  
  233. void
  234. rewinddir(DIR *dirp)
  235. {
  236.     dirp->curr = dirp->start;
  237. }
  238.  
  239. //
  240. // This just free\'s the memory allocated by opendir
  241. //
  242.  
  243. void
  244. closedir(DIR *dirp)
  245. {
  246.     Safefree(dirp->start);
  247.     Safefree(dirp);
  248. }
  249.  
  250.  
  251. //
  252. // These are memory allocation functions which came from PERL.
  253. //
  254.  
  255. /* NOTE:  Do not call the next three routines directly.  Use the macros
  256.  * in handy.h, so that we can easily redefine everything to do tracking of
  257.  * allocated hunks back to the original New to track down any memory leaks.
  258.  */
  259.  
  260. char *
  261. safemalloc(size)
  262. MEM_SIZE size;
  263. {
  264.     char *ptr;
  265.  
  266.     ptr = malloc(size?size:1);    /* malloc(0) is NASTY on our system */
  267.     if (ptr != Nullch)
  268.     return ptr;
  269.     else if (nomemok)
  270.     return Nullch;
  271.     else {
  272.     fputs(nomem,stderr) FLUSH;
  273.     exit(1);
  274.     }
  275.     /*NOTREACHED*/
  276. }
  277.  
  278. /* paranoid version of realloc */
  279.  
  280. char *
  281. saferealloc(where,size)
  282. char *where;
  283. MEM_SIZE size;
  284. {
  285.     char *ptr;
  286.  
  287.     if (!where)
  288.     fatal("Null realloc");
  289.     ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  290.     if (ptr != Nullch)
  291.     return ptr;
  292.     else if (nomemok)
  293.     return Nullch;
  294.     else {
  295.     fputs(nomem,stderr) FLUSH;
  296.     exit(1);
  297.     }
  298.     /*NOTREACHED*/
  299. }
  300.  
  301. /* safe version of free */
  302.  
  303. void
  304. safefree(where)
  305. char *where;
  306. {
  307.     if (where) {
  308.     /*SUPPRESS 701*/
  309.     free(where);
  310.     }
  311. }
  312.  
  313.  
  314.  
  315.  
  316.  
  317. void *memzero( char *pcszTarget, size_t lNumBytes )
  318. {
  319.     return( memset( pcszTarget, 0, lNumBytes ) );
  320. }
  321.  
  322. /* Print an error message containing the string TEXT, then exit.  */
  323.  
  324. static void fatal(char *string)
  325. {
  326.     fprintf(stderr, "%s\n", string);
  327.     exit(2);
  328. }
  329.  
  330. /***** END OF FILE nt.c *****/
  331.  
  332.