libdebian-installer
Functions
Di_parser_rfc822

Functions

int di_parser_rfc822_read (char *begin, size_t size, di_parser_info *fieldinfo, di_parser_read_entry_new entry_new, di_parser_read_entry_finish entry_finish, void *user_data)
 
int di_parser_rfc822_read_file (const char *file, di_parser_info *fieldinfo, di_parser_read_entry_new entry_new, di_parser_read_entry_finish entry_finish, void *user_data)
 
int di_parser_rfc822_write_file (const char *file, di_parser_info *fieldinfo, di_parser_write_entry_next entry_next, void *user_data)
 

Detailed Description

Function Documentation

◆ di_parser_rfc822_read()

int di_parser_rfc822_read ( char *  begin,
size_t  size,
di_parser_info fieldinfo,
di_parser_read_entry_new  entry_new,
di_parser_read_entry_finish  entry_finish,
void *  user_data 
)

Parse a rfc822 formated file

Parameters
beginbegin of memory segment
sizesize of memory segment
fieldinfoparser info
entry_newfunction which is called before each entry, may return the new entry or return NULL
entry_finishfunction which is called after each entry, return non-0 aborts the parsing
user_datauser_data for parser functions
Returns
number of parsed entries
39 {
40  char *cur, *end;
41  char *field_begin, *field_end;
42 #if MODIFIER
43  char *field_modifier_begin, *field_modifier_end;
44 #endif
45  char *value_begin, *value_end;
46 #ifndef HAVE_MEMRCHR
47  char *temp;
48 #endif
49  int nr = 0;
50  size_t readsize;
51  size_t field_size;
52 #if MODIFIER
53  size_t field_modifier_size;
54 #endif
55  size_t value_size;
56  const di_parser_fieldinfo *fip = NULL;
57  di_rstring field_string;
58  di_rstring field_modifier_string;
59  di_rstring value_string;
60  void *act = NULL;
61 
62  cur = begin;
63  end = begin + size;
64 
65  while (cur < end)
66  {
67  if (*cur == '\n')
68  {
69  cur++;
70  continue;
71  }
72 
73  nr++;
74 
75  if (entry_new)
76  act = entry_new (user_data);
77  else
78  act = NULL;
79 
80  while (1)
81  {
82  field_begin = cur;
83  readsize = end - field_begin;
84  if (!readsize)
85  break;
86  field_end = memchr (cur, ':', readsize);
87 #if MODIFIER
88  field_modifier_end = field_end;
89 #endif
90  if (!field_end)
91  {
92  di_warning ("parser_rfc822: Iek! Don't find end of field!");
93  return -1;
94  }
95  field_size = field_end - field_begin;
96 
97 #if MODIFIER
98 #ifdef HAVE_MEMRCHR
99  if ((field_modifier_begin = memrchr (field_begin, '-', field_end - field_begin)))
100  field_modifier_begin++;
101  if (field_modifier_begin)
102 #else
103  field_modifier_begin = field_begin;
104  while ((temp = memchr (field_modifier_begin, '-', field_end - field_modifier_begin)))
105  field_modifier_begin = temp + 1;
106  if (field_modifier_begin != field_begin)
107 #endif
108  {
109  field_modifier_size = field_modifier_end - field_modifier_begin;
110  }
111  else
112  {
113  field_modifier_begin = 0;
114  field_modifier_size = 0;
115  }
116 #endif
117 
118  value_begin = field_end + 1;
119  while (value_begin < end && (*value_begin == ' ' || *value_begin == '\t'))
120  value_begin++;
121  readsize = end - field_begin;
122  value_end = memchr (field_begin, '\n', readsize);
123  if (!value_end)
124  {
125  di_warning ("parser_rfc822: Iek! Don't find end of value!");
126  return -1;
127  }
128  if (value_end < field_end)
129  {
130  di_warning ("parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
131  return -1;
132  }
133 
134  /* while (isblank (value_end[1])) FIXME: C99 */
135  while (value_end[1] == ' ' || value_end[1] == '\t')
136  {
137  readsize = end - value_end + 1;
138  if ((value_end = memchr (value_end + 1, '\n', readsize)) == NULL)
139  {
140  di_warning ("Iek! Don't find end of large value\n");
141  return -1;
142  }
143  }
144  value_size = value_end - value_begin;
145 
146  field_string.string = field_begin;
147  field_string.size = field_size;
148  value_string.string = value_begin;
149  value_string.size = value_size;
150 
151  fip = di_hash_table_lookup (info->table, &field_string);
152 
153  if (fip)
154  {
155  fip->read (&act, fip, NULL, &value_string, user_data);
156  goto next;
157  }
158 
159 #if MODIFIER
160  if (info->wildcard)
161  goto wildcard;
162  else if (!info->modifier)
163  goto next;
164 
165  field_string.size = field_size - field_modifier_size - 1;
166 
167  fip = di_hash_table_lookup (info->table, &field_string);
168 
169  if (fip)
170  {
171  field_modifier_string.string = field_modifier_begin;
172  field_modifier_string.size = field_modifier_size;
173 
174  fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
175 
176  goto next;
177  }
178 #endif
179 
180  if (!info->wildcard)
181  goto next;
182 
183 #if MODIFIER
184 wildcard:
185 #endif
186  field_string.size = 0;
187 
188  fip = di_hash_table_lookup (info->table, &field_string);
189 
190  if (fip)
191  {
192  field_modifier_string.string = field_begin;
193  field_modifier_string.size = field_size;
194 
195  fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
196  }
197 
198 next:
199  cur = value_end + 1;
200  if (cur >= end || *cur == '\n')
201  break;
202  }
203 
204  if (entry_finish && entry_finish (act, user_data))
205  return -1;
206  }
207 
208  return nr;
209 }
void * di_hash_table_lookup(di_hash_table *hash_table, const void *key)
Definition: hash.c:169
#define di_warning(format...)
Definition: log.h:59
Info about a parser field.
Definition: parser.h:105
di_parser_fields_function_read * read
Definition: parser.h:107
raw string
Definition: string.h:38
di_ksize_t size
Definition: string.h:40
char * string
Definition: string.h:39

References di_hash_table_lookup(), di_warning, di_parser_info::modifier, di_parser_fieldinfo::read, di_rstring::size, di_rstring::string, di_parser_info::table, and di_parser_info::wildcard.

Referenced by di_parser_rfc822_read_file().

◆ di_parser_rfc822_read_file()

int di_parser_rfc822_read_file ( const char *  file,
di_parser_info fieldinfo,
di_parser_read_entry_new  entry_new,
di_parser_read_entry_finish  entry_finish,
void *  user_data 
)

Parse a rfc822 formated file

Parameters
filefilename
fieldinfoparser info
entry_newfunction which is called before each entry, may return the new entry or return NULL
entry_finishfunction which is called after each entry, return non-0 aborts the parsing
user_datauser_data for parser functions
Returns
number of parsed entries
212 {
213  struct stat statbuf;
214  char *begin;
215  int fd, ret = -1;
216 
217  if ((fd = open (file, O_RDONLY)) < 0)
218  return ret;
219  if (fstat (fd, &statbuf))
220  goto cleanup;
221  if (!statbuf.st_size)
222  {
223  ret = 0;
224  goto cleanup;
225  }
226  begin = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
227  if (begin == MAP_FAILED)
228  goto cleanup;
229  madvise (begin, statbuf.st_size, MADV_SEQUENTIAL);
230 
231  ret = di_parser_rfc822_read (begin, statbuf.st_size, info, entry_new, entry_finish, user_data);
232 
233  munmap (begin, statbuf.st_size);
234 
235 cleanup:
236  close (fd);
237 
238  return ret;
239 }
int di_parser_rfc822_read(char *begin, size_t size, di_parser_info *info, di_parser_read_entry_new entry_new, di_parser_read_entry_finish entry_finish, void *user_data)
Definition: parser_rfc822.c:38

References di_parser_rfc822_read().

◆ di_parser_rfc822_write_file()

int di_parser_rfc822_write_file ( const char *  file,
di_parser_info fieldinfo,
di_parser_write_entry_next  entry_next,
void *  user_data 
)

Dump a rfc822 formated file

Parameters
filefilename
fieldinfoparser info
entry_nextfunction which is called to gather the next entry
user_datauser_data for parser functions
Returns
number of dumped entries
251 {
252  int nr = 0;
253  const di_parser_fieldinfo *fip;
254  void *act = NULL, *state_data = NULL;
255  di_slist_node *node;
256  FILE *f;
257  char tmpfile[PATH_MAX];
258 
259 
260  if (!strncmp (file, "-", 1))
261  {
262  tmpfile[0] = '\0';
263  f = stdout;
264  }
265  else
266  {
267  snprintf (tmpfile, sizeof (tmpfile), "%s.tmp", file);
268  f = fopen (tmpfile, "w");
269  }
270 
271  if (!f)
272  return -1;
273 
274  while (1)
275  {
276  act = entry_next (&state_data, user_data);
277  if (!act)
278  break;
279 
280  nr++;
281 
282  for (node = info->list.head; node; node = node->next)
283  {
284  fip = node->data;
285  if (fip->write)
286  fip->write (&act, fip, callback, f, user_data);
287  }
288  fputc ('\n', f);
289  }
290 
291  if (*tmpfile)
292  {
293  fclose (f);
294  if (rename (tmpfile, file))
295  return -1;
296  }
297 
298  return nr;
299 }
di_parser_fields_function_write * write
Definition: parser.h:108
Node of a single-linked list.
Definition: slist.h:46
di_slist_node * next
Definition: slist.h:47
void * data
Definition: slist.h:48

References di_slist_node::data, di_slist::head, di_parser_info::list, di_slist_node::next, and di_parser_fieldinfo::write.