source: trunk/src/emx/src/lib/io/eadread.c@ 236

Last change on this file since 236 was 236, checked in by zap, 23 years ago

See ChangeLog.

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