// Caller must delete! //static _SharedPtr<OTCachedKey> OTCachedKey::CreateMasterPassword(OTPassword & theOutput, const char * szDisplay/*=NULL*/, int32_t nTimeoutSeconds/*=OT_MASTER_KEY_TIMEOUT*/) { _SharedPtr<OTCachedKey> pMaster(new OTCachedKey(nTimeoutSeconds)); // ------------------- const OTString strDisplay((NULL == szDisplay) ? "Creating a passphrase..." : szDisplay); // todo internationalization / hardcoding. const bool bGotPassphrase = pMaster->GetMasterPassword(pMaster, theOutput, strDisplay.Get(), true); //bool bVerifyTwice=false by default. Really we didn't have to pass true here, since it asks twice anyway, when first generating the key. if (bGotPassphrase) // success! return pMaster; // ---------------------------- // If we're still here, that means bGotPassphrase failed. // // delete pMaster; pMaster = NULL; return _SharedPtr<OTCachedKey>(); }
void load_database_t::update_albumlist() { t_size track_count = m_tracks.get_count(); { mmh::permutation_t pTrackAIDInit(track_count); mmh::g_sort_get_permutation_qsort_v2(m_tracks.get_ptr(), pTrackAIDInit, t_track::g_compare_album_id, false); for (t_size i = 0; i<m_album_list.m_master_list.get_count(); i++) { t_size index; if (pfc::bsearch_permutation_t(track_count, m_tracks, t_track::g_compare_album_id_value, m_album_list.m_master_list[i]->id, pTrackAIDInit, index)) { m_album_list.m_master_list[i]->temp_track_pid = m_tracks[index]->pid; m_album_list.m_master_list[i]->temp_media_type = m_tracks[index]->media_type2; } } } mmh::permutation_t pMaster(m_album_list.m_master_list.get_count()); //pfc::list_t<t_album::ptr> newSongs, newPodcasts, newTvShows; mmh::g_sort_get_permutation_qsort_v2(m_album_list.m_master_list.get_ptr(), pMaster, t_album::g_compare_album_mixed, false); m_album_list.m_master_list.reorder(pMaster.get_ptr()); //pfc::list_permutation_t<t_album> masterListOrdered( //m_album_list.m_normal.reorder(pNormal.get_ptr()); t_uint32 next_id = 0x81; t_size current_album_count = m_album_list.m_master_list.get_count(); if (current_album_count) { mmh::permutation_t perm(current_album_count); mmh::g_sort_get_permutation_qsort_v2(m_album_list.m_master_list.get_ptr(), perm, t_album::g_compare_id, false); next_id = m_album_list.m_master_list[perm[current_album_count - 1]]->id + 1; } //console::formatter() << (m_album_list.m_normal.get_count() + m_album_list.m_podcasts.get_count() + m_album_list.m_tv_shows.get_count()) << " " << m_album_list.m_master_list.get_count(); t_size i, count = m_tracks.get_count(); for (i = 0; i<count; i++) { t_track::ptr p_track = m_tracks[i]; t_size index = pfc_infinite; bool b_found = false, b_other_type = false; pfc::rcptr_t<itunesdb::t_track> track = m_tracks[i]; t_uint32 type = 0; if (m_tracks[i]->media_type == itunesdb::t_track::type_audio //|| m_tracks[i]->media_type == itunesdb::t_track::type_video || m_tracks[i]->media_type == itunesdb::t_track::type_music_video //|| m_tracks[i]->media_type == itunesdb::t_track::type_audiobook ) type = ai_types::song; else if (m_tracks[i]->media_type & itunesdb::t_track::type_podcast) type = ai_types::podcast; else if (m_tracks[i]->media_type & itunesdb::t_track::type_tv_show) type = ai_types::tv_show; else { type = ai_types::song; b_other_type = true; } if (b_found = m_album_list.m_master_list.bsearch_t(t_album::g_compare_album_mixed_track, m_tracks[i], index)) m_tracks[i]->album_id = m_album_list.m_master_list[index]->id; if (!b_found) { t_album::ptr temp = new t_album; temp->id = next_id; temp->kind = type; if (type == ai_types::song) { if (!b_other_type) { if (m_tracks[i]->album_artist_valid) { temp->artist_valid = true; temp->artist = m_tracks[i]->album_artist; temp->album_artist_strict = temp->artist; temp->album_artist_strict_valid = true; } else if (m_tracks[i]->artist_valid) { temp->artist_valid = true; temp->artist = m_tracks[i]->artist; } if (m_tracks[i]->album_valid) { temp->album_valid = true; temp->album = m_tracks[i]->album; } } //m_album_list.m_normal.insert_item(temp, index); } else if (type == ai_types::podcast) { if (m_tracks[i]->album_valid) { temp->album_valid = true; temp->album = m_tracks[i]->album; } if (m_tracks[i]->podcast_rss_url_valid) { temp->podcast_url_valid = true; temp->podcast_url = m_tracks[i]->podcast_rss_url; } //m_album_list.m_podcasts.insert_item(temp, index); } else if (type == ai_types::tv_show) { if (m_tracks[i]->show_valid) { temp->show_valid = true; temp->show = m_tracks[i]->show; } temp->season_number = m_tracks[i]->season_number; //m_album_list.m_tv_shows.insert_item(temp, index); } temp->temp_track_pid = m_tracks[i]->pid; temp->temp_media_type = m_tracks[i]->media_type2; m_tracks[i]->album_id = temp->id; m_album_list.m_master_list.insert_item(temp, index); next_id++; } } //purge dead entries current_album_count = m_album_list.m_master_list.get_count(); pfc::array_staticsize_t<bool> mask(current_album_count); mmh::permutation_t perm_aid(m_tracks.get_count()); mmh::g_sort_get_permutation_qsort_v2(m_tracks.get_ptr(), perm_aid, t_track::g_compare_album_id, false); t_size dummy; for (i = 0; i<current_album_count; i++) mask[i] = !pfc::bsearch_permutation_t(m_tracks.get_count(), m_tracks, t_track::g_compare_album_id_value, m_album_list.m_master_list[i]->id, perm_aid, dummy); m_album_list.m_master_list.remove_mask(mask.get_ptr()); //generate pids current_album_count = m_album_list.m_master_list.get_count(); mmh::permutation_t perm_pid(current_album_count); mmh::g_sort_get_permutation_qsort_v2(m_album_list.m_master_list.get_ptr(), perm_pid, t_album::g_compare_pid, false); genrand_service::ptr p_genrand = genrand_service::g_create(); p_genrand->seed(GetTickCount()); for (i = 0; i<current_album_count; i++) { if (m_album_list.m_master_list[i]->pid == NULL) { t_uint64 new_pid = NULL; t_size attempts = 66; do { t_uint64 p1 = p_genrand->genrand(MAXUINT32 - 1) + 1; t_uint64 p2 = p_genrand->genrand(MAXUINT32); new_pid = p1 | (p2 << 32); } while (m_album_list.have_pid(new_pid) && --attempts); if (attempts) m_album_list.m_master_list[i]->pid = new_pid; else break; } } //fill artwork_item_pids { pfc::list_t< pfc::rcptr_t <t_track>, pfc::alloc_fast_aggressive > p_artwork_tracks; p_artwork_tracks.prealloc(count); for (i = 0; i<count; i++) if (m_tracks[i]->artwork_flag == 0x1) p_artwork_tracks.add_item(m_tracks[i]); t_size count_artwork_tracks = p_artwork_tracks.get_count(); mmh::permutation_t perm_track_pid(count_artwork_tracks), perm_track_album_id(count_artwork_tracks); mmh::g_sort_get_permutation_qsort_v2(p_artwork_tracks.get_ptr(), perm_track_pid, ipod::tasks::load_database_t::g_compare_track_dbid, false); mmh::g_sort_get_permutation_qsort_v2(p_artwork_tracks.get_ptr(), perm_track_album_id, ipod::tasks::load_database_t::g_compare_track_album_id, false); for (i = 0; i<current_album_count; i++) { t_album::ptr album = m_album_list.m_master_list[i]; t_size dummy_index = pfc_infinite; if (album->artwork_item_pid == NULL || !p_artwork_tracks.bsearch_permutation_t(ipod::tasks::load_database_t::g_compare_track_dbid_with_dbid, album->artwork_item_pid, perm_track_pid, dummy_index)) { t_size index; if (p_artwork_tracks.bsearch_permutation_t(t_track::g_compare_album_id_value, album->id, perm_track_album_id, index)) { album->artwork_item_pid = p_artwork_tracks[index]->pid; } else album->artwork_item_pid = NULL; } } } //rebuild seperated lists m_album_list.m_normal.remove_all(); m_album_list.m_podcasts.remove_all(); m_album_list.m_tv_shows.remove_all(); for (i = 0; i<current_album_count; i++) { t_album::ptr album = m_album_list.m_master_list[i]; switch (album->kind) { case itunesdb::ai_types::song: m_album_list.m_normal.add_item(album); break; case itunesdb::ai_types::podcast: m_album_list.m_podcasts.add_item(album); break; case itunesdb::ai_types::tv_show: m_album_list.m_tv_shows.add_item(album); break; } } }
// if you pass in a master key, it will look it up on an existing cached map of master keys, // based on the ID of the master key passed in. (Where it stores its own cached copy of the same // master key.) // NOTE: If you use it this way, then you must NEVER use the actual master key being cached (such as // the one stored in a password-protected purse.) Instead, you must always look up the cached version, // and use THAT master key, instead of the actual one in your OTPurse. The only time // you can use your master key itself is when loading it (such as when OTPurse loads // its internal Master Key.) But thereafter, use the cached version of it for all operations // and for saving. // //static _SharedPtr<OTCachedKey> OTCachedKey::It(OTCachedKey & theSourceKey) // Note: parameter no longer const due to need to lock its mutex. { // tthread::lock_guard<tthread::mutex> lock(*(theSourceKey.GetMutex())); // ---------------------------------------------------------------- // There is no chance of failure since he passed the master key itself, // since even if it's not already on the map, we'll just create a copy and put // it there ourselves, returning a pointer either way. // // Except... if theSourceKey isn't generated... // if (!(const_cast<OTCachedKey &>(theSourceKey)).IsGenerated()) //it's only not const due to the mutex inside { OTLog::vError("OTCachedKey::%s: theSourceKey.IsGenerated() returned false. " "(Returning NULL.)\n", __FUNCTION__); return _SharedPtr<OTCachedKey>(); } // ---------------------------------- tthread::lock_guard<tthread::mutex> lock_keys(OTCachedKey::s_mutexCachedKeys); // ---------------------------------- const OTIdentifier theSourceID(theSourceKey); // ---------------------------------- const OTString strIdentifier (theSourceID); const std::string str_identifier(strIdentifier.Get()); // Let's see if it's already there on the map... // mapOfCachedKeys::iterator it_keys = s_mapCachedKeys.find(str_identifier); if (s_mapCachedKeys.end() != it_keys) // found it! { _SharedPtr<OTCachedKey> pMaster(it_keys->second); if (pMaster) return pMaster; else s_mapCachedKeys.erase(it_keys); } // ---------------------------------- // By this point, pMaster is definitely NULL. (Not found on the map, needs to be added.) // // ---------------------------------- // Here we make a copy of the master key and insert it into the map. // Then we return a pointer to it. // OTASCIIArmor ascCachedKey; if ((const_cast<OTCachedKey &>(theSourceKey)).SerializeTo(ascCachedKey)) //it's only not const due to the mutex inside { _SharedPtr<OTCachedKey> pMaster(new OTCachedKey); //int32_t nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT; // ---------------------------------- pMaster->SetCachedKey(ascCachedKey); // ---------------------------------- s_mapCachedKeys.insert(std::pair<std::string, _SharedPtr<OTCachedKey> >(str_identifier, pMaster)); // takes ownership here. return pMaster; } // theSourceKey WAS generated, but SerializeTo FAILED? Very strange... else OTLog::vError("%s: theSourceKey.SerializeTo(ascCachedKey) failed. " "Returning NULL.\n", __FUNCTION__); // ---------------------------------- return _SharedPtr<OTCachedKey>(); }