Longstick的学习周记——第七周

 

目录

前言

MEGAcmd调试日志

一、MEGAcmd的主体流程

二、void megacmd() 函数

对于MEGAcmd结构的认知


前言

完了。

摸鱼的一个星期,回家果然就是啥也不想干,就是想着摸鱼。

好累啊,明明什么也没有干,但是就是想躺着。这不行啊!!!赶紧打起精神,旅游完一定要元气回归。加油加油


MEGAcmd调试日志

任务分配下来了。负责源码主流程的分析,目前的状况是要弄清楚signup的整体流程。这个流程其实老师也已经有指引着做一部分了,但是具体详细的内容还需要自己多分析。

一、MEGAcmd的主体流程

仔细看了一下,目前来说,我看见的程序入口是这样的:
首先整个程序的源文件即megacmd.cpp,里面包含了main主函数,这个就是程序运行的部分。在main主函数中,前面部分就是在初始化各种日志LOG以及管理器,最后(line5014)调用的同文件的void megacmd ( ) 函数,即程序主流程的核心循环流程。

二、void megacmd() 函数

void megacmd()
{
    threadRetryConnections = new MegaThread();
    threadRetryConnections->start(retryConnections, NULL);

    LOG_info << "Listening to petitions ... ";

    for (;; )
    {
        cm->waitForPetition();

        api->retryPendingConnections();

        if (doExit)
        {
            LOG_verbose << "closing after wait ..." ;
            return;
        }

        if (cm->receivedPetition())
        {

            LOG_verbose << "Client connected ";

            CmdPetition *inf = cm->getPetition();

            LOG_verbose << "petition registered: " << inf->line;

            delete_finished_threads();

            if (!inf || !strcmp(inf->getLine(),"ERROR"))
            {
                LOG_warn << "Petition couldn't be registered. Dismissing it.";
                delete inf;
            }
            // if state register petition
            else  if (!strncmp(inf->getLine(),"registerstatelistener",strlen("registerstatelistener")) ||
                      !strncmp(inf->getLine(),"Xregisterstatelistener",strlen("Xregisterstatelistener")))
            {

                cm->registerStateListener(inf);

                // communicate client ID
                string s = "clientID:";
                s+=SSTR(currentclientID);
                s+=(char)0x1F;
                inf->clientID = currentclientID;
                currentclientID++;
                cm->informStateListener(inf,s);

#if defined(_WIN32) || defined(__APPLE__)
                string message="";
                ostringstream os;
                MegaCmdListener *megaCmdListener = new MegaCmdListener(NULL);
                api->getLastAvailableVersion("BdARkQSQ",megaCmdListener);
                if (!megaCmdListener->trywait(2000))
                {
                    if (!megaCmdListener->getError())
                    {
                        LOG_fatal << "No MegaError at getLastAvailableVersion: ";
                    }
                    else if (megaCmdListener->getError()->getErrorCode() != MegaError::API_OK)
                    {
                        LOG_debug << "Couldn't get latests available version: " << megaCmdListener->getError()->getErrorString();
                    }
                    else
                    {
                        if (megaCmdListener->getRequest()->getNumber() != MEGACMD_CODE_VERSION)
                        {
                            os << "---------------------------------------------------------------------" << endl;
                            os << "--        There is a new version available of megacmd: " << setw(12) << left << megaCmdListener->getRequest()->getName() << "--" << endl;
                            os << "--        Please, update this one: See \"update --help\".          --" << endl;
                            os << "--        Or download the latest from https://mega.nz/cmd          --" << endl;
#if defined(__APPLE__)
                            os << "--        Before installing enter \"exit\" to close MEGAcmd          --" << endl;
#endif
                            os << "---------------------------------------------------------------------" << endl;
                        }
                    }
                    delete megaCmdListener;
                }
                else
                {
                    LOG_debug << "Couldn't get latests available version (petition timed out)";

                    api->removeRequestListener(megaCmdListener);
                    delete megaCmdListener;
                }

                int autoupdate = ConfigurationManager::getConfigurationValue("autoupdate", -1);
                if (autoupdate == -1 || autoupdate == 2)
                {
                    os << "ENABLING AUTOUPDATE BY DEFAULT. You can disable it with \"update --auto=off\"" << endl;
                    autoupdate = 1;
                }

                if (autoupdate == 1)
                {
                    startcheckingForUpdates();
                }
                message=os.str();


                if (message.size())
                {
                    s += "message:";
                    s+=message;
                    s+=(char)0x1F;
                }
#endif

                bool isOSdeprecated = false;
#ifdef MEGACMD_DEPRECATED_OS
                isOSdeprecated = true;
#endif


#ifdef _WIN32
                OSVERSIONINFOEX osvi;
                ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
                osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
                if (GetVersionEx((OSVERSIONINFO*)&osvi) && osvi.dwMajorVersion < 6)
                {
                    isOSdeprecated = true;
                }
#elif defined(__APPLE__)
                char releaseStr[256];
                size_t size = sizeof(releaseStr);
                if (!sysctlbyname("kern.osrelease", releaseStr, &size, NULL, 0)  && size > 0)
                {
                    if (strchr(releaseStr,'.'))
                    {
                        char *token = strtok(releaseStr, ".");
                        if (token)
                        {
                            errno = 0;
                            char *endPtr = NULL;
                            long majorVersion = strtol(token, &endPtr, 10);
                            if (endPtr != token && errno != ERANGE && majorVersion >= INT_MIN && majorVersion <= INT_MAX)
                            {
                                if((int)majorVersion < 13) // Older versions from 10.9 (mavericks)
                                {
                                    isOSdeprecated = true;
                                }
                            }
                        }
                    }
                }
#endif
                if (isOSdeprecated)
                {
                    s += "message:";
                    s += "Your Operative System is too old.\n";
                    s += "You might not receive new updates for this application.\n";
                    s += "We strongly recommend you to update to a new version.\n";
                    s+=(char)0x1F;
                }

                if (sandboxCMD->storageStatus != MegaApi::STORAGE_STATE_GREEN)
                {
                    s += "message:";

                    if (sandboxCMD->storageStatus == MegaApi::STORAGE_STATE_PAYWALL)
                    {
                        std::unique_ptr<char[]> myEmail(api->getMyEmail());
                        std::unique_ptr<MegaIntegerList> warningsList(api->getOverquotaWarningsTs());
                        s += "We have contacted you by email to " + string(myEmail.get()) + " on ";
                        s += getReadableTime(warningsList->get(0),"%b %e %Y");
                        if (warningsList->size() > 1)
                        {
                            for (int i = 1; i < warningsList->size() - 1; i++)
                            {
                                s += ", " + getReadableTime(warningsList->get(i),"%b %e %Y");
                            }
                            s += " and " + getReadableTime(warningsList->get(warningsList->size() - 1),"%b %e %Y");
                        }
                        std::unique_ptr<MegaNode> rootNode(api->getRootNode());
                        long long totalFiles = 0;
                        long long totalFolders = 0;
                        getNumFolderFiles(rootNode.get(),api,&totalFiles,&totalFolders);
                        s += ", but you still have " + std::to_string(totalFiles) + " files taking up " + sizeToText(sandboxCMD->receivedStorageSum);
                        s += " in your MEGA account, which requires you to upgrade your account.\n\n";
                        long long daysLeft = (api->getOverquotaDeadlineTs() - m_time(NULL)) / 86400;
                        if (daysLeft > 0)
                        {
                             s += "You have " + std::to_string(daysLeft) + " days left to upgrade. ";
                             s += "After that, your data is subject to deletion.\n";
                        }
                        else
                        {
                             s += "You must act immediately to save your data. From now on, your data is subject to deletion.\n";
                        }
                    }
                    else if (sandboxCMD->storageStatus == MegaApi::STORAGE_STATE_RED)
                    {
                        s += "You have exeeded your available storage.\n";
                        s += "You can change your account plan to increase your quota limit.\n";
                    }
                    else
                    {
                        s += "You are running out of available storage.\n";
                        s += "You can change your account plan to increase your quota limit.\n";
                    }
                    s += "See \"help --upgrade\" for further details.\n";
                    s += (char)0x1F;
                }

                // if server resuming session, lets give him a very litle while before sending greeting message to the early clients
                // (to aovid "Resuming session..." being printed fast resumed session)
                while (getloginInAtStartup() && ((m_time(nullptr) - timeLoginStarted() < RESUME_SESSION_TIMEOUT * 0.3)))
                {
                    sleepMilliSeconds(300);
                }

                {
                    std::lock_guard<std::mutex> g(greetingsmsgsMutex);

                    while(greetingsFirstClientMsgs.size())
                    {
                        cm->informStateListener(inf,greetingsFirstClientMsgs.front().append(1, (char)0x1F));
                        greetingsFirstClientMsgs.pop_front();
                    }

                    for (auto m: greetingsAllClientMsgs)
                    {
                        cm->informStateListener(inf,m.append(1, (char)0x1F));
                    }
                }

                // if server resuming session, lets give him a litle while before returning a prompt to the early clients
                // This will block the server from responging any commands in the meantime, but that assumable, it will only happen
                // the first time the server is initiated.
                while (getloginInAtStartup() && ((m_time(nullptr) - timeLoginStarted() < RESUME_SESSION_TIMEOUT * 0.7)))
                {
                    sleepMilliSeconds(300);
                }

                // communicate status info
                s+= "prompt:";
                s+=dynamicprompt;
                s+=(char)0x1F;

                if (!sandboxCMD->getReasonblocked().size())
                {
                    cmdexecuter->checkAndInformPSA(inf);
                }

                cm->informStateListener(inf,s);
            }
            else
            { // normal petition
                processCommandInPetitionQueues(inf);
            }
        }
    }
}

文件中也有标识( // main loop ),这个函数就是程序的核心循环,里面包含了程序不断循环监听的流程。

首先可以看到,函数的头两行,创建了一个新的MEGAThread线程,这个Retry线程就是不断的循环连接服务器,保证在线。

下来掉入一个无限for循环,在这个循环中进行以下流程:

  1. 对话监听器进入等待waitForPetition()
  2. api接口不断等待连接
  3. 如果退出,则执行退出程序
  4. 如果收到指令,日志登记,其中:
    1. 如果指令为ERROR或无指令的话,报错
    2. 如果是指令为registerstatelistener或者Xregisterstatelistener,则说明陈述的是请求需要注册,然后让对话监听器先监听该请求的状态。

余下的部分暂时还没有分析,需要继续。

对于MEGAcmd结构的认知

通过不断的函数调用追踪发现,在megacmd.cpp源文件中调用的大部分全局定义的类是从megaapi这个接口中调用的,并且该api接口调用的是sdk中的megaapi_impl,即api接口中类的定义与实现,大部分功能其实都是在这个megaapi_impl中实现的,很多函数就是跳转到这里进行研究,其实算是sdk打包的一部分,个人认为在之后的开发中这个impl文件是主要参考的部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值