static int sync_db_read(alpm_db_t *db, struct archive *archive, struct archive_entry *entry, alpm_pkg_t **likely_pkg) { const char *entryname, *filename; alpm_pkg_t *pkg; struct archive_read_buffer buf; entryname = archive_entry_pathname(entry); if(entryname == NULL) { _alpm_log(db->handle, ALPM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n"); return -1; } _alpm_log(db->handle, ALPM_LOG_FUNCTION, "loading package data from archive entry %s\n", entryname); memset(&buf, 0, sizeof(buf)); /* 512K for a line length seems reasonable */ buf.max_line_size = 512 * 1024; pkg = load_pkg_for_entry(db, entryname, &filename, *likely_pkg); if(pkg == NULL) { _alpm_log(db->handle, ALPM_LOG_DEBUG, "entry %s could not be loaded into %s sync database", entryname, db->treename); return -1; } if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 || strcmp(filename, "deltas") == 0) { int ret; while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) { char *line = buf.line; if(_alpm_strip_newline(line, buf.real_line_size) == 0) { /* length of stripped line was zero */ continue; } if(strcmp(line, "%NAME%") == 0) { READ_NEXT(); if(strcmp(line, pkg->name) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name " "mismatch on package %s\n"), db->treename, pkg->name); } } else if(strcmp(line, "%VERSION%") == 0) { READ_NEXT(); if(strcmp(line, pkg->version) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version " "mismatch on package %s\n"), db->treename, pkg->name); } } else if(strcmp(line, "%FILENAME%") == 0) { READ_AND_STORE(pkg->filename); } else if(strcmp(line, "%DESC%") == 0) { READ_AND_STORE(pkg->desc); } else if(strcmp(line, "%GROUPS%") == 0) { READ_AND_STORE_ALL(pkg->groups); } else if(strcmp(line, "%URL%") == 0) { READ_AND_STORE(pkg->url); } else if(strcmp(line, "%LICENSE%") == 0) { READ_AND_STORE_ALL(pkg->licenses); } else if(strcmp(line, "%ARCH%") == 0) { READ_AND_STORE(pkg->arch); } else if(strcmp(line, "%BUILDDATE%") == 0) { READ_NEXT(); pkg->builddate = _alpm_parsedate(line); } else if(strcmp(line, "%PACKAGER%") == 0) { READ_AND_STORE(pkg->packager); } else if(strcmp(line, "%CSIZE%") == 0) { READ_NEXT(); pkg->size = _alpm_strtoofft(line); } else if(strcmp(line, "%ISIZE%") == 0) { READ_NEXT(); pkg->isize = _alpm_strtoofft(line); } else if(strcmp(line, "%MD5SUM%") == 0) { READ_AND_STORE(pkg->md5sum); } else if(strcmp(line, "%SHA256SUM%") == 0) { READ_AND_STORE(pkg->sha256sum); } else if(strcmp(line, "%PGPSIG%") == 0) { READ_AND_STORE(pkg->base64_sig); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_SPLITDEP(pkg->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { READ_AND_SPLITDEP(pkg->depends); } else if(strcmp(line, "%OPTDEPENDS%") == 0) { READ_AND_SPLITDEP(pkg->optdepends); } else if(strcmp(line, "%MAKEDEPENDS%") == 0) { /* currently unused */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; } } else if(strcmp(line, "%CHECKDEPENDS%") == 0) { /* currently unused */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; } } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_SPLITDEP(pkg->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { READ_AND_SPLITDEP(pkg->provides); } else if(strcmp(line, "%DELTAS%") == 0) { /* Different than the rest because of the _alpm_delta_parse call. */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(db->handle, line)); } } } if(ret != ARCHIVE_EOF) { goto error; } *likely_pkg = pkg; } else if(strcmp(filename, "files") == 0) { /* currently do nothing with this file */ } else { /* unknown database file */ _alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename); } return 0; error: _alpm_log(db->handle, ALPM_LOG_DEBUG, "error parsing database file: %s\n", filename); return -1; }
static int sync_db_read(alpm_db_t *db, struct archive *archive, struct archive_entry *entry, alpm_pkg_t **likely_pkg) { const char *entryname, *filename; alpm_pkg_t *pkg; struct archive_read_buffer buf; entryname = archive_entry_pathname(entry); if(entryname == NULL) { _alpm_log(db->handle, ALPM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n"); return -1; } _alpm_log(db->handle, ALPM_LOG_FUNCTION, "loading package data from archive entry %s\n", entryname); memset(&buf, 0, sizeof(buf)); /* 512K for a line length seems reasonable */ buf.max_line_size = 512 * 1024; pkg = load_pkg_for_entry(db, entryname, &filename, *likely_pkg); if(pkg == NULL) { _alpm_log(db->handle, ALPM_LOG_DEBUG, "entry %s could not be loaded into %s sync database", entryname, db->treename); return -1; } if(filename == NULL) { /* A file exists outside of a subdirectory. This isn't a read error, so return * success and try to continue on. */ _alpm_log(db->handle, ALPM_LOG_WARNING, _("unknown database file: %s\n"), filename); return 0; } if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 || strcmp(filename, "files") == 0 || (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) { int ret; while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) { char *line = buf.line; if(_alpm_strip_newline(line, buf.real_line_size) == 0) { /* length of stripped line was zero */ continue; } if(strcmp(line, "%NAME%") == 0) { READ_NEXT(); if(strcmp(line, pkg->name) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name " "mismatch on package %s\n"), db->treename, pkg->name); } } else if(strcmp(line, "%VERSION%") == 0) { READ_NEXT(); if(strcmp(line, pkg->version) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version " "mismatch on package %s\n"), db->treename, pkg->name); } } else if(strcmp(line, "%FILENAME%") == 0) { READ_AND_STORE(pkg->filename); if(_alpm_validate_filename(db, pkg->name, pkg->filename) < 0) { return -1; } } else if(strcmp(line, "%BASE%") == 0) { READ_AND_STORE(pkg->base); } else if(strcmp(line, "%DESC%") == 0) { READ_AND_STORE(pkg->desc); } else if(strcmp(line, "%GROUPS%") == 0) { READ_AND_STORE_ALL(pkg->groups); } else if(strcmp(line, "%URL%") == 0) { READ_AND_STORE(pkg->url); } else if(strcmp(line, "%LICENSE%") == 0) { READ_AND_STORE_ALL(pkg->licenses); } else if(strcmp(line, "%ARCH%") == 0) { READ_AND_STORE(pkg->arch); } else if(strcmp(line, "%BUILDDATE%") == 0) { READ_NEXT(); pkg->builddate = _alpm_parsedate(line); } else if(strcmp(line, "%PACKAGER%") == 0) { READ_AND_STORE(pkg->packager); } else if(strcmp(line, "%CSIZE%") == 0) { READ_NEXT(); pkg->size = _alpm_strtoofft(line); } else if(strcmp(line, "%ISIZE%") == 0) { READ_NEXT(); pkg->isize = _alpm_strtoofft(line); } else if(strcmp(line, "%MD5SUM%") == 0) { READ_AND_STORE(pkg->md5sum); } else if(strcmp(line, "%SHA256SUM%") == 0) { READ_AND_STORE(pkg->sha256sum); } else if(strcmp(line, "%PGPSIG%") == 0) { READ_AND_STORE(pkg->base64_sig); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_SPLITDEP(pkg->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { READ_AND_SPLITDEP(pkg->depends); } else if(strcmp(line, "%OPTDEPENDS%") == 0) { READ_AND_SPLITDEP(pkg->optdepends); } else if(strcmp(line, "%MAKEDEPENDS%") == 0) { /* currently unused */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; } } else if(strcmp(line, "%CHECKDEPENDS%") == 0) { /* currently unused */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; } } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_SPLITDEP(pkg->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { READ_AND_SPLITDEP(pkg->provides); } else if(strcmp(line, "%DELTAS%") == 0) { /* Different than the rest because of the _alpm_delta_parse call. */ while(1) { READ_NEXT(); if(strlen(line) == 0) break; pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(db->handle, line)); } } else if(strcmp(line, "%FILES%") == 0) { /* TODO: this could lazy load if there is future demand */ size_t files_count = 0, files_size = 0; alpm_file_t *files = NULL; while(1) { if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) { goto error; } line = buf.line; if(_alpm_strip_newline(line, buf.real_line_size) == 0) { break; } if(!_alpm_greedy_grow((void **)&files, &files_size, (files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) { goto error; } STRDUP(files[files_count].name, line, goto error); files_count++; } /* attempt to hand back any memory we don't need */ files = realloc(files, sizeof(alpm_file_t) * files_count); /* make sure the list is sorted */ qsort(files, files_count, sizeof(alpm_file_t), _alpm_files_cmp); pkg->files.count = files_count; pkg->files.files = files; } }