Ejemplo n.º 1
0
retvalue pull_checkupdate(struct pull_distribution *distributions) {
	struct pull_distribution *d;
	retvalue result, r;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = distribution_loadalloverrides(d->distribution);
		if (RET_WAS_ERROR(r))
			return r;
	}

	if (verbose >= 0)
		fprintf(stderr, "Calculating packages to get...\n");

	result = RET_NOTHING;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = pull_search(stderr, d);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			break;
		pull_dump(d);
	}

	return result;
}
Ejemplo n.º 2
0
static inline retvalue gotcapabilities(struct aptmethod *method, const char *chunk) {
	retvalue r;

	r = chunk_gettruth(chunk, "Single-Instance");
	if (RET_WAS_ERROR(r))
		return r;
// TODO: what to do with this?
//	if (r != RET_NOTHING) {
//		fprintf(stderr, "WARNING: Single-instance not yet supported!\n");
//	}
	r = chunk_gettruth(chunk, "Send-Config");
	if (RET_WAS_ERROR(r))
		return r;
	if (r != RET_NOTHING) {
		assert(method->command == NULL);
		method->alreadywritten = 0;
		method->command = method->config;
		method->config = NULL;
		method->output_length = strlen(method->command);
		if (verbose > 11) {
			fprintf(stderr, "Sending config: '%s'\n",
					method->command);
		}
	} else {
		free(method->config);
		method->config = NULL;
	}
	method->status = ams_ok;
	return RET_OK;
}
Ejemplo n.º 3
0
retvalue trackingdata_switch(struct trackingdata *data, const char *source, const char *version) {
	retvalue r;

	if (data->pkg != NULL) {
		if (strcmp(data->pkg->sourcename, source) == 0 &&
				strcmp(data->pkg->sourceversion, version) == 0)
			return RET_OK;
		r = tracking_saveonly(data->tracks, data->pkg);
		if (RET_WAS_ERROR(r))
			return r;
		r = trackingdata_remember(data, data->pkg->sourcename,
				data->pkg->sourceversion);
		strlist_done(&data->pkg->filekeys);
		free(data->pkg->refcounts);
		free(data->pkg->filetypes);
		free(data->pkg);
		data->pkg = NULL;
		if (RET_WAS_ERROR(r))
			return r;
	}
	r = tracking_getornew(data->tracks, source, version, &data->pkg);
	assert (r != RET_NOTHING);
	if (RET_WAS_ERROR(r))
		return r;
	return RET_OK;
}
Ejemplo n.º 4
0
static inline retvalue gotredirect(struct aptmethod *method, const char *chunk) {
	char *uri, *newuri;
	retvalue r;

	r = chunk_getvalue(chunk, "URI", &uri);
	if (r == RET_NOTHING) {
		fprintf(stderr,
"Missing URI header in uriredirect received from '%s' method!\n", method->name);
		r = RET_ERROR;
	}
	if (RET_WAS_ERROR(r))
		return r;
	r = chunk_getvalue(chunk, "New-URI", &newuri);
	if (r == RET_NOTHING) {
		fprintf(stderr,
"Missing New-URI header in uriredirect received from '%s' method!\n", method->name);
		r = RET_ERROR;
	}
	if (RET_WAS_ERROR(r)) {
		free(uri);
		return r;
	}
	r = uriredirect(method, uri, newuri);
	free(uri);
	return r;
}
Ejemplo n.º 5
0
static inline retvalue goturierror(struct aptmethod *method, const char *chunk) {
	retvalue r;
	char *uri, *message;

	r = chunk_getvalue(chunk, "URI", &uri);
	if (r == RET_NOTHING) {
		fprintf(stderr,
"Missing URI header in urierror received from '%s' method!\n", method->name);
		r = RET_ERROR;
	}
	if (RET_WAS_ERROR(r))
		return r;

	r = chunk_getvalue(chunk, "Message", &message);
	if (r == RET_NOTHING) {
		message = NULL;
	}
	if (RET_WAS_ERROR(r)) {
		free(uri);
		return r;
	}

	r = urierror(method, uri, message);
	free(uri);
	return r;
}
Ejemplo n.º 6
0
static retvalue addpackages(struct target *target, const char *packagename, const char *controlchunk, /*@null@*/const char *oldcontrolchunk, const char *version, /*@null@*/const char *oldversion, const struct strlist *files, /*@only@*//*@null@*/struct strlist *oldfiles, /*@null@*/struct logger *logger, /*@null@*/struct trackingdata *trackingdata, architecture_t architecture, /*@null@*/const char *oldsource, /*@null@*/const char *oldsversion, /*@null@*/const char *causingrule, /*@null@*/const char *suitefrom) {

	retvalue result, r;
	struct table *table = target->packages;
	enum filetype filetype;

	assert (atom_defined(architecture));

	if (architecture == architecture_source)
		filetype = ft_SOURCE;
	else if (architecture == architecture_all)
		filetype = ft_ALL_BINARY;
	else
		filetype = ft_ARCH_BINARY;

	/* mark it as needed by this distribution */

	r = references_insert(target->identifier, files, oldfiles);

	if (RET_WAS_ERROR(r)) {
		if (oldfiles != NULL)
			strlist_done(oldfiles);
		return r;
	}

	/* Add package to the distribution's database */

	if (oldcontrolchunk != NULL) {
		result = table_replacerecord(table, packagename, controlchunk);

	} else {
		result = table_adduniqrecord(table, packagename, controlchunk);
	}

	if (RET_WAS_ERROR(result)) {
		if (oldfiles != NULL)
			strlist_done(oldfiles);
		return result;
	}

	if (logger != NULL)
		logger_log(logger, target, packagename,
				version, oldversion,
				controlchunk, oldcontrolchunk,
				files, oldfiles, causingrule, suitefrom);

	r = trackingdata_insert(trackingdata, filetype, files,
			oldsource, oldsversion, oldfiles);
	RET_UPDATE(result, r);

	/* remove old references to files */

	if (oldfiles != NULL) {
		r = references_delete(target->identifier, oldfiles, files);
		RET_UPDATE(result, r);
		strlist_done(oldfiles);
	}

	return result;
}
Ejemplo n.º 7
0
retvalue pull_update(struct pull_distribution *distributions) {
	retvalue result, r;
	struct pull_distribution *d;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = distribution_prepareforwriting(d->distribution);
		if (RET_WAS_ERROR(r))
			return r;
		r = distribution_loadalloverrides(d->distribution);
		if (RET_WAS_ERROR(r))
			return r;
	}

	if (verbose >= 0)
		printf("Calculating packages to pull...\n");

	result = RET_NOTHING;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = pull_search(stdout, d);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			break;
		// TODO: make already here sure the files are ready?
	}
	if (RET_WAS_ERROR(result)) {
		for (d=distributions ; d != NULL ; d=d->next) {
			struct pull_target *u;
			for (u=d->targets ; u != NULL ; u=u->next) {
				upgradelist_free(u->upgradelist);
				u->upgradelist = NULL;
			}
		}
		return result;
	}
	if (verbose >= 0)
		printf("Installing (and possibly deleting) packages...\n");

	for (d=distributions ; d != NULL ; d=d->next) {
		if (global.onlysmalldeletes) {
			if (pull_isbigdelete(d)) {
				fprintf(stderr,
"Not processing '%s' because of --onlysmalldeletes\n",
						d->distribution->codename);
				continue;
			}
		}
		r = pull_install(d);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			break;
	}
	logger_wait();

	return result;
}
Ejemplo n.º 8
0
static retvalue upload_conditions_add_group(struct upload_conditions **c_p, const struct uploadergroup **groups) {
	const struct uploadergroup *group;
	retvalue r;

	while ((group = *(groups++)) != NULL) {
		r = upload_conditions_add(c_p, &group->permissions);
		if (!RET_WAS_ERROR(r) && group->memberof != NULL)
			r = upload_conditions_add_group(c_p, group->memberof);
		if (RET_WAS_ERROR(r))
			return r;
	}
	return RET_OK;
}
Ejemplo n.º 9
0
retvalue trackingdata_insert(struct trackingdata *data, enum filetype filetype, const struct strlist *filekeys, /*@null@*//*@only@*/char*oldsource, /*@null@*//*@only@*/char*oldversion, /*@null@*/const struct strlist *oldfilekeys) {
	retvalue result, r;
	struct trackedpackage *pkg;

	if (data == NULL) {
		assert(oldversion == NULL && oldsource == NULL);
		free(oldversion);
		free(oldsource);
		return RET_OK;
	}
	assert(data->pkg != NULL);
	result = trackedpackage_adddupfilekeys(data->tracks, data->pkg,
			filetype, filekeys, true);
	if (RET_WAS_ERROR(result)) {
		free(oldsource); free(oldversion);
		return result;
	}
	if (oldsource == NULL || oldversion == NULL || oldfilekeys == NULL) {
		assert(oldsource==NULL&&oldversion==NULL&&oldfilekeys==NULL);
		return RET_OK;
	}
	if (strcmp(oldversion, data->pkg->sourceversion) == 0 &&
			strcmp(oldsource, data->pkg->sourcename) == 0) {
		/* Unlikely, but it may also be the same source version as
		 * the package we are currently adding */
		free(oldsource); free(oldversion);
		return trackedpackage_removefilekeys(data->tracks, data->pkg,
				oldfilekeys);
	}
	r = tracking_get(data->tracks, oldsource, oldversion, &pkg);
	if (RET_WAS_ERROR(r)) {
		free(oldsource); free(oldversion);
		return r;
	}
	if (r == RET_NOTHING) {
		fprintf(stderr,
"Could not found tracking data for %s_%s in %s to remove old files from it.\n",
			oldsource, oldversion, data->tracks->codename);
		free(oldsource); free(oldversion);
		return result;
	}
	r = trackedpackage_removefilekeys(data->tracks, pkg, oldfilekeys);
	RET_UPDATE(result, r);
	r = tracking_save(data->tracks, pkg);
	RET_UPDATE(result, r);
	r = trackingdata_remember(data, oldsource, oldversion);
	RET_UPDATE(result, r);

	return result;
}
Ejemplo n.º 10
0
retvalue tracking_tidyall(trackingdb t) {
	struct cursor *cursor;
	retvalue result, r;
	struct trackedpackage *pkg;
	const char *key, *value, *data;
	size_t datalen;

	r = table_newglobalcursor(t->table, &cursor);
	if (!RET_IS_OK(r))
		return r;

	result = RET_NOTHING;

	while (cursor_nextpair(t->table, cursor,
				&key, &value, &data, &datalen)) {
		r = parse_data(key, value, data, datalen, &pkg);
		if (RET_WAS_ERROR(r)) {
			result = r;
			break;
		}
		r = trackedpackage_tidy(t, pkg);
		RET_UPDATE(result, r);
		r = tracking_saveatcursor(t, cursor, pkg);
		RET_UPDATE(result, r);
		trackedpackage_free(pkg);
	}
	r = cursor_close(t->table, cursor);
	RET_UPDATE(result, r);
	return result;
}
Ejemplo n.º 11
0
retvalue set_ignore(const char *given, bool newvalue, enum config_option_owner newowner) {
	const char *g, *p;
	retvalue r;

	assert (given != NULL);

	g = given;

	while (true) {
		p = g;
		while (*p != '\0' && *p != ',')
			p++;
		if (p == g) {
			fprintf(stderr,
"Empty ignore option in --ignore='%s'!\n",
					given);
			return RET_ERROR_MISSING;
		}
		r = set(g, p - g, newvalue, newowner);
		if (RET_WAS_ERROR(r))
			return r;
		if (*p == '\0')
			return RET_OK;
		g = p+1;
	}
}
Ejemplo n.º 12
0
retvalue space_needed(struct devices *devices, const char *filename, const struct checksums *checksums) {
	size_t l = strlen(filename);
	char buffer[l+1];
	struct stat s;
	struct device *device;
	int ret;
	retvalue r;
	fsblkcnt_t blocks;
	off_t filesize;

	if (devices == NULL)
		return RET_NOTHING;

	while (l > 0 && filename[l-1] != '/')
		l--;
	assert (l > 0);
	memcpy(buffer, filename, l);
	buffer[l] = '\0';

	ret = stat(buffer, &s);
	if (ret != 0) {
		int e = errno;
		fprintf(stderr, "Error stat'ing %s: %d=%s\n", filename,
						e, strerror(e));
		return RET_ERRNO(e);
	}
	r = device_find_or_create(devices, s.st_dev, buffer, &device);
	if (RET_WAS_ERROR(r))
		return r;
	filesize = checksums_getfilesize(checksums);
	blocks = (filesize + device->blocksize - 1) / device->blocksize;
	device->needed += 1 + blocks;

	return RET_OK;
}
Ejemplo n.º 13
0
retvalue space_prepare(struct devices **devices, enum spacecheckmode mode, off_t reservedfordb, off_t reservedforothers) {
	struct devices *n;
	struct device *d;
	struct stat s;
	int ret;
	retvalue r;

	if (mode == scm_NONE) {
		*devices = NULL;
		return RET_OK;
	}
	assert (mode == scm_FULL);
	n = NEW(struct devices);
	if (FAILEDTOALLOC(n))
		return RET_ERROR_OOM;
	n->root = NULL;
	n->reserved = reservedforothers;

	ret = stat(global.dbdir, &s);
	if (ret != 0) {
		int e = errno;
		fprintf(stderr, "Error stat'ing %s: %d=%s\n",
				global.dbdir, e, strerror(e));
		free(n);
		return RET_ERRNO(e);
	}
	r = device_find_or_create(n, s.st_dev, global.dbdir, &d);
	if (RET_WAS_ERROR(r)) {
		space_free(n);
		return r;
	}
	d->reserved += reservedfordb/d->blocksize+1;
	*devices = n;
	return RET_OK;
}
Ejemplo n.º 14
0
static inline retvalue add_patches(const char *diffindexfile, struct diffindex *n, const struct strlist *patches) {
	int i;

	assert (patches->count == n->patchcount);

	for (i = 0 ; i < n->patchcount; i++) {
		struct hashes hashes;
		const char *patchname;
		retvalue r;

		parse_sha1line(patches->values[i], &hashes, &patchname);
		if (hashes.hashes[cs_sha1sum].len == 0
				|| hashes.hashes[cs_length].len == 0
				|| *patchname == '\0') {
			r = RET_ERROR;
		} else
			r = checksums_initialize(&n->patches[i].checksums,
					hashes.hashes);
		ASSERT_NOT_NOTHING(r);
		if (RET_WAS_ERROR(r)) {
			fprintf(stderr,
"Error parsing SHA1-Patches line %d in '%s':!\n'%s'\n",
				i, diffindexfile, patches->values[i]);
			return r;
		}
		n->patches[i].name = strdup(patchname);
		if (FAILEDTOALLOC(n))
			return RET_ERROR_OOM;
	}
	return RET_OK;
}
Ejemplo n.º 15
0
static retvalue generatepulltarget(struct pull_distribution *pd, struct target *target) {
	struct pull_source **s;
	struct pull_target *pt;
	retvalue r;
	int i;

	pt = NEW(struct pull_target);
	if (FAILEDTOALLOC(pt))
		return RET_ERROR_OOM;
	pt->target = target;
	pt->next = pd->targets;
	pt->upgradelist = NULL;
	pt->sources = NULL;
	s = &pt->sources;
	pd->targets = pt;

	for (i = 0 ; i < pd->distribution->pulls.count ; i++) {
		struct pull_rule *rule = pd->rules[i];

		if (rule == NULL)
			r = pull_createdelete(&s);
		else
			r = pull_createsource(rule, target, &s);
		if (RET_WAS_ERROR(r))
			return r;
	}

	return RET_OK;
}
Ejemplo n.º 16
0
static inline retvalue checkorimprove(const char *filekey, struct checksums **checksums_p) {
	const struct checksums *checksums = *checksums_p;
	struct checksums *indatabase;
	bool improves;
	retvalue r;

	r = files_get_checksums(filekey, &indatabase);
	if (r == RET_NOTHING) {
		fprintf(stderr, "Missing file %s\n", filekey);
		return RET_ERROR_MISSING;
	}
	if (RET_WAS_ERROR(r))
		return r;
	if (!checksums_check(checksums, indatabase, &improves)) {
		fprintf(stderr,
"File \"%s\" is already registered with different checksums!\n",
				filekey);
		checksums_printdifferences(stderr, indatabase, checksums);
		r = RET_ERROR_WRONG_MD5;
	} else if (improves) {
		r = checksums_combine(checksums_p, indatabase, NULL);
	} else
		r = RET_NOTHING;
	checksums_free(indatabase);
	return r;
}
Ejemplo n.º 17
0
/* check if file is already there (RET_NOTHING) or could be added (RET_OK)
 * or RET_ERROR_WRONG_MD5SUM if filekey  already has different md5sum */
retvalue files_canadd(const char *filekey, const struct checksums *checksums) {
	retvalue r;
	struct checksums *indatabase;
	bool improves;

	r = files_get_checksums(filekey, &indatabase);
	if (r == RET_NOTHING)
		return RET_OK;
	if (RET_WAS_ERROR(r))
		return r;
	if (!checksums_check(indatabase, checksums, &improves)) {
		fprintf(stderr,
"File \"%s\" is already registered with different checksums!\n",
				filekey);
		checksums_printdifferences(stderr, indatabase, checksums);
		checksums_free(indatabase);
		return RET_ERROR_WRONG_MD5;

	}
	// TODO: sometimes the caller might want to have additional
	// checksums from the database already, think about ways to
	// make them available...
	checksums_free(indatabase);
	return RET_NOTHING;
}
Ejemplo n.º 18
0
/* read the data from a .deb, make some checks and extract some data */
static retvalue deb_read(/*@out@*/struct debpackage **pkg, const char *filename, bool needssourceversion) {
	retvalue r;
	struct debpackage *deb;

	deb = zNEW(struct debpackage);
	if (FAILEDTOALLOC(deb))
		return RET_ERROR_OOM;

	r = binaries_readdeb(&deb->deb, filename, needssourceversion);
	if (RET_IS_OK(r))
		r = properpackagename(deb->deb.name);
	if (RET_IS_OK(r))
		r = propersourcename(deb->deb.source);
	if (RET_IS_OK(r) && needssourceversion)
		r = properversion(deb->deb.sourceversion);
	if (RET_IS_OK(r))
		r = properversion(deb->deb.version);
	if (RET_WAS_ERROR(r)) {
		deb_free(deb);
		return r;
	}
	*pkg = deb;

	return RET_OK;
}
Ejemplo n.º 19
0
retvalue getfilelist(/*@out@*/char **filelist, size_t *size, const char *debfile) {
	struct ar_archive *ar;
	retvalue r;
	bool hadcandidate = false;

	r = ar_open(&ar, debfile);
	if (RET_WAS_ERROR(r))
		return r;
	assert (r != RET_NOTHING);
	do {
		char *filename;
		enum compression c;

		r = ar_nextmember(ar, &filename);
		if (RET_IS_OK(r)) {
			if (strncmp(filename, "data.tar", 8) != 0) {
				free(filename);
				continue;
			}
			hadcandidate = true;
			for (c = 0 ; c < c_COUNT ; c++) {
				if (strcmp(filename + 8,
						uncompression_suffix[c]) == 0)
					break;
			}
			if (c >= c_COUNT) {
				free(filename);
				continue;
			}
			ar_archivemember_setcompression(ar, c);
			if (uncompression_supported(c)) {
				struct archive *tar;

				tar = archive_read_new();
				r = read_data_tar(filelist, size,
						debfile, ar, tar);
				// TODO: check how to get an error message here..
				archive_read_finish(tar);
				if (r != RET_NOTHING) {
					ar_close(ar);
					free(filename);
					return r;
				}

			}
			free(filename);
		}
	} while (RET_IS_OK(r));
	ar_close(ar);
	if (hadcandidate)
		fprintf(stderr,
"Could not find a suitable data.tar file within '%s'!\n", debfile);
	else
		fprintf(stderr,
"Could not find a data.tar file within '%s'!\n", debfile);
	return RET_ERROR_MISSING;
}
Ejemplo n.º 20
0
retvalue tracking_retrack(struct distribution *d, bool needsretrack) {
	struct target *t;
	trackingdb tracks;
	retvalue r, rr;

	if (d->tracking == dt_NONE)
		return RET_NOTHING;

	for (t = d->targets ; !needsretrack && t != NULL ; t = t->next) {
		if (t->staletracking)
			needsretrack = true;
	}
	if (!needsretrack)
		return RET_NOTHING;

	if (verbose > 0)
		printf("Retracking %s...\n", d->codename);

	r = tracking_initialize(&tracks, d, false);
	if (!RET_IS_OK(r))
		return r;
	/* first forget that any package is there*/
	r = tracking_reset(tracks);
	if (!RET_WAS_ERROR(r)) {
		/* add back information about actually used files */
		r = distribution_foreach_package(d,
				atom_unknown, atom_unknown, atom_unknown,
				package_retrack, NULL, tracks);
	}
	if (RET_IS_OK(r)) {
		for (t = d->targets ; t != NULL ; t = t->next) {
			t->staletracking = false;
		}
	}
	if (!RET_WAS_ERROR(r)) {
		/* now remove everything no longer needed */
		r = tracking_tidyall(tracks);
	}
	rr = tracking_done(tracks);
	RET_ENDUPDATE(r, rr);
	return r;
}
Ejemplo n.º 21
0
retvalue uploaders_permissions(struct uploaders *u, const struct signatures *signatures, struct upload_conditions **c_p) {
	struct upload_conditions *conditions = NULL;
	retvalue r;
	int j;

	r = upload_conditions_add(&conditions,
			&u->anybodypermissions);
	if (RET_WAS_ERROR(r))
		return r;
	if (signatures == NULL) {
		/* signatures.count might be 0 meaning there is
		 * something lile a gpg header but we could not get
		 * keys, because of a gpg error or because of being
		 * compiling without libgpgme */
		r = upload_conditions_add(&conditions,
				&u->unsignedpermissions);
		if (RET_WAS_ERROR(r)) {
			free(conditions);
			return r;
		}
	}
	if (signatures != NULL && signatures->validcount > 0) {
		r = upload_conditions_add(&conditions,
				&u->anyvalidkeypermissions);
		if (RET_WAS_ERROR(r)) {
			free(conditions);
			return r;
		}
	}
	if (signatures != NULL) {
		for (j = 0 ; j < signatures->count ; j++) {
			r = find_key_and_add(u, &conditions,
					&signatures->signatures[j]);
			if (RET_WAS_ERROR(r)) {
				free(conditions);
				return r;
			}
		}
	}
	*c_p = conditions;
	return RET_OK;
}
Ejemplo n.º 22
0
static retvalue parse_architectures(/*@out@*/struct atomlist *atoms, const char **pp, const struct filebeingparsed *fbp, int column) {
	const char *p = *pp;
	retvalue r;

	atomlist_init(atoms);
	do {
		const char *startp, *endp;
		atom_t atom;

		while (*p != '\0' && xisspace(*p))
			p++;
		if (*p != '\'') {
			errorcol(fbp, column + (int)(p - *pp),
"starting \"'\" expected!");
			return RET_ERROR;
		}
		p++;
		startp = p;
		while (*p != '\0' && *p != '\'' && *p != '*' && *p != '?')
			p++;
		if (*p == '*' || *p == '?') {
			errorcol(fbp, column + (int)(p - *pp),
"Wildcards are not allowed in architectures!");
			return RET_ERROR;
		}
		if (*p == '\0') {
			errorcol(fbp, column + (int)(p - *pp),
"closing \"'\" expected!");
			return RET_ERROR;
		}
		assert (*p == '\'');
		endp = p;
		p++;
		atom = architecture_find_l(startp, endp - startp);
		if (!atom_defined(atom)) {
			errorcol(fbp, column + (int)(startp-*pp),
"Unknown architecture '%.*s'! (Did you mistype?)",
					(int)(endp-startp), startp);
			return RET_ERROR;
		}
		r = atomlist_add_uniq(atoms, atom);
		if (RET_WAS_ERROR(r))
			return r;
		while (*p != '\0' && xisspace(*p))
			p++;
		column += (p - *pp);
		*pp = p;
		if (**pp == '|') {
			p++;
		}
	} while (**pp == '|');
	*pp = p;
	return RET_OK;
}
Ejemplo n.º 23
0
static retvalue tracking_foreachversion(trackingdb t, struct distribution *distribution,  const char *sourcename, retvalue (action)(trackingdb t, struct trackedpackage *, struct distribution *)) {
	struct cursor *cursor;
	retvalue result, r;
	struct trackedpackage *pkg;
	const char *value, *data;
	size_t datalen;

	r = table_newduplicatecursor(t->table, sourcename, &cursor,
			&value, &data, &datalen);
	if (!RET_IS_OK(r))
		return r;

	result = RET_NOTHING;

	do {
		r = parse_data(sourcename, value, data, datalen, &pkg);
		if (RET_WAS_ERROR(r)) {
			result = r;
			break;
		}
		if (verbose > 10)
			printf("Processing track of '%s' version '%s'\n",
					pkg->sourcename, pkg->sourceversion);
		r = action(t, pkg, distribution);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r)) {
			(void)cursor_close(t->table, cursor);
			trackedpackage_free(pkg);
			return r;
		}
		r = trackedpackage_tidy(t, pkg);
		RET_ENDUPDATE(result, r);
		r = tracking_saveatcursor(t, cursor, pkg);
		RET_UPDATE(result, r);
		trackedpackage_free(pkg);
	} while (cursor_nextpair(t->table, cursor, NULL,
				&value, &data, &datalen));
	r = cursor_close(t->table, cursor);
	RET_UPDATE(result, r);
	return result;
}
Ejemplo n.º 24
0
/* check for file in the database and if not found there, if it can be detected */
retvalue files_expect(const char *filekey, const struct checksums *checksums, bool warnifadded) {
	retvalue r;
	char *filename;
	struct checksums *improvedchecksums = NULL;

	r = files_canadd(filekey, checksums);
	if (r == RET_NOTHING)
		return RET_OK;
	if (RET_WAS_ERROR(r))
		return r;

	/* ready to add means missing, so have to look for the file itself: */
	filename = files_calcfullfilename(filekey);
	if (FAILEDTOALLOC(filename))
		return RET_ERROR_OOM;

	/* first check if a possible manually put (or left over from previous
	 * downloads attepts) file is there and is correct */
	r = checksums_test(filename, checksums, &improvedchecksums);
	if (r == RET_ERROR_WRONG_MD5) {
		fprintf(stderr,
"Deleting unexpected file '%s'!\n"
"(not in database and wrong in pool)\n ",
				filename);
		if (unlink(filename) == 0)
			r = RET_NOTHING;
		else {
			int e = errno;
			fprintf(stderr,
"Error %d deleting '%s': %s!\n", e, filename, strerror(e));
		}
	}
	free(filename);
	if (!RET_IS_OK(r))
		return r;

	if (warnifadded)
		fprintf(stderr,
"Warning: readded existing file '%s' mysteriously missing from the checksum database.\n",
				filekey);

	// TODO: some callers might want the updated checksum when
	// improves is true, how to get them there?

	/* add found file to database */
	if (improvedchecksums != NULL) {
		r = files_add_checksums(filekey, improvedchecksums);
		checksums_free(improvedchecksums);
	} else
		r = files_add_checksums(filekey, checksums);
	assert (r != RET_NOTHING);
	return r;
}
Ejemplo n.º 25
0
/* add possible already existing references */
retvalue references_add(const char *identifier, const struct strlist *files) {
	int i;
	retvalue r;

	for (i = 0 ; i < files->count ; i++) {
		const char *filekey = files->values[i];
		r = table_addrecord(rdb_references, filekey,
				identifier, strlen(identifier), true);
		if (RET_WAS_ERROR(r))
			return r;
	}
	return RET_OK;
}
Ejemplo n.º 26
0
retvalue pull_dumpupdate(struct pull_distribution *distributions) {
	struct pull_distribution *d;
	retvalue result, r;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = distribution_loadalloverrides(d->distribution);
		if (RET_WAS_ERROR(r))
			return r;
	}

	result = RET_NOTHING;

	for (d=distributions ; d != NULL ; d=d->next) {
		r = pull_search(NULL, d);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			break;
		pull_dumplist(d);
	}

	return result;
}
Ejemplo n.º 27
0
static retvalue pull_search(/*@null@*/FILE *out, struct pull_distribution *d) {
	retvalue result, r;
	struct pull_target *u;

	result = RET_NOTHING;
	for (u=d->targets ; u != NULL ; u=u->next) {
		r = pull_searchformissing(out, u);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			break;
	}
	return result;
}
Ejemplo n.º 28
0
retvalue tracking_reset(trackingdb t) {
	struct cursor *cursor;
	retvalue result, r;
	struct trackedpackage *pkg;
	const char *key, *value, *data;
	char *newdata;
	size_t datalen, newdatalen;
	int i;

	r = table_newglobalcursor(t->table, &cursor);
	if (!RET_IS_OK(r))
		return r;

	result = RET_NOTHING;

	while (cursor_nextpair(t->table, cursor,
				&key, &value, &data, &datalen)) {
		// this would perhaps be more stable if it just replaced
		// everything within the string just received...
		result = parse_data(key, value, data, datalen, &pkg);
		if (RET_WAS_ERROR(result))
			break;
		for (i = 0 ; i < pkg->filekeys.count ; i++) {
			pkg->refcounts[i] = 0;
		}
		result = gen_data(pkg, &newdata, &newdatalen);
		trackedpackage_free(pkg);
		if (RET_IS_OK(result))
			result = cursor_replace(t->table, cursor,
					newdata, newdatalen);
		free(newdata);
		if (RET_WAS_ERROR(result))
			break;
	}
	r = cursor_close(t->table, cursor);
	RET_UPDATE(result, r);
	return result;
}
Ejemplo n.º 29
0
static inline retvalue pull_searchformissing(/*@null@*/FILE *out, struct pull_target *p) {
	struct pull_source *source;
	retvalue result, r;

	if (verbose > 2 && out != NULL)
		fprintf(out, "  pulling into '%s'\n", p->target->identifier);
	assert(p->upgradelist == NULL);
	r = upgradelist_initialize(&p->upgradelist, p->target);
	if (RET_WAS_ERROR(r))
		return r;

	result = RET_NOTHING;

	for (source=p->sources ; source != NULL ; source=source->next) {

		if (source->rule == NULL) {
			if (verbose > 4 && out != NULL)
				fprintf(out,
"  marking everything to be deleted\n");
			r = upgradelist_deleteall(p->upgradelist);
			RET_UPDATE(result, r);
			if (RET_WAS_ERROR(r))
				return result;
			continue;
		}

		if (verbose > 4 && out != NULL)
			fprintf(out, "  looking what to get from '%s'\n",
					source->source->identifier);
		r = upgradelist_pull(p->upgradelist, source->source,
				ud_decide_by_rule, source->rule, source);
		RET_UPDATE(result, r);
		if (RET_WAS_ERROR(r))
			return result;
	}

	return result;
}
Ejemplo n.º 30
0
/* hardlink file with known checksums and add it to database */
retvalue files_hardlinkandadd(const char *tempfile, const char *filekey, const struct checksums *checksums) {
	retvalue r;

	/* an additional check to make sure nothing tricks us into
	 * overwriting it by another file */
	r = files_canadd(filekey, checksums);
	if (!RET_IS_OK(r))
		return r;
	r = checksums_hardlink(global.outdir, filekey, tempfile, checksums);
	if (RET_WAS_ERROR(r))
		return r;

	return files_add_checksums(filekey, checksums);
}