/* * release.c * * Copyright (C) 2003 Bastian Blank * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include /** * @addtogroup di_release_parser * @{ */ /** * @internal * parser info */ const di_parser_fieldinfo internal_di_release_parser_field_origin = DI_PARSER_FIELDINFO ( "Origin", di_parser_read_string, NULL, offsetof (di_release, origin) ), internal_di_release_parser_field_suite = DI_PARSER_FIELDINFO ( "Suite", di_parser_read_string, NULL, offsetof (di_release, suite) ), internal_di_release_parser_field_codename = DI_PARSER_FIELDINFO ( "Codename", di_parser_read_string, NULL, offsetof (di_release, codename) ), internal_di_release_parser_field_md5sum = DI_PARSER_FIELDINFO ( "MD5Sum", di_release_parser_read_file, NULL, 0 ), internal_di_release_parser_field_sha256 = DI_PARSER_FIELDINFO ( "SHA256", di_release_parser_read_file, NULL, 1 ); /** * Standard Release file */ const di_parser_fieldinfo *di_release_parser_fieldinfo[] = { &internal_di_release_parser_field_origin, &internal_di_release_parser_field_suite, &internal_di_release_parser_field_codename, &internal_di_release_parser_field_md5sum, &internal_di_release_parser_field_sha256, NULL }; /** @} */ static void internal_di_release_file_destroy_func (void *data) { di_release_file *file = data; di_free (file->filename); di_free (file->sum[0]); di_free (file->sum[1]); } /** * Allocate di_release */ di_release *di_release_alloc (void) { di_release *ret; ret = di_new0 (di_release, 1); ret->sha256 = di_hash_table_new_full (di_rstring_hash, di_rstring_equal, NULL, internal_di_release_file_destroy_func); ret->release_file_mem_chunk = di_mem_chunk_new (sizeof (di_release_file), 4096); return ret; } /** * Free di_release */ void di_release_free (di_release *release) { di_free (release->origin); di_free (release->suite); di_free (release->codename); di_hash_table_destroy (release->sha256); di_mem_chunk_destroy (release->release_file_mem_chunk); di_free (release); } static void *parser_new (void *user_data) { return user_data; } /** * Read a standard Release file * * @param file file to read */ di_release *di_release_read_file (const char *file) { di_release *release; di_parser_info *info; release = di_release_alloc (); info = di_parser_info_alloc (); di_parser_info_add (info, di_release_parser_fieldinfo); if (di_parser_rfc822_read_file (file, info, parser_new, NULL, release) < 0) { di_release_free (release); return NULL; } return release; } void di_release_parser_read_file (data, fip, field_modifier, value, user_data) void **data; const di_parser_fieldinfo *fip __attribute__ ((unused)); di_rstring *field_modifier __attribute__ ((unused)); di_rstring *value; void *user_data __attribute__ ((unused)); { char *begin = value->string, *next = begin, *end = value->string + value->size; char *buf_sum, buf_filename[129]; int ret; size_t buf_size; di_release *release = *data; di_hash_table *table = release->sha256; while (1) { next = memchr (begin, '\n', end - begin); if (!next) next = end; ret = sscanf (begin, "%ms %zu %128s", &buf_sum, &buf_size, buf_filename); if (ret == 3) { di_rstring key = { buf_filename, strlen (buf_filename) }; di_release_file *file = di_hash_table_lookup (table, &key); if (!file) { file = di_mem_chunk_alloc0 (release->release_file_mem_chunk); file->key.string = strdup (buf_filename); file->key.size = strlen (buf_filename); di_hash_table_insert (table, &file->key, file); } file->size = buf_size; file->sum[fip->integer] = buf_sum; } begin = next + 1; if (begin >= end) break; } }