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