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 }
|
1.3.5