⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 updatemanager.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                        localMinorVersion = 0;

                    if(numFields < 1)
                        localMajorVersion = 0;
            
                    numFields = sscanf(item->GetCurrentFileVersion().c_str(),
                           "%lu.%lu.%lu.%lu", 
                           &currentMajorVersion,&currentMinorVersion,
                           &currentRevisionVersion, &currentFileVersion);

                    if(numFields < 4)
                        currentFileVersion = 0;

                    if(numFields < 3)
                        currentRevisionVersion = 0;

                    if(numFields < 2)
                        currentMinorVersion = 0;

                    if(numFields < 1)
                        currentMajorVersion = 0;

                    // is the version on the server more recent?
                    if( (currentMajorVersion > localMajorVersion) ||
                        (currentMajorVersion == localMajorVersion && 
                         currentMinorVersion > localMinorVersion) ||
                        (currentMajorVersion == localMajorVersion && 
                         currentMinorVersion == localMinorVersion &&
                         currentRevisionVersion > localRevisionVersion) ||
                        (currentMajorVersion == localMajorVersion && 
                         currentMinorVersion == localMinorVersion &&
                         currentRevisionVersion == localRevisionVersion &&
                         currentFileVersion > localFileVersion))
                    {
                        currentVersionMoreRecent = true;
                    }
                }
                

                if(currentVersionMoreRecent)
                {
                    result = DownloadItem(item, function, cookie);

                    if(IsntError(result))
                    {
                        downloadCount++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        if(IsntError(result))
        {
            if(function)
            {
                UMEvent event;

                memset(&event, 0x00, sizeof(UMEvent));
                event.type = kUMEvent_Done;

                if(downloadCount)
                    event.eventString = "Finished retrieving latest components.";
                else
                    event.eventString = "There are no new versions available at this time.";
                function(&event, cookie);
            }
        }
        else if(result != kError_UserCancel)
        {
            if(function)
            {
                UMEvent event;

                memset(&event, 0x00, sizeof(UMEvent));
                event.type = kUMEvent_Error;
                event.data.errorData.errorCode = result;
                function(&event, cookie);
            }

        }


        if(!downloadCount)
            result = kError_NoItemsUpdated;

        m_mutex.Release();
    }

    return result;
}

const uint8 kHttpPort = 80;
const uint32 kMaxHostNameLen = 64;

