예제 #1
0
bool read_configuration_file(char *filename)
{
	GError *error = NULL;

	keyfile = g_key_file_new();

	if (!g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_NONE, &error)) {
		printf("Failed to Load configuration file: %s (%s)\n", filename, error->message);
		g_error_free(error);
		return false;
	}
#if 0
	char *c;

	printf("Configuration settings:\n");

	c = config_image_base();
	printf("    image base path  : %s\n", c);
	free(c);

	c = config_output_dir();
	printf("    output directory : %s\n", c);
	free(c);

	c = config_empty_dir();
	printf("    empty  directory : %s\n", c);
	free(c);

	printf("\n");
#endif
	return true;
}
예제 #2
0
void create_fullfiles(struct manifest *manifest)
{
	GList *deduped_file_list;
	char *path;
	char *conf, *empty;

	empty = config_empty_dir();

	char *const rmcmd[] = { "rm", "-rf", empty, NULL };
	if (system_argv(rmcmd) != 0) {
		assert(0);
	}
	g_mkdir_with_parents(empty, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
	free(empty);

	conf = config_output_dir();

	string_or_die(&path, "%s/%i", conf, manifest->version);
	if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
		if (errno != EEXIST) {
			LOG(NULL, "Failed to create directory ", "%s", path);
			return;
		}
	}
	free(path);
	string_or_die(&path, "%s/%i/files/", conf, manifest->version);
	if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
		if (errno != EEXIST) {
			LOG(NULL, "Failed to create directory ", "%s", path);
			return;
		}
	}
	free(path);
	free(conf);

	/* De-duplicate the list of fullfiles needing created to avoid races */
	deduped_file_list = get_deduplicated_fullfile_list(manifest);

	/* Submit tasks to create full files */
	submit_fullfile_tasks(deduped_file_list);

	g_list_free(deduped_file_list);
}
예제 #3
0
/* output must be a file, which is a (compressed) tar file, of the file denoted by "file", without any of its
   directory paths etc etc */
