home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / IO / EADREAD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  5.0 KB  |  205 lines

  1. /* eadread.c (emx+gcc) -- Copyright (c) 1993 by Eberhard Mattes */
  2.  
  3. #define INCL_DOSFILEMGR
  4. #include <os2.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <io.h>
  8. #include <errno.h>
  9. #include <sys/ead.h>
  10. #include "ea.h"
  11.  
  12. struct gea_data
  13. {
  14.   int gea_alloc;
  15.   int gea_used;
  16.   int total_name_len;
  17.   int total_value_size;
  18.   int fea_size;
  19.   int count;
  20.   ULONG *patch;
  21.   PGEA2LIST gea_ptr;
  22. };
  23.  
  24.  
  25. static int _ead_make_gea (struct _ead_data *ead, PDENA2 pdena, void *arg)
  26. {
  27.   ULONG size;
  28.   PGEA2 pgea;
  29.   struct gea_data *p;
  30.  
  31.   p = arg;
  32.   size = _EA_ALIGN (sizeof (GEA2) + pdena->cbName);
  33.   if (p->gea_used + size > p->gea_alloc)
  34.     {
  35.       p->gea_alloc += 512;             /* increment must be > size */
  36.       p->gea_ptr = realloc (p->gea_ptr, p->gea_alloc);
  37.       if (p->gea_ptr == NULL)
  38.         {
  39.           errno = ENOMEM;
  40.           return (-1);
  41.         }
  42.     }
  43.   pgea = (PGEA2)((char *)p->gea_ptr + p->gea_used);
  44.   pgea->oNextEntryOffset = size;
  45.   pgea->cbName = pdena->cbName;
  46.   if (pdena->szName[pdena->cbName] != 0)
  47.     abort ();
  48.   memcpy (pgea->szName, pdena->szName, pdena->cbName + 1);
  49.   p->patch = &pgea->oNextEntryOffset;
  50.   p->gea_used += size;
  51.   size = _EA_SIZE2 (pdena);
  52.   p->fea_size += size;
  53.   p->total_name_len += pdena->cbName;
  54.   p->total_value_size += pdena->cbValue;
  55.   ++p->count;
  56.   return (0);
  57. }
  58.  
  59.  
  60. int _ead_read (_ead ead, const char *path, int handle, int flags)
  61. {
  62.   ULONG rc;
  63.   struct gea_data gd;
  64.   EAOP2 eaop;
  65.  
  66.   _ead_clear (ead);
  67.   if (_osmode != OS2_MODE)
  68.     {
  69.       if (path != NULL)
  70.         {
  71.           if (access (path, 0) != 0)
  72.             return (-1);
  73.         }
  74.       else
  75.         {
  76.           if (tell (handle) == -1)
  77.             return (-1);
  78.         }
  79.       return (0);
  80.     }
  81.   gd.gea_alloc = sizeof (GEA2LIST);
  82.   gd.gea_ptr = malloc (gd.gea_alloc);
  83.   if (gd.gea_ptr == NULL)
  84.     {
  85.       errno = ENOMEM;
  86.       return (-1);
  87.     }
  88.   gd.gea_used = sizeof (eaop.fpGEA2List->cbList);
  89.   gd.fea_size = sizeof (eaop.fpFEA2List->cbList);
  90.   gd.total_name_len = 0;
  91.   gd.total_value_size = 0;
  92.   gd.count = 0;
  93.   gd.patch = NULL;
  94.   if (_ead_enum (ead, path, handle, _ead_make_gea, &gd) < 0)
  95.     {
  96.       if (gd.gea_ptr != NULL)
  97.         free (gd.gea_ptr);
  98.       return (-1);
  99.     }
  100.   if (gd.count > 0)
  101.     {
  102.       *gd.patch = 0;
  103.       eaop.fpGEA2List = gd.gea_ptr; gd.gea_ptr = NULL;
  104.       eaop.fpGEA2List->cbList = gd.gea_used;
  105.       if (_ead_size_buffer (ead, gd.fea_size) < 0)
  106.         {
  107.           free (eaop.fpGEA2List);
  108.           return (-1);
  109.         }
  110.       ead->buffer->cbList = gd.fea_size;
  111.       eaop.fpFEA2List = ead->buffer;
  112.       eaop.oError = 0;
  113.       if (path == NULL)
  114.         rc = DosQueryFileInfo (handle, FIL_QUERYEASFROMLIST, &eaop,
  115.                                sizeof (eaop));
  116.       else
  117.         rc = DosQueryPathInfo (path, FIL_QUERYEASFROMLIST, &eaop,
  118.                                sizeof (eaop));
  119.       if (rc != 0)
  120.         {
  121.           free (eaop.fpGEA2List);
  122.           _ea_set_errno (rc);
  123.           return (-1);
  124.         }
  125.       free (eaop.fpGEA2List); eaop.fpGEA2List = NULL;
  126.     }
  127.   if (gd.count != 0 &&  _ead_make_index (ead, gd.count) < 0)
  128.     {
  129.       errno = ENOMEM;
  130.       return (-1);
  131.     }
  132.   ead->count = gd.count;
  133.   ead->total_value_size = gd.total_value_size;
  134.   ead->total_name_len = gd.total_name_len;
  135.   return (0);
  136. }
  137.  
  138.  
  139. int _ead_enum (struct _ead_data *ead, const char *path, int handle,
  140.                int (*function)(struct _ead_data *ead, PDENA2 pdena, void *arg),
  141.                void *arg)
  142. {
  143.   void *dena_buf;
  144.   const void *fileref;
  145.   ULONG dena_buf_size, index, count, rc, reftype, hf, i;
  146.   PDENA2 pdena;
  147.   int expand_dena_buf;
  148.  
  149.   if (path != NULL)
  150.     {
  151.       reftype = ENUMEA_REFTYPE_PATH;
  152.       fileref = path;
  153.     }
  154.   else
  155.     {
  156.       hf = handle;
  157.       reftype = ENUMEA_REFTYPE_FHANDLE;
  158.       fileref = &hf;
  159.     }
  160.   dena_buf_size = 0; dena_buf = NULL;
  161.   expand_dena_buf = 1; index = 1;
  162.   for (;;)
  163.     {
  164.       if (expand_dena_buf)
  165.         {
  166.           dena_buf_size += 512;
  167.           dena_buf = realloc (dena_buf, dena_buf_size);
  168.           if (dena_buf == NULL)
  169.             {
  170.               errno = ENOMEM;
  171.               return (-1);
  172.             }
  173.         }
  174.       count = -1;
  175.       rc = DosEnumAttribute (reftype, fileref, index,
  176.                              dena_buf, dena_buf_size, &count,
  177.                              ENUMEA_LEVEL_NO_VALUE);
  178.       if (rc == ERROR_BUFFER_OVERFLOW)
  179.         expand_dena_buf = 1;
  180.       else if (rc != 0)
  181.         {
  182.           free (dena_buf);
  183.           _ea_set_errno (rc);
  184.           return (-1);
  185.         }
  186.       else if (count == 0)
  187.         break;
  188.       else
  189.         {
  190.           expand_dena_buf = 0; pdena = dena_buf;
  191.           for (i = 0; i < count; ++i)
  192.             {
  193.               if (function (ead, pdena, arg) < 0)
  194.                 {
  195.                   free (dena_buf);
  196.                   return (-1);
  197.                 }
  198.               pdena = (PDENA2)((char *)pdena + pdena->oNextEntryOffset);
  199.             }
  200.           index += count;
  201.         }
  202.     }
  203.   return (0);
  204. }
  205.