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 && (*value_begin == ' ' || *value_begin == '\t'))
00119         value_begin++;
00120       readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00121       value_end = memchr (field_begin, '\n', readsize);
00122       if (!value_end)
00123       {
00124         di_warning ("parser_rfc822: Iek! Don't find end of value!");
00125         return -1;
00126       }
00127       if (value_end < field_end)
00128       {
00129         di_warning ("parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
00130         return -1;
00131       }
00132 
00133       /* while (isblank (value_end[1])) FIXME: C99 */
00134       while (value_end[1] == ' ' || value_end[1] == '\t')
00135       {
00136         readsize = end - value_end + 1 < READSIZE ? end - value_end + 1 : READSIZE;
00137         if ((value_end = memchr (value_end + 1, '\n', readsize)) == NULL)
00138         {
00139           di_warning ("Iek! Don't find end of large value\n");
00140           return -1;
00141         }
00142       }
00143       value_size = value_end - value_begin;
00144 
00145       field_string.string = field_begin;
00146       field_string.size = field_size;
00147       value_string.string = value_begin;
00148       value_string.size = value_size;
00149 
00150       fip = di_hash_table_lookup (info->table, &field_string);
00151 
00152       if (fip)
00153       {
00154         fip->read (&act, fip, NULL, &value_string, user_data);
00155         goto next;
00156       }
00157 
00158 #if MODIFIER
00159       if (info->wildcard)
00160         goto wildcard;
00161       else if (!info->modifier)
00162         goto next;
00163 
00164       field_string.size = field_size - field_modifier_size - 1;
00165 
00166       fip = di_hash_table_lookup (info->table, &field_string);
00167 
00168       if (fip)
00169       {
00170         field_modifier_string.string = field_modifier_begin;
00171         field_modifier_string.size = field_modifier_size;
00172 
00173         fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
00174 
00175         goto next;
00176       }
00177 #endif
00178 
00179       if (!info->wildcard)
00180         goto next;
00181 
00182 #if MODIFIER
00183 wildcard:
00184 #endif
00185       field_string.size = 0;
00186 
00187       fip = di_hash_table_lookup (info->table, &field_string);
00188           
00189       if (fip)
00190       {
00191         field_modifier_string.string = field_begin;
00192         field_modifier_string.size = field_size;
00193 
00194         fip->read (&act, fip, &field_modifier_string, &value_string, user_data);
00195       }
00196 
00197 next:
00198       cur = value_end + 1;
00199       if (cur >= end)
00200         break;
00201       if (*cur == '\n')
00202       {
00203         while (cur < end && *++cur == '\n');
00204         break;
00205       }
00206     }
00207 
00208     if (entry_finish && entry_finish (act, user_data))
00209       return -1;
00210   }
00211 
00212   return nr;
00213 }

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

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


Generated on Sat Sep 29 08:45:16 2007 for libdebian-installer by  doxygen 1.5.1