static void create_fullfile(struct file *file)
{
	char *origin;
	char *tarname = NULL;
	char *rename_source = NULL;
	char *rename_target = NULL;
	char *rename_tmpdir = NULL;
	int ret;
	struct stat sbuf;
	char *empty, *indir, *outdir;
	char *param1, *param2;

	if (file->is_deleted) {
		return; /* file got deleted -> by definition we cannot tar it up */
	}

	empty = config_empty_dir();
	indir = config_image_base();
	outdir = config_output_dir();

	string_or_die(&tarname, "%s/%i/files/%s.tar", outdir, file->last_change, file->hash);
	if (access(tarname, R_OK) == 0) {
		/* output file already exists...done */
		free(tarname);
		return;
	}
	free(tarname);
	//printf("%s was missing\n", file->hash);

	string_or_die(&origin, "%s/%i/full/%s", indir, file->last_change, file->filename);
	if (lstat(origin, &sbuf) < 0) {
		/* no input file: means earlier phase of update creation failed */
		LOG(NULL, "Failed to stat", "%s: %s", origin, strerror(errno));
		assert(0);
	}

	if (file->is_dir) { /* directories are easy */
		char *tmp1, *tmp2, *dir, *base;

		tmp1 = strdup(origin);
		assert(tmp1);
		base = basename(tmp1);

		tmp2 = strdup(origin);
		assert(tmp2);
		dir = dirname(tmp2);

		string_or_die(&rename_tmpdir, "%s/XXXXXX", outdir);
		if (!mkdtemp(rename_tmpdir)) {
			LOG(NULL, "Failed to create temporary directory for %s move", origin);
			assert(0);
		}

		string_or_die(&param1, "--exclude=%s/?*", base);
		string_or_die(&param2, "./%s", base);
		char *const tarcfcmd[] = { TAR_COMMAND, "-C", dir, TAR_PERM_ATTR_ARGS_STRLIST, "-cf", "-", param1, param2, NULL };
		char *const tarxfcmd[] = { TAR_COMMAND, "-C", rename_tmpdir, TAR_PERM_ATTR_ARGS_STRLIST, "-xf", "-", NULL };

		int tarcmdresult = system_argv_pipe(tarcfcmd, tarxfcmd);
		if (tarcmdresult != 0) {
			LOG(NULL, "Tar command for copying directory full file failed with code %d", tarcmdresult);
			assert(0);
		}
		free(param1);
		free(param2);

		string_or_die(&rename_source, "%s/%s", rename_tmpdir, base);
		string_or_die(&rename_target, "%s/%s", rename_tmpdir, file->hash);
		if (rename(rename_source, rename_target)) {
			LOG(NULL, "rename failed for %s to %s", rename_source, rename_target);
			assert(0);
		}
		free(rename_source);

		/* for a directory file, tar up simply with gzip */
		string_or_die(&param1, "%s/%i/files/%s.tar", outdir, file->last_change, file->hash);
		char *const tarcmd[] = { TAR_COMMAND, "-C", rename_tmpdir, TAR_PERM_ATTR_ARGS_STRLIST, "-zcf", param1, file->hash, NULL };

		if (system_argv(tarcmd) != 0) {
			assert(0);
		}
		free(param1);

		if (rmdir(rename_target)) {
			LOG(NULL, "rmdir failed for %s", rename_target);
		}
		free(rename_target);
		if (rmdir(rename_tmpdir)) {
			LOG(NULL, "rmdir failed for %s", rename_tmpdir);
		}
		free(rename_tmpdir);

		free(tmp1);
		free(tmp2);
	} else { /* files are more complex */
		char *gzfile = NULL, *bzfile = NULL, *xzfile = NULL;
		char *tempfile;
		uint64_t gz_size = LONG_MAX, bz_size = LONG_MAX, xz_size = LONG_MAX;

		/* step 1: hardlink the guy to an empty directory with the hash as the filename */
		string_or_die(&tempfile, "%s/%s", empty, file->hash);
		if (link(origin, tempfile) < 0) {
			LOG(NULL, "hardlink failed", "%s due to %s (%s -> %s)", file->filename, strerror(errno), origin, tempfile);
			char *const argv[] = { "cp", "-a", origin, tempfile, NULL };
			if (system_argv(argv) != 0) {
				assert(0);
			}
		}

		/* step 2a: tar it with each compression type  */
		// lzma
		string_or_die(&param1, "--directory=%s", empty);
		string_or_die(&param2, "%s/%i/files/%s.tar.xz", outdir, file->last_change, file->hash);
		char *const tarlzmacmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-Jcf", param2, file->hash, NULL };

		if (system_argv(tarlzmacmd) != 0) {
			assert(0);
		}
		free(param1);
		free(param2);

		// gzip
		string_or_die(&param1, "--directory=%s", empty);
		string_or_die(&param2, "%s/%i/files/%s.tar.gz", outdir, file->last_change, file->hash);
		char *const targzipcmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-zcf", param2, file->hash, NULL };

		if (system_argv(targzipcmd) != 0) {
			assert(0);
		}
		free(param1);
		free(param2);

#ifdef SWUPD_WITH_BZIP2
		string_or_die(&param1, "--directory=%s", empty);
		string_or_die(&param2, "%s/%i/files/%s.tar.bz2", outdir, file->last_change, file->hash);
		char *const tarbzip2cmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-jcf", param2, file->hash, NULL };

		if (system_argv(tarbzip2cmd) != 0) {
			assert(0);
		}
		free(param1);
		free(param2);

#endif

		/* step 2b: pick the smallest of the three compression formats */
		string_or_die(&gzfile, "%s/%i/files/%s.tar.gz", outdir, file->last_change, file->hash);
		if (stat(gzfile, &sbuf) == 0) {
			gz_size = sbuf.st_size;
		}
		string_or_die(&bzfile, "%s/%i/files/%s.tar.bz2", outdir, file->last_change, file->hash);
		if (stat(bzfile, &sbuf) == 0) {
			bz_size = sbuf.st_size;
		}
		string_or_die(&xzfile, "%s/%i/files/%s.tar.xz", outdir, file->last_change, file->hash);
		if (stat(xzfile, &sbuf) == 0) {
			xz_size = sbuf.st_size;
		}
		string_or_die(&tarname, "%s/%i/files/%s.tar", outdir, file->last_change, file->hash);
		if (gz_size <= xz_size && gz_size <= bz_size) {
			ret = rename(gzfile, tarname);
		} else if (xz_size <= bz_size) {
			ret = rename(xzfile, tarname);
		} else {
			ret = rename(bzfile, tarname);
		}
		if (ret != 0) {
			LOG(file, "post-tar rename failed", "ret=%d", ret);
		}
		unlink(bzfile);
		unlink(xzfile);
		unlink(gzfile);
		free(bzfile);
		free(xzfile);
		free(gzfile);
		free(tarname);

		/* step 3: remove the hardlink */
		unlink(tempfile);
		free(tempfile);
	}

	free(indir);
	free(outdir);
	free(empty);
	free(origin);
}