HttpScan

//*****************************************************************************
//*
//*
//*        CHttpScan
//*
//*
//*****************************************************************************
#include    "StdAfx.h"

#define     AZ_LIB_ADDAFX
#include    <afxinet.h>
#include    <stdio.h>
#include    "FileBuffer.h"
#include    "FileFunctions.h"
#include    "HttpScan.h"



BOOL    bProgressMode = FALSE;


DWORD dwHttpRequestFlags =
    INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;

const TCHAR szHeaders[] = _T("Accept: text/*/r/nUser-Agent: AZ_HttpScan/r/n");


char *IndexNames[]    = {    "index.html",
                        "welcome.html",
                        "index.htm",
                        "welcome.htm",
                        "Index.html",
                        "Welcome.html",
                        "Index.htm",
                        "Welcome.htm",
                        "INDEX.HTM",
                        "WELCOME.HTM",
                        "",
                        0};


#define     MAX_WEBPATH    512
#define     WEB_TYPES    "htm;html;php;php3;asp;aspx;cgi"

//*****************************************************************************
//*
//*        Konstruktor
//*
//*****************************************************************************
CHttpScan::CHttpScan()
{
    dwFileLength=0;
    dwAccessType=INTERNET_OPEN_TYPE_DIRECT;
    dont_scan.DataLength(sizeof(int));
    proc=0;
    stop=0;
    tick=0;
}


//*****************************************************************************
//*
//*        Destruktor
//*
//*****************************************************************************
CHttpScan::~CHttpScan()
{

}


//*****************************************************************************
//*
//*        GetPath
//*
//*****************************************************************************
//    Entfernt #? aus einem Pfad
LPCSTR CHttpScan::GetPath(LPCSTR    Path)
{


    xpath=Path;
    xpath.Remove('*');
    xpath.Remove('?');


return xpath;
}

//*****************************************************************************
//*
//*        SetMinusFilter
//*
//*****************************************************************************
int CHttpScan::SetMinusFilter(LPCTSTR Filter)
{
int        len,anz=0;
char    filter[256]="*.";


    mfilter.Del();
    if(!Filter)return 0;

    while(*Filter)
        {
        len=strchar(Filter,';');
        if(len && len<250)
            {
            strncpy(filter,Filter,len);
            filter[len]=0;
            mfilter.Add(len,Filter);

            filter[len+1]=0;
            if(len>4 && !stricmp(filter+len-4,".htm"))
                {
                filter[len]='l';
                mfilter.Add(filter);
                filter[len]=0;
                }
            if(len>5 && !stricmp(filter+len-5,".html"))
                {
                filter[len-1]=0;
                mfilter.Add(filter);
                }

            anz++;
            }

            Filter+=len;
        if(*Filter)Filter++;
        }


return anz;
}

//*****************************************************************************
//*
//*        SetPlusFilter
//*
//*****************************************************************************
int CHttpScan::SetPlusFilter(LPCTSTR Filter)
{
int        len,nr,anz=0;
char   *types,*ptr,filter[256]="*.";



    pfilter.Del();
    if(!Filter || !*Filter)return 0;

    while(*Filter)
        {
        len=strchar(Filter,';');
        if(len && len<250)
            {
            strncpy(filter,Filter,len);
            filter[len]=0;
            pfilter.Add(len,Filter);

            filter[len+1]=0;
            if(len>4 && !stricmp(filter+len-4,".htm"))
                {
                filter[len]='l';
                pfilter.Add(filter);
                filter[len]=0;
                }
            if(len>5 && !stricmp(filter+len-5,".html"))
                {
                filter[len-1]=0;
                pfilter.Add(filter);
                }

            anz++;
            }

            Filter+=len;
        if(*Filter)Filter++;
        }


    types=WEB_TYPES;
    while(*types)
        {
        len=strcspn(types,";");
        memcpy(filter+2,types,len);
        filter[len+2]=0;

            types+=len;
        if(*types)types++;

        for(nr=0;nr<pfilter.Count();nr++)
            {
            ptr=strstr(pfilter[nr],filter+2);
            if(!ptr)continue;
            if(ptr[len]==0)break;
            }
        if(nr>=pfilter.Count())pfilter.Add(filter);
        }

return anz;
}


//*****************************************************************************
//*
//*        SetSubFilter
//*
//*****************************************************************************
//    Setzt einen Pfad mit in dem alle HTML Dateinen nche der ersten liegen m黶sen
//    Wenn Filter==0 oder Filter=="" wird der Filder gel鰏cht
int CHttpScan::SetSubFilter(LPCTSTR Filter)
{

    if(!Filter || *Filter==0)
        {
        sfilter="";
        sfilter_on=0;
        return 0;
        }

    sfilter=Filter;
    AddBackSlash(sfilter);
    CheckWebPath(sfilter);

return 1;
}


