void ModifyContactListTask::processFolderChange( Field::MultiField * container ) { if ( !( container->method() == NMFIELD_METHOD_ADD || container->method() == NMFIELD_METHOD_DELETE ) ) return; client()->debug( "ModifyContactListTask::processFolderChange()" ); FolderItem folder; Field::SingleField * current; Field::FieldList fl = container->fields(); // object id current = fl.findSingleField( NM_A_SZ_OBJECT_ID ); folder.id = current->value().toInt(); // sequence number current = fl.findSingleField( NM_A_SZ_SEQUENCE_NUMBER ); folder.sequence = current->value().toInt(); // name current = fl.findSingleField( NM_A_SZ_DISPLAY_NAME ); folder.name = current->value().toString(); // parent current = fl.findSingleField( NM_A_SZ_PARENT_ID ); folder.parentId = current->value().toInt(); if ( container->method() == NMFIELD_METHOD_ADD ) emit gotFolderAdded( folder ); else if ( container->method() == NMFIELD_METHOD_DELETE ) emit gotFolderDeleted( folder ); }
void ChatPropertiesTask::setChat( const QString &displayName ) { Field::FieldList lst; m_chat = displayName; lst.append( new Field::SingleField( NM_A_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, m_chat ) ); createTransfer( "chatproperties", lst ); }
bool GetStatusTask::take( Transfer * transfer ) { if ( !forMe( transfer ) ) return false; Response * response = dynamic_cast<Response *>( transfer ); if ( !response ) return false; Field::FieldList responseFields = response->fields(); responseFields.dump( true ); // parse received details and signal like billio Field::SingleField * sf = 0; Q_UINT16 status; sf = responseFields.findSingleField( NM_A_SZ_STATUS ); if ( sf ) { // As of Sept 2004 the server always responds with 2 (Available) here, even if the sender is not // This must be because the sender is not on our contact list but has sent us a message. // TODO: Check that the change to sending DNs above has fixed this problem. status = sf->value().toInt(); // unfortunately getstatus doesn't give us an away message so we pass QString::null here emit gotStatus( m_userDN, status, QString::null ); setSuccess(); } else setError(); return true; }
void GetStatusTask::userDN( const QString & dn ) { m_userDN = dn; // set up Transfer Field::FieldList lst; // changed from USERID to DN as per Gaim/GWIM lst.append( new Field::SingleField( NM_A_SZ_DN, 0, NMFIELD_TYPE_UTF8, m_userDN ) ); createTransfer( "getstatus", lst ); }
void CreateContactInstanceTask::contact( Field::SingleField * id, const QString & displayName, const int parentFolder ) { Field::FieldList lst; lst.append( new Field::SingleField( Field::NM_A_SZ_PARENT_ID, 0, NMFIELD_TYPE_UTF8, QString::number( parentFolder ) ) ); // this is either a user Id or a DN lst.append( id ); if ( displayName.isEmpty() ) // fallback so that the contact is created lst.append( new Field::SingleField( Field::NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, m_dn ) ); else lst.append( new Field::SingleField( Field::NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, displayName ) ); createTransfer( "createcontact", lst ); }
int main() { CoreProtocol testObject; RequestFactory testFactory; QByteArray command("login"); Request * firstRequest = testFactory.request( command ); Field::FieldList lst; lst.append( new Field::SingleField( Field::NM_A_SZ_USERID, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_UTF8, "*****@*****.**" ) ); firstRequest->setFields( lst ); testObject.outgoingTransfer( firstRequest ); return 0; }
void UpdateFolderTask::renameFolder( const QString & newName, const GroupWise::FolderItem & existing ) { Field::FieldList lst; // add the old version of the folder, marked delete lst.append( new Field::MultiField( NM_A_FA_FOLDER, NMFIELD_METHOD_DELETE, 0, NMFIELD_TYPE_ARRAY, folderToFields( existing) ) ); GroupWise::FolderItem renamed = existing; renamed.name = newName; // add the new version of the folder, marked add lst.append( new Field::MultiField( NM_A_FA_FOLDER, NMFIELD_METHOD_ADD, 0, NMFIELD_TYPE_ARRAY, folderToFields( renamed ) ) ); // let our parent class package it up as a contactlist in a transfer UpdateItemTask::item( lst ); }
bool ModifyContactListTask::take( Transfer * transfer ) { if ( !forMe( transfer ) ) return false; Response * response = dynamic_cast<Response *>( transfer ); if ( !response ) return false; client()->debug( "ModifyContactListTask::take()" ); // scan the contact list received // emit each add and delete as a signal Field::FieldList fl = response->fields(); fl.dump( true ); Field::FieldListIterator it = fl.begin(); Field::FieldListIterator end = fl.end(); Field::MultiField * current = fl.findMultiField( NM_A_FA_RESULTS ); if ( current ) fl = current->fields(); current = fl.findMultiField( NM_A_FA_CONTACT_LIST ); if ( current ) { Field::FieldList contactList = current->fields(); Field::FieldListIterator cursor = contactList.begin(); const Field::FieldListIterator end = contactList.end(); while ( cursor != end ) { Field::MultiField * mf = dynamic_cast< Field::MultiField * >( *cursor ); if ( mf->tag() == NM_A_FA_CONTACT ) { // contact change processContactChange( mf ); } else if ( mf->tag() == NM_A_FA_FOLDER ) { // folder change processFolderChange( mf ); } ++cursor; } } // TODO: call virtual here to read any fields after the contact list... if ( response->resultCode() == GroupWise::None ) setSuccess(); else setError( response->resultCode() ); return true; }
void SetStatusTask::status( Status newStatus, const QString &awayMessage, const QString &autoReply ) { if ( newStatus > GroupWise::Invalid ) { setError( 1, "Invalid Status" ); return; } m_status = newStatus; m_awayMessage = awayMessage; m_autoReply = autoReply; Field::FieldList lst; lst.append( new Field::SingleField( NM_A_SZ_STATUS, 0, NMFIELD_TYPE_UTF8, QString::number( newStatus ) ) ); if ( !awayMessage.isNull() ) lst.append( new Field::SingleField( NM_A_SZ_STATUS_TEXT, 0, NMFIELD_TYPE_UTF8, awayMessage ) ); if ( !autoReply.isNull() ) lst.append( new Field::SingleField( NM_A_SZ_MESSAGE_BODY, 0, NMFIELD_TYPE_UTF8, autoReply ) ); createTransfer( "setstatus", lst ); }
void ModifyContactListTask::processContactChange( Field::MultiField * container ) { if ( !( container->method() == NMFIELD_METHOD_ADD || container->method() == NMFIELD_METHOD_DELETE ) ) return; client()->debug( "ModifyContactListTask::processContactChange()" ); Field::SingleField * current; Field::FieldList fl = container->fields(); ContactItem contact; current = fl.findSingleField( NM_A_SZ_OBJECT_ID ); contact.id = current->value().toInt(); current = fl.findSingleField( NM_A_SZ_PARENT_ID ); contact.parentId = current->value().toInt(); current = fl.findSingleField( NM_A_SZ_SEQUENCE_NUMBER ); contact.sequence = current->value().toInt(); current = fl.findSingleField( NM_A_SZ_DISPLAY_NAME ); contact.displayName = current->value().toString(); current = fl.findSingleField( NM_A_SZ_DN ); contact.dn = current->value().toString(); if ( container->method() == NMFIELD_METHOD_ADD ) emit gotContactAdded( contact ); else if ( container->method() == NMFIELD_METHOD_DELETE ) emit gotContactDeleted( contact ); }
bool PollSearchResultsTask::take( Transfer * transfer ) { if ( !forMe( transfer ) ) return false; Response * response = dynamic_cast<Response *>( transfer ); if ( !response ) return false; if ( response->resultCode() ) { setError( response->resultCode() ); return true; } // look for the status code Field::FieldList responseFields = response->fields(); Field::SingleField * sf = responseFields.findSingleField( Field::NM_A_SZ_STATUS ); m_queryStatus = sf->value().toInt(); Field::MultiField * resultsArray = responseFields.findMultiField( Field::NM_A_FA_RESULTS ); if ( !resultsArray ) { setError( Protocol ); return true; } Field::FieldList matches = resultsArray->fields(); const Field::FieldListIterator end = matches.end(); for ( Field::FieldListIterator it = matches.find( Field::NM_A_FA_CONTACT ); it != end; it = matches.find( ++it, Field::NM_A_FA_CONTACT ) ) { Field::MultiField * mf = static_cast<Field::MultiField *>( *it ); Field::FieldList contact = mf->fields(); GroupWise::ContactDetails cd = extractUserDetails( contact ); m_results.append( cd ); } // first field: Field::NM_A_SZ_STATUS contains #define SEARCH_PENDING 0 #define SEARCH_INPROGRESS 1 #define SEARCH_COMPLETED 2 #define SEARCH_TIMEOUT 3 #define SEARCH_CANCELLED 4 #define SEARCH_ERROR 5 // set a status code if needed // followed by Field::NM_A_FA_RESULTS, looks like a getdetails // add an accessor to get at the results list of ContactItems, probably if ( m_queryStatus != 2 ) setError( m_queryStatus ); else setSuccess( m_queryStatus ); return true; }
Field::FieldList UpdateFolderTask::folderToFields( const GroupWise::FolderItem & folder ) { Field::FieldList lst; lst.append( new Field::SingleField( NM_A_SZ_OBJECT_ID, 0, NMFIELD_TYPE_UTF8, folder.id ) ); lst.append( new Field::SingleField( NM_A_SZ_PARENT_ID, 0, NMFIELD_TYPE_UTF8, 0 ) ); lst.append( new Field::SingleField( NM_A_SZ_TYPE, 0, NMFIELD_TYPE_UTF8, 1 ) ); lst.append( new Field::SingleField( NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_TYPE_UTF8, folder.sequence ) ); if ( !folder.name.isEmpty() ) lst.append( new Field::SingleField( NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, folder.name ) ); return lst; }
bool ChatPropertiesTask::take( Transfer * transfer ) { if ( !forMe( transfer ) ) return false; Response * response = dynamic_cast<Response *>( transfer ); if ( !response ) return false; if ( response->resultCode() ) { setError( response->resultCode() ); return true; } Field::FieldList responseFields = response->fields(); Field::MultiField * resultsArray = responseFields.findMultiField( NM_A_FA_CHAT ); if ( !resultsArray ) { setError( Protocol ); return true; } Field::FieldList lst = resultsArray->fields(); const Field::FieldListIterator end = lst.end(); for ( Field::FieldListIterator it = lst.begin(); it != end; ++it ) { Field::SingleField * sf = dynamic_cast<Field::SingleField *>( *it ); if ( sf ) { if ( sf->tag() == NM_A_DISPLAY_NAME ) continue; else if ( sf->tag() == NM_A_CHAT_OWNER_DN ) m_ownerDn = sf->value().toString(); else if ( sf->tag() == NM_A_CHAT_CREATOR_DN ) m_creatorDn= sf->value().toString(); else if ( sf->tag() == NM_A_DESCRIPTION ) m_description = sf->value().toString(); else if ( sf->tag() == NM_A_DISCLAIMER ) m_disclaimer = sf->value().toString(); else if ( sf->tag() == NM_A_QUERY ) m_query = sf->value().toString(); else if ( sf->tag() == NM_A_ARCHIVE ) m_archive = sf->value().toString(); else if ( sf->tag() == NM_A_SZ_TOPIC ) m_topic = sf->value().toString(); else if ( sf->tag() == NM_A_CREATION_TIME ) m_creationTime.setTime_t( sf->value().toInt() ); else if ( sf->tag() == NM_A_UD_CHAT_RIGHTS ) m_rights = sf->value().toInt(); } else { Field::MultiField * mf = dynamic_cast<Field::MultiField *>( *it ); if ( mf ) { if ( mf->tag() == NM_A_FA_CHAT_ACL ) { Field::FieldList acl = mf->fields(); const Field::FieldListIterator aclEnd = acl.end(); for ( Field::FieldListIterator aclIt = acl.begin(); aclIt != aclEnd; ++aclIt ) { Field::MultiField * aclEntryFields = dynamic_cast<Field::MultiField *>( *aclIt ); if ( aclEntryFields ) { ChatContact entry; Field::FieldList entryFields = aclEntryFields->fields(); Field::SingleField * sf; if ( ( sf = entryFields.findSingleField ( NM_A_SZ_DN ) ) ) entry.dn = sf->value().toString(); if ( ( sf = entryFields.findSingleField ( NM_A_SZ_ACCESS_FLAGS ) ) ) entry.chatRights = sf->value().toInt(); kdDebug ( GROUPWISE_DEBUG_GLOBAL ) << "got acl entry: " << entry.dn << ", " << entry.chatRights << endl; m_aclEntries.append( entry ); } } } } } } kdDebug ( GROUPWISE_DEBUG_GLOBAL ) << "Got chatroom properties: " << m_chat << " : " << m_ownerDn << ", " << m_description << ", " << m_disclaimer << ", " << m_query << ", " << m_archive << ", " << m_topic << ", " << m_creatorDn << ", " << m_creationTime.toString() << ", " << m_rights << endl; finished(); return true; }
bool ResponseProtocol::readFields( int fieldCount, Field::FieldList * list ) { // build a list of fields. // If there is already a list of fields stored in m_collatingFields, // the list we're reading on this iteration must be a nested list // so when we're done reading it, add it to the MultiList element // that is the last element in the top list in m_collatingFields. // if we find the beginning of a new nested list, push the current list onto m_collatingFields debug( "ResponseProtocol::readFields()" ); if ( fieldCount > 0 ) debug( QString( "reading %1 fields" ).arg( fieldCount ) ); Field::FieldList currentList; while ( fieldCount != 0 ) // prevents bad input data from ruining our day { // the field being read // read field Q_UINT8 type, method; Q_UINT32 val; QCString tag; // read uint8 type if ( !okToProceed() ) { currentList.purge(); return false; } m_din >> type; m_bytes += sizeof( Q_UINT8 ); // if type is 0 SOMETHING_INVALID, we're at the end of the fields if ( type == 0 ) /*&& m_din->atEnd() )*/ { debug( "- end of field list" ); m_packetState = FieldsRead; // do something to indicate we're done break; } // read uint8 method if ( !okToProceed() ) { currentList.purge(); return false; } m_din >> method; m_bytes += sizeof( Q_UINT8 ); // read tag and length if ( !safeReadBytes( tag, val ) ) { currentList.purge(); return false; } debug( QString( "- type: %1, method: %2, tag: %3," ).arg( type ).arg( method ).arg( tag.data() ) ); // if multivalue or array if ( type == NMFIELD_TYPE_MV || type == NMFIELD_TYPE_ARRAY ) { // read length uint32 if ( !okToProceed() ) { currentList.purge(); return false; } m_din >> val; m_bytes += sizeof( Q_UINT32 ); // create multifield debug( QString( " multi field containing: %1" ).arg( val ) ); Field::MultiField* m = new Field::MultiField( tag, method, 0, type ); currentList.append( m ); if ( !readFields( val, ¤tList) ) { currentList.purge(); return false; } } else { if ( type == NMFIELD_TYPE_UTF8 || type == NMFIELD_TYPE_DN ) { QCString rawData; if( !safeReadBytes( rawData, val ) ) { currentList.purge(); return false; } if ( val > NMFIELD_MAX_STR_LENGTH ) { m_packetState = ProtocolError; break; } // convert to unicode - ignore the terminating NUL, because Qt<3.3.2 doesn't sanity check val. QString fieldValue = QString::fromUtf8( rawData.data(), val - 1 ); debug( QString( "- utf/dn single field: %1" ).arg( fieldValue ) ); // create singlefield Field::SingleField* s = new Field::SingleField( tag, method, 0, type, fieldValue ); currentList.append( s ); } else { // otherwise ( numeric ) // read value uint32 if ( !okToProceed() ) { currentList.purge(); return false; } m_din >> val; m_bytes += sizeof( Q_UINT32 ); debug( QString( "- numeric field: %1" ).arg( val ) ); Field::SingleField* s = new Field::SingleField( tag, method, 0, type, val ); currentList.append( s ); } } // decrease the fieldCount if we're using it if ( fieldCount > 0 ) fieldCount--; }
void PollSearchResultsTask::poll( const QString & queryHandle ) { Field::FieldList lst; lst.append( new Field::SingleField( Field::NM_A_SZ_OBJECT_ID, 0, NMFIELD_TYPE_UTF8, queryHandle ) ); createTransfer( "getresults", lst ); }
GroupWise::ContactDetails PollSearchResultsTask::extractUserDetails( Field::FieldList & fields ) { ContactDetails cd; cd.status = GroupWise::Invalid; cd.archive = false; // read the supplied fields, set metadata and status. Field::SingleField * sf; if ( ( sf = fields.findSingleField ( Field::NM_A_SZ_AUTH_ATTRIBUTE ) ) ) cd.authAttribute = sf->value().toString(); if ( ( sf = fields.findSingleField ( Field::NM_A_SZ_DN ) ) ) cd.dn =sf->value().toString().toLower(); // HACK: lowercased DN if ( ( sf = fields.findSingleField ( Field::KOPETE_NM_USER_DETAILS_CN ) ) ) cd.cn = sf->value().toString(); if ( ( sf = fields.findSingleField ( Field::KOPETE_NM_USER_DETAILS_GIVEN_NAME ) ) ) cd.givenName = sf->value().toString(); if ( ( sf = fields.findSingleField ( Field::KOPETE_NM_USER_DETAILS_SURNAME ) ) ) cd.surname = sf->value().toString(); if ( ( sf = fields.findSingleField ( Field::KOPETE_NM_USER_DETAILS_FULL_NAME ) ) ) cd.fullName = sf->value().toString(); if ( ( sf = fields.findSingleField ( Field::KOPETE_NM_USER_DETAILS_ARCHIVE_FLAG ) ) ) cd.archive = ( sf->value().toInt() == 1 ); if ( ( sf = fields.findSingleField ( Field::NM_A_SZ_STATUS ) ) ) cd.status = sf->value().toInt(); if ( ( sf = fields.findSingleField ( Field::NM_A_SZ_MESSAGE_BODY ) ) ) cd.awayMessage = sf->value().toString(); Field::MultiField * mf; QMap< QString, QVariant > propMap; if ( ( mf = fields.findMultiField ( Field::NM_A_FA_INFO_DISPLAY_ARRAY ) ) ) { Field::FieldList fl = mf->fields(); const Field::FieldListIterator end = fl.end(); for ( Field::FieldListIterator it = fl.begin(); it != end; ++it ) { // assumes each property only present once // check in logintask.cpp and if it's a multi field, // get the value of this instance, check if it's already in the property map and append if found. Field::SingleField * propField = dynamic_cast<Field::SingleField *>( *it ); if ( propField ) { QString propName = propField->tag(); QString propValue = propField->value().toString(); propMap.insert( propName, propValue ); } else { Field::MultiField * propList = dynamic_cast<Field::MultiField*>( *it ); if ( propList ) { QString parentName = propList->tag(); Field::FieldList propFields = propList->fields(); const Field::FieldListIterator end = propFields.end(); for ( Field::FieldListIterator it = propFields.begin(); it != end; ++it ) { propField = dynamic_cast<Field::SingleField *>( *it ); if ( propField ) { QString propValue = propField->value().toString(); QString contents = propMap[ propField->tag() ].toString(); if ( !contents.isEmpty() ) contents.append( ", " ); contents.append( propField->value().toString()); propMap.insert( propField->tag(), contents ); } } } } } } if ( !propMap.empty() ) { cd.properties = propMap; } return cd; }