Commit eafea02d authored by Bernhard Link's avatar Bernhard Link

some more upgrading code...

parent 3cc71c2e
......@@ -3,8 +3,8 @@ bin_PROGRAMS = mirrorer
CPPFLAGS = @CPPFLAGS@ -D_GNU_SOURCE=1 -DPKGDATADIR=\"$(pkgdatadir)\" -Wall
mirrorer_SOURCES = main.c guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c packages.c binaries.c sources.c names.c dpkgversions.c release.c mprintf.c download.c updates.c strlist.c signature.c distribution.c extractcontrol.c checkindeb.c checkindsc.c checkin.c copyfile.c strtupel.c upgrade.c upgradelist.c
mirrorer_SOURCES = main.c guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c packages.c binaries.c sources.c names.c dpkgversions.c release.c mprintf.c download.c updates.c strlist.c signature.c distribution.c extractcontrol.c checkindeb.c checkindsc.c checkin.c copyfile.c strtupel.c upgrade.c upgradelist.c target.c
mirrorer_LDFLAGS += -ldb3
noinst_HEADERS = guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h packages.h binaries.h sources.h names.h release.h error.h mprintf.h download.h updates.h strlist.h signature.h distribution.h extractcontrol.h checkindeb.h checkindsc.h copyfile.h strtupel.h upgrade.h upgradelist.h
noinst_HEADERS = guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h packages.h binaries.h sources.h names.h release.h error.h mprintf.h download.h updates.h strlist.h signature.h distribution.h extractcontrol.h checkindeb.h checkindsc.h copyfile.h strtupel.h upgrade.h upgradelist.h target.h
MAINTAINERCLEANFILES = Makefile.in configure install-sh stamp-h.in aclocal.m4 config.h.in mkinstalldirs
......@@ -247,6 +247,21 @@ retvalue binaries_calcfilekeys(const char *component,const char *sourcename,cons
return r;
}
static inline retvalue calcnewcontrol(const char *chunk,const char *sourcename,const char *basename,const char *component,struct strlist *filekeys,char **newchunk) {
retvalue r;
r = binaries_calcfilekeys(component,sourcename,basename,filekeys);
if( RET_WAS_ERROR(r) )
return r;
*newchunk = chunk_replacefield(chunk,"Filename",filekeys->values[0]);
if( !*newchunk ) {
strlist_done(filekeys);
return RET_ERROR_OOM;
}
return RET_OK;
}
static inline retvalue callaction(new_package_action *action,void *data,
const char *chunk,const char *packagename,const char *version,
const char *sourcename,const char *basename,
......@@ -258,17 +273,10 @@ static inline retvalue callaction(new_package_action *action,void *data,
char *newchunk;
struct strlist filekeys;
r = binaries_calcfilekeys(component,sourcename,basename,&filekeys);
r = calcnewcontrol(chunk,sourcename,basename,component,&filekeys,&newchunk);
if( RET_WAS_ERROR(r) )
return r;
// Calculating the following here will cause work done
// unnecesarrily, but it unifies handling afterwards:
newchunk = chunk_replacefield(chunk,"Filename",filekeys.values[0]);
if( !newchunk ) {
strlist_done(&filekeys);
return RET_ERROR_OOM;
}
r = (*action)(data,newchunk,packagename,version,
&filekeys,origfiles,md5sums,oldfiles);
free(newchunk);
......@@ -376,3 +384,49 @@ retvalue binaries_addtodist(const char *dbpath,DB *references,const char *codena
strlist_done(&oldfilekeys);
return result;
}
retvalue binaries_getname(target t,const char *control,char **packagename){
retvalue r;
r = chunk_getvalue(control,"Package",packagename);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Package name in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
retvalue binaries_getversion(target t,const char *control,char **version) {
retvalue r;
r = chunk_getvalue(control,"Version",version);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Version in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
retvalue binaries_getinstalldata(target t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *filekeys,struct strlist *md5sums) {
char *sourcename,*basename;
retvalue r;
//TODO replace this with code doing only the needed work...
r = binaries_parse_chunk(chunk,NULL,&sourcename,&basename,md5sums,NULL);
if( RET_WAS_ERROR(r) ) {
return r;
} else if( r == RET_NOTHING ) {
fprintf(stderr,"Does not look like a binary package: '%s'!\n",chunk);
return RET_ERROR;
}
r = calcnewcontrol(chunk,sourcename,basename,t->component,filekeys,control);
if( RET_WAS_ERROR(r) ) {
strlist_done(md5sums);
}
free(sourcename);free(basename);
return r;
}
......@@ -9,6 +9,9 @@
#include "packages.h"
#warning "What's hapening here?"
#endif
#ifndef __MIRRORER_TARGET_H
#include "target.h"
#endif
/* get files out of a "Packages.gz"-chunk. */
retvalue binaries_parse_getfiles(const char *chunk,struct strlist *files);
......@@ -48,4 +51,9 @@ retvalue binaries_findnew(
* of it, if necesary. */
retvalue binaries_addtodist(const char *dbpath,DB *references,const char *codename,const char *component,const char *architecture,const char *package,const char *version,const char *controlchunk,const struct strlist *filekeys);
/* Functions for the target.h-stuff: */
retvalue binaries_getname(target t,const char *chunk,char **packagename);
retvalue binaries_getversion(target t,const char *chunk,char **version);
retvalue binaries_getinstalldata(target t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *files,struct strlist *md5sums);
#endif
......@@ -32,6 +32,7 @@
#include "md5sum.h"
#include "chunks.h"
#include "files.h"
#include "target.h"
#include "packages.h"
#include "reference.h"
#include "binaries.h"
......@@ -893,6 +894,7 @@ static int upgrade(int argc,char *argv[]) {
retvalue result,r;
upgradelist upgrade;
packagesdb pkgs;
target target;
if( argc <=1 ) {
fprintf(stderr,"mirrorer upgrade [<distributions>]\n");
......@@ -904,12 +906,19 @@ static int upgrade(int argc,char *argv[]) {
return EXIT_RET(result);
}
r = packages_initialize(&pkgs,dbdir,"woody-main-source");
r = target_initialize_source("woody","main",&target);
if( RET_WAS_ERROR(r) ) {
return EXIT_RET(r);
}
result = upgradelist_initialize(&upgrade,pkgs,ud_always);
r = packages_initialize(&pkgs,dbdir,target->identifier);
if( RET_WAS_ERROR(r) ) {
target_done(target);
return EXIT_RET(r);
}
result = upgradelist_initialize(&upgrade,target,pkgs,ud_always);
if( RET_WAS_ERROR(result) ) {
target_done(target);
(void)packages_done(pkgs);
return EXIT_RET(result);
}
......
......@@ -341,39 +341,52 @@ retvalue sources_lookforolder(
return RET_OK;
}
static inline retvalue callaction(new_package_action *action, void *data,
const char *chunk, const char *package, const char *version,
const char *origdirectory, const struct strlist *basenames,
const struct strlist *md5sums,
const char *component, const struct strlist *oldfilekeys) {
char *directory,*newchunk;
struct strlist origfiles,filekeys;
static retvalue calcnewcontrol(
const char *chunk, const char *package,
const struct strlist *basenames,
const char *component,
struct strlist *filekeys,char **newchunk) {
char *directory;
retvalue r;
directory = calc_sourcedir(component,package);
if( !directory )
return RET_ERROR_OOM;
r = calc_dirconcats(directory,basenames,&filekeys);
r = calc_dirconcats(directory,basenames,filekeys);
if( RET_WAS_ERROR(r) ) {
free(directory);
return r;
}
*newchunk = chunk_replacefield(chunk,"Directory",directory);
free(directory);
if( !newchunk ) {
strlist_done(filekeys);
return RET_ERROR_OOM;
}
return RET_OK;
}
static inline retvalue callaction(new_package_action *action, void *data,
const char *chunk, const char *package, const char *version,
const char *origdirectory, const struct strlist *basenames,
const struct strlist *md5sums,
const char *component, const struct strlist *oldfilekeys) {
char *newchunk;
struct strlist origfiles,filekeys;
retvalue r;
r = calcnewcontrol(chunk,package,basenames,component,&filekeys,&newchunk);
if( RET_WAS_ERROR(r) )
return r;
r = calc_dirconcats(origdirectory,basenames,&origfiles);
if( RET_WAS_ERROR(r) ) {
strlist_done(&filekeys);
free(directory);
free(newchunk);
return r;
}
newchunk = chunk_replacefield(chunk,"Directory",directory);
free(directory);
if( !newchunk ) {
strlist_done(&origfiles);
strlist_done(&filekeys);
return RET_ERROR_OOM;
}
// Calculating origfiles and newchunk will both not be needed in half of the
// cases. This could be avoided by pushing flags to sources_findnew which
// to generete. (doing replace_field here makes handling in main.c so
......@@ -527,3 +540,53 @@ retvalue sources_calcfilelines(const struct strlist *basenames,const struct strl
*(--result) = '\0';
return RET_OK;
}
retvalue sources_getname(target t,const char *control,char **packagename){
retvalue r;
r = chunk_getvalue(control,"Package",packagename);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Package name in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
retvalue sources_getversion(target t,const char *control,char **version) {
retvalue r;
r = chunk_getvalue(control,"Version",version);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Version in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
retvalue sources_getinstalldata(target t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *filekeys,struct strlist *md5sums) {
retvalue r;
struct strlist filelines,basenames;
r = chunk_getextralinelist(chunk,"Files",&filelines);
if( r == RET_NOTHING ) {
fprintf(stderr,"Missing 'Files' entry in '%s'!\n",chunk);
r = RET_ERROR;
}
if( RET_WAS_ERROR(r) )
return r;
r = getBasenamesAndMd5(&filelines,&basenames,md5sums);
strlist_done(&filelines);
if( RET_WAS_ERROR(r) )
return r;
r = calcnewcontrol(chunk,packagename,&basenames,t->component,
filekeys,control);
strlist_done(&basenames);
if( RET_WAS_ERROR(r) ) {
strlist_done(md5sums);
}
return r;
}
......@@ -10,6 +10,9 @@
#include "packages.h"
#warning "What's hapening here?"
#endif
#ifndef __MIRRORER_TARGET_H
#include "target.h"
#endif
/* get filename and md5sum from a files: line" */
retvalue sources_getfile(const char *fileline,
......@@ -36,4 +39,10 @@ retvalue sources_addtodist(const char *dbpath,DB *references,const char *codenam
/* Calculate the filelines in a form suitable for chunk_replacefields: */
retvalue sources_calcfilelines(const struct strlist *basenames,const struct strlist *md5sums,char **item);
/* Functions for the target.h-stuff: */
retvalue sources_getname(target t,const char *chunk,char **packagename);
retvalue sources_getversion(target ,const char *chunk,char **version);
retvalue sources_getinstalldata(target t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *files,struct strlist *md5sums);
#endif
/* This file is part of "mirrorer" (TODO: find better title)
* Copyright (C) 2004 Bernhard R. Link
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <malloc.h>
#include "error.h"
#include "strlist.h"
#include "names.h"
#include "chunks.h"
#include "packages.h"
#include "binaries.h"
#include "sources.h"
#include "names.h"
#include "target.h"
extern int verbose;
static retvalue target_initialize(
const char *codename,const char *component,const char *architecture,
get_name getname,get_version getversion,get_installdata getinstalldata,
target *d) {
target t;
t = calloc(1,sizeof(struct s_target));
if( t == NULL )
return RET_ERROR_OOM;
t->codename = strdup(codename);
t->component = strdup(component);
t->architecture = strdup(architecture);
t->identifier = calc_identifier(codename,component,architecture);
if( !t->codename|| !t->component|| !t->architecture|| !t->identifier) {
target_done(t);
return RET_ERROR_OOM;
}
t->getname = getname;
t->getversion = getversion;
t->getinstalldata = getinstalldata;
*d = t;
return RET_OK;
}
retvalue target_initialize_binary(const char *codename,const char *component,const char *architecture,target *target) {
return target_initialize(codename,component,architecture,binaries_getname,binaries_getversion,binaries_getinstalldata,target);
}
retvalue target_initialize_source(const char *codename,const char *component,target *target) {
return target_initialize(codename,component,"source",sources_getname,sources_getversion,sources_getinstalldata,target);
}
void target_done(target target) {
if( target == NULL )
return;
free(target->codename);
free(target->component);
free(target->architecture);
free(target->identifier);
free(target);
}
#ifndef __MIRRORER_TARGET_H
#define __MIRRORER_TARGET_H
#ifndef __MIRRORER_STRLIST_H
#include "strlist.h"
#endif
typedef struct s_target *target;
typedef retvalue get_name(target,const char *,char **);
typedef retvalue get_version(target,const char *,char **);
typedef retvalue get_installdata(target,const char *,const char *,const char *,char **,struct strlist *,struct strlist *);
struct s_target {
char *codename;
char *component;
char *architecture;
char *identifier;
get_name *getname;
get_version *getversion;
get_installdata *getinstalldata;
};
retvalue target_initialize_binary(const char *distribution,const char *component,const char *architecture,target *target);
retvalue target_initialize_source(const char *distribution,const char *component,target *target);
void target_done(target target);
#endif
......@@ -58,52 +58,12 @@ typedef struct s_package_data {
struct s_upgradelist {
upgrade_decide_function *decide;
packagesdb packages;
target target;
package_data *list;
/* NULL or the last/next thing to test in alphabetical order */
package_data *current,*last;
};
/* extract a package name out of a chunk */
//TODO: to be replaced by a call to a packagelist-specific callback.
static retvalue getpackagename(const char *control,char **version) {
retvalue r;
r = chunk_getvalue(control,"Package",version);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Version in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
/* extract a version out of a chunk */
//TODO: to be replaced by a call to a packagelist-specific callback.
static retvalue getversion(const char *control,char **version) {
retvalue r;
r = chunk_getvalue(control,"Version",version);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr,"Did not found Version in chunk:'%s'\n",control);
return RET_ERROR;
}
return r;
}
/* calculate files and control-chunk */
//TODO: to be replaced by a call to a packagelist-specific callback.
static retvalue getinstalldata(const char *control,char **newcontrol,struct strlist *newfiles,struct strlist *newmd5sums) {
retvalue r;
*newcontrol = strdup(control);
if( *newcontrol == NULL )
return RET_ERROR_OOM;
r = strlist_init_singleton(strdup("blub"),newfiles);
r = strlist_init_singleton(strdup("blub"),newmd5sums);
return r;
}
static void package_data_free(package_data *data){
if( data == NULL )
return;
......@@ -124,7 +84,7 @@ static retvalue save_package_version(void *d,const char *packagename,const char
retvalue r;
package_data *package;
r = getversion(chunk,&version);
r = upgrade->target->getversion(upgrade->target,chunk,&version);
if( RET_WAS_ERROR(r) )
return r;
......@@ -165,7 +125,7 @@ static retvalue save_package_version(void *d,const char *packagename,const char
}
retvalue upgradelist_initialize(upgradelist *ul,packagesdb packages,upgrade_decide_function *decide) {
retvalue upgradelist_initialize(upgradelist *ul,target t,packagesdb packages,upgrade_decide_function *decide) {
upgradelist upgrade;
retvalue r;
......@@ -175,6 +135,7 @@ retvalue upgradelist_initialize(upgradelist *ul,packagesdb packages,upgrade_deci
upgrade->decide = decide;
upgrade->packages = packages;
upgrade->target = t;
r = packages_foreach(packages,save_package_version,upgrade,0);
......@@ -212,10 +173,10 @@ retvalue upgradelist_trypackage(upgradelist upgrade,const char *chunk){
retvalue r;
upgrade_decision decision;
r = getpackagename(chunk,&packagename);
r = upgrade->target->getname(upgrade->target,chunk,&packagename);
if( RET_WAS_ERROR(r) )
return r;
r = getversion(chunk,&version);
r = upgrade->target->getversion(upgrade->target,chunk,&version);
if( RET_WAS_ERROR(r) ) {
free(packagename);
return r;
......@@ -292,7 +253,7 @@ retvalue upgradelist_trypackage(upgradelist upgrade,const char *chunk){
new->new_version = version;
new->version = version;
version = NULL; //to be sure...
r = getinstalldata(chunk,&new->new_control,&new->new_files,&new->new_md5sums);
r = upgrade->target->getinstalldata(upgrade->target,new->name,new->new_version,chunk,&new->new_control,&new->new_files,&new->new_md5sums);
if( RET_WAS_ERROR(r) ) {
package_data_free(new);
return RET_ERROR_OOM;
......@@ -310,11 +271,10 @@ retvalue upgradelist_trypackage(upgradelist upgrade,const char *chunk){
package_data *current = upgrade->current;
char *control;struct strlist files,md5sums;
free(packagename);
packagename = NULL; // to be sure...
r = dpkgversions_isNewer(version,current->version);
if( RET_WAS_ERROR(r) ) {
free(packagename);
free(version);
return r;
}
......@@ -334,6 +294,7 @@ retvalue upgradelist_trypackage(upgradelist upgrade,const char *chunk){
free(version);
}
free(packagename);
return RET_NOTHING;
}
decision = upgrade->decide(current->name,
......@@ -341,10 +302,12 @@ retvalue upgradelist_trypackage(upgradelist upgrade,const char *chunk){
if( decision != UD_UPGRADE ) {
//TODO: perhaps set a flag if hold was applied...
free(version);
free(packagename);
return RET_NOTHING;
}
r = getinstalldata(chunk,&control,&files,&md5sums);
r = upgrade->target->getinstalldata(upgrade->target,packagename,version,chunk,&control,&files,&md5sums);
free(packagename);
if( RET_WAS_ERROR(r) ) {
free(version);
return r;
......@@ -373,7 +336,24 @@ retvalue upgradelist_dump(upgradelist upgrade){
pkg = upgrade->list;
while( pkg ) {
printf("'%s': have: '%s' found: '%s' take: '%s'\n",pkg->name,pkg->version_in_use,pkg->new_version,pkg->version);
if( pkg->version == pkg->version_in_use ) {
if( verbose > 0 )
printf("'%s': '%s' will be kept "
"(best new: '%s')\n",
pkg->name,pkg->version_in_use,
pkg->new_version);
} else {
printf("'%s': '%s' will be upgraded to '%s':\n "
"files needed: ",
pkg->name,pkg->version_in_use,
pkg->new_version);
strlist_fprint(stdout,&pkg->new_files);
printf("\nwith md5sums: ");
strlist_fprint(stdout,&pkg->new_md5sums);
printf("\ninstalling as: '%s'\n",pkg->new_control);
}
pkg = pkg->next;
}
return RET_OK;
......
#ifndef __MIRRORER_UPGRADELIST_H
#define __MIRRORER_UPGRADELIST_H
#ifndef __MIRRORER_PACKAGES_H
#include "packages.h"
#endif
#ifndef __MIRRORER_TARGET_H
#include "target.h"
#endif
/* Things for making decisions what to upgrade and what not */
......@@ -13,7 +20,11 @@ upgrade_decision ud_always(const char *p,const char *ov,const char *nv);
typedef struct s_upgradelist *upgradelist;
retvalue upgradelist_initialize(upgradelist *ul,packagesdb packages,upgrade_decide_function *decide);
retvalue upgradelist_initialize(upgradelist *ul,target target, packagesdb packages,upgrade_decide_function *decide);
retvalue upgradelist_done(upgradelist upgrade);
retvalue upgradelist_dump(upgradelist upgrade);
retvalue upgradelist_update(upgradelist upgrade,const char *filename,int force);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment