Commit 12e477ab authored by Bernhard Link's avatar Bernhard Link

improve parsing of update's Config lines

parent 9d9adbee
2007-09-10 Bernhard R. Link <brlink@debian.org>
* improve parsing of update's Config lines
2007-09-09 Bernhard R. Link <brlink@debian.org>
* never hardlink index files, but copy them always into the lists
directory. (Should not make a difference yet, but feels safer).
......
TODO:
check for empty lists... (decide which should not be empty and which may)
test new config parser: do update's Config still work?
test new config parser
do not put/leave files in pool when include gets an older version than already there
write more automated test-cases
finish import from incoming dir, implement sending mails to uploader
......
......@@ -90,6 +90,7 @@ static void aptmethod_free(/*@only@*/struct aptmethod *method) {
return;
free(method->name);
free(method->baseuri);
free(method->config);
free(method->fallbackbaseuri);
free(method->inputbuffer);
free(method->command);
......@@ -176,7 +177,7 @@ retvalue aptmethod_initialize_run(struct aptmethodrun **run) {
}
}
retvalue aptmethod_newmethod(struct aptmethodrun *run,const char *uri,const char *fallbackuri,const char *config,struct aptmethod **m) {
retvalue aptmethod_newmethod(struct aptmethodrun *run, const char *uri, const char *fallbackuri, const struct strlist *config, struct aptmethod **m) {
struct aptmethod *method;
const char *p;
......@@ -231,17 +232,19 @@ retvalue aptmethod_newmethod(struct aptmethodrun *run,const char *uri,const char
return RET_ERROR_OOM;
}
}
if( config != NULL ) {
method->config = strdup(config);
if( method->config == NULL ) {
free(method->fallbackbaseuri);
free(method->baseuri);
free(method->name);
free(method);
return RET_ERROR_OOM;
}
} else {
method->config = NULL;
#define CONF601 "601 Configuration"
#define CONFITEM "\nConfig-Item: "
if( config->count == 0 )
method->config = strdup(CONF601 CONFITEM "Dir=/" "\n\n");
else
method->config = strlist_concat(config,
CONF601 CONFITEM, CONFITEM, "\n\n");
if( method->config == NULL ) {
free(method->fallbackbaseuri);
free(method->baseuri);
free(method->name);
free(method);
return RET_ERROR_OOM;
}
method->next = run->methods;
run->methods = method;
......@@ -358,67 +361,6 @@ inline static retvalue aptmethod_startup(struct aptmethodrun *run,struct aptmeth
return RET_OK;
}
/************************Sending Configuration**************************/
static inline retvalue sendconfig(struct aptmethod *method) {
#define CONF601 "601 Configuration"
#define CONFITEM "\nConfig-Item: "
size_t l;
const char *p;
char *c;
bool wasnewline;
assert(method->command == NULL);
method->alreadywritten = 0;
if( method->config == NULL ) {
method->command = mprintf(CONF601 "Config-Item: Dir=/\n\n");
if( method->command == NULL ) {
return RET_ERROR_OOM;
}
method->output_length = strlen(method->command);
return RET_OK;
}
l = sizeof(CONF601)+sizeof(CONFITEM)+1;
for( p = method->config; *p != '\0' ; p++ ) {
if( *p == '\n' )
l += sizeof(CONFITEM)-1;
else
l++;
}
c = method->command = malloc(l);
if( method->command == NULL ) {
return RET_ERROR_OOM;
}
strcpy(c,CONF601 CONFITEM);
c += sizeof(CONF601)+sizeof(CONFITEM)-2;
wasnewline = true;
for( p = method->config; *p != '\0' ; p++ ) {
if( *p != '\n' ) {
if( !wasnewline || !xisspace(*p) )
*(c++) = *p;
wasnewline = false;
} else {
strcpy(c,CONFITEM);
c += sizeof(CONFITEM)-1;
wasnewline = true;
}
}
*(c++) = '\n';
*(c++) = '\n';
*c = '\0';
if( verbose > 11 ) {
fprintf(stderr,"Sending config: '%s'\n",method->command);
}
method->output_length = strlen(method->command);
return RET_OK;
}
/**************************how to add files*****************************/
/*@null@*/static inline struct tobedone *newtodo(const char *baseuri,const char *origfile,const char *destfile,/*@null@*/const char *md5sum,/*@null@*/const char *filekey) {
......@@ -722,9 +664,17 @@ static inline retvalue gotcapabilities(struct aptmethod *method,const char *chun
if( RET_WAS_ERROR(r) )
return r;
if( r != RET_NOTHING ) {
r = sendconfig(method);
if( RET_WAS_ERROR(r) )
return r;
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;
......
......@@ -25,7 +25,7 @@ struct tobedone {
};
retvalue aptmethod_initialize_run(/*@out@*/struct aptmethodrun **run);
retvalue aptmethod_newmethod(struct aptmethodrun *run,const char *uri,const char *fallbackuri,const char *config,/*@out@*/struct aptmethod **m);
retvalue aptmethod_newmethod(struct aptmethodrun *, const char *uri, const char *fallbackuri, const struct strlist *config, /*@out@*/struct aptmethod **);
/* md5sum can be NULL(filekey then, too): if todo != NULL, then *todo will be set */
retvalue aptmethod_queuefile(struct aptmethod *, const char *origfile, const char *destfile, const char *md5sum, const char *filekey, /*@out@*/struct tobedone **);
......
......@@ -350,9 +350,10 @@ int config_nextnonspaceinline(struct configiterator *iter) {
iter->filename, iter->line, \
iter->column, ## __VA_ARGS__);
inline retvalue config_completeword(struct configiterator *iter, char c, char **result_p) {
inline retvalue config_completeword(struct configiterator *iter, char firstc, char **result_p) {
size_t size = 0, len = 0;
char *value = NULL, *nv;
int c = firstc;
iter->markerline = iter->line;
iter->markercolumn = iter->column;
......@@ -757,3 +758,75 @@ retvalue config_getnumber(struct configiterator *iter, const char *name, long lo
*result_p = value;
return RET_OK;
}
static retvalue config_getline(struct configiterator *iter, char **result_p) {
size_t size = 0, len = 0;
char *value = NULL, *nv;
int c;
c = config_nextnonspace(iter);
if( c == EOF )
return RET_NOTHING;
iter->markerline = iter->line;
iter->markercolumn = iter->column;
do {
if( len + 2 >= size ) {
nv = realloc(value, size+128);
if( nv == NULL ) {
free(value);
return RET_ERROR_OOM;
}
size += 128;
value = nv;
}
value[len] = c;
len++;
c = fgetc(iter->f);
if( c == EOF )
break;
if( c == '\n' ) {
iter->eol = true;
break;
}
iter->column++;
} while( true );
assert( len > 0 );
assert( len < size );
while( len > 0 &&
(value[len-1] == ' ' || value[len-1] == '\t'
|| value[len-1] == '\r' ) )
len--;
assert( len > 0 );
value[len] = '\0';
nv = realloc(value, len+1);
if( nv == NULL )
*result_p = value;
else
*result_p = nv;
return RET_OK;
}
retvalue config_getlines(struct configiterator *iter, struct strlist *result) {
char *line;
struct strlist list;
retvalue r;
strlist_init(&list);
do {
r = config_getline(iter, &line);
if( RET_WAS_ERROR(r) ) {
strlist_done(&list);
return r;
}
if( r == RET_NOTHING )
r = strlist_add_dup(&list, "");
else
r = strlist_add(&list, line);
if( RET_WAS_ERROR(r) ) {
strlist_done(&list);
return r;
}
} while( config_nextline(iter) );
strlist_move(result, &list);
return RET_OK;
}
......@@ -40,6 +40,7 @@ unsigned int config_markerline(const struct configiterator *) __attribute__((pur
unsigned int config_markercolumn(const struct configiterator *) __attribute__((pure));
retvalue config_getflags(struct configiterator *, const char *, const struct constant *, bool *, bool, const char *msg);
int config_nextnonspaceinline(struct configiterator *iter);
retvalue config_getlines(struct configiterator *,struct strlist *);
retvalue config_getwords(struct configiterator *,struct strlist *);
retvalue config_getall(struct configiterator *iter, char **result_p);
retvalue config_getword(struct configiterator *, char **);
......@@ -51,8 +52,6 @@ retvalue config_gettruth(struct configiterator *, const char *, bool *);
retvalue config_getnumber(struct configiterator *, const char *, long long *, long long minval, long long maxval);
retvalue config_getconstant(struct configiterator *, const struct constant *, int *);
#define config_getenum(iter,type,constants,result) ({int _val;retvalue _r = config_getconstant(iter, type ## _ ## constants, &_val);*(result) = (enum type)_val;_r;})
// retvalue config_getword(struct configiterator *, char **);
char *config_getline(struct configiterator *);
retvalue config_completeword(struct configiterator *, char, char **);
void config_overline(struct configiterator *);
bool config_nextline(struct configiterator *);
......@@ -81,6 +80,11 @@ static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UN
struct sname *item = data; \
return config_getonlyword(iter, name, NULL, &item->field); \
}
#define CFlinelistSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *confdir), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
return config_getlines(iter, &item->field); \
}
#define CFstrlistSETPROC(sname, field) \
static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), UNUSED(const char *confdir), UNUSED(const char *name), void *data, struct configiterator *iter) { \
struct sname *item = data; \
......
......@@ -285,3 +285,39 @@ bool *strlist_preparefoundlist(const struct strlist *list) {
}
return found;
}
char *strlist_concat(const struct strlist *list, const char *prefix, const char *infix, const char *suffix) {
size_t l, prefix_len, infix_len, suffix_len, line_len;
char *c, *n;
int i;
prefix_len = strlen(prefix);
infix_len = strlen(infix);
suffix_len = strlen(suffix);
l = prefix_len + suffix_len;
for( i = 0 ; i < list->count ; i++ )
l += strlen(list->values[i]);
if( list->count > 0 )
l += (list->count-1)*infix_len;
c = malloc(l + 1);
if( c == NULL )
return c;
memcpy(c, prefix, prefix_len);
n = c + prefix_len;
for( i = 0 ; i < list->count ; i++ ) {
line_len = strlen(list->values[i]);
memcpy(n, list->values[i], line_len);
n += line_len;
if( i+1 < list->count ) {
memcpy(n, infix, infix_len);
n += infix_len;
} else {
memcpy(n, suffix, suffix_len);
n += suffix_len;
}
}
assert( (size_t)(n-c) == l );
*n = '\0';
return c;
}
......@@ -48,4 +48,7 @@ bool strlist_subset(const struct strlist *strlist, const struct strlist *subset,
/* a list of bool for all values, duplicates already set to true */
bool *strlist_preparefoundlist(const struct strlist *);
/* concatenate <prefix> <values separated by infix> <suffix> */
char *strlist_concat(const struct strlist *, const char *prefix, const char *infix, const char *suffix);
#endif
......@@ -133,7 +133,7 @@ struct update_pattern {
//e.g. "Fallback: ftp://ftp.debian.org/pub/linux/debian"
char *fallback; // can be other server or dir, but must be same method
//e.g. "Config: Dir=/"
/*@null@*/char *config;
struct strlist config;
//e.g. "Suite: woody" or "Suite: <asterix>/updates" (NULL means "*")
/*@null@*/char *suite_from;
//e.g. "IgnoreRelease: Yes" for 1 (default is 0)
......@@ -211,11 +211,11 @@ static void update_pattern_free(/*@only@*/struct update_pattern *update) {
if( update == NULL )
return;
free(update->name);
free(update->config);
free(update->method);
free(update->fallback);
free(update->suite_from);
free(update->verifyrelease);
strlist_done(&update->config);
strlist_done(&update->architectures_from);
strlist_done(&update->architectures_into);
strlist_done(&update->components_from);
......@@ -312,7 +312,7 @@ CFurlSETPROC(update_pattern, method)
CFurlSETPROC(update_pattern, fallback)
/* what here? */
CFvalueSETPROC(update_pattern, verifyrelease)
CFallSETPROC(update_pattern, config)
CFlinelistSETPROC(update_pattern, config)
CFtruthSETPROC(update_pattern, ignorerelease)
CFscriptSETPROC(update_pattern, listhook)
CFsplitstrlistSETPROC(update_pattern, architectures)
......@@ -925,7 +925,7 @@ static inline retvalue startuporigin(struct aptmethodrun *run,struct update_orig
assert( origin != NULL && origin->pattern != NULL );
r = aptmethod_newmethod(run,origin->pattern->method,
origin->pattern->fallback,
origin->pattern->config,&method);
&origin->pattern->config, &method);
if( RET_WAS_ERROR(r) ) {
origin->download = NULL;
origin->failed = true;
......
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