Пример #1
0
int
sha256_file(const char *path, char out[65])
{
	FILE *fp;
	char buffer[BUFSIZ];
	unsigned char hash[SHA256_DIGEST_LENGTH];
	size_t r = 0;
	SHA256_CTX sha256;

	if ((fp = fopen(path, "rb")) == NULL)
		return (pkg_error_set(EPKG_FATAL, "fopen(%s): %s", path,
							  strerror(errno)));

	SHA256_Init(&sha256);

	while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0)
		SHA256_Update(&sha256, buffer, r);

	if (ferror(fp) != 0) {
		fclose(fp);
		out[0] = '\0';
		return (pkg_error_set(EPKG_FATAL, "fread(%s): %s", path,
							  strerror(errno)));

	}

	fclose(fp);

	SHA256_Final(hash, &sha256);
	sha256_hash(hash, out);

	return (EPKG_OK);
}
Пример #2
0
Файл: fetch.c Проект: flz/pkgng
int
pkg_fetch_buffer(const char *url, char **buffer, void *data, fetch_cb cb)
{
	FILE *remote = NULL;
	struct url_stat st;
	off_t done = 0;
	off_t r;
	int retry = 3;
	time_t begin_dl;
	time_t now;
	time_t last = 0;
	int retcode = EPKG_OK;

	while (remote == NULL) {
		remote = fetchXGetURL(url, &st, "");
		if (remote == NULL) {
			--retry;
			if (retry == 0) {
				pkg_error_set(EPKG_FATAL, "%s", fetchLastErrString);
				goto cleanup;
			}
			sleep(1);
		}
	}

	*buffer = malloc(st.size + 1);

	begin_dl = time(NULL);
	while (done < st.size) {
		if ((r = fread(*buffer + done, 1, 10240, remote)) < 1)
			break;

		done += r;

		now = time(NULL);
		/* Only call the callback every second */

		if (cb != NULL && (now > last || done == st.size)) {
			cb(data, url, st.size, done, (now - begin_dl));
			last = now;
		}
	}

	if (ferror(remote)) {
		retcode = pkg_error_set(EPKG_FATAL, "%s", fetchLastErrString);
		goto cleanup;
	}

	cleanup:

	if (remote != NULL)
		fclose(remote);

	return (retcode);
}
Пример #3
0
/* Based off src/bin/mkdir/mkdir.c 1.32 */
int
pkg_dir_build(const char *path)
{
	struct stat sb;
	int last, retval;
	char *str, *p;

	str = strdup(path);
	if (!str) {
		pkg_error_set(&pkg_null, "Out of Memory");
		return PKG_FAIL;
	}
	p = str;
	retval = PKG_OK;
	if (p[0] == '/')		/* Skip leading '/'. */
		++p;
	for (last = 0; !last ; ++p) {
		if (p[0] == '\0')
			last = 1;
		else if (p[0] != '/')
			continue;
		*p = '\0';
		if (!last && p[1] == '\0')
			last = 1;
		if (mkdir(str, S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
			if (errno == EEXIST || errno == EISDIR) {
				if (stat(str, &sb) < 0) {
					retval = PKG_FAIL;
					pkg_error_set(&pkg_null,
					    "Could not stat %s", str);
					break;
				} else if (!S_ISDIR(sb.st_mode)) {
					if (last)
						errno = EEXIST;
					else
						errno = ENOTDIR;
					retval = PKG_FAIL;
					pkg_error_set(&pkg_null,
					    "%s is not a directory", str);
					break;
				}
			} else {
				retval = PKG_FAIL;
				pkg_error_set(&pkg_null, "Could not create %s",
				    str);
				break;
			}
		}
		if (!last)
		    *p = '/';
	}
	free(str);
	return (retval);
}
Пример #4
0
Файл: pkgdb.c Проект: flz/pkgng
int
pkgdb_compact(struct pkgdb *db)
{
	int64_t page_count = 0;
	int64_t freelist_count = 0;
	char *errmsg;
	int retcode = EPKG_OK;

	if (db == NULL)
		return (ERROR_BAD_ARG("db"));

	if (get_pragma(db->sqlite, "PRAGMA page_count;", &page_count) != EPKG_OK)
		return (EPKG_FATAL);

	if (get_pragma(db->sqlite, "PRAGMA freelist_count;", &freelist_count) !=
		EPKG_OK)
		return (EPKG_FATAL);

	/*
	 * Only compact if we will save 25% (or more) of the current used space.
	 */
	if (freelist_count / (float)page_count < 0.25)
		return (EPKG_OK);

	if (sqlite3_exec(db->sqlite, "VACUUM;", NULL, NULL, &errmsg) != SQLITE_OK){
		retcode = pkg_error_set(EPKG_FATAL, "%s", errmsg);
		sqlite3_free(errmsg);
	}

	return (retcode);
}
Пример #5
0
int
pkg_delete(struct pkg *pkg, struct pkgdb *db, int force)
{
	struct pkg **rdeps;
	int i, ret;
	struct sbuf *rdep_msg;

	if (pkg == NULL)
		return (ERROR_BAD_ARG("pkg"));

	if (db == NULL)
		return (ERROR_BAD_ARG("db"));

	/*
	 * Ensure that we have all the informations we need
	 */
	if ((ret = pkgdb_loadrdeps(db, pkg)) != EPKG_OK)
		return (ret);
	if ((ret = pkgdb_loadfiles(db, pkg)) != EPKG_OK)
		return (ret);
	if ((ret = pkgdb_loadscripts(db, pkg)) != EPKG_OK)
		return (ret);
	if ((ret = pkgdb_loadmtree(db, pkg)) != EPKG_OK)
		return (ret);

	rdeps = pkg_rdeps(pkg);

	if (rdeps[0] != NULL) {
		rdep_msg = sbuf_new_auto();
		sbuf_printf(rdep_msg, "%s-%s is required by other packages:", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION));
		for (i = 0;rdeps[i] != NULL; i++) {
			sbuf_cat(rdep_msg, " ");
			sbuf_printf(rdep_msg, "%s-%s", pkg_get(rdeps[i], PKG_NAME), pkg_get(rdeps[i], PKG_VERSION));
		}
		if (!force) {
			sbuf_finish(rdep_msg);
			ret = pkg_error_set(EPKG_REQUIRED, "%s", sbuf_get(rdep_msg));
			sbuf_free(rdep_msg);
			return ret;
		}
		sbuf_cat(rdep_msg, ", deleting anyway");
		sbuf_finish(rdep_msg);
		fprintf(stderr, "%s\n", sbuf_get(rdep_msg));
		sbuf_free(rdep_msg);
	}

	if ((ret = pkg_script_pre_deinstall(pkg)) != EPKG_OK)
		return (ret);

	if ((ret = pkg_delete_files(pkg, force)) != EPKG_OK)
		return (ret);

	if ((ret = pkg_script_post_deinstall(pkg)) != EPKG_OK)
		return (ret);

	return (pkgdb_unregister_pkg(db, pkg_get(pkg, PKG_ORIGIN)));
}
Пример #6
0
int
file_to_buffer(const char *path, char **buffer, off_t *sz)
{
	int fd;
	struct stat st;

	if (path == NULL || path[0] == '\0')
		return (ERROR_BAD_ARG("path"));

	if (buffer == NULL)
		return (ERROR_BAD_ARG("buffer"));

	if ((fd = open(path, O_RDONLY)) == -1) {
		return (pkg_error_set(EPKG_FATAL, "can not open %s: %s", path,
				strerror(errno)));
	}

	if (fstat(fd, &st) == -1) {
		close(fd);
		return (pkg_error_set(EPKG_FATAL, "fstat(): %s", strerror(errno)));
	}

	if ((*buffer = malloc(st.st_size + 1)) == NULL) {
		close(fd);
		return (pkg_error_set(EPKG_FATAL, "malloc(): %s", strerror(errno)));
	}

	if (read(fd, *buffer, st.st_size) == -1) {
		close(fd);
		return (pkg_error_set(EPKG_FATAL, "read(): %s", strerror(errno)));
	}

	close(fd);

	/* NULL terminate the buffer so it can be used by stdio.h functions */
	(*buffer)[st.st_size] = '\0';

	*sz = st.st_size;
	return (EPKG_OK);
}
Пример #7
0
Файл: pkgdb.c Проект: flz/pkgng
int
pkgdb_register_finale(struct pkgdb *db, int retcode)
{
	int ret = EPKG_OK;
	const char *commands[] = { "COMMIT;", "ROLLBACK;", NULL };
	const char *command;
	char *errmsg;

	if (!pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT)) {
		ret = pkg_error_set(EPKG_FATAL, "database command not in flight");
		return ret;
	}

	command = (retcode == EPKG_OK) ? commands[0] : commands[1];
	if (sqlite3_exec(db->sqlite, command, NULL, NULL, &errmsg) != SQLITE_OK) {
		ret = pkg_error_set(EPKG_FATAL, "sqlite: %s", errmsg);
		sqlite3_free(errmsg);
	}
	PKGDB_UNSET_FLAG(db, PKGDB_FLAG_IN_FLIGHT);

	return ret;
}
Пример #8
0
/* Checks a file against a given md5 checksum */
int
pkg_checksum_md5(struct pkg_file *file, char *chk_sum)
{
	char sum[33];

	if (!file) {
		pkg_error_set(&pkg_null, "No file specified");
		return PKG_FAIL;
	}

	if (!sum) {
		pkg_error_set((struct pkg_object *)file, "No checksum specified");
		return PKG_FAIL;
	}

	/* Perform a checksum on the file to install */
	MD5Data(file->contents, file->len, sum);
	if (strcmp(sum, chk_sum)) {
		pkg_error_set((struct pkg_object *)file,
		    "File checksum incorrect");
		return PKG_FAIL;
	}
	return PKG_OK;
}
Пример #9
0
Файл: pkgdb.c Проект: flz/pkgng
static struct pkgdb_it *
pkgdb_it_new(struct pkgdb *db, sqlite3_stmt *s, int type)
{
	struct pkgdb_it *it;

	if ((it = malloc(sizeof(struct pkgdb_it))) == NULL) {
		pkg_error_set(EPKG_FATAL, "malloc(): %s", strerror(errno));
		sqlite3_finalize(s);
		return (NULL);
	}

	it->db = db;
	it->stmt = s;
	it->type = type;
	return (it);
}
Пример #10
0
int
pkg_create_installed(const char *outdir, pkg_formats format, const char *rootdir, struct pkg *pkg)
{
	struct packing *pkg_archive;
	int required_flags = PKG_LOAD_DEPS | PKG_LOAD_CONFLICTS | PKG_LOAD_FILES |
						 PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS |
						 PKG_LOAD_MTREE;

	if (pkg->type != PKG_INSTALLED)
		return (ERROR_BAD_ARG("pkg"));

	pkg_archive = pkg_create_archive(outdir, pkg, format, required_flags);
	if (pkg_archive == NULL)
		return pkg_error_set(EPKG_FATAL, "unable to create archive"); /* XXX do better */

	pkg_create_from_dir(pkg, rootdir, pkg_archive);

	return packing_finish(pkg_archive);
}
Пример #11
0
Файл: fetch.c Проект: flz/pkgng
int
pkg_fetch_file(const char *url, const char *dest, void *data, fetch_cb cb)
{
	int fd = -1;
	FILE *remote = NULL;
	struct url_stat st;
	off_t done = 0;
	off_t r;
	int retry = 3;
	time_t begin_dl;
	time_t now;
	time_t last = 0;
	char buf[10240];
	int retcode = EPKG_OK;

	if ((fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
		retcode = pkg_error_set(EPKG_FATAL, "open(%s): %s", dest,
								strerror(errno));
		goto cleanup;
	}

	while (remote == NULL) {
		remote = fetchXGetURL(url, &st, "");
		if (remote == NULL) {
			--retry;
			if (retry == 0) {
				retcode = pkg_error_set(EPKG_FATAL, "%s", fetchLastErrString);
				goto cleanup;
			}
			sleep(1);
		}
	}

	begin_dl = time(NULL);
	while (done < st.size) {
		if ((r = fread(buf, 1, sizeof(buf), remote)) < 1)
			break;

		if (write(fd, buf, r) != r) {
			retcode = pkg_error_set(EPKG_FATAL, "write(%s): %s", dest,
									strerror(errno));
			goto cleanup;
		}

		done += r;
		now = time(NULL);
		/* Only call the callback every second */
		if (cb != NULL && (now > last || done == st.size)) {
			cb(data, url, st.size, done, (now - begin_dl));
			last = now;
		}
	}

	if (ferror(remote)) {
		retcode = pkg_error_set(EPKG_FATAL, "%s", fetchLastErrString);
		goto cleanup;
	}

	cleanup:

	if (fd > 0)
		close(fd);

	if (remote != NULL)
		fclose(remote);

	/* Remove local file if fetch failed */
	if (retcode != EPKG_OK)
		unlink(dest);

	return (retcode);
}
Пример #12
0
Файл: pkgdb.c Проект: flz/pkgng
int
pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg)
{
	struct pkg **deps;
	struct pkg_file **files;
	struct pkg_conflict **conflicts;
	struct pkg_script **scripts;
	struct pkg_option **options;

	sqlite3 *s;
	sqlite3_stmt *stmt_pkg = NULL;
	sqlite3_stmt *stmt_sel_pkg = NULL;
	sqlite3_stmt *stmt_dep = NULL;
	sqlite3_stmt *stmt_conflict = NULL;
	sqlite3_stmt *stmt_file = NULL;
	sqlite3_stmt *stmt_script = NULL;
	sqlite3_stmt *stmt_option = NULL;
	sqlite3_stmt *stmt_dirs = NULL;

	int i;
	int ret;
	int retcode = EPKG_OK;
	const char *path;
	int64_t package_id;
	char *errmsg;

	const char sql_begin[] = "BEGIN TRANSACTION;";
	const char sql_pkg[] = ""
		"INSERT INTO pkg_mtree( "
			"origin, name, version, comment, desc, mtree, message, arch, "
			"osversion, maintainer, www, prefix, flatsize) "
		"VALUES( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13);";
	const char sql_sel_pkg[] = ""
		"SELECT id FROM packages "
		"WHERE origin = ?1;";
	const char sql_dep[] = ""
		"INSERT INTO deps (origin, name, version, package_id) "
		"VALUES (?1, ?2, ?3, ?4);";
	const char sql_conflict[] = ""
		"INSERT INTO conflicts (name, package_id) "
		"VALUES (?1, ?2);";
	const char sql_file[] = ""
		"INSERT INTO files (path, sha256, package_id) "
		"VALUES (?1, ?2, ?3);";
	const char sql_script[] = ""
		"INSERT INTO scripts (script, type, package_id) "
		"VALUES (?1, ?2, ?3);";
	const char sql_option[] = ""
		"INSERT INTO options (option, value, package_id) "
		"VALUES (?1, ?2, ?3);";
	const char sql_dir[] = ""
		"INSERT INTO pkg_dirs(origin, path) "
		"VALUES (?1, ?2);";

	if (pkgdb_has_flag(db, PKGDB_FLAG_IN_FLIGHT)) {
		pkg_error_set(EPKG_FATAL, "tried to register a package with an in-flight SQL command");
		return (EPKG_FATAL);
	}

	s = db->sqlite;

	if (sqlite3_exec(s, sql_begin, NULL, NULL, &errmsg) != SQLITE_OK) {
		pkg_error_set(EPKG_FATAL, "sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}
	PKGDB_SET_FLAG(db, PKGDB_FLAG_IN_FLIGHT);

	/*
	 * Insert package record
	 */
	if (sqlite3_prepare_v2(s, sql_pkg, -1, &stmt_pkg, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}
	sqlite3_bind_text(stmt_pkg, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 2, pkg_get(pkg, PKG_NAME), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 3, pkg_get(pkg, PKG_VERSION), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 4, pkg_get(pkg, PKG_COMMENT), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 5, pkg_get(pkg, PKG_DESC), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 6, pkg_get(pkg, PKG_MTREE), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 7, pkg_get(pkg, PKG_MESSAGE), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 8, pkg_get(pkg, PKG_ARCH), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 9, pkg_get(pkg, PKG_OSVERSION), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 10, pkg_get(pkg, PKG_MAINTAINER), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 11, pkg_get(pkg, PKG_WWW), -1, SQLITE_STATIC);
	sqlite3_bind_text(stmt_pkg, 12, pkg_get(pkg, PKG_PREFIX), -1, SQLITE_STATIC);
	sqlite3_bind_int64(stmt_pkg, 13, pkg_flatsize(pkg));

	if ((ret = sqlite3_step(stmt_pkg)) != SQLITE_DONE) {
		if ( ret == SQLITE_CONSTRAINT)
			retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
					"pkg with %s", pkg_get(pkg, PKG_ORIGIN));
		else
			retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	/*
	 * Get the generated package_id
	 */

	if (sqlite3_prepare_v2(s, sql_sel_pkg, -1, &stmt_sel_pkg, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}
	sqlite3_bind_text(stmt_sel_pkg, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC);
	ret = sqlite3_step(stmt_sel_pkg);
	if (ret == SQLITE_ROW) {
		package_id = sqlite3_column_int64(stmt_sel_pkg, 0);
		ret = SQLITE_DONE;
	} else {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	/*
	 * Insert dependencies list
	 */

	if (sqlite3_prepare_v2(s, sql_dep, -1, &stmt_dep, NULL) != SQLITE_OK) {

		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	deps = pkg_deps(pkg);
	for (i = 0; deps[i] != NULL; i++) {
		sqlite3_bind_text(stmt_dep, 1, pkg_get(deps[i], PKG_ORIGIN), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_dep, 2, pkg_get(deps[i], PKG_NAME), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_dep, 3, pkg_get(deps[i], PKG_VERSION), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_dep, 4, package_id);

		if ((ret = sqlite3_step(stmt_dep)) != SQLITE_DONE) {
			if ( ret == SQLITE_CONSTRAINT)
				retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
						"deps with %s", pkg_get(deps[i], PKG_ORIGIN));
			else
				retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

		sqlite3_reset(stmt_dep);
	}

	/*
	 * Insert conflicts list
	 */

	if (sqlite3_prepare_v2(s, sql_conflict, -1, &stmt_conflict, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	conflicts = pkg_conflicts(pkg);
	for (i = 0; conflicts[i] != NULL; i++) {
		sqlite3_bind_text(stmt_conflict, 1, pkg_conflict_glob(conflicts[i]), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_conflict, 2, package_id);

		if ((ret = sqlite3_step(stmt_conflict)) != SQLITE_DONE) {
			if ( ret == SQLITE_CONSTRAINT)
				retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
						"conflicts with %s", pkg_conflict_glob(conflicts[i]));
			else
				retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

		sqlite3_reset(stmt_conflict);
	}

	/*
	 * Insert file
	 * and dirs
	 */

	if (sqlite3_prepare_v2(s, sql_file, -1, &stmt_file, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	if (sqlite3_prepare_v2(s, sql_dir, -1, &stmt_dirs, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	files = pkg_files(pkg);
	for (i = 0; files[i] != NULL; i++) {
		path = pkg_file_path(files[i]);
		if (path[strlen(path) - 1 ] != '/') {
			sqlite3_bind_text(stmt_file, 1, pkg_file_path(files[i]), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_file, 2, pkg_file_sha256(files[i]), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_file, 3, package_id);

			if ((ret = sqlite3_step(stmt_file)) != SQLITE_DONE) {
				if ( ret == SQLITE_CONSTRAINT)
					retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
							"path with %s", pkg_file_path(files[i]));
				else
					retcode = ERROR_SQLITE(s);
				goto cleanup;
			}
			sqlite3_reset(stmt_file);
		} else {
			sqlite3_bind_text(stmt_dirs, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_dirs, 2, pkg_file_path(files[i]), -1, SQLITE_STATIC);
			
			if ((ret = sqlite3_step(stmt_dirs)) != SQLITE_DONE) {
				if ( ret == SQLITE_CONSTRAINT)
					retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
							"dirs with %s", pkg_file_path(files[i]));
				else
					retcode = ERROR_SQLITE(s);
				goto cleanup;
			}
			sqlite3_reset(stmt_dirs);
		}

	}

	/*
	 * Insert scripts
	 */

	if (sqlite3_prepare_v2(s, sql_script, -1, &stmt_script, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	scripts = pkg_scripts(pkg);
	for (i = 0; scripts[i] != NULL; i++) {
		sqlite3_bind_text(stmt_script, 1, pkg_script_data(scripts[i]), -1, SQLITE_STATIC);
		sqlite3_bind_int(stmt_script, 2, pkg_script_type(scripts[i]));
		sqlite3_bind_int64(stmt_script, 3, package_id);

		if (sqlite3_step(stmt_script) != SQLITE_DONE) {
			if ( ret == SQLITE_CONSTRAINT)
				retcode = pkg_error_set(EPKG_FATAL, "constraint violation on "
						"scripts with %s", pkg_script_data(scripts[i]));
			else
				retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

		sqlite3_reset(stmt_script);
	}

	/*
	 * Insert options
	 */

	options = pkg_options(pkg);
	if (sqlite3_prepare_v2(s, sql_option, -1, &stmt_option, NULL) != SQLITE_OK) {
		retcode = ERROR_SQLITE(s);
		goto cleanup;
	}

	for (i = 0; options[i] != NULL; i++) {
		sqlite3_bind_text(stmt_option, 1, pkg_option_opt(options[i]), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_option, 2, pkg_option_value(options[i]), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_option, 3, package_id);

		if (sqlite3_step(stmt_option) != SQLITE_DONE) {
			retcode = ERROR_SQLITE(s);
			goto cleanup;
		}

		sqlite3_reset(stmt_option);
	}

	cleanup:

	if (stmt_pkg != NULL)
		sqlite3_finalize(stmt_pkg);

	if (stmt_sel_pkg != NULL)
		sqlite3_finalize(stmt_sel_pkg);

	if (stmt_dep != NULL)
		sqlite3_finalize(stmt_dep);

	if (stmt_conflict != NULL)
		sqlite3_finalize(stmt_conflict);

	if (stmt_file != NULL)
		sqlite3_finalize(stmt_file);

	if (stmt_script != NULL)
		sqlite3_finalize(stmt_script);

	if (stmt_option != NULL)
		sqlite3_finalize(stmt_option);
	
	if (stmt_dirs != NULL)
		sqlite3_finalize(stmt_dirs);

	return (retcode);
}
Пример #13
0
Файл: pkgdb.c Проект: flz/pkgng
int
pkgdb_open(struct pkgdb **db, pkgdb_t remote, int mode)
{
	int retcode;
	struct stat st;
	char *errmsg;
	char localpath[MAXPATHLEN];
	char remotepath[MAXPATHLEN];
	char sql[BUFSIZ];
	const char *dbdir;

	/* First check to make sure PKG_DBDIR exists before trying to use it */
	dbdir = pkg_config("PKG_DBDIR");
	if (eaccess(dbdir, mode) == -1)
		return (pkg_error_set(EPKG_FATAL, "Package database directory "
		    "%s error: %s", dbdir, strerror(errno)));

	snprintf(localpath, sizeof(localpath), "%s/local.sqlite", dbdir);

	if ((*db = calloc(1, sizeof(struct pkgdb))) == NULL)
		return (pkg_error_set(EPKG_FATAL, "calloc(): %s", strerror(errno)));

	(*db)->remote = remote;

	retcode = stat(localpath, &st);
	if (retcode == -1 && errno != ENOENT)
		return (pkg_error_set(EPKG_FATAL, "can not stat %s: %s", localpath,
							  strerror(errno)));

	if (remote == PKGDB_REMOTE) {
		snprintf(remotepath, sizeof(localpath), "%s/repo.sqlite", dbdir);
		retcode = stat(remotepath, &st);
		if (retcode == -1 && errno != ENOENT)
			return (pkg_error_set(EPKG_FATAL, "can not stat %s: %s", remotepath,
						strerror(errno)));
	}

	if (sqlite3_open(localpath, &(*db)->sqlite) != SQLITE_OK)
		return (ERROR_SQLITE((*db)->sqlite));

	if (remote == PKGDB_REMOTE) {
		sqlite3_snprintf(BUFSIZ, sql, "ATTACH \"%s\" as remote;", remotepath);

		if (sqlite3_exec((*db)->sqlite, sql, NULL, NULL, &errmsg) != SQLITE_OK){
			sqlite3_free(errmsg);
			return ERROR_SQLITE((*db)->sqlite);
		}
	}

	/* If the database is missing we have to initialize it */
	if (retcode == -1)
		if ((retcode = pkgdb_init((*db)->sqlite)) != EPKG_OK)
			return (ERROR_SQLITE((*db)->sqlite));

	sqlite3_create_function((*db)->sqlite, "regexp", 2, SQLITE_ANY, NULL,
							pkgdb_regex_basic, NULL, NULL);
	sqlite3_create_function((*db)->sqlite, "eregexp", 2, SQLITE_ANY, NULL,
							pkgdb_regex_extended, NULL, NULL);
	sqlite3_create_function((*db)->sqlite, "pkglt", 2, SQLITE_ANY, NULL,
			pkgdb_pkglt, NULL, NULL);
	sqlite3_create_function((*db)->sqlite, "pkggt", 2, SQLITE_ANY, NULL,
			pkgdb_pkggt, NULL, NULL);

	/*
	 * allow forign key option which will allow to have clean support for
	 * reinstalling
	 */
	if (sqlite3_exec((*db)->sqlite, "PRAGMA foreign_keys = ON;", NULL, NULL,
		&errmsg) != SQLITE_OK) {
		pkg_error_set(EPKG_FATAL, "sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
Пример #14
0
Файл: pkgdb.c Проект: flz/pkgng
static int
pkgdb_init(sqlite3 *sdb)
{
	char *errmsg;
	const char sql[] = ""
	"CREATE TABLE packages ("
		"id INTEGER PRIMARY KEY,"
		"origin TEXT UNIQUE,"
		"name TEXT,"
		"version TEXT,"
		"comment TEXT,"
		"desc TEXT,"
		"mtree_id INTEGER REFERENCES mtree(id) ON DELETE RESTRICT"
			" ON UPDATE CASCADE,"
		"message TEXT,"
		"arch TEXT,"
		"osversion TEXT,"
		"maintainer TEXT,"
		"www TEXT,"
		"prefix TEXT,"
		"flatsize INTEGER,"
		"automatic INTEGER,"
		"pkg_format_version INTEGER"
	");"
	"CREATE TABLE mtree ("
		"id INTEGER PRIMARY KEY,"
		"content TEXT UNIQUE"
	");"
	"CREATE TRIGGER clean_mtree AFTER DELETE ON packages BEGIN "
		"DELETE FROM mtree WHERE id NOT IN (SELECT DISTINCT mtree_id FROM packages);"
	"END;"
	"CREATE VIEW pkg_mtree AS "
	"SELECT origin, name, version, comment, desc, mtree.content AS mtree, message, arch, osversion, "
	"maintainer, www, prefix, flatsize, automatic, pkg_format_version FROM packages "
	"INNER JOIN mtree ON packages.mtree_id = mtree.id;"
	"CREATE TRIGGER pkg_insert INSTEAD OF INSERT ON pkg_mtree "
	"FOR EACH ROW BEGIN "
		"INSERT OR IGNORE INTO mtree (content) VALUES (NEW.mtree);"
		"INSERT OR REPLACE INTO packages(origin, name, version, comment, desc, mtree_id, "
		"message, arch, osversion, maintainer, www, prefix, flatsize) "
		"VALUES (NEW.origin, NEW.name, NEW.version, NEW.comment, NEW.desc, "
		"(SELECT id FROM mtree WHERE content = NEW.mtree), "
		"NEW.message, NEW.arch, NEW.osversion, NEW.maintainer, NEW.www, NEW.prefix, "
		"NEW.flatsize);"
	"END;"
	"CREATE TABLE scripts ("
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE,"
		"script TEXT,"
		"type INTEGER,"
		"PRIMARY KEY (package_id, type)"
	");"
	"CREATE INDEX scripts_package ON scripts(package_id);"
	"CREATE TABLE options ("
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE,"
		"option TEXT,"
		"value TEXT,"
		"PRIMARY KEY (package_id,option)"
	");"
	"CREATE INDEX options_package ON options(package_id);"
	"CREATE TABLE deps ("
		"origin TEXT,"
		"name TEXT,"
		"version TEXT,"
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE,"
		"PRIMARY KEY (package_id,origin)"
	");"
	"CREATE INDEX deps_origin ON deps(origin);"
	"CREATE INDEX deps_package ON deps(package_id);"
	"CREATE TABLE files ("
		"path TEXT PRIMARY KEY,"
		"sha256 TEXT,"
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE"
	");"
	"CREATE INDEX files_package ON files(package_id);"
	"CREATE TABLE conflicts ("
		"name TEXT,"
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE,"
		"PRIMARY KEY (package_id,name)"
	");"
	"CREATE INDEX conflicts_package ON conflicts(package_id);"
	"CREATE TABLE directories ("
		"id INTEGER PRIMARY KEY, "
		"path TEXT "
	");"
	"CREATE TABLE pkg_dirs_assoc ("
		"package_id INTEGER REFERENCES packages(id) ON DELETE CASCADE"
			" ON UPDATE CASCADE, "
		"directory_id INTEGER REFERENCES directories(id) ON DELETE RESTRICT"
			" ON UPDATE RESTRICT, "
		"PRIMARY KEY (package_id, directory_id)"
	");"
	"CREATE VIEW pkg_dirs AS SELECT origin, path FROM packages "
	"INNER JOIN pkg_dirs_assoc ON packages.id = pkg_dirs_assoc.package_id "
	"INNER JOIN directories ON pkg_dirs_assoc.directory_id = directories.id;"
	"CREATE TRIGGER pkg_dirs_clean AFTER DELETE ON packages BEGIN "
		"DELETE from directories WHERE id NOT IN (SELECT DISTINCT directory_id FROM pkg_dirs_assoc);"
	"END;"
	"CREATE TRIGGER dir_insert INSTEAD OF INSERT ON pkg_dirs "
	"FOR EACH ROW BEGIN "
		"INSERT OR IGNORE INTO directories (path) VALUES (NEW.path);"
		"INSERT INTO pkg_dirs_assoc (package_id, directory_id) VALUES "
			"((SELECT id FROM packages WHERE origin = NEW.origin), "
			"(SELECT id FROM directories WHERE path = NEW.path));"
	"END;"
	;

	if (sqlite3_exec(sdb, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
		pkg_error_set(EPKG_FATAL, "sqlite: %s", errmsg);
		sqlite3_free(errmsg);
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}