libdebian-installer
Functions
RFC822 parser

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

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

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().

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

References di_parser_rfc822_read().

Referenced by di_release_read_file().

214 {
215  struct stat statbuf;
216  char *begin;
217  int fd, ret = -1;
218 
219  if ((fd = open (file, O_RDONLY)) < 0)
220  return ret;
221  if (fstat (fd, &statbuf))
222  goto cleanup;
223  if (!statbuf.st_size)
224  {
225  ret = 0;
226  goto cleanup;
227  }
228  begin = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
229  if (begin == MAP_FAILED)
230  goto cleanup;
231  madvise (begin, statbuf.st_size, MADV_SEQUENTIAL);
232 
233  ret = di_parser_rfc822_read (begin, statbuf.st_size, info, entry_new, entry_finish, user_data);
234 
235  munmap (begin, statbuf.st_size);
236 
237 cleanup:
238  close (fd);
239 
240  return ret;
241 }
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

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

253 {
254  int nr = 0;
255  const di_parser_fieldinfo *fip;
256  void *act = NULL, *state_data = NULL;
257  di_slist_node *node;
258  FILE *f;
259  char tmpfile[PATH_MAX];
260 
261 
262  if (!strncmp (file, "-", 1))
263  {
264  tmpfile[0] = '\0';
265  f = stdout;
266  }
267  else
268  {
269  snprintf (tmpfile, sizeof (tmpfile), "%s.tmp", file);
270  f = fopen (tmpfile, "w");
271  }
272 
273  if (!f)
274  return -1;
275 
276  while (1)
277  {
278  act = entry_next (&state_data, user_data);
279  if (!act)
280  break;
281 
282  nr++;
283 
284  for (node = info->list.head; node; node = node->next)
285  {
286  fip = node->data;
287  if (fip->write)
288  fip->write (&act, fip, callback, f, user_data);
289  }
290  fputc ('\n', f);
291  }
292 
293  if (*tmpfile)
294  {
295  fclose (f);
296  if (rename (tmpfile, file))
297  return -1;
298  }
299 
300  return nr;
301 }