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) |
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
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 |
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
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 |
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
file | filename | |
fieldinfo | parser info | |
entry_next | function which is called to gather the next entry | |
user_data | user_data for parser functions |
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 }