HashTable TableNew(int elemSize, int nBuckets, TableHashFn hashFn, TableCompareFn compFn, TableElementFreeFn freeFn) { HashTable table; int i; if(!hashFn) gspyi.error("TableNew: hashFn is NULL."); if(!compFn) gspyi.error("TableNew: compFn is NULL."); if(elemSize <= 0) gspyi.error("TableNew: bad elemSize."); if(nBuckets <= 0) gspyi.error("TableNew: bad nBuckets."); table = (HashTable)malloc(sizeof(struct HashImplementation)); if(!table) gspyi.error("TableNew: table is NULL."); table->buckets = (DArray *)malloc(nBuckets * sizeof(DArray)); if(!table->buckets) gspyi.error("TableNew: table->buckets is NULL."); for (i = 0; i < nBuckets; i++) //ArrayNew will assert if allocation fails table->buckets[i] = ArrayNew(elemSize, 0, freeFn); table->nbuckets = nBuckets; table->freefn = freeFn; table->compfn = compFn; table->hashfn = hashFn; return table; }
GPIPeer * gpiAddPeer( GPConnection * connection, int profileid, GPIBool initiate ) { GPIPeer * peer; GPIConnection * iconnection = (GPIConnection*)*connection; // Create a new peer. ///////////////////// peer = (GPIPeer *)gsimalloc(sizeof(GPIPeer)); if(peer == NULL) return NULL; memset(peer, 0, sizeof(GPIPeer)); peer->state = GPI_PEER_NOT_CONNECTED; peer->initiated = initiate; //peer->sock = INVALID_SOCKET; peer->profile = profileid; peer->timeout = (time(NULL) + GPI_PEER_TIMEOUT); peer->pnext = iconnection->peerList; peer->messages = ArrayNew(sizeof(GPIMessage), 0, gpiFreeMessage); iconnection->peerList = peer; peer->peerOpQueue.first = NULL; peer->peerOpQueue.last = NULL; peer->peerOpQueue.opList = NULL; return peer; }
Assembler* AsmNew() { Assembler *a=ObjNew(Assembler, 1); a->codes = ArrayNew(10); a->symTable = HashTableNew(127); a->opTable = OpTableNew(); return a; }
int Cache_Init (/*in*/ tApp * a) { epaTHX_ pProviders = newHV () ; pCacheItems = newHV () ; ArrayNew (a, &pCachesToRelease, 16, sizeof (tCacheItem *)) ; /* lprintf (a, "XXXXX Cache_Init [%d/%d] pProviders=%x pCacheItems=%x pCachesToRelease=%x", _getpid(), GetCurrentThreadId(), pProviders, pCacheItems, pCachesToRelease) ; */ return ok ; }
int Cache_AddDependency (/*in*/ req * r, /*in*/ tCacheItem * pItem, /*in*/ tCacheItem * pDependsOn) { int n ; if (!pItem -> pDependsOn) ArrayNew (r -> pApp, &pItem -> pDependsOn, 2, sizeof (tCacheItem *)) ; n = ArrayAdd (r -> pApp, &pItem -> pDependsOn, 1) ; pItem -> pDependsOn[n] = pDependsOn ; if (!pDependsOn -> pNeededFor) ArrayNew (r -> pApp, &pDependsOn -> pNeededFor, 2, sizeof (tCacheItem *)) ; n = ArrayAdd (r -> pApp, &pDependsOn -> pNeededFor, 1) ; pDependsOn -> pNeededFor[n] = pItem ; return ok ; }
GPResult gpiCheckNpStatus( GPConnection * connection ) { int ret = 0; int status = SCE_NP_MANAGER_STATUS_OFFLINE; SceNpId npId; GPIConnection * iconnection = (GPIConnection*)*connection; // Get NP status //////////////// ret = sceNpManagerGetStatus(&status); if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpGetStatus() failed. ret = 0x%x\n", ret); } gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "gpiCheckNpStatus: sceNpGetStatus - status = %d\n", status); // If NP status != online after the timeout period, stop syncing //////////////////////////////////////////////////////////////// if (status != SCE_NP_MANAGER_STATUS_ONLINE && (current_time() - iconnection->loginTime > GPI_NP_STATUS_TIMEOUT)) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: NP Status not online - timed out\n"); // Flag to stop the sync process //////////////////////////////// iconnection->npPerformBuddySync = gsi_false; iconnection->npPerformBlockSync = gsi_false; return GP_MISC_ERROR; } // Once status is online, finish NP init //////////////////////////////////////// if (status == SCE_NP_MANAGER_STATUS_ONLINE) { iconnection->loginTime = current_time(); // Note - we ignore error messages here - if something fails we really don't care ///////////////////////////////////////////////////////////////////////////////// if (!iconnection->npBasicGameInitialized) { ret = sceNpBasicInit(); //obsolete? if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpBasicInit() failed. ret = 0x%x\n", ret); } ret = sceNpBasicRegisterHandler(&gpi_communication_id, gpiNpBasicCallback, NULL); if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpBasicRegisterHandler() failed. ret = 0x%x\n", ret); } } ret = sceNpLookupInit(); if (ret == SCE_NP_COMMUNITY_ERROR_ALREADY_INITIALIZED) { // If already initialized - DO NOT terminate after GP destroy (game might need it) ////////////////////////////////////////////////////////////////////////////////// iconnection->npLookupGameInitialized = gsi_true; } else if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpLookupInit() failed. ret = 0x%x\n", ret); iconnection->npLookupGameInitialized = gsi_true; } else iconnection->npLookupGameInitialized = gsi_false; // Regardless of game, create a title context id for GP to use for lookups /////////////////////////////////////////////////////////////////////////// ret = sceNpManagerGetNpId(&npId); if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpManagerGetNpId() failed. ret = 0x%x\n", ret); } ret = sceNpLookupCreateTitleCtx(&gpi_communication_id, &npId); if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiCheckNpStatus: sceNpLookupCreateTitleCtx() failed. ret = 0x%x\n", ret); } iconnection->npLookupTitleCtxId = ret; // Mark status retrieval completed ////////////////////////////////// iconnection->npStatusRetrieved = gsi_true; gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "gpiCheckNpStatus: NP is now initialized with status.\n"); iconnection->npTransactionList = ArrayNew(sizeof(npIdLookupTrans), 1, gpiNpTransactionListFree); if (!iconnection->npTransactionList) Error(connection, GP_MEMORY_ERROR, "Out of memory."); } return GP_NO_ERROR; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // Message handlers are added using this function // The initial message and header of a message handler cannot be empty // However, they can be the same. // User data can be useful for keeping track of Message Handler GSUdpErrorCode gsUdpEngineAddMsgHandler(char theInitMsg[GS_UDP_MSG_HEADER_LEN], char theHeader[GS_UDP_MSG_HEADER_LEN], gsUdpErrorCallback theMsgHandlerError, gsUdpConnConnectedCallback theMsgHandlerConnected, gsUdpConnClosedCallback theMsgHandlerClosed, gsUdpConnPingCallback theMsgHandlerPing, gsUdpConnReceivedDataCallback theMsgHandlerRecv, void *theUserData) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpMsgHandler aMsgHandler; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theInitMsg || theInitMsg[0]); GS_ASSERT(theHeader || theHeader[0]); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return GS_UDP_NETWORK_ERROR; } // setup a message handler that the UDP engine will use to pass connection attempts to //check for valid input if (!theInitMsg[0]) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Invalid init message\n"); return GS_UDP_PARAMETER_ERROR; } if (!theHeader[0]) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Invalid header\n"); return GS_UDP_PARAMETER_ERROR; } // This check is not necessary. Some SDKs may not use all callbacks /*if (!theMsgHandlerError || !theMsgHandlerConnected || !theMsgHandlerClosed || !theMsgHandlerPing || !theMsgHandlerRecv) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Invalid callback(s)"); return GS_UDP_PARAMETER_ERROR; } */ aMsgHandler.mClosed = theMsgHandlerClosed; aMsgHandler.mConnected = theMsgHandlerConnected; aMsgHandler.mPingReply = theMsgHandlerPing; aMsgHandler.mReceived = theMsgHandlerRecv; aMsgHandler.mNetworkError = theMsgHandlerError; memcpy(aMsgHandler.mInitialMsg, theInitMsg, GS_UDP_MSG_HEADER_LEN); memcpy(aMsgHandler.mHeader, theHeader, GS_UDP_MSG_HEADER_LEN); aMsgHandler.mPendingConnections = ArrayNew(sizeof(GSUdpRemotePeer *), 1, NULL); if (aMsgHandler.mPendingConnections == NULL) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Memory, GSIDebugLevel_HotError, "[Udp Engine] No more memory!!!\n"); return GS_UDP_NO_MEMORY; } aMsgHandler.mUserData = theUserData; ArrayAppend(aUdp->mMsgHandlers, &aMsgHandler); return GS_UDP_NO_ERROR; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Initializes the UDP layer // A specific port can be used if needed. // An app must register their callbacks here. // An App must also call this before starting SDKs since they might start // the UDP layer without the app having a chance to register its callbacks. // Any message handler can get the port the UDP layer is using if it did not // initialize the UDP Layer. // Use of the UDP Layer requires it to be initialized as is the case with most // functions below. GSUdpErrorCode gsUdpEngineInitialize(unsigned short thePort, int theIncomingBufSize, int theOutgoingBufSize, gsUdpErrorCallback theAppNetworkError, gsUdpConnConnectedCallback theAppConnected, gsUdpConnClosedCallback theAppClosed, gsUdpConnPingCallback theAppPing, gsUdpConnReceivedDataCallback theAppReceive, gsUdpUnknownMsgCallback theAppUnownMsg, gsUdpAppConnectAttemptCallback theAppConnectAttempt, void *theAppUserData) { int incomingBufferSize, outgoingBufferSize; char anAddr[GS_IP_ADDR_AND_PORT]; GT2Result aGt2Result; // Grab the single instance of the UDP Communication Engine GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); // Setup our gt2 buffer sizes for reliable messages incomingBufferSize = theIncomingBufSize != 0 ? theIncomingBufSize : GS_UDP_DEFAULT_IN_BUFFSIZE; outgoingBufferSize = theOutgoingBufSize != 0 ? theOutgoingBufSize : GS_UDP_DEFAULT_OUT_BUFFSIZE; // Setup our internal socket that will be shared among more than one application aUdp->mAppNetworkError = theAppNetworkError; aUdp->mAppUnknownMessage = theAppUnownMsg; aUdp->mAppConnected = theAppConnected; aUdp->mAppClosed = theAppClosed; aUdp->mAppPingReply = theAppPing; aUdp->mAppRecvData = theAppReceive; aUdp->mAppConnAttempt = theAppConnectAttempt; // Any port can be used gt2AddressToString(0, thePort, anAddr); aGt2Result = gt2CreateSocket(&aUdp->mSocket, anAddr, outgoingBufferSize, incomingBufferSize, gsUdpSocketError); if (aGt2Result != GT2Success) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_WarmError, "[Udp Engine] error creating gt2 socket, error code: %d\n", aGt2Result); return GS_UDP_NETWORK_ERROR; } // We'll need to keep track of connections with an array of GPconnection to address mapping aUdp->mRemotePeers = ArrayNew(sizeof(GSUdpRemotePeer), 1, NULL); if (aUdp->mRemotePeers == NULL) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Memory, GSIDebugLevel_HotError, "[Udp Engine] No more memory!!!\n"); return GS_UDP_NO_MEMORY; } aUdp->mMsgHandlers = ArrayNew(sizeof(GSUdpMsgHandler), 1, gsUdpMsgHandlerFree); if (aUdp->mMsgHandlers == NULL) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Memory, GSIDebugLevel_HotError, "[Udp Engine] No more memory!!!\n"); return GS_UDP_NO_MEMORY; } // Used by the manager to receive messages from backend services or other clients // that may not be using gt2 gt2SetUnrecognizedMessageCallback(aUdp->mSocket, gsUdpUnrecognizedMsgCB); // Automatically start listening for all SDKS and the game if game uses UDP Engine gt2Listen(aUdp->mSocket, gsUdpConnAttemptCB); aUdp->mLocalAddr = gt2GetLocalIP(aUdp->mSocket); aUdp->mLocalPort = gt2GetLocalPort(aUdp->mSocket); aUdp->mAppPendingConnections = 0; aUdp->mInitialized = gsi_true; if (theAppUserData) { aUdp->mAppUserData = theAppUserData; } else aUdp->mAppUserData = NULL; return GS_UDP_NO_ERROR; }
GPResult gpiProcessRecvBuddyList( GPConnection * connection, const char * input ) { int i=0, j=0; int num = 0; int index = 0; char c; char *str = NULL; char buffer[512]; GPIProfile * profile; GPProfile profileid; GPIConnection * iconnection = (GPIConnection*)*connection; // Check for an error. ////////////////////// if(gpiCheckForError(connection, input, GPITrue)) return GP_SERVER_ERROR; // Process Buddy List Retrieval msg - Format like: /* =============================================== \bdy\<num in list>\list\<block list - comma delimited>\final\ =============================================== */ if(!gpiValueForKeyWithIndex(input, "\\bdy\\", &index, buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); num = atoi(buffer); // Check to make sure list is there /////////////////////////////////// str = strstr(input, "\\list\\"); if (str == NULL) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Then increment index to get ready for parsing //////////////////////////////////////////////// str += 6; index += 6; for (i=0; i < num; i++) { if (i==0) { // Manually grab first profile in list - comma delimiter //////////////////////////////////////////////////////// for(j=0 ; (j < sizeof(buffer)) && ((c = str[j]) != '\0') && (c != ',') ; j++) { buffer[j] = c; } buffer[j] = '\0'; index += j; } else { if(!gpiValueForKeyWithIndex(input, ",", &index, buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); } profileid = atoi(buffer); // Get the profile, adding if needed. ///////////////////////////////////// profile = gpiProfileListAdd(connection, profileid); if(!profile) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Mark as offline buddy for now until we get the real status ///////////////////////////////////////////////////////////// #ifdef GP_NEW_STATUS_INFO // Use new status info as placeholder profile->buddyStatusInfo = (GPIBuddyStatusInfo *)gsimalloc(sizeof(GPIBuddyStatusInfo)); if(!profile->buddyStatusInfo) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(profile->buddyStatusInfo, 0, sizeof(GPIBuddyStatusInfo)); profile->buddyStatusInfo->extendedInfoKeys = ArrayNew(sizeof(GPIKey), GPI_INITIAL_NUM_KEYS, gpiStatusInfoKeyFree); if (!profile->buddyStatusInfo->extendedInfoKeys) Error(connection, GP_MEMORY_ERROR, "Out of memory."); profile->buddyStatusInfo->buddyIndex = iconnection->profileList.numBuddies++; profile->buddyStatusInfo->statusState = GP_OFFLINE; #else // Use buddy status as placeholder profile->buddyStatus = (GPIBuddyStatus *)gsimalloc(sizeof(GPIBuddyStatus)); if(!profile->buddyStatus) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(profile->buddyStatus, 0, sizeof(GPIBuddyStatus)); profile->buddyStatus->buddyIndex = iconnection->profileList.numBuddies++; profile->buddyStatus->status = GP_OFFLINE; #endif } return GP_NO_ERROR; }
GPResult gpiProcessRecvBuddyStatusInfo(GPConnection *connection, const char *input) { char buffer[1024]; int profileid; time_t date; GPICallback callback; GPIProfile * profile; GPIBuddyStatusInfo * buddyStatusInfo; GPIConnection * iconnection = (GPIConnection*)*connection; // This is what the message should look like. Its broken up for easy viewing. // // "\bsi\\state\\profile\\bip\\bport\\hostip\\hprivip\" // "\qport\\hport\\sessflags\\rstatus\\gameType\" // "\gameVnt\\gameMn\\product\\qmodeflags\" //////////////////////////////// date = time(NULL); // Get the buddy's profile //////////////////////////////// if(!gpiValueForKey(input, "\\profile\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); profileid = atoi(buffer); // Get the profile from the SDK's list, adding it if needed. ///////////////////////////////////// profile = gpiProfileListAdd(connection, profileid); if(!profile) Error(connection, GP_MEMORY_ERROR, "Out of memory."); // Make sure profile wasn't blocked prior to getting the status update ////////////////////////////////////////////////////////////////////// if (!profile->blocked) { // This is a buddy. /////////////////// if(!profile->buddyStatusInfo) { profile->buddyStatusInfo = (GPIBuddyStatusInfo *)gsimalloc(sizeof(GPIBuddyStatusInfo)); if(!profile->buddyStatusInfo) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(profile->buddyStatusInfo, 0, sizeof(GPIBuddyStatusInfo)); if (profile->buddyStatus) { profile->buddyStatusInfo->buddyIndex = profile->buddyStatus->buddyIndex; gpiRemoveBuddyStatus(profile->buddyStatus); profile->buddyStatus = NULL; } else profile->buddyStatusInfo->buddyIndex = iconnection->profileList.numBuddies++; profile->buddyStatusInfo->extendedInfoKeys = ArrayNew(sizeof(GPIKey), GPI_INITIAL_NUM_KEYS, gpiStatusInfoKeyFree); if (!profile->buddyStatusInfo->extendedInfoKeys) Error(connection, GP_MEMORY_ERROR, "Out of memory."); } // extract the buddy status information and // fill in appropriate information. ///////////////////////////////////////////// buddyStatusInfo = profile->buddyStatusInfo; if (!gpiValueForKey(input, "\\state\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->statusState = (GPEnum)atoi(buffer); if (!gpiValueForKey(input, "\\bip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->buddyIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\bport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->buddyPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\hostip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\hprivip\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostPrivateIp = htonl((unsigned int)atoi(buffer)); if (!gpiValueForKey(input, "\\qport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->queryPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\hport\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->hostPort = (unsigned short)atoi(buffer); if (!gpiValueForKey(input, "\\sessflags\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->sessionFlags = (unsigned int)atoi(buffer); freeclear(buddyStatusInfo->richStatus); if (!gpiValueForKey(input, "\\rstatus\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->richStatus = goastrdup(buffer); freeclear(buddyStatusInfo->gameType); if (!gpiValueForKey(input, "\\gameType\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameType = goastrdup(buffer); freeclear(buddyStatusInfo->gameVariant); if (!gpiValueForKey(input, "\\gameVnt\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameVariant = goastrdup(buffer); freeclear(buddyStatusInfo->gameMapName); if (!gpiValueForKey(input, "\\gameMn\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->gameMapName = goastrdup(buffer); if (!gpiValueForKey(input, "\\product\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->productId = (int)atoi(buffer); if (!gpiValueForKey(input, "\\qmodeflags\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); buddyStatusInfo->quietModeFlags = (GPEnum)atoi(buffer); callback = iconnection->callbacks[GPI_RECV_BUDDY_STATUS]; if (callback.callback != NULL) { GPRecvBuddyStatusArg *anArg; anArg = (GPRecvBuddyStatusArg *)gsimalloc(sizeof(GPRecvBuddyStatusArg)); if (anArg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); anArg->date = (unsigned int)date; anArg->index = buddyStatusInfo->buddyIndex; anArg->profile = profileid; CHECK_RESULT(gpiAddCallback(connection, callback, anArg, NULL, 0)); } } return GP_NO_ERROR; }