void Graph::kruskal(){ DisjointSets trees(nvertices); prepare_search(); bfs_worker(1, &(do_nothing),&(do_nothing),&(insert_edge_to_heap)); edgepair *p; int x, y; vector<edgepair*> spanning_tree; while(!min_heap.empty()){ p = min_heap.remove_top(); x = p->x; y = p->y; int root1 = trees.find(x); int root2 = trees.find(y); if(root1 == root2) continue; else{ spanning_tree.push_back(p); trees.sets_union(root1,root2); } } for(vector<edgepair*>::iterator it = spanning_tree.begin(); it != spanning_tree.end(); it++){ cout << (*it)->x << ", " << (*it)->y << " -- " << (*it)->weight << endl; } }
void Graph::twocolor(){ prepare_search(); for(int i = 1; i <= this->nvertices; i++){ if(!discovered[i]){ color[i] = WHITE; this->bfs_worker(i, &(do_nothing), &(do_nothing), &(color_edge)); } } }
void Graph::connected_components(){ prepare_search(); int c = 0; for(int i = 1; i <= nvertices; i++){ if(!discovered[i]){ c = c + 1; cout << "Component" << c << ":" << endl; bfs_worker(i, &(do_nothing), &(print_vertex), &(do_nothing)); } } }
void Graph::topsort(){ prepare_search(); if(!lifo->empty()){ delete lifo; lifo = new stack<int>; } for(int i = 1; i <= this->nvertices; i++) if(discovered[i] == FALSE) this->dfs_worker(1, &(do_nothing), &push_stack, &(do_nothing)); while(!lifo->empty()){ cout << lifo->top() << " "; lifo->pop(); } cout << endl; }
/* * Search through the keyring(s), starting at the current position, * for a keyblock which contains one of the keys described in the DESC array. */ int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex) { int rc; PACKET pkt; int save_mode; off_t offset, main_offset; size_t n; int need_uid, need_words, need_keyid, need_fpr, any_skip; int pk_no, uid_no; int initial_skip; int use_offtbl; PKT_user_id *uid = NULL; PKT_public_key *pk = NULL; PKT_secret_key *sk = NULL; u32 aki[2]; /* figure out what information we need */ need_uid = need_words = need_keyid = need_fpr = any_skip = 0; for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: need_uid = 1; break; case KEYDB_SEARCH_MODE_WORDS: need_uid = 1; need_words = 1; break; case KEYDB_SEARCH_MODE_SHORT_KID: case KEYDB_SEARCH_MODE_LONG_KID: need_keyid = 1; break; case KEYDB_SEARCH_MODE_FPR16: case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: need_fpr = 1; break; case KEYDB_SEARCH_MODE_FIRST: /* always restart the search in this mode */ keyring_search_reset (hd); break; default: break; } if (desc[n].skipfnc) { any_skip = 1; need_keyid = 1; } } rc = prepare_search (hd); if (rc) return rc; use_offtbl = !hd->secret && kr_offtbl; if (!use_offtbl) ; else if (!kr_offtbl_ready) need_keyid = 1; else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) { struct off_item *oi; oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid); if (!oi) { /* We know that we don't have this key */ hd->found.kr = NULL; hd->current.eof = 1; return -1; } /* We could now create a positive search status and return. * However the problem is that another instance of gpg may * have changed the keyring so that the offsets are not valid * anymore - therefore we don't do it */ } if (need_words) { const char *name = NULL; log_debug ("word search mode does not yet work\n"); /* FIXME: here is a long standing bug in our function and in addition we just use the first search description */ for (n=0; n < ndesc && !name; n++) { if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) name = desc[n].u.name; } assert (name); if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) { /* name changed */ xfree (hd->word_match.name); xfree (hd->word_match.pattern); hd->word_match.name = xstrdup (name); hd->word_match.pattern = prepare_word_match (name); } name = hd->word_match.pattern; } init_packet(&pkt); save_mode = set_packet_list_mode(0); hd->found.kr = NULL; main_offset = 0; pk_no = uid_no = 0; initial_skip = 1; /* skip until we see the start of a keyblock */ while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) { main_offset = offset; pk_no = uid_no = 0; initial_skip = 0; } if (initial_skip) { free_packet (&pkt); continue; } pk = NULL; sk = NULL; uid = NULL; if ( pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_PUBLIC_SUBKEY) { pk = pkt.pkt.public_key; ++pk_no; if (need_fpr) { fingerprint_from_pk (pk, afp, &an); while (an < 20) /* fill up to 20 bytes */ afp[an++] = 0; } if (need_keyid) keyid_from_pk (pk, aki); if (use_offtbl && !kr_offtbl_ready) update_offset_hash_table (kr_offtbl, aki, main_offset); } else if (pkt.pkttype == PKT_USER_ID) { uid = pkt.pkt.user_id; ++uid_no; } else if ( pkt.pkttype == PKT_SECRET_KEY || pkt.pkttype == PKT_SECRET_SUBKEY) { sk = pkt.pkt.secret_key; ++pk_no; if (need_fpr) { fingerprint_from_sk (sk, afp, &an); while (an < 20) /* fill up to 20 bytes */ afp[an++] = 0; } if (need_keyid) keyid_from_sk (sk, aki); } for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_NONE: BUG (); break; case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: case KEYDB_SEARCH_MODE_WORDS: if ( uid && !compare_name (desc[n].mode, desc[n].u.name, uid->name, uid->len)) goto found; break; case KEYDB_SEARCH_MODE_SHORT_KID: if ((pk||sk) && desc[n].u.kid[1] == aki[1]) goto found; break; case KEYDB_SEARCH_MODE_LONG_KID: if ((pk||sk) && desc[n].u.kid[0] == aki[0] && desc[n].u.kid[1] == aki[1]) goto found; break; case KEYDB_SEARCH_MODE_FPR16: if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16)) goto found; break; case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20)) goto found; break; case KEYDB_SEARCH_MODE_FIRST: if (pk||sk) goto found; break; case KEYDB_SEARCH_MODE_NEXT: if (pk||sk) goto found; break; default: rc = G10ERR_INV_ARG; goto found; } } free_packet (&pkt); continue; found: /* Record which desc we matched on. Note this value is only meaningful if this function returns with no errors. */ if(descindex) *descindex=n; for (n=any_skip?0:ndesc; n < ndesc; n++) { if (desc[n].skipfnc && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid)) break; } if (n == ndesc) goto real_found; free_packet (&pkt); } real_found: if (!rc) { hd->found.offset = main_offset; hd->found.kr = hd->current.kr; hd->found.pk_no = (pk||sk)? pk_no : 0; hd->found.uid_no = uid? uid_no : 0; } else if (rc == -1) { hd->current.eof = 1; /* if we scanned all keyrings, we are sure that * all known key IDs are in our offtbl, mark that. */ if (use_offtbl && !kr_offtbl_ready) { KR_NAME kr; /* First set the did_full_scan flag for this keyring (ignore secret keyrings) */ for (kr=kr_names; kr; kr = kr->next) { if (!kr->secret && hd->resource == kr) { kr->did_full_scan = 1; break; } } /* Then check whether all flags are set and if so, mark the offtbl ready */ for (kr=kr_names; kr; kr = kr->next) { if (!kr->secret && !kr->did_full_scan) break; } if (!kr) kr_offtbl_ready = 1; } } else hd->current.error = rc; free_packet(&pkt); set_packet_list_mode(save_mode); return rc; }
void Graph::bfs(int start){ prepare_search(); bfs_worker(start, &(do_nothing), &(print_vertex), &(do_nothing)); }
void Graph::shortest_path(int v, int y){ prepare_search(); this->bfs(v); find_path(y); }
/* * Search through the keyring(s), starting at the current position, * for a keyblock which contains one of the keys described in the DESC array. */ int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc, size_t *descindex, int ignore_legacy) { int rc; PACKET pkt; struct parse_packet_ctx_s parsectx; int save_mode; off_t offset, main_offset; size_t n; int need_uid, need_words, need_keyid, need_fpr, any_skip; int pk_no, uid_no; int initial_skip; int scanned_from_start; int use_key_present_hash; PKT_user_id *uid = NULL; PKT_public_key *pk = NULL; u32 aki[2]; /* figure out what information we need */ need_uid = need_words = need_keyid = need_fpr = any_skip = 0; for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: need_uid = 1; break; case KEYDB_SEARCH_MODE_WORDS: need_uid = 1; need_words = 1; break; case KEYDB_SEARCH_MODE_SHORT_KID: case KEYDB_SEARCH_MODE_LONG_KID: need_keyid = 1; break; case KEYDB_SEARCH_MODE_FPR16: case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: need_fpr = 1; break; case KEYDB_SEARCH_MODE_FIRST: /* always restart the search in this mode */ keyring_search_reset (hd); break; default: break; } if (desc[n].skipfnc) { any_skip = 1; need_keyid = 1; } } if (DBG_LOOKUP) log_debug ("%s: need_uid = %d; need_words = %d; need_keyid = %d; need_fpr = %d; any_skip = %d\n", __func__, need_uid, need_words, need_keyid, need_fpr, any_skip); rc = prepare_search (hd); if (rc) { if (DBG_LOOKUP) log_debug ("%s: prepare_search failed: %s (%d)\n", __func__, gpg_strerror (rc), gpg_err_code (rc)); return rc; } use_key_present_hash = !!key_present_hash; if (!use_key_present_hash) { if (DBG_LOOKUP) log_debug ("%s: no offset table.\n", __func__); } else if (!key_present_hash_ready) { if (DBG_LOOKUP) log_debug ("%s: initializing offset table. (need_keyid: %d => 1)\n", __func__, need_keyid); need_keyid = 1; } else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID) { struct key_present *oi; if (DBG_LOOKUP) log_debug ("%s: look up by long key id, checking cache\n", __func__); oi = key_present_hash_lookup (key_present_hash, desc[0].u.kid); if (!oi) { /* We know that we don't have this key */ if (DBG_LOOKUP) log_debug ("%s: cache says not present\n", __func__); hd->found.kr = NULL; hd->current.eof = 1; return -1; } /* We could now create a positive search status and return. * However the problem is that another instance of gpg may * have changed the keyring so that the offsets are not valid * anymore - therefore we don't do it */ } if (need_words) { const char *name = NULL; log_debug ("word search mode does not yet work\n"); /* FIXME: here is a long standing bug in our function and in addition we just use the first search description */ for (n=0; n < ndesc && !name; n++) { if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) name = desc[n].u.name; } log_assert (name); if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) { /* name changed */ xfree (hd->word_match.name); xfree (hd->word_match.pattern); hd->word_match.name = xstrdup (name); hd->word_match.pattern = prepare_word_match (name); } /* name = hd->word_match.pattern; */ } init_packet(&pkt); save_mode = set_packet_list_mode(0); hd->found.kr = NULL; main_offset = 0; pk_no = uid_no = 0; initial_skip = 1; /* skip until we see the start of a keyblock */ scanned_from_start = iobuf_tell (hd->current.iobuf) == 0; if (DBG_LOOKUP) log_debug ("%s: %ssearching from start of resource.\n", __func__, scanned_from_start ? "" : "not "); init_parse_packet (&parsectx, hd->current.iobuf); while (1) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; rc = search_packet (&parsectx, &pkt, &offset, need_uid); if (ignore_legacy && gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) { free_packet (&pkt, &parsectx); continue; } if (rc) break; if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY) { main_offset = offset; pk_no = uid_no = 0; initial_skip = 0; } if (initial_skip) { free_packet (&pkt, &parsectx); continue; } pk = NULL; uid = NULL; if ( pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_PUBLIC_SUBKEY || pkt.pkttype == PKT_SECRET_KEY || pkt.pkttype == PKT_SECRET_SUBKEY) { pk = pkt.pkt.public_key; ++pk_no; if (need_fpr) { fingerprint_from_pk (pk, afp, &an); while (an < 20) /* fill up to 20 bytes */ afp[an++] = 0; } if (need_keyid) keyid_from_pk (pk, aki); if (use_key_present_hash && !key_present_hash_ready && scanned_from_start) key_present_hash_update (key_present_hash, aki); } else if (pkt.pkttype == PKT_USER_ID) { uid = pkt.pkt.user_id; ++uid_no; } for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_NONE: BUG (); break; case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILEND: case KEYDB_SEARCH_MODE_WORDS: if ( uid && !compare_name (desc[n].mode, desc[n].u.name, uid->name, uid->len)) goto found; break; case KEYDB_SEARCH_MODE_SHORT_KID: if (pk && desc[n].u.kid[1] == aki[1]) goto found; break; case KEYDB_SEARCH_MODE_LONG_KID: if (pk && desc[n].u.kid[0] == aki[0] && desc[n].u.kid[1] == aki[1]) goto found; break; case KEYDB_SEARCH_MODE_FPR16: if (pk && !memcmp (desc[n].u.fpr, afp, 16)) goto found; break; case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: if (pk && !memcmp (desc[n].u.fpr, afp, 20)) goto found; break; case KEYDB_SEARCH_MODE_FIRST: if (pk) goto found; break; case KEYDB_SEARCH_MODE_NEXT: if (pk) goto found; break; default: rc = GPG_ERR_INV_ARG; goto found; } } free_packet (&pkt, &parsectx); continue; found: if (rc) goto real_found; if (DBG_LOOKUP) log_debug ("%s: packet starting at offset %lld matched descriptor %zu\n" , __func__, (long long)offset, n); /* Record which desc we matched on. Note this value is only meaningful if this function returns with no errors. */ if(descindex) *descindex=n; for (n=any_skip?0:ndesc; n < ndesc; n++) { if (desc[n].skipfnc && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid_no)) { if (DBG_LOOKUP) log_debug ("%s: skipping match: desc %zd's skip function returned TRUE\n", __func__, n); break; } } if (n == ndesc) goto real_found; free_packet (&pkt, &parsectx); } real_found: if (!rc) { if (DBG_LOOKUP) log_debug ("%s: returning success\n", __func__); hd->found.offset = main_offset; hd->found.kr = hd->current.kr; hd->found.pk_no = pk? pk_no : 0; hd->found.uid_no = uid? uid_no : 0; } else if (rc == -1) { if (DBG_LOOKUP) log_debug ("%s: no matches (EOF)\n", __func__); hd->current.eof = 1; /* if we scanned all keyrings, we are sure that * all known key IDs are in our offtbl, mark that. */ if (use_key_present_hash && !key_present_hash_ready && scanned_from_start) { KR_RESOURCE kr; /* First set the did_full_scan flag for this keyring. */ for (kr=kr_resources; kr; kr = kr->next) { if (hd->resource == kr) { kr->did_full_scan = 1; break; } } /* Then check whether all flags are set and if so, mark the offtbl ready */ for (kr=kr_resources; kr; kr = kr->next) { if (!kr->did_full_scan) break; } if (!kr) key_present_hash_ready = 1; } } else { if (DBG_LOOKUP) log_debug ("%s: error encountered during search: %s (%d)\n", __func__, gpg_strerror (rc), rc); hd->current.error = rc; } free_packet (&pkt, &parsectx); deinit_parse_packet (&parsectx); set_packet_list_mode(save_mode); return rc; }