static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) { FILE *fp = NULL; char line[1024]; char *pkgpath; alpm_db_t *db = info->origin_data.db; /* bitmask logic here: * infolevel: 00001111 * inforeq: 00010100 * & result: 00000100 * == to inforeq? nope, we need to load more info. */ if((info->infolevel & inforeq) == inforeq) { /* already loaded all of this info, do nothing */ return 0; } if(info->infolevel & INFRQ_ERROR) { /* We've encountered an error loading this package before. Don't attempt * repeated reloads, just give up. */ return -1; } _alpm_log(db->handle, ALPM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", info->name, inforeq); pkgpath = _alpm_local_db_pkgpath(db, info, NULL); if(!pkgpath || access(pkgpath, F_OK)) { /* directory doesn't exist or can't be opened */ _alpm_log(db->handle, ALPM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n", info->name, info->version, db->treename); goto error; } free(pkgpath); /* clear out 'line', to be certain - and to make valgrind happy */ memset(line, 0, sizeof(line)); /* DESC */ if(inforeq & INFRQ_DESC && !(info->infolevel & INFRQ_DESC)) { char *path = _alpm_local_db_pkgpath(db, info, "desc"); if(!path || (fp = fopen(path, "r")) == NULL) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); free(path); goto error; } free(path); while(!feof(fp)) { if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) { goto error; } if(_alpm_strip_newline(line) == 0) { /* length of stripped line was zero */ continue; } if(strcmp(line, "%NAME%") == 0) { READ_NEXT(); if(strcmp(line, info->name) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name " "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%VERSION%") == 0) { READ_NEXT(); if(strcmp(line, info->version) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version " "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%DESC%") == 0) { READ_AND_STORE(info->desc); } else if(strcmp(line, "%GROUPS%") == 0) { READ_AND_STORE_ALL(info->groups); } else if(strcmp(line, "%URL%") == 0) { READ_AND_STORE(info->url); } else if(strcmp(line, "%LICENSE%") == 0) { READ_AND_STORE_ALL(info->licenses); } else if(strcmp(line, "%ARCH%") == 0) { READ_AND_STORE(info->arch); } else if(strcmp(line, "%BUILDDATE%") == 0) { READ_NEXT(); info->builddate = _alpm_parsedate(line); } else if(strcmp(line, "%INSTALLDATE%") == 0) { READ_NEXT(); info->installdate = _alpm_parsedate(line); } else if(strcmp(line, "%PACKAGER%") == 0) { READ_AND_STORE(info->packager); } else if(strcmp(line, "%REASON%") == 0) { READ_NEXT(); info->reason = (alpm_pkgreason_t)atoi(line); } else if(strcmp(line, "%SIZE%") == 0) { READ_NEXT(); info->isize = _alpm_strtoofft(line); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_SPLITDEP(info->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { READ_AND_SPLITDEP(info->depends); } else if(strcmp(line, "%OPTDEPENDS%") == 0) { READ_AND_STORE_ALL(info->optdepends); } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_SPLITDEP(info->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { READ_AND_SPLITDEP(info->provides); } } fclose(fp); fp = NULL; info->infolevel |= INFRQ_DESC; } /* FILES */ if(inforeq & INFRQ_FILES && !(info->infolevel & INFRQ_FILES)) { char *path = _alpm_local_db_pkgpath(db, info, "files"); if(!path || (fp = fopen(path, "r")) == NULL) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); free(path); goto error; } free(path); while(fgets(line, sizeof(line), fp)) { _alpm_strip_newline(line); if(strcmp(line, "%FILES%") == 0) { size_t files_count = 0, files_size = 0; alpm_file_t *files = NULL; while(fgets(line, sizeof(line), fp) && _alpm_strip_newline(line)) { if(files_count >= files_size) { size_t old_size = files_size; if(files_size == 0) { files_size = 8; } else { files_size *= 2; } files = realloc(files, sizeof(alpm_file_t) * files_size); if(!files) { ALLOC_FAIL(sizeof(alpm_file_t) * files_size); goto error; } /* ensure all new memory is zeroed out, in both the initial * allocation and later reallocs */ memset(files + old_size, 0, sizeof(alpm_file_t) * (files_size - old_size)); } STRDUP(files[files_count].name, line, goto error); /* TODO: lstat file, get mode/size */ files_count++; } /* attempt to hand back any memory we don't need */ files = realloc(files, sizeof(alpm_file_t) * files_count); info->files.count = files_count; info->files.files = files; } else if(strcmp(line, "%BACKUP%") == 0) {
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 local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq) { FILE *fp = NULL; char line[1024]; alpm_db_t *db = info->origin_data.db; /* bitmask logic here: * infolevel: 00001111 * inforeq: 00010100 * & result: 00000100 * == to inforeq? nope, we need to load more info. */ if((info->infolevel & inforeq) == inforeq) { /* already loaded all of this info, do nothing */ return 0; } if(info->infolevel & INFRQ_ERROR) { /* We've encountered an error loading this package before. Don't attempt * repeated reloads, just give up. */ return -1; } _alpm_log(db->handle, ALPM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", info->name, inforeq); /* clear out 'line', to be certain - and to make valgrind happy */ memset(line, 0, sizeof(line)); /* DESC */ if(inforeq & INFRQ_DESC && !(info->infolevel & INFRQ_DESC)) { char *path = _alpm_local_db_pkgpath(db, info, "desc"); if(!path || (fp = fopen(path, "r")) == NULL) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); free(path); goto error; } free(path); while(!feof(fp)) { if(safe_fgets(line, sizeof(line), fp) == NULL && !feof(fp)) { goto error; } if(_alpm_strip_newline(line, 0) == 0) { /* length of stripped line was zero */ continue; } if(strcmp(line, "%NAME%") == 0) { READ_NEXT(); if(strcmp(line, info->name) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name " "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%VERSION%") == 0) { READ_NEXT(); if(strcmp(line, info->version) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version " "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%BASE%") == 0) { READ_AND_STORE(info->base); } else if(strcmp(line, "%DESC%") == 0) { READ_AND_STORE(info->desc); } else if(strcmp(line, "%GROUPS%") == 0) { READ_AND_STORE_ALL(info->groups); } else if(strcmp(line, "%URL%") == 0) { READ_AND_STORE(info->url); } else if(strcmp(line, "%LICENSE%") == 0) { READ_AND_STORE_ALL(info->licenses); } else if(strcmp(line, "%ARCH%") == 0) { READ_AND_STORE(info->arch); } else if(strcmp(line, "%BUILDDATE%") == 0) { READ_NEXT(); info->builddate = _alpm_parsedate(line); } else if(strcmp(line, "%INSTALLDATE%") == 0) { READ_NEXT(); info->installdate = _alpm_parsedate(line); } else if(strcmp(line, "%PACKAGER%") == 0) { READ_AND_STORE(info->packager); } else if(strcmp(line, "%REASON%") == 0) { READ_NEXT(); info->reason = (alpm_pkgreason_t)atoi(line); } else if(strcmp(line, "%VALIDATION%") == 0) { alpm_list_t *i, *v = NULL; READ_AND_STORE_ALL(v); for(i = v; i; i = alpm_list_next(i)) { if(strcmp(i->data, "none") == 0) { info->validation |= ALPM_PKG_VALIDATION_NONE; } else if(strcmp(i->data, "md5") == 0) { info->validation |= ALPM_PKG_VALIDATION_MD5SUM; } else if(strcmp(i->data, "sha256") == 0) { info->validation |= ALPM_PKG_VALIDATION_SHA256SUM; } else if(strcmp(i->data, "pgp") == 0) { info->validation |= ALPM_PKG_VALIDATION_SIGNATURE; } else { _alpm_log(db->handle, ALPM_LOG_WARNING, _("unknown validation type for package %s: %s\n"), info->name, (const char *)i->data); } } FREELIST(v); } else if(strcmp(line, "%SIZE%") == 0) { READ_NEXT(); info->isize = _alpm_strtoofft(line); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_SPLITDEP(info->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { READ_AND_SPLITDEP(info->depends); } else if(strcmp(line, "%OPTDEPENDS%") == 0) { READ_AND_SPLITDEP(info->optdepends); } else if(strcmp(line, "%CONFLICTS%") == 0) { READ_AND_SPLITDEP(info->conflicts); } else if(strcmp(line, "%PROVIDES%") == 0) { READ_AND_SPLITDEP(info->provides); } } fclose(fp); fp = NULL; info->infolevel |= INFRQ_DESC; } /* FILES */ if(inforeq & INFRQ_FILES && !(info->infolevel & INFRQ_FILES)) { char *path = _alpm_local_db_pkgpath(db, info, "files"); if(!path || (fp = fopen(path, "r")) == NULL) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); free(path); goto error; } free(path); while(safe_fgets(line, sizeof(line), fp)) { _alpm_strip_newline(line, 0); if(strcmp(line, "%FILES%") == 0) { size_t files_count = 0, files_size = 0, len; alpm_file_t *files = NULL; while(safe_fgets(line, sizeof(line), fp) && (len = _alpm_strip_newline(line, 0))) { if(!_alpm_greedy_grow((void **)&files, &files_size, (files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) { goto error; } /* since we know the length of the file string already, * we can do malloc + memcpy rather than strdup */ len += 1; MALLOC(files[files_count].name, len, goto error); memcpy(files[files_count].name, line, len); files_count++; } /* attempt to hand back any memory we don't need */ if(files_count > 0) { 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); } else { FREE(files); } info->files.count = files_count; info->files.files = files; } else if(strcmp(line, "%BACKUP%") == 0) {
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; } }