Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

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)

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

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

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

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

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

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


Generated on Wed Apr 21 23:39:52 2004 for libdebian-installer by doxygen 1.3.6-20040222