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

  begin | begin of memory segment
  size | size of memory segment
  fieldinfo | parser info
  entry_new | function which is called before each entry, may return the new entry or return NULL
  entry_finish | function which is called after each entry, return non-0 aborts the parsing
  user_data | user_data for parser functions

Returns
  number of parsed entries

{
char *cur, *end;
char *field_begin, *field_end;
#if MODIFIER
char *field_modifier_begin, *field_modifier_end;
#endif
char *value_begin, *value_end;
#ifndef HAVE_MEMRCHR
char *temp;
#endif
int nr = 0;
size_t readsize;
size_t field_size;
#if MODIFIER
size_t field_modifier_size;
#endif
size_t value_size;
const di_parser_fieldinfo *fip = NULL;
di_rstring field_string;
di_rstring field_modifier_string;
di_rstring value_string;
void *act = NULL;
cur = begin;
end = begin + size;
while (cur < end)
{
if (*cur == '\n')
{
cur++;
continue;
}
nr++;
if (entry_new)
act = entry_new (user_data);
else
act = NULL;
while (1)
{
field_begin = cur;
readsize = end - field_begin;
if (!readsize)
break;
field_end = memchr (cur, ':', readsize);
#if MODIFIER
field_modifier_end = field_end;
#endif
if (!field_end)
{
di_warning ("parser_rfc822: Iek! Don't find end of field!");
return -1;
}
field_size = field_end - field_begin;
#if MODIFIER
#ifdef HAVE_MEMRCHR
if ((field_modifier_begin = memrchr (field_begin, '-', field_end - field_begin)))
field_modifier_begin++;
if (field_modifier_begin)
#else
field_modifier_begin = field_begin;
while ((temp = memchr (field_modifier_begin, '-', field_end - field_modifier_begin)))
field_modifier_begin = temp + 1;
if (field_modifier_begin != field_begin)
#endif
{
field_modifier_size = field_modifier_end - field_modifier_begin;
}
else
{
field_modifier_begin = 0;
field_modifier_size = 0;
}
#endif
value_begin = field_end + 1;
while (value_begin < end && (*value_begin == ' ' || *value_begin == '\t'))
value_begin++;
readsize = end - field_begin;
value_end = memchr (field_begin, '\n', readsize);
if (!value_end)
{
di_warning ("parser_rfc822: Iek! Don't find end of value!");
return -1;
}
if (value_end < field_end)
{
di_warning ("parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
return -1;
}
/* while (isblank (value_end[1])) FIXME: C99 */
while (value_end[1] == ' ' || value_end[1] == '\t')
{
readsize = end - value_end + 1;
if ((value_end = memchr (value_end + 1, '\n', readsize)) == NULL)
{
di_warning ("Iek! Don't find end of large value\n");
return -1;
}
}
value_size = value_end - value_begin;
field_string.string = field_begin;
field_string.size = field_size;
value_string.string = value_begin;
value_string.size = value_size;
fip = di_hash_table_lookup (info->table, &field_string);
if (fip)
{
fip->read (&act, fip, NULL, &value_string, user_data);
goto next;
}
#if MODIFIER
if (info->wildcard)
goto wildcard;
else if (!info->modifier)
goto next;
field_string.size = field_size - field_modifier_size - 1;
fip = di_hash_table_lookup (info->table, &field_string);
if (fip)
{
field_modifier_string.string = field_modifier_begin;
field_modifier_string.size = field_modifier_size;
fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
goto next;
}
#endif
if (!info->wildcard)
goto next;
#if MODIFIER
wildcard:
#endif
field_string.size = 0;
fip = di_hash_table_lookup (info->table, &field_string);
if (fip)
{
field_modifier_string.string = field_begin;
field_modifier_string.size = field_size;
fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
}
next:
cur = value_end + 1;
if (cur >= end || *cur == '\n')
break;
}
if (entry_finish && entry_finish (act, user_data))
return -1;
}
return nr;
}
di_hash_table_lookup
void * di_hash_table_lookup(di_hash_table *hash_table, const void *key)
Definition: hash.c:169
di_warning
#define di_warning(format...)
Definition: log.h:59
di_parser_fieldinfo
Info about a parser field.
Definition: parser.h:105
di_parser_fieldinfo::read
di_parser_fields_function_read * read
Definition: parser.h:107
di_rstring
raw string
Definition: string.h:38
di_rstring::size
di_ksize_t size
Definition: string.h:40
di_rstring::string
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

  file | filename
  fieldinfo | parser info
  entry_new | function which is called before each entry, may return the new entry or return NULL
  entry_finish | function which is called after each entry, return non-0 aborts the parsing
  user_data | user_data for parser functions

Returns
  number of parsed entries

{
struct stat statbuf;
char *begin;
int fd, ret = -1;
if ((fd = open (file, O_RDONLY)) < 0)
return ret;
if (fstat (fd, &statbuf))
goto cleanup;
if (!statbuf.st_size)
{
ret = 0;
goto cleanup;
}
begin = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (begin == MAP_FAILED)
goto cleanup;
madvise (begin, statbuf.st_size, MADV_SEQUENTIAL);
ret = di_parser_rfc822_read (begin, statbuf.st_size, info, entry_new, entry_finish, user_data);
munmap (begin, statbuf.st_size);
cleanup:
close (fd);
return ret;
}
di_parser_rfc822_read
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

  file | filename
  fieldinfo | parser info
  entry_next | function which is called to gather the next entry
  user_data | user_data for parser functions

Returns
  number of dumped entries

{
int nr = 0;
const di_parser_fieldinfo *fip;
void *act = NULL, *state_data = NULL;
di_slist_node *node;
FILE *f;
char tmpfile[PATH_MAX];
if (!strncmp (file, "-", 1))
{
tmpfile[0] = '\0';
f = stdout;
}
else
{
snprintf (tmpfile, sizeof (tmpfile), "%s.tmp", file);
f = fopen (tmpfile, "w");
}
if (!f)
return -1;
while (1)
{
act = entry_next (&state_data, user_data);
if (!act)
break;
nr++;
for (node = info->list.head; node; node = node->next)
{
fip = node->data;
if (fip->write)
fip->write (&act, fip, callback, f, user_data);
}
fputc ('\n', f);
}
if (*tmpfile)
{
fclose (f);
if (rename (tmpfile, file))
return -1;
}
return nr;
}
di_parser_fieldinfo::write
di_parser_fields_function_write * write
Definition: parser.h:108
di_slist_node
Node of a single-linked list.
Definition: slist.h:46
di_slist_node::next
di_slist_node * next
Definition: slist.h:47
di_slist_node::data
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.