From: Jonathan McDowell Date: Mon, 31 May 2004 23:47:19 +0000 (+0000) Subject: cscvs to tla changeset 46 X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/commitdiff_plain/5913c95f2c7abf4c3cb06e27d384d80fb4c83547 cscvs to tla changeset 46 Author: noodles Date: 2002/11/24 13:55:40 Removed circular code dependencies; split keyindex up into key decoding and key display files and moved signature caching from hash.c to keydb.c --- diff --git a/Makefile b/Makefile index 9855c7c..dc8d5ce 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,8 @@ DBTYPE = db3 LIBS = -L/usr/local/lib -ldb3 PROGS = add lookup gpgwww onak -CORE_OBJS = armor.o charfuncs.o getcgi.o hash.o keydb_$(DBTYPE).o keyid.o \ - keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o +CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o keydb_$(DBTYPE).o \ + keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha.o OBJS = merge.o md5.o stats.o sendsync.o $(CORE_OBJS) SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha.c main.c getcgi.c stats.c \ keyindex.c mem.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \ diff --git a/decodekey.c b/decodekey.c new file mode 100644 index 0000000..6a16604 --- /dev/null +++ b/decodekey.c @@ -0,0 +1,233 @@ +/* + * decodekey.c - Routines to further decode an OpenPGP key. + * + * Jonathan McDowell + * + * Copyright 2002 Project Purple + */ + +#include +#include +#include +#include +#include +#include + +#include "decodekey.h" +#include "hash.h" +#include "keyid.h" +#include "keystructs.h" +#include "ll.h" + +/* + * parse_subpackets - Parse the subpackets of a Type 4 signature. + * @data: The subpacket data. + * @keyid: A pointer to where we should return the keyid. + * + * This function parses the subkey data of a Type 4 signature and fills + * in the supplied variables. It also returns the length of the data + * processed. + */ +int parse_subpackets(unsigned char *data, uint64_t *keyid) +{ + int offset = 0; + int length = 0; + int packetlen = 0; + + assert(data != NULL); + + length = (data[0] << 8) + data[1] + 2; + + offset = 2; + while (offset < length) { + packetlen = data[offset++]; + if (packetlen > 191 && packetlen < 255) { + packetlen = ((packetlen - 192) << 8) + + data[offset++] + 192; + } else if (packetlen == 255) { + packetlen = data[offset++]; + packetlen <<= 8; + packetlen = data[offset++]; + packetlen <<= 8; + packetlen = data[offset++]; + packetlen <<= 8; + packetlen = data[offset++]; + } + switch (data[offset]) { + case 2: + /* + * Signature creation time. Might want to output this? + */ + break; + case 0x83: + /* + * Signature expiration time. Might want to output this? + */ + break; + case 16: + *keyid = data[offset+packetlen - 8]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 7]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 6]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 5]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 4]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 3]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 2]; + *keyid <<= 8; + *keyid += data[offset+packetlen - 1]; + break; + case 23: + /* + * Key server preferences. Including no-modify. + */ + break; + case 25: + /* + * Primary UID. + */ + break; + default: + /* + * We don't care about unrecognized packets unless bit + * 7 is set in which case we prefer an error than + * ignoring it. + */ + assert(!(data[offset] & 0x80)); + } + offset += packetlen; + } + + return length; +} + +/** + * keysigs - Return the sigs on a given OpenPGP signature list. + * @curll: The current linked list. Can be NULL to create a new list. + * @sigs: The signature list we want the sigs on. + * + * Returns a linked list of stats_key elements containing the sigs on the + * supplied OpenPGP packet list. + */ +struct ll *keysigs(struct ll *curll, + struct openpgp_packet_list *sigs) +{ + uint64_t keyid = 0; + + while (sigs != NULL) { + keyid = sig_keyid(sigs->packet); + sigs = sigs->next; + curll = lladd(curll, createandaddtohash(keyid)); + } + + return curll; +} + +/** + * sig_keyid - Return the keyid for a given OpenPGP signature packet. + * @packet: The signature packet. + * + * Returns the keyid for the supplied signature packet. + */ +uint64_t sig_keyid(struct openpgp_packet *packet) +{ + int length = 0; + uint64_t keyid = 0; + + if (packet != NULL) { + keyid = 0; + switch (packet->data[0]) { + case 2: + case 3: + keyid = packet->data[7]; + keyid <<= 8; + keyid += packet->data[8]; + keyid <<= 8; + keyid += packet->data[9]; + keyid <<= 8; + keyid += packet->data[10]; + keyid <<= 8; + keyid += packet->data[11]; + keyid <<= 8; + keyid += packet->data[12]; + keyid <<= 8; + keyid += packet->data[13]; + keyid <<= 8; + keyid += packet->data[14]; + break; + case 4: + length = parse_subpackets(&packet->data[4], + &keyid); + parse_subpackets(&packet->data[length + 4], + &keyid); + /* + * Don't bother to look at the unsigned packets. + */ + break; + default: + break; + } + } + + return keyid; +} + +/* + * TODO: Abstract out; all our linked lists should be generic and then we can + * llsize them. + */ +int spsize(struct openpgp_signedpacket_list *list) +{ + int size = 0; + struct openpgp_signedpacket_list *cur; + + for (cur = list; cur != NULL; cur = cur->next, size++) ; + + return size; +} + +/** + * keyuids - Takes a key and returns an array of its UIDs + * @key: The key to get the uids of. + * @primary: A pointer to store the primary UID in. + * + * keyuids takes a public key structure and builds an array of the UIDs + * on the key. It also attempts to work out the primary UID and returns a + * separate pointer to that particular element of the array. + */ +char **keyuids(struct openpgp_publickey *key, char **primary) +{ + struct openpgp_signedpacket_list *curuid = NULL; + char buf[1024]; + char **uids = NULL; + int count = 0; + + if (key != NULL && key->uids != NULL) { + uids = malloc((spsize(key->uids) + 1) * sizeof (char *)); + + curuid = key->uids; + while (curuid != NULL) { + buf[0] = 0; + if (curuid->packet->tag == 13) { + snprintf(buf, 1023, "%.*s", + (int) curuid->packet->length, + curuid->packet->data); + uids[count++] = strdup(buf); + } + curuid = curuid -> next; + } + uids[count] = NULL; + } + /* + * TODO: Parse subpackets for real primary ID (v4 keys) + */ + if (primary != NULL) { + *primary = uids[0]; + } + + return uids; +} diff --git a/decodekey.h b/decodekey.h new file mode 100644 index 0000000..f7df5ef --- /dev/null +++ b/decodekey.h @@ -0,0 +1,45 @@ +/* + * keyindex.h - Routines to list an OpenPGP key. + * + * Jonathan McDowell + * + * Copyright 2002 Project Purple + */ + +#ifndef __DECODEKEY_H__ +#define __DECODEKEY_H__ + +#include "keystructs.h" +#include "ll.h" + +/** + * keysigs - Return the sigs on a given OpenPGP signature packet list. + * @curll: The current linked list. Can be NULL to create a new list. + * @sigs: The signature list we want the sigs on. + * + * Returns a linked list of stats_key elements containing the sigs for the + * supplied OpenPGP signature packet list. + */ +struct ll *keysigs(struct ll *curll, + struct openpgp_packet_list *sigs); + +/** + * sig_keyid - Return the keyid for a given OpenPGP signature packet. + * @packet: The signature packet. + * + * Returns the keyid for the supplied signature packet. + */ +uint64_t sig_keyid(struct openpgp_packet *packet); + +/** + * keyuids - Takes a key and returns an array of its UIDs + * @key: The key to get the uids of. + * @primary: A pointer to store the primary UID in. + * + * keyuids takes a public key structure and builds an array of the UIDs + * on the key. It also attempts to work out the primary UID and returns a + * separate pointer to that particular element of the array. + */ +char **keyuids(struct openpgp_publickey *key, char **primary); + +#endif diff --git a/hash.c b/hash.c index e131d03..91f3b9e 100644 --- a/hash.c +++ b/hash.c @@ -10,11 +10,9 @@ #include #include "hash.h" -#include "keydb.h" -#include "keyid.h" +#include "keystructs.h" #include "ll.h" #include "mem.h" -#include "stats.h" /** * hashtable - the hash table array. @@ -126,42 +124,3 @@ struct ll *gethashtableentry(int entry) { return hashtable[entry]; } - -/** - * hash_getkeysigs - Gets the signatures on a key. - * @keyid: The key we want the signatures for. - * - * This function gets the signatures on a key. It's the same as the - * getkeysigs function from the keydb module except we also cache the data - * so that if we need it again we already have it available. - */ -struct ll *hash_getkeysigs(uint64_t keyid) -{ - struct stats_key *key = NULL; - - if (keyid == 0) { - return NULL; - } - - key = findinhash(keyid); - if (key == NULL) { - key = malloc(sizeof(*key)); - if (key != NULL) { - key->keyid = keyid; - key->colour = 0; - key->parent = 0; - key->sigs = NULL; - key->gotsigs = false; - addtohash(key); - } else { - perror("hash_getkeysigs()"); - return NULL; - } - } - if (key->gotsigs == false) { - key->sigs = getkeysigs(key->keyid); - key->gotsigs = true; - } - - return key->sigs; -} diff --git a/hash.h b/hash.h index 284095d..6cb0216 100644 --- a/hash.h +++ b/hash.h @@ -9,8 +9,8 @@ #ifndef __HASH_H__ #define __HASH_H__ +#include "keystructs.h" #include "ll.h" -#include "stats.h" #define HASHSIZE 1024 #define HASHMASK 0x3FF @@ -73,14 +73,4 @@ unsigned long hashelements(void); */ struct ll *gethashtableentry(int entry); -/** - * hash_getkeysigs - Gets the signatures on a key. - * @keyid: The key we want the signatures for. - * - * This function gets the signatures on a key. It's the same as the - * getkeysigs function from the keydb module except we also cache the data - * so that if we need it again we already have it available. - */ -struct ll *hash_getkeysigs(uint64_t keyid); - #endif /* __HASH_H__ */ diff --git a/keydb.c b/keydb.c index 3acf711..3fe3d34 100644 --- a/keydb.c +++ b/keydb.c @@ -16,9 +16,10 @@ #include +#include "decodekey.h" +#include "hash.h" #include "keydb.h" #include "keyid.h" -#include "keyindex.h" #include "keystructs.h" #include "mem.h" #include "parsekey.h" @@ -83,6 +84,45 @@ struct ll *getkeysigs(uint64_t keyid) } #endif +/** + * cached_getkeysigs - Gets the signatures on a key. + * @keyid: The key we want the signatures for. + * + * This function gets the signatures on a key. It's the same as the + * getkeysigs function above except we use the hash module to cache the + * data so if we need it again it's already loaded. + */ +struct ll *cached_getkeysigs(uint64_t keyid) +{ + struct stats_key *key = NULL; + + if (keyid == 0) { + return NULL; + } + + key = findinhash(keyid); + if (key == NULL) { + key = malloc(sizeof(*key)); + if (key != NULL) { + key->keyid = keyid; + key->colour = 0; + key->parent = 0; + key->sigs = NULL; + key->gotsigs = false; + addtohash(key); + } else { + perror("cached_getkeysigs()"); + return NULL; + } + } + if (key->gotsigs == false) { + key->sigs = getkeysigs(key->keyid); + key->gotsigs = true; + } + + return key->sigs; +} + #ifdef NEED_GETFULLKEYID /** * getfullkeyid - Maps a 32bit key id to a 64bit one. diff --git a/keydb.h b/keydb.h index 4ad761b..647916c 100644 --- a/keydb.h +++ b/keydb.h @@ -115,6 +115,15 @@ char *keyid2uid(uint64_t keyid); */ struct ll *getkeysigs(uint64_t keyid); +/** + * cached_getkeysigs - Gets the signatures on a key. + * @keyid: The key we want the signatures for. + * + * This function gets the signatures on a key. It's the same as the + * getkeysigs function above except we use the hash module to cache the + */ +struct ll *cached_getkeysigs(uint64_t keyid); + /** * getfullkeyid - Maps a 32bit key id to a 64bit one. * @keyid: The 32bit keyid. diff --git a/keyindex.c b/keyindex.c index a8f9193..5911cac 100644 --- a/keyindex.c +++ b/keyindex.c @@ -7,21 +7,20 @@ */ #include +#include #include #include -#include #include #include #include +#include "decodekey.h" #include "getcgi.h" #include "hash.h" #include "keydb.h" #include "keyid.h" #include "keyindex.h" #include "keystructs.h" -#include "ll.h" -#include "stats.h" int list_sigs(struct openpgp_packet_list *sigs, bool html) { @@ -139,7 +138,6 @@ int list_subkeys(struct openpgp_signedpacket_list *subkeys, bool verbose, return 0; } - /** * key_index - List a set of OpenPGP keys. * @keys: The keys to display. @@ -223,216 +221,3 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, return 0; } - -/* - * parse_subpackets - Parse the subpackets of a Type 4 signature. - * @data: The subpacket data. - * @keyid: A pointer to where we should return the keyid. - * - * This function parses the subkey data of a Type 4 signature and fills - * in the supplied variables. It also returns the length of the data - * processed. - */ -int parse_subpackets(unsigned char *data, uint64_t *keyid) -{ - int offset = 0; - int length = 0; - int packetlen = 0; - - assert(data != NULL); - - length = (data[0] << 8) + data[1] + 2; - - offset = 2; - while (offset < length) { - packetlen = data[offset++]; - if (packetlen > 191 && packetlen < 255) { - packetlen = ((packetlen - 192) << 8) + - data[offset++] + 192; - } else if (packetlen == 255) { - packetlen = data[offset++]; - packetlen <<= 8; - packetlen = data[offset++]; - packetlen <<= 8; - packetlen = data[offset++]; - packetlen <<= 8; - packetlen = data[offset++]; - } - switch (data[offset]) { - case 2: - /* - * Signature creation time. Might want to output this? - */ - break; - case 0x83: - /* - * Signature expiration time. Might want to output this? - */ - break; - case 16: - *keyid = data[offset+packetlen - 8]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 7]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 6]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 5]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 4]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 3]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 2]; - *keyid <<= 8; - *keyid += data[offset+packetlen - 1]; - break; - case 23: - /* - * Key server preferences. Including no-modify. - */ - break; - case 25: - /* - * Primary UID. - */ - break; - default: - /* - * We don't care about unrecognized packets unless bit - * 7 is set in which case we prefer an error than - * ignoring it. - */ - assert(!(data[offset] & 0x80)); - } - offset += packetlen; - } - - return length; -} - -/** - * keysigs - Return the sigs on a given OpenPGP signature list. - * @curll: The current linked list. Can be NULL to create a new list. - * @sigs: The signature list we want the sigs on. - * - * Returns a linked list of stats_key elements containing the sigs on the - * supplied OpenPGP packet list. - */ -struct ll *keysigs(struct ll *curll, - struct openpgp_packet_list *sigs) -{ - uint64_t keyid = 0; - - while (sigs != NULL) { - keyid = sig_keyid(sigs->packet); - sigs = sigs->next; - curll = lladd(curll, createandaddtohash(keyid)); - } - - return curll; -} - -/** - * sig_keyid - Return the keyid for a given OpenPGP signature packet. - * @packet: The signature packet. - * - * Returns the keyid for the supplied signature packet. - */ -uint64_t sig_keyid(struct openpgp_packet *packet) -{ - int length = 0; - uint64_t keyid = 0; - - if (packet != NULL) { - keyid = 0; - switch (packet->data[0]) { - case 2: - case 3: - keyid = packet->data[7]; - keyid <<= 8; - keyid += packet->data[8]; - keyid <<= 8; - keyid += packet->data[9]; - keyid <<= 8; - keyid += packet->data[10]; - keyid <<= 8; - keyid += packet->data[11]; - keyid <<= 8; - keyid += packet->data[12]; - keyid <<= 8; - keyid += packet->data[13]; - keyid <<= 8; - keyid += packet->data[14]; - break; - case 4: - length = parse_subpackets(&packet->data[4], - &keyid); - parse_subpackets(&packet->data[length + 4], - &keyid); - /* - * Don't bother to look at the unsigned packets. - */ - break; - default: - break; - } - } - - return keyid; -} - -/* - * TODO: Abstract out; all our linked lists should be generic and then we can - * llsize them. - */ -int spsize(struct openpgp_signedpacket_list *list) -{ - int size = 0; - struct openpgp_signedpacket_list *cur; - - for (cur = list; cur != NULL; cur = cur->next, size++) ; - - return size; -} - -/** - * keyuids - Takes a key and returns an array of its UIDs - * @key: The key to get the uids of. - * @primary: A pointer to store the primary UID in. - * - * keyuids takes a public key structure and builds an array of the UIDs - * on the key. It also attempts to work out the primary UID and returns a - * separate pointer to that particular element of the array. - */ -char **keyuids(struct openpgp_publickey *key, char **primary) -{ - struct openpgp_signedpacket_list *curuid = NULL; - char buf[1024]; - char **uids = NULL; - int count = 0; - - if (key != NULL && key->uids != NULL) { - uids = malloc((spsize(key->uids) + 1) * sizeof (char *)); - - curuid = key->uids; - while (curuid != NULL) { - buf[0] = 0; - if (curuid->packet->tag == 13) { - snprintf(buf, 1023, "%.*s", - (int) curuid->packet->length, - curuid->packet->data); - uids[count++] = strdup(buf); - } - curuid = curuid -> next; - } - uids[count] = NULL; - } - /* - * TODO: Parse subpackets for real primary ID (v4 keys) - */ - if (primary != NULL) { - *primary = uids[0]; - } - - return uids; -} diff --git a/keyindex.h b/keyindex.h index c0b29ed..a9f7976 100644 --- a/keyindex.h +++ b/keyindex.h @@ -26,34 +26,4 @@ int key_index(struct openpgp_publickey *keys, bool verbose, bool fingerprint, bool html); -/** - * keysigs - Return the sigs on a given OpenPGP signature packet list. - * @curll: The current linked list. Can be NULL to create a new list. - * @sigs: The signature list we want the sigs on. - * - * Returns a linked list of stats_key elements containing the sigs for the - * supplied OpenPGP signature packet list. - */ -struct ll *keysigs(struct ll *curll, - struct openpgp_packet_list *sigs); - -/** - * sig_keyid - Return the keyid for a given OpenPGP signature packet. - * @packet: The signature packet. - * - * Returns the keyid for the supplied signature packet. - */ -uint64_t sig_keyid(struct openpgp_packet *packet); - -/** - * keyuids - Takes a key and returns an array of its UIDs - * @key: The key to get the uids of. - * @primary: A pointer to store the primary UID in. - * - * keyuids takes a public key structure and builds an array of the UIDs - * on the key. It also attempts to work out the primary UID and returns a - * separate pointer to that particular element of the array. - */ -char **keyuids(struct openpgp_publickey *key, char **primary); - #endif diff --git a/keystructs.h b/keystructs.h index 10dfcc6..ec1d555 100644 --- a/keystructs.h +++ b/keystructs.h @@ -9,9 +9,12 @@ #ifndef __KEYSTRUCTS_H__ #define __KEYSTRUCTS_H__ +#include #include #include +#include "ll.h" + /** * struct openpgp_packet - Stores an OpenPGP packet. * @tag: The packet tag (ie type). @@ -78,4 +81,20 @@ struct openpgp_publickey { struct openpgp_publickey *next; }; +/** + * struct stats_key - holds key details suitable for doing stats on. + * @keyid: The keyid. + * @colour: Used for marking during DFS/BFS. + * @parent: The key that lead us to this one for DFS/BFS. + * @sigs: A linked list of the signatures on this key. + * @gotsigs: A bool indicating if we've initialized the sigs element yet. + */ +struct stats_key { + uint64_t keyid; + int colour; + uint64_t parent; + struct ll *sigs; + bool gotsigs; +}; + #endif /* __KEYSTRUCTS_H__ */ diff --git a/maxpath.c b/maxpath.c index 509616e..0bb5fcf 100644 --- a/maxpath.c +++ b/maxpath.c @@ -24,12 +24,12 @@ void findmaxpath(unsigned long max) distance = 0; from = to = tmp = NULL; - hash_getkeysigs(0xF1BD4BE45B430367); + cached_getkeysigs(0xF1BD4BE45B430367); for (loop = 0; (loop < HASHSIZE) && (distance < max); loop++) { curkey = gethashtableentry(loop); while (curkey != NULL && distance < max) { - hash_getkeysigs(((struct stats_key *) + cached_getkeysigs(((struct stats_key *) curkey->object)->keyid); initcolour(false); tmp = furthestkey((struct stats_key *) diff --git a/mem.c b/mem.c index 0795bf3..bb68ac3 100644 --- a/mem.c +++ b/mem.c @@ -13,7 +13,6 @@ #include "keystructs.h" #include "ll.h" #include "mem.h" -#include "stats.h" /** * packet_dup - duplicate an OpenPGP packet. diff --git a/mem.h b/mem.h index 103c417..875bb4c 100644 --- a/mem.h +++ b/mem.h @@ -10,7 +10,6 @@ #define __MEM_H_ #include "keystructs.h" -#include "stats.h" /** * packet_dup - duplicate an OpenPGP packet. diff --git a/merge.c b/merge.c index 8d870a2..7f1773e 100644 --- a/merge.c +++ b/merge.c @@ -10,9 +10,9 @@ #include #include +#include "decodekey.h" #include "keydb.h" #include "keyid.h" -#include "keyindex.h" #include "keystructs.h" #include "ll.h" #include "mem.h" diff --git a/stats.c b/stats.c index 3f897ca..39e96c0 100644 --- a/stats.c +++ b/stats.c @@ -67,7 +67,7 @@ unsigned long findpath(struct stats_key *have, struct stats_key *want) oldkeys = keys; while (keys != NULL && have->colour == 0) { - sigs = hash_getkeysigs(((struct stats_key *) + sigs = cached_getkeysigs(((struct stats_key *) keys->object)->keyid); while (sigs != NULL && have->colour == 0) { /* @@ -129,8 +129,8 @@ void dofindpath(uint64_t have, uint64_t want, bool html) /* * Make sure the keys we have and want are in the cache. */ - hash_getkeysigs(fullhave); - hash_getkeysigs(fullwant); + cached_getkeysigs(fullhave); + cached_getkeysigs(fullwant); if ((keyinfoa = findinhash(fullhave)) == NULL) { printf("Couldn't find key 0x%llX.\n", have); @@ -232,7 +232,7 @@ struct stats_key *furthestkey(struct stats_key *have) curll = lladd(NULL, have); while (curll != NULL) { - sigs = hash_getkeysigs(((struct stats_key *) + sigs = cached_getkeysigs(((struct stats_key *) curll->object)->keyid); while (sigs != NULL) { if (((struct stats_key *) sigs->object)->colour == 0) { diff --git a/stats.h b/stats.h index df32ab6..4b7cf09 100644 --- a/stats.h +++ b/stats.h @@ -19,28 +19,12 @@ key_getsigns - get the keys a key signs. */ #ifndef __STATS_H__ #define __STATS_H__ -#include -// #include #include +#include +#include "keystructs.h" #include "ll.h" -/** - * struct stats_key - holds key details suitable for doing stats on. - * @keyid: The keyid. - * @colour: Used for marking during DFS/BFS. - * @parent: The key that lead us to this one for DFS/BFS. - * @sigs: A linked list of the signatures on this key. - * @gotsigs: A bool indicating if we've initialized the sigs element yet. - */ -struct stats_key { - uint64_t keyid; - int colour; - uint64_t parent; - struct ll *sigs; - bool gotsigs; -}; - /** * initcolour - Clear the key graph ready for use. * @parent: Do we want to clear the parent pointers too?