int main()
{
	unsigned long nMsg = 0;
	char *cmnd, *uname1, *uname2;
	int k;
	user *users = NULL;
	
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	
	cmnd = (char*)malloc(sizeof(char)*10);
	while(scanf("%s", cmnd)!=EOF)
	{
		if(DEBUG)
			printf("cmnd read: %s\n", cmnd);
			
		if(!strcmp(cmnd, "ADD"))
		{
			uname1 = getUser();
			if(users==NULL)
				init(uname1, &users);
			else
				addUser(uname1, users);
		}
		else if(!strcmp(cmnd, "FOLLOW"))
		{
			uname1 = getUser(), uname2 = getUser();
			follow(uname1, uname2, users);
		}
		else if(!strcmp(cmnd, "SEND"))
		{
			uname1 = getUser();
			sendMsg(uname1, ++nMsg, users);
		}
		else if(!strcmp(cmnd, "RESEND"))
		{
			uname1 = getUser();
			scanf("%d", &k);
			resendMsg(uname1, k, users);
		}
		else if(!strcmp(cmnd, "INACTIVE"))
		{
			uname1 = getUser();
			inactivate(uname1, users);
		}
		else if(!strcmp(cmnd, "ACTIVE"))
		{
			uname1 = getUser();
			activate(uname1, users);
		}
		else //UNFOLLOW
		{
			uname1 = getUser(), uname2 = getUser();
			unfollow(uname1, uname2, users);
		}
	}
	
	user *cur = users;
	do
	{
		print(*cur);
		cur = cur->next;
	}
	while(cur!=users);
	
	return 0;
}
static ClRcT rmdSendTimerFunc(void *pData)
{
    ClCntNodeHandleT    nodeHandle;
    ClRmdRecordSendT    *rec         = NULL;
    ClRcT               rc;
    ClRcT               retCode      = 0;
    ClRmdObjT           *pRmdObject;
    ClRmdAsyncCallbackT fpTempPtr;
    void                *cookie;
    ClBufferHandleT     outMsgHdl;
    ClEoExecutionObjT   *pThis       = NULL;
    ClUint64T           msgId        = (ClUint32T)(ClWordT) pData;

    CL_FUNC_ENTER();
    if (pData == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }
    rc = clEoMyEoObjectGet(&pThis);

    if ( CL_OK != rc )
    {
        return rc;
    }

    pRmdObject = (ClRmdObjT *) (pThis->rmdObj);
    if (pRmdObject == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }

    rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 0");
    rc = clCntNodeFind(pRmdObject->sndRecContainerHandle, (ClPtrT)(ClWordT)msgId,
                       &nodeHandle);
    if (rc == CL_OK)
    {
        clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 1");

        rc = clCntNodeUserDataGet(pRmdObject->sndRecContainerHandle, nodeHandle,
                                  (ClCntDataHandleT *) &rec);
        if (rc == CL_OK)
        {
            clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 2");
            if (rec)
            {
                /*
                 * Disabling retries for ASYNC since we dont want
                 * to land up in duplicate send mess as anyway we have
                 * accounted for the retries while creating the async timer.
                 */
                if (0 && rec->recType.asyncRec.noOfRetry > 0)
                {
                    /*
                     * key is part of record so no need to free just reuse
                     */
                    retCode = resendMsg(rec, pRmdObject, pThis);
                }
                else
                {
                    /*
                     * key is part of record so no need to free, it will be
                     * freed by hash delete callback
                     */
                    RMD_STAT_INC(pRmdObject->rmdStats.nCallTimeouts);
                    retCode = clTimerDeleteAsync(&rec->recType.asyncRec.timerID);
                    if (rec->recType.asyncRec.func)
                    {
                        /*
                         * unlocking it as callback func can make the rmd call
                         */
                        ClBufferHandleT message;

                        fpTempPtr = rec->recType.asyncRec.func;
                        cookie = rec->recType.asyncRec.cookie;
                        outMsgHdl = rec->recType.asyncRec.outMsgHdl;
                        message = rec->recType.asyncRec.sndMsgHdl;
                        clBufferHeaderTrim(message, rec->hdrLen);
                        rc = clCntNodeDelete(pRmdObject->sndRecContainerHandle,
                                             nodeHandle);
                        rc = clOsalMutexUnlock(pRmdObject->
                                               semaForSendHashTable);
                        fpTempPtr((CL_RMD_RC(CL_ERR_TIMEOUT)), cookie, message,
                                  outMsgHdl);
                        clBufferDelete(&(message));
                        rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
                    }
                }
            }
        }
    }

    rc = clOsalMutexUnlock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    CL_FUNC_EXIT();
    return CL_OK;

}