//*****************************************************************************
//*
//*        CheckWebPath
//*
//*****************************************************************************
//    Ergibt 1 wenn Path ein Internet Pfad ist
//    Pfade die nicht mit "http:" anfangen werden erweitert
int CHttpScan::CheckWebPath(CString &Path)
{
int        x;

       x=IsWebPath(Path);
    if(x==2)
        {
        CString temp;
        temp=Path;
        Path ="http://";
        Path+=temp;
        x=1;
        }

    PathConvert(Path,'/');


return x;
}

//*****************************************************************************
//*
//*        IsWebPath
//*
//*****************************************************************************
//    Ergibt 1 wenn Path ein Internet Pfad ist                   "http://xxxx"
//    Ergibt 2 wenn Path ein unvollst鋘tiger Internet Pfad ist   "www.xxxxxxx"
int CHttpScan::IsWebPath(const char *Path)
{
    if(!strnicmp(Path,"www."   ,4))return 2;
    if(!strnicmp(Path,"http://",7))return 1;

return 0;
}



//*****************************************************************************
//*
//*        IsFile
//*
//*****************************************************************************
//    Ergibt 1 wenn Path auf eine Datei zeigt "xxxxxxxxxxxxx/yyy.zzz"
//    Ergibt 0 wenn Path ohne Dateinamen ist  "xxxxxxxxxxxxx/"
int CHttpScan::IsFile(const char *Path)
{
int len,is_web;



       is_web=IsWebPath(Path);
    if(is_web)
        {
        len=FilePathLen(Path,3-is_web);
        if(!len      )return 0;
        if(!Path[len])return 0;
            len=strlen(Path);
        if(!len      )return 0;
        if(Path[len-1]=='/' )return 0;
        if(Path[len-1]=='//')return 0;
        }
    else{
            len=strlen(Path);
        if(!len)return 0;
        if(Path[len-1]=='/'  )return 0;
        if(Path[len-1]=='//' )return 0;
        if(ExistFile(Path)>=2)return 0;
        }

return 1;
}


//*****************************************************************************
//*
//*        SetLogProc
//*
//*****************************************************************************
int    CHttpScan::SetLogProc(void (__cdecl *Proc)(void *,const char *,int),void *Param)
{

    proc  = Proc;
    param = Param;

return 1;
}