Error UpdateManager::DownloadInfo(string& info, 
                                  UMCallBackFunction function,
                                  void* cookie)
{
    Error result = kError_NoErr;
    char hostname[kMaxHostNameLen + 1];
    char localname[kMaxHostNameLen + 1];
    char proxyname[kMaxHostNameLen + 1];
    unsigned short  port;
    struct sockaddr_in  addr;
    struct hostent      host;
    SOCKET s = -1;
    bool useProxy;
    const char* file = NULL;
    uint32 length;

    m_context->prefs->GetPrefBoolean(kUseProxyPref, &useProxy);

    length = sizeof(proxyname);
    m_context->prefs->GetPrefString(kProxyHostPref, proxyname, &length);

    if(useProxy)
    {
        int32 numFields;

        numFields = sscanf(proxyname, 
                           "http://%[^:/]:%hu", hostname, &port);

        sprintf(proxyname, "http://%s%s", kUpdateServer, kUpdateFile);
        file = proxyname;

        if(numFields < 1)
            result = kError_InvalidURL;     

        if(numFields < 2)
            port = kHttpPort;
    }
    else
    {
        strcpy(hostname, kUpdateServer);
        port = kUpdatePort;
        file = kUpdateFile;
    }

    if(function)
    {
        UMEvent event;

        memset(&event, 0x00, sizeof(UMEvent));
        event.type = kUMEvent_Status;
        event.eventString = "Looking up server address...";
        bool ok = function(&event, cookie);

        if(!ok)
            result = kError_UserCancel;
    }

    // get hostname
    if(IsntError(result))
    {
        struct hostent* hostByName;
        struct hostent  hostByIP;
        hostByName = gethostbyname(hostname);

        // On some stacks a numeric IP address
        // will not parse with gethostbyname.  
        // If that didn't work try to convert it as a
        // numeric address before giving up.
        if(!hostByName)
        {
            static unsigned long ip;
            static char *addr_ptr[2] = {(char*)&ip, NULL};

            if((ip = inet_addr(hostname)) < 0) 
                result =  kError_CantFindHost;
            else
            {
                hostByIP.h_length = sizeof(uint32);
                hostByIP.h_addrtype = AF_INET;
                hostByIP.h_addr_list = (char**)&addr_ptr;
                hostByName = &hostByIP;
            }
        }

        if(IsntError(result))
        {
            memcpy(&host, hostByName, sizeof(struct hostent));
        }
    }

    if(function)
    {
        UMEvent event;

        memset(&event, 0x00, sizeof(UMEvent));
        event.type = kUMEvent_Status;
        event.eventString = "Found server address...";
        bool ok = function(&event, cookie);

        if(!ok)
            result = kError_UserCancel;
    }

    // open socket
    if(IsntError(result))
    {
        memset(&addr, 0x00, sizeof(struct sockaddr_in));
        memcpy(&addr.sin_addr, host.h_addr, host.h_length);
        addr.sin_family= host.h_addrtype;
        addr.sin_port= htons(port); 

        s = socket(host.h_addrtype, SOCK_STREAM, 0);

        if(s < 0)
            result = kError_CantCreateSocket;
    }

    if(function)
    {
        UMEvent event;

        memset(&event, 0x00, sizeof(UMEvent));
        event.type = kUMEvent_Status;
        event.eventString = "Connecting to the server...";
        bool ok = function(&event, cookie);

        if(!ok)
            result = kError_UserCancel;
    }

    // connect and send request
    if(IsntError(result))
    {
        if(connect(s,(const struct sockaddr*)&addr, sizeof(struct sockaddr)))
            result = kError_CannotBind;

        if(function)
        {
            UMEvent event;

            memset(&event, 0x00, sizeof(UMEvent));
            event.type = kUMEvent_Status;
            event.eventString = "Requesting latest version info...";
            bool ok = function(&event, cookie);

            if(!ok)
                result = kError_UserCancel;
        }

        if(IsntError(result))
        {
            gethostname(localname, kMaxHostNameLen);    

            char* query = new char[ strlen(kUpdateRequest) + 
                                    strlen(file) +
                                    strlen(localname) +
                                    strlen(FREEAMP_VERSION) + 1];
        
            sprintf(query, kUpdateRequest, file, localname, FREEAMP_VERSION);

            int count;

            count = send(s, query, strlen(query), 0);

            if(count != (int)strlen(query))
            {
                result = kError_IOError;
            }

            delete [] query;
        }
    }

    if(function)
    {
        UMEvent event;

        memset(&event, 0x00, sizeof(UMEvent));
        event.type = kUMEvent_Status;
        event.eventString = "Receiving latest version info...";
        bool ok = function(&event, cookie);

        if(!ok)
            result = kError_UserCancel;
    }

    // receive response
    if(IsntError(result))
    {
        uint32 bufferSize = 2048;
        char* buffer = NULL;
        int count;
        uint32 total = 0;

        buffer = (char*)malloc(bufferSize + 1);

        result = kError_OutOfMemory;

        if(buffer)
        {
            result = kError_NoErr;

            do
            {
                count = recv(s, buffer, bufferSize, 0);

                if(count > 0)
                {
                    buffer[count] = 0x00;
                    info += buffer;
                    total += count;
                }

                if(count < 0)
                    result = kError_IOError;
                
                if(function)
                {
                    UMEvent event;

                    memset(&event, 0x00, sizeof(UMEvent));
                    event.type = kUMEvent_Status;
                    event.eventString = "Receiving latest version info...";
                    bool ok = function(&event, cookie);

                    if(!ok)
                        result = kError_UserCancel;
                }

            }while(count > 0 && IsntError(result));

            free(buffer);
        }
    }

    if(s > 0)
        closesocket(s);


    return result;
}

static bool IsHTTPHeaderComplete(char* buffer, uint32 length)
{
    bool result = false;

    //if(length >= 4)
    //{
        //if( (buffer[0] == 'H' && buffer[1] == 'T' 
        //       && buffer[2] == 'T' && buffer[3] == 'P'))
        //{
            //cout << "buffer is HTTP" << endl;

            for(char* cp = buffer; cp < buffer + length; cp++)
            {
                if(!strncmp(cp, "\n\n", 2) || !strncmp(cp, "\r\n\r\n", 4))
                {
                    result = true;
                    break;
                }
            }
        //}
    //}

    return result;
}

static int32 GetContentLengthFromHeader(const char* buffer)
{
    int32 result = -1;

    char* cp = strstr(buffer, "Content-Length:");

    if(cp)
    {
        cp += strlen("Content-Length:") + 1;

        result = atoi(cp);
    }

    return result;
}

Error UpdateManager::DownloadItem(UpdateItem* item, 
                                  UMCallBackFunction function,
                                  void* cookie)
{
    Error result = kError_InvalidParam;
    
    assert(item);

    if(item)
    {   
        //cout << "Downloading " << item->GetLocalFileName() << endl;

        char hostname[kMaxHostNameLen + 1];
        char localname[kMaxHostNameLen + 1];
        char proxyname[kMaxHostNameLen + 1];
        unsigned short port;
        struct sockaddr_in  addr;
        struct hostent      host;
        SOCKET s = -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -