Example #1
0
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) {
Example #2
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;
			}
		}