//*****************************************************************************
//*
//*        GetFile
//*
//*****************************************************************************
int CHttpScan::GetFile(LPCTSTR HttpPath,LPCTSTR FilePath,int Test)
{
CString     path;
FILE    *file;
int         nRetCode=0,blen=0,flen=0,pos;
char     block[512];



    dwFileLength=0;

    if(stop)return -2;                                // Benutzer Abbruch


    GetFilePath(path,FilePath);
    DelBackSlash(path);
    if(ExistFile(GetPath(path))==1)                    // Datei l鰏chen falls sie wie der Pfad heist
        {
        DeleteFile(GetPath(path));
        }

    CreatePath(GetPath(path));
    path_name = HttpPath;

        file=fopen(GetPath(FilePath),"wb");
    if(!file)return -1;


    CInternetSession session(_T("AZ - Http Grapper"), 1 , dwAccessType);
    CHttpConnection* pServer = NULL;
    CHttpFile* pFile = NULL;
    try    {
        // check to see if this is a reasonable URL

        CString strServerName;
        CString strObject;
        INTERNET_PORT nPort;
        DWORD dwServiceType;

        if (!AfxParseURL(HttpPath, dwServiceType, strServerName, strObject, nPort) ||
            dwServiceType != INTERNET_SERVICE_HTTP)
            {
            //cerr << _T("Error: can only use URLs beginning with http://") << endl;
            throw 1;
            }

        if (bProgressMode)
            {
            //cerr << _T("Opening Internet...");
            VERIFY(session.EnableStatusCallback(TRUE));
            }

        tick++;
        pServer = session.GetHttpConnection(strServerName, nPort);

        pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
        pFile->AddRequestHeaders(szHeaders);
        pFile->SendRequest();

        DWORD dwRet;
        pFile->QueryInfoStatusCode(dwRet);

        // if access was denied, prompt the user for the password

        if(dwRet == HTTP_STATUS_DENIED)
            {
            DWORD dwPrompt;
            dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
                FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);

            // if the user cancelled the dialog, bail out

            if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
                {
                //cerr << _T("Access denied: Invalid password/n");
                throw 1;
                }

            pFile->SendRequest();
            pFile->QueryInfoStatusCode(dwRet);
            }

        CString strNewLocation;
        pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);

        // were we redirected?
        // these response status codes come from WININET.H

        if (dwRet == HTTP_STATUS_MOVED ||
            dwRet == HTTP_STATUS_REDIRECT ||
            dwRet == HTTP_STATUS_REDIRECT_METHOD)
            {
            CString strNewLocation;
            pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);

            int nPlace = strNewLocation.Find(_T("Location: "));
            if (nPlace == -1)
                {
                //cerr << _T("Error: Site redirects with no new location") << endl;
                throw 2;
                }

            strNewLocation = strNewLocation.Mid(nPlace + 10);
            nPlace = strNewLocation.Find('/n');
            if (nPlace > 0)
                strNewLocation = strNewLocation.Left(nPlace);

            // close up the redirected site

            pFile->Close();
            delete pFile;
            pServer->Close();
            delete pServer;

            if (bProgressMode)
                {
                //cerr << _T("Caution: redirected to ");
                //cerr << (LPCTSTR) strNewLocation << endl;
                }

            // figure out what the old place was
            if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort))
                {
                //cerr << _T("Error: the redirected URL could not be parsed.") << endl;
                throw 2;
                }

            if (dwServiceType != INTERNET_SERVICE_HTTP)
                {
                //cerr << _T("Error: the redirected URL does not reference a HTTP resource.") << endl;
                throw 2;
                }

            // try again at the new location
            pServer = session.GetHttpConnection(strServerName, nPort);
            pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
                strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
            pFile->AddRequestHeaders(szHeaders);
            pFile->SendRequest();

            pFile->QueryInfoStatusCode(dwRet);
            if (dwRet != HTTP_STATUS_OK)
                {
                //cerr << _T("Error: Got status code ") << dwRet << endl;
                throw 2;
                }
            }

        //cerr << _T("Status Code is ") << dwRet << endl;

        TCHAR   sz[1024];
        int        count;

        for(;;) 
            {
            if(stop)throw -2;
            count=pFile->Read(sz, sizeof(sz));
            if(!count)break;

                                                // Pr黤e ob HTML Typ Fehler
            if(!flen && count>8 && !CmpFileType(FilePath,WEB_TYPES))
                {
                pos=strwlen(sz,0x70,count-8);
                if(!strnicmp(sz+pos,"<HTML>",6))throw -3;
                }

            if(blen<sizeof(block))
                {
                int i;

                i=sizeof(block)-blen;
                if(count<i)i=count;
                memcpy(block+blen,sz,i);
                blen+=i;
                }

            flen+=count;
            fwrite(sz,count,1,file);
            dwFileLength=flen;
            tick++;
            }


        pFile->Close();
        pServer->Close();
        }
    catch (CInternetException* pEx)
        {
        // catch errors from WinINet
        TCHAR szErr[1024];
        pEx->GetErrorMessage(szErr, 1024);

        if(!Test)
            {
            error_text=szErr;
            error_file=HttpPath;
            }

        nRetCode = pEx->m_dwError;
        pEx->Delete();
        }

    catch (int pEx)
        {
        // catch things wrong with parameters, etc
        nRetCode = pEx;
        if(!Test)
            {
            if(nRetCode==-3)
                    error_text.Format("Error: Reciving wrong FileType");
            else    error_text.Format("Error: Exiting with CTearException(%d)",nRetCode);
            error_file=HttpPath;
            }
        }

    if(flen<=0)
        {
        nRetCode=-1;
        if(!Test)
            {
            error_text.Format("Error: Reviving empty file.");
            error_file=HttpPath;
            }
        }

    if (pFile   != NULL)delete pFile;
    if (pServer != NULL)delete pServer;

    session.Close();

    fclose(file);

    if(nRetCode)
        {
        RemoveFile(GetPath(FilePath));
        }
    else{
        if(blen>=sizeof(block))blen=sizeof(block)-1;
        block[blen]=0;

        if(flen<0x20000 && strifind(block,"<HTML>")>=0)
            {
            char buffer[0x20000];

                file=fopen(GetPath(FilePath),"rb");
            if(!file)return nRetCode;
            fread(buffer,flen,1,file);
            fclose(file);

                file=fopen(GetPath(FilePath),"wb");
            if(!file)return nRetCode;
            fprintf(file,"<!-- saved from url=(0039)%s -->/n",HttpPath);
            fwrite(buffer,flen,1,file);
            fclose(file);
            }
        }


return nRetCode;
}



//*****************************************************************************
//*
//*        WritePath
//*
//*****************************************************************************
//    Schreibt den Pfad 'Path' nach File
//    Der Pfad wird dabei in einen realtiven Pfad umgewandelt
//    BasePath    : Web-Basis-Pfad der Datei in der 'Path' stand
//    Path        : Pfad der gespeichert werden soll
//    FileBase    : Disk-Pfad der Datei in der 'Path' stand
//    File        : Dort wird der Basis Pfad gespeichert
//    Sufix        : Wenn 1 dann werden Anf黵ungs Zeichen mit gespeichert
//    Ergibbt 1 wenn ein realtiver Pfad erzeugt werden konnte sonst 0
int    CHttpScan::WritePath(const char  *BasePath,
                         const char  *Path,
                         const char  *FileBase,
                         CFileBuffer *File,
                         int          Sufix)
{
CString        path,temp,add;
int            len,nr,is_web;
char       *file;



    path    = Path;
    is_web  = CheckWebPath(path);
    len=strcspn(Path,"#&");
    if(Path[len])
        {
        path=path.Left(len);
        add =Path+len;
        }



    if(is_web)                                    // "http://xyz" zu "http://xyz/"
        {
        len    =  FilePathLen(path,2);
        if(CmpFileType((LPCSTR)path+len,""))
            {
               len  = strlen(path);
            if(len && path[len-1]!='/')path+="/";
            }
        }

       is_web |= IsWebPath(BasePath);
    if(is_web)                                    // Zu absoluten Web-Pfad machen
        {
        PathFullMake(temp,BasePath,path,2);
        len    = FilePathLen(path,2);
        if(CmpFileType((LPCSTR)path+len,""))    // "http://xyz" zu "http://xyz/"
            {
               len  = strlen(path);
            if(len && path[len-1]!='/')path+="/";
            }
        }
    else{
        AddFileName (temp,BasePath,path);
        }

    len=PathOffset (path,BasePath,temp,2);        // Erzeuge relativ Pfad
        PathConvert(path,'/');

    if(len<0)                                    // Relativ Pfad nicht m鰃lich
        {
        path=Path;
        add="";
        }
    else{
        if(!len || path[len-1]=='/')            // Suche HTLM Startseite
            {
            GetFilePath(temp,FileBase);
            temp+=path;
            for(nr=0;IndexNames[nr];nr++)
                {
                SetFileName(temp,IndexNames[nr]);
                if(ExistFile(GetPath(temp)))break;
                }
            if(!IndexNames[nr])nr=0;
            path+=IndexNames[nr];
            }
        }


    if(CmpFileType(path,"htm"))                    // "*.htm" zu "*.html"
        {
        SetFileType(path,"html");
        }

    file=GetFileName(path);
    for(nr=1;IndexNames[nr];nr++)                // Tausche "welcome.html" to "index.html"
        {
        if(stricmp (file,IndexNames[nr]))continue;
        SetFileName(path,IndexNames[0]);
        break;
        }

    PathConvert(path,'/');
    if(Sufix)File->Write("/"", 1);
             File->Write(path);
             File->Write(add);
    if(Sufix)File->Write("/"", 1);



return len>=0;
}


//*****************************************************************************
//*
//*        SetAccessType
//*
//*****************************************************************************
void CHttpScan::SetAccessType(int iType)
{
int aType[3]={    INTERNET_OPEN_TYPE_PRECONFIG,
                INTERNET_OPEN_TYPE_DIRECT,
                INTERNET_OPEN_TYPE_PROXY
              };

    if(iType>=0 && iType<=2)dwAccessType=aType[iType];

}

//*****************************************************************************
//*
//*        ScanFile
//*
//*****************************************************************************
//    FilePath    : Datei die gescannt werden soll
//    Kette        : Dort werden alle gefunden Pfadangaben gespeichert
//    OutPath        : Datei f黵 die Ausgaben
//    BasePath    : Web-Basis-Pfad der Datei ("http://www.abcdef.com/xyz/")
//    Ergibt die Anzahl der gefundenen Pfadangaben
int    CHttpScan::ScanFile(LPCTSTR FilePath,CStringChain *Kette,LPCTSTR OutPath,LPCTSTR BasePath)
{
char            *mem,wort[MAX_WEBPATH],zeichen;
int                 add=0,len;
CTextBuffer         in,out;



    if(!in.Open(GetPath(FilePath)))return 0;

    if(OutPath)
        {
        if(!out.Open(GetPath(OutPath),CRK_CREATE))return 0;
        }

    if(!BasePath)BasePath="";

    while(in.Text(add,&mem))
        {
        if(stop)return -1;                    // Benutzer Abbruch

        for(add=0;mem[add];add++)            // Suche TAG
            {
            if(mem[add]=='<')break;
            }

        out.Write(mem,add);
        if(mem[add]!='<')continue;

        out.Write(mem+add,1);
            in.Text(add+1,&mem);
        add=in.TextWord(wort,sizeof(wort));
        out.Write(mem,add);
            in.Text(add  ,&mem);

        if(!stricmp(wort,"A"))                // Referenz
            {
            add=in.TextEmpty(1);
            out.Write(mem,add);
                in.Text(add,&mem);
            add=in.TextWord(wort,sizeof(wort));
            out.Write(mem,add);
            if(stricmp(wort,"HREF"))continue;
                in.Text(add,&mem);
            add=in.TextEmpty(1);
            out.Write(mem,add);
                in.Text(add,&mem);
            out.Write(mem,1);
            if(*mem!='='){add=1;continue;}
                in.Text(1,&mem);
            add=in.TextEmpty(1);
                in.Text(add,&mem);
            if(mem[0]=='/'')
                {
                add=in.TextString(wort,sizeof(wort),'/'','/'');
                }
            else{
                add=in.TextString(wort,sizeof(wort));
                }
            if(add)
                {
                len=strcspnr(wort,"#?&///");
                if(len<=0 || wort[len]=='/'    || wort[len]=='//')
                    {
                    len=strlen(wort);
                    }
                if(len>0)Kette->Add(len,wort);
                WritePath(BasePath,wort,FilePath,&out);
                continue;
                }

            add=in.TextEmpty(1);
            out.Write(mem,add);
                in.Text(add,&mem);

            add=strcspn(mem," /t/n/r>");
            if(add)
                {
                Kette->Add(add,mem);
                strlcpy(wort,mem,add+1);
                WritePath(BasePath,wort,FilePath,&out);
                }

            continue;
            }

        if(!stricmp(wort,"IMG"  ) ||        // Bild oder Frame
           !stricmp(wort,"FRAME") )
            {
            for(add=0;mem[add];add++)
                {
                if(mem[add]=='>')break;
                if(!strnicmp(mem+add,"src",3))break;
                }

            out.Write(mem,add);
            if(strnicmp(mem+add,"src",3))continue;
            out.Write(mem+add,3);

                in.Text(add+3,&mem);
            add=in.TextEmpty(1);
            out.Write(mem,add);
                in.Text(add,&mem);

            if(*mem!='='){add=0;continue;}
            out.Write(mem,1);
                in.Text(1,&mem);
            add=in.TextEmpty(1);
                in.Text(add,&mem);

            if(mem[0]=='/'')
                {
                add=in.TextString(wort,sizeof(wort),'/'','/'');
                }
            else{
                add=in.TextString(wort,sizeof(wort));
                }
            if(add)
                {
                Kette->Add(wort);
                WritePath(BasePath,wort,FilePath,&out);
                continue;
                }

            add=in.TextEmpty(1);
                in.Text(add,&mem);

            add=strcspn(mem," /t/n/r>");
            if(add)
                {
                Kette->Add(add,mem);
                strlcpy(wort,mem,add+1);
                WritePath(BasePath,wort,FilePath,&out);
                }
            continue;
            }

        if(!stricmp(wort,"META"))            // Automatische Weiterleitung
            {
            add=in.TextEmpty(1);
            out.Write(mem,add);
                in.Text(add,&mem);

            if(strnicmp(mem,"http-equiv",10)){add=0;continue;}

            out.Write(mem,10);
                in.Text(10,&mem);
            add=in.TextChar(&zeichen);
            out.Write(mem,add);
                in.Text(add,&mem);
            add=in.TextString(wort,sizeof(wort));
            out.Write(mem,add);
                in.Text(add,&mem);

            if(zeichen!='=' || stricmp(wort,"refresh")){add=0;continue;}

            add=in.TextWord(wort,sizeof(wort));
            out.Write(mem,add);
                in.Text(add,&mem);

            if(zeichen!='=' || stricmp(wort,"content")){add=0;continue;}

            add=in.TextChar(&zeichen);
            out.Write(mem,add);
                in.Text(add,&mem);

            if(zeichen!='='){add=0;continue;}

            add=in.TextString(wort,sizeof(wort));
                in.Text(add,&mem);

            for(add=0;wort[add];add++)
                {
                if(strnicmp (wort+add,"URL",3))continue;
                add+=strcspn(wort+add,"=");
                if(wort[add]!='=')continue;
                add++;
                add+=strspn (wort+add," /t/n/r");
                len =strcspn(wort+add,"/"/n/r>");
                wort[add+len]=0;
                Kette->Add(wort+add);
                out.Write("/"0; URL=");
                WritePath(BasePath,wort+add,FilePath,&out,0);
                out.Write("/"");
                break;
                }

            add=0;
            continue;
            }

        add=1;
        out.Write(mem,add);
        }


    out.Close();
    in .Close();


return Kette->Count();
}

//*****************************************************************************
//*
//*        MultiScan
//*
//*****************************************************************************
//    Scanned ab HttpPath alle Links und speichert sie im Pfad FilePath
//    黚er einen Index kann Reihe von Dateien angegeben die durchsucht werden
//    HttpPath    : Kann eine HTML-Datei auf der Festplatte sein
//                  Ein Web-Pfad   "www.abc_server.com"
//                                 "http://www.abc_server.com"
//                                 "http://www.abc_server.com/files"
//                                 "http://www.abc_server.com/files/"
//                  Eine Web-Datei "www.abc_server.com/main.htm"
//                                 "http://www.abc_server.com/main.html"
//                  mit %i,%x,%02i ... kann man den Ort der Reihe angeben
//    FilePath    : Ist der Ziel-Pfad auf der Festplatte
//    Ebene        : Ist die Maximale Anzahl an Link Ebene die durchlaufen werden
//    Flags        : CHS_LOKAL        0x0001    Nur lokale Pfade
//                  CHS_LOKALNEXT    0x0002    Nur lokale Pfade ab der 2. Ebenen
//                  CHS_SUBFILTER    0x0004    Nur Pfade die zum Subfilterpassen weiterverfolgen
//                  CHS_DEBUG        0x0008    Einzel Abfrage starten
//                  CHS_SERVER    0x0010    Nur am gleichen Server suchen
//    Start        : Anfangs Index
//    End            : End Index
//    Step        : Schrittweite f黵 Index
//    Ergibt die Anzahl der gescannten Dateien bzw. -1 bei einem Benutzter Abbruch
int CHttpScan::MultiScan(LPCTSTR HttpPath,LPCTSTR FilePath,int Ebene,int Flags,int Start,int End,int Step)
{
char            *file;
int                 nr;
CString             path,http;
CStringChain     files;
BOOL             is_web,is_file,is_type;
FILE            *temp;


    http   = HttpPath;                        // Pfad Testen
    is_web = CheckWebPath(http);
             PathCompress(http);
             PathConvert (http,'/');

    if(is_web)                                // BackSlash anh鋘gen
        {
        is_file = IsFile(http);
        is_type = CmpFileType(http,"");
        if(is_file && is_type)
            {
            AddBackSlash(http);
            PathConvert (http,'/');
            is_file=0;
            }
        }


//******************** Tempor鋜e Datei erzeugen *******************************

    if(is_web)
        {
        if(!is_file)return 0;

        path =FilePath;
        path+=(LPCSTR)http+FilePathLen(http,1);
        }
    else{
        file=GetFileName(http);
        is_file=(*file!=0);
        if(!is_file)return 0;

        path =FilePath;
        path+=(LPCSTR)http+FilePathLen(http,2);
        }

    SetFileName(path,"");
    CreatePath (GetPath(path));
    SetFileName(path,"HttpScan.tmp.html");

        temp=fopen(GetPath(path),"wb");
    if(!temp)return 0;

    fprintf(temp,"<HTML><BODY>/n");

    for(nr=Start;nr<End;nr+=Step)
        {
        fprintf(temp,"<a href=/"");
        fprintf(temp,http,nr);
        fprintf(temp,"/">"    );
        fprintf(temp,http,nr);
        fprintf(temp,"</a><br>/n");
        }

    fprintf(temp,"</HTML></BODY>/n");
    fclose(temp);

    SetFileName(http,"HttpScan.tmp.html");

    return Scan(http,FilePath,Ebene+1,Flags|CHS_TEMPREAD);
}

//*****************************************************************************
//*
//*        Scan
//*
//*****************************************************************************
//    Scanned ab HttpPath alle Links und speichert sie im Pfad FilePath
//    HttpPath    : Kann eine HTML-Datei auf der Festplatte sein
//                  Ein Web-Pfad   "www.abc_server.com"
//                                 "http://www.abc_server.com"
//                                 "http://www.abc_server.com/files"
//                                 "http://www.abc_server.com/files/"
//                  Eine Web-Datei "www.abc_server.com/main.htm"
//                                 "http://www.abc_server.com/main.html"
//    FilePath    : Ist der Ziel-Pfad auf der Festplatte
//    Ebene        : Ist die Maximale Anzahl an Link Ebene die durchlaufen werden
//    Flags        : CHS_LOKAL        0x0001    Nur lokale Pfade
//                  CHS_LOKALNEXT    0x0002    Nur lokale Pfade ab der 2. Ebenen
//                  CHS_SUBFILTER    0x0004    Nur Pfade die zum Subfilterpassen weiterverfolgen
//                  CHS_DEBUG        0x0008    Einzel Abfrage starten
//                  CHS_SERVER    0x0010    Nur am gleichen Server suchen
//                  CHS_NEWREAD    0x0020    HTML Dateien immer neu downloaden
//                  CHS_NEXTTURN    0x8000    Ist nicht der 1. Aufruf
//                  CHS_NEWLOCAL    0x4000    Neuer lokaler Zweig
//                  CHS_TEMPREAD    0x2000    Erste HTML Datei nie downloaden
//    Ergibt die Anzahl der gescannten Dateien bzw. -1 bei einem Benutzter Abbruch
int CHttpScan::Scan(LPCTSTR HttpPath,LPCTSTR FilePath,int Ebene,int Flags)
{
char            *file;
int                 x,y,nr,anz=0,server_len;
CString             path,temp,http,base,save;
CStringChain     files;
BOOL             is_web=0,is_file,is_lokal=0,is_type;





    http   = HttpPath;                        // Pfad Testen
    is_web = CheckWebPath(http);
             PathCompress(http);
             PathConvert (http,'/');

    if(is_web)                                // BackSlash anh鋘gen
        {
        is_file = IsFile(http);
        is_type = CmpFileType(http,"");
        if(!is_file || is_type)
            {
            AddBackSlash(http);
            PathConvert (http,'/');
            is_file=0;
            }
        }

    if(~Flags&CHS_NEXTTURN)                    // Erster Aufruf
        {
        tick=0;
        stop=0;
        path_name="";
        error_text="";
        dont_scan.Del();
        }

       x=dont_scan.FindFast(http,0,-1,1);    // Schon gescannt oder gesperrt
    if(x!=-1)
        {
        if(dont_scan.GetData(x)>=Ebene)return 0;
        }

    if(Flags&CHS_DEBUG)                        // Abfragen ob scannen
    if(CmpFileType(http,WEB_TYPES))            // Nur Html Dateien Scannen
        {
        path  = "Soll die Datei:/n";
        path += HttpPath;
        path += "/ngesannt werden ?";
           x =MessageBox(0,path,"HttpScann",MB_YESNOCANCEL|MB_ICONQUESTION);
        if(x==IDNO){x=1000;dont_scan.Add(HttpPath,CSC_END,&x);return 0;}
        if(x==IDCANCEL){Break();return -1;}
        }

    if(Ebene<0)return 0;                    // Pr黤e Ebene

//******************** Web-Datei herunter laden *******************************

    if(is_web)
        {
        if(!is_file)
            {
            path =FilePath;
            path+=(LPCSTR)http+FilePathLen(http,1);

            AddBackSlash(path);

            x=FilePathLen(path,2);
            y=FilePathLen(path);

            path+=IndexNames[0];
            nr=(y>x)? -1:0;                    // Gibt es einen unter Pfad

                                            // Schon gescannt oder gesperrt
            if(dont_scan.FindFast(path,0,-1,1)!=-1)return 0;

            for(;;nr++)                        // Suche Index Datei
                {
                if(nr>=0 && !IndexNames[nr])break;
                if(stop)return -1;            // Benutzer Abbruch

                if(nr>=0)SetFileName(http,IndexNames[nr]);

                save=GetPath (path);
                if(ExistFile (save)==1)        // Datei schon vorhanden ?
                if(LenghtFile(save)> 0)is_lokal=1;

                if(~Flags&CHS_TEMPREAD)        // Nie neu runder laden
                if( Flags&CHS_NEWREAD)        // Immer neu runder laden
                if(CmpFileType(path,WEB_TYPES))
                    {
                    is_lokal=0;
                    }

                if(is_lokal)break;

                int err=GetFile(http,path,(IndexNames[nr+1])? 1:0);
                if(!err)break;
                if( err==12007)Break();        // Benutzer Abbruch
                }

            if(!IndexNames[nr])                // WebFile nicht gefunden
                {
                SetFileName(http,IndexNames[0]);
                if(proc)proc(param,http,CHS_ERR_NOTFOUND);
                return 0;
                }
            }
        else{                                // Pfad mit Dateiangabe
            path =FilePath;
            path+=(LPCSTR)http+FilePathLen(http,1);

                                            // Schon gescannt oder gesperrt
            if(dont_scan.FindFast(path,0,-1,1)!=-1)return 0;

            file=GetFileName(path);
            for(nr=1;IndexNames[nr];nr++)    // Tausche "welcome.html" to "index.html"
                {
                if(stricmp (file,IndexNames[nr]))continue;
                SetFileName(path,IndexNames[0]);
                break;
                }

            if(CmpFileType(path,"htm"))        // "*.htm" zu "*.html"
                {
                SetFileType(path,"html");
                }

            save=GetPath (path);
            if(ExistFile (save)==1)            // Datei schon vorhanden ?
            if(LenghtFile(save)>0)is_lokal=1;

            if(~Flags&CHS_TEMPREAD)            // Nie neu runder laden
            if( Flags&CHS_NEWREAD)            // Immer neu runder laden
            if(CmpFileType(path,WEB_TYPES))
                {
                is_lokal=0;
                }

            if(!is_lokal)
            if(GetFile(http,path))
                {
                if(proc)proc(param,http,CHS_ERR_NOTFOUND);
                return 0;
                }
            }
        }

//******************** Normale Datei laden ************************************

    if(!is_web)
        {
        save=GetPath(http);
        if(ExistFile(save)>=2)                // Zeigt Pfad auf ein Verzeichniss
            {
            AddBackSlash(http);
            }

        file=GetFileName(http);
        is_file=(*file!=0);

        if(!is_file)                        // Keine Datei angabe
            {
            path =FilePath;
            path+=(LPCSTR)http+FilePathLen(http,2);
            path+=IndexNames[0];
            PathConvert(path,'/');
            GetFilePath(temp,path);
            CreatePath (GetPath(temp));

            for(nr=0;IndexNames[nr];nr++)    // Suche Index Datei
                {
                if(stop)return -1;            // Benutzer Abbruch

                SetFileName(http,IndexNames[nr]);

                save =GetPath(path);
                if(ExistFile (save)==1)
                if(LenghtFile(save)> 0)
                    {
                    is_lokal=1;break;
                    }

                if(CopyFile(GetPath(http),save,0))break;
                }

            if(!IndexNames[nr])                // Datei nicht gefunden
                {
                SetFileName(http,IndexNames[0]);
                if(proc)proc(param,http,CHS_ERR_NOTFOUND);
                return 0;
                }
            }
        else{
            path  = FilePath;
            path += (LPCSTR)http+FilePathLen(http,1);
            PathConvert(path,'/');
            GetFilePath(temp,path);
            CreatePath (GetPath(temp));

            save=GetPath(path);
            if(ExistFile(save)==1)is_lokal=1;
            else if(!CopyFile(GetPath(http),save,0))
                {
                if(proc)proc(param,http,CHS_ERR_NOTFOUND);
                return 0;
                }
            }
        }

//******************** Pr黤en ob die gescannt werden soll *********************

    if(proc)proc(param,http,(is_lokal)? CHS_OK_LOKAL:CHS_OK);
    if(!CmpFileType(path,WEB_TYPES))        // Nur Html Dateien Scannen
        {
        return 1;
        }


    if(Ebene<=0)return 0;

    dont_scan.Add(http,CSC_ABCG,&Ebene);    // Nur einmal Scannen
    dont_scan.Add(path,CSC_ABCG,&Ebene);


//******************** Dateien in HTML Datei scannen **************************

    temp =path;                                // Tempor鋜 Datei
    temp+=".tmp";

    base=http;
    SubFileName (base);
    AddBackSlash(base);
    PathConvert (base,'/');

    if(!(Flags&CHS_NEXTTURN)  ||            // Neuer lokaler Zweig
        (Flags&CHS_NEWLOCAL))
        {
        path_base=base;
        Flags&=~CHS_NEWLOCAL;
        }

    ScanFile(path,&files,temp,base);

    save=GetPath(temp);
    if(ExistFile(save)==1)                    // Tempor鋜 File benutzen
        {
        if(LenghtFile(save)>0)
            {
            RemoveFile(save);
            MoveFile  (GetPath(temp),save);
            }
        else{
            RemoveFile(save);
            }
        }


    server_len =FilePathLen(path_base,2);

    for(x=0;x<files.Count();x++)            // Sub Dateien Holen
        {
        if(stop)break;                        // Benutzer Abbruch

        path=files[x];
        is_lokal=1;
        is_web=CheckWebPath(path);

        if(!is_web)                            // Voller Dateiname
            {
            PathFullMake(temp,base,path,2);
            path=temp;
            }

             PathCompress(path);            // Entferne . und ..
             PathConvert (path,'/');
        file=GetFileName (path);

        if(~Flags&CHS_TEMPREAD)
        if( Flags&CHS_LOKAL)                // Nur Lokale Links
            {
            if(strnicmp(path,path_base,path_base.GetLength()))
                {
                if(proc)proc(param,path,CHS_ERR_LOCAL);
                continue;
                }
            }

        if(~Flags&CHS_TEMPREAD)
        if( Flags&CHS_SERVER)                // Nur Server Links
            {
            if(strnicmp(path,path_base,server_len))
                {
                if(proc)proc(param,path,CHS_ERR_SERVER);
                continue;
                }
            }

        if(~Flags&CHS_TEMPREAD)
        if( Flags&CHS_SUBFILTER && sfilter_on)// Nur bestimmte SubPfade
            {
            if(strnicmp(path,sfilter,sfilter.GetLength()))
                {
                if(proc)proc(param,path,CHS_ERR_SUBFILTER);
                continue;
                }
            }


        if(*file && pfilter.Count())        // Plus Filter
            {
            for(y=0;y<pfilter.Count();y++)
                {
                if(!memxcmp(pfilter[y],file,strlen(file),1))break;
                }
            if(y>=pfilter.Count())
                {
                if(proc)proc(param,path,CHS_ERR_PLUS);
                continue;
                }
            }

        if(*file && mfilter.Count())        // Minus Filter
            {
            for(y=0;y<mfilter.Count();y++)
                {
                if(!memxcmp(mfilter[y],file,strlen(file),1))break;
                }
            if(y<mfilter.Count())
                {
                if(proc)proc(param,path,CHS_ERR_MINUS);
                continue;
                }
            }

        if(Flags&CHS_LOKAL)Flags&=~CHS_LOKALNEXT;

        if(Flags&CHS_TEMPREAD)
            {
            anz+=Scan(path,FilePath,Ebene-1,Flags&~CHS_TEMPREAD);
            }
        else if(Flags&CHS_LOKALNEXT)
            {
            Flags|=CHS_LOKAL;
            temp=path_base;
            anz+=Scan(path,FilePath,Ebene-1,Flags|CHS_NEXTTURN|CHS_LOKAL|CHS_NEWLOCAL);
            path_base=temp;
            }
        else{
            anz+=Scan(path,FilePath,Ebene-1,Flags|CHS_NEXTTURN);
            }
        }


return anz;
}


<script type="text/javascript"> var strProjectId = "10012"; var strProjectPic = "http://www.vcforge.net/1007/HttpScan.gif"; var strProjectName = "HttpScan"; var strProjectCreateUser = "anonymous"; var strProjectCreateDate = "07-07-02 09:02:58"; var strProjectCategory = "Networking"; </script> <script src="http://www.vcforge.net/javascript/float.js" type="text/javascript"></script>
   
HttpScan
anonymous
07-07-02 09:02:58
Networking
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值