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) |
|
Parse a rfc822 formated 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 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 } |
|
Parse a rfc822 formated file
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 } |
|
Dump a rfc822 formated file
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 } |