RFC822 parser
[Generic 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:
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

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

00044 {
00045   char *cur, *end;
00046   char *field_begin, *field_end;
00047 #if MODIFIER
00048   char *field_modifier_begin, *field_modifier_end;
00049 #endif
00050   char *value_begin, *value_end;
00051 #ifndef HAVE_MEMRCHR
00052   char *temp;
00053 #endif
00054   int nr = 0;
00055   size_t readsize;
00056   size_t field_size;
00057 #if MODIFIER
00058   size_t field_modifier_size;
00059 #endif
00060   size_t value_size;
00061   const di_parser_fieldinfo *fip = NULL;
00062   di_rstring field_string;
00063   di_rstring field_modifier_string;
00064   di_rstring value_string;
00065   void *act = NULL;
00066 
00067   cur = begin;
00068   end = begin + size;
00069 
00070   while (cur < end)
00071   {
00072     if (*cur == '\n')
00073     {
00074       cur++;
00075       continue;
00076     }
00077 
00078     nr++;
00079 
00080     if (entry_new)
00081       act = entry_new (user_data);
00082     else
00083       act = NULL;
00084 
00085     while (1)
00086     {
00087       field_begin = cur;
00088       readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00089       if (!readsize)
00090         break;
00091       field_end = memchr (cur, ':', readsize);
00092 #if MODIFIER
00093       field_modifier_end = field_end;
00094 #endif
00095       if (!field_end)
00096       {
00097         di_warning ("parser_rfc822: Iek! Don't find end of field!");
00098         return -1;
00099       }
00100       field_size = field_end - field_begin;
00101 
00102 #if MODIFIER
00103 #ifdef HAVE_MEMRCHR
00104       if ((field_modifier_begin = memrchr (field_begin, '-', field_end - field_begin)))
00105         field_modifier_begin++;
00106       if (field_modifier_begin)
00107 #else
00108       field_modifier_begin = field_begin;
00109       while ((temp = memchr (field_modifier_begin, '-', field_end - field_modifier_begin)))
00110         field_modifier_begin = temp + 1;
00111       if (field_modifier_begin != field_begin)
00112 #endif
00113       {
00114         field_modifier_size = field_modifier_end - field_modifier_begin;
00115       }
00116       else
00117       {
00118         field_modifier_begin = 0;
00119         field_modifier_size = 0;
00120       }
00121 #endif
00122 
00123       value_begin = field_end + 1;
00124       while (value_begin < end && (*value_begin == ' ' || *value_begin == '\t'))
00125         value_begin++;
00126       readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00127       value_end = memchr (field_begin, '\n', readsize);
00128       if (!value_end)
00129       {
00130         di_warning ("parser_rfc822: Iek! Don't find end of value!");
00131         return -1;
00132       }
00133       if (value_end < field_end)
00134       {
00135         di_warning ("parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
00136         return -1;
00137       }
00138 
00139       /* while (isblank (value_end[1])) FIXME: C99 */
00140       while (value_end[1] == ' ' || value_end[1] == '\t')
00141       {
00142         readsize = end - value_end + 1 < READSIZE ? end - value_end + 1 : READSIZE;
00143         if ((value_end = memchr (value_end + 1, '\n', readsize)) == NULL)
00144         {
00145           di_warning ("Iek! Don't find end of large value\n");
00146           return -1;
00147         }
00148       }
00149       value_size = value_end - value_begin;
00150 
00151       field_string.string = field_begin;
00152       field_string.size = field_size;
00153       value_string.string = value_begin;
00154       value_string.size = value_size;
00155 
00156       fip = di_hash_table_lookup (info->table, &field_string);
00157 
00158       if (fip)
00159       {
00160         fip->read (&act, fip, NULL, &value_string, user_data);
00161         goto next;
00162       }
00163 
00164 #if MODIFIER
00165       if (info->wildcard)
00166         goto wildcard;
00167       else if (!info->modifier)
00168         goto next;
00169 
00170       field_string.size = field_size - field_modifier_size - 1;
00171 
00172       fip = di_hash_table_lookup (info->table, &field_string);
00173 
00174       if (fip)
00175       {
00176         field_modifier_string.string = field_modifier_begin;
00177         field_modifier_string.size = field_modifier_size;
00178 
00179         fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
00180 
00181         goto next;
00182       }
00183 #endif
00184 
00185       if (!info->wildcard)
00186         goto next;
00187 
00188 #if MODIFIER
00189 wildcard:
00190 #endif
00191       field_string.size = 0;
00192 
00193       fip = di_hash_table_lookup (info->table, &field_string);
00194 
00195       if (fip)
00196       {
00197         field_modifier_string.string = field_begin;
00198         field_modifier_string.size = field_size;
00199 
00200         fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
00201       }
00202 
00203 next:
00204       cur = value_end + 1;
00205       if (cur >= end || *cur == '\n')
00206         break;
00207     }
00208 
00209     if (entry_finish && entry_finish (act, user_data))
00210       return -1;
00211   }
00212 
00213   return nr;
00214 }

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

References di_parser_rfc822_read().

Referenced by di_release_read_file().

00217 {
00218   struct stat statbuf;
00219   char *begin;
00220   int fd, ret = -1;
00221 
00222   if ((fd = open (file, O_RDONLY)) < 0)
00223     return ret;
00224   if (fstat (fd, &statbuf))
00225     goto cleanup;
00226   if (!statbuf.st_size)
00227   {
00228     ret = 0;
00229     goto cleanup;
00230   }
00231   if (!(begin = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)))
00232     goto cleanup;
00233   madvise (begin, statbuf.st_size, MADV_SEQUENTIAL);
00234 
00235   ret = di_parser_rfc822_read (begin, statbuf.st_size, info, entry_new, entry_finish, user_data);
00236 
00237   munmap (begin, statbuf.st_size);
00238 
00239 cleanup:
00240   close (fd);
00241 
00242   return ret;
00243 }

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

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

00255 {
00256   int nr = 0;
00257   const di_parser_fieldinfo *fip;
00258   void *act = NULL, *state_data = NULL;
00259   di_slist_node *node;
00260   FILE *f;
00261   char tmpfile[PATH_MAX];
00262 
00263 
00264   if (!strncmp (file, "-", 1))
00265   {
00266     tmpfile[0] = '\0';
00267     f = stdout;
00268   }
00269   else
00270   {
00271     snprintf (tmpfile, sizeof (tmpfile), "%s.tmp", file);
00272     f = fopen (tmpfile, "w");
00273   }
00274 
00275   if (!f)
00276     return -1;
00277 
00278   while (1)
00279   {
00280     act = entry_next (&state_data, user_data);
00281     if (!act)
00282       break;
00283 
00284     nr++;
00285 
00286     for (node = info->list.head; node; node = node->next)
00287     {
00288       fip = node->data;
00289       if (fip->write)
00290         fip->write (&act, fip, callback, f, user_data);
00291     }
00292     fputc ('\n', f);
00293   }
00294 
00295   if (*tmpfile)
00296   {
00297     fclose (f);
00298     if (rename (tmpfile, file))
00299       return -1;
00300   }
00301 
00302   return nr;
00303 }

Generated on Tue Apr 13 12:07:06 2010 for libdebian-installer by  doxygen 1.6.3