home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 April / PCWorld_2000-04_cd.bin / Komunik / Servery / PinkNet / pnws1076prof.exe / file0134.bin < prev    next >
Encoding:
Text File  |  2000-03-12  |  8.2 KB  |  285 lines

  1. library LogApache;
  2. {******************************************************
  3.  *  Knihovna PinkNet Web Serveru - Open Source Part   *
  4.  *                                                    *
  5.  * Tento soubor loguje protokol o cinnosti tak jako   *
  6.  * server Appache. Je s nim kompatibilni. Informace   *
  7.  * naleznete na http://pnws.pinknet.cz/               *
  8.  *                                                    *
  9.  * Copyright ⌐1999, Tomas Rosa, Tomas.Rosa@pinknet.cz *
  10.  *                                                    *
  11.  ******************************************************}
  12.  
  13. uses
  14.   SysUtils,
  15.   Classes;
  16.  
  17. type PSvrNames=^TSvrNames;
  18.      TSvrNames=record
  19.         svrname:ShortString;
  20.         next:PSvrNames;
  21.      end;
  22.  
  23.      PMySvrNames=^TMySvrNames;
  24.      TMySvrNames=record
  25.         svrname,
  26.         prefix:ShortString;
  27.         ac_buffer,
  28.         ref_buffer,
  29.         agent_buffer:TStringList;
  30.         f_ac,
  31.         f_ref,
  32.         f_agent:TFileStream;
  33.         next:PMySvrNames;
  34.      end;
  35.  
  36. var FSvrNames:PMySvrNames;
  37.     FOldNames:PSvrNames;
  38.     FPath:string;           //cesta k logum
  39.     DefSvr:PMySvrNames;       //pokud se nenajde jmeno, pouzije se toto
  40.     ErrorFile:TFileStream;
  41.     ErrorBuf:TStringList;
  42.  
  43. function OpenLogFile(fname:string;newfile:boolean):TFileStream;
  44. var f:file;
  45. begin
  46.    if newfile then
  47.    try
  48.       assign(f,fname);
  49.       erase(f);
  50.    except
  51.       //hm, nelze smazat, tak holt pokracujem
  52.    end;
  53.    if not FileExists(fname) then
  54.       result:=TFileStream.Create(fname,fmCreate or {fmShareDenyWrite}fmShareDenyNone)
  55.    else
  56.       result:=TFileStream.Create(fname,fmOpenReadWrite or {fmShareDenyWrite}fmShareDenyNone);
  57. end;
  58.  
  59. //LogPath je cesta k logum tak jak je nastavena v setupu
  60. //NeedTimer je TRUE, pokud knihovna chce casovani na ukladani dat
  61. //             FALSE, pokud nic nechce, zapisuje to hned
  62. //SvrNames je ukazatel na seznam jmen serveru
  63. //NewLog je TRUE, pokud se logy maji pri startu vycistit
  64. //Funkce vraci TRUE, pokud se podarilo inicializovat
  65. function LogDllInit(logpath:ShortString;var needtimer:boolean;svrnames:PSvrNames;newlog:boolean):boolean; stdcall;
  66. var x:PSvrNames;
  67.     n,tmp:PMySvrNames;
  68.     m:integer;
  69. begin
  70.    Result:=false;
  71.    needtimer:=true;   //chceme casovac
  72.    FSvrNames:=nil;
  73.    FOldNames:=SvrNames;
  74.    FPath:=logpath;
  75.    if (length(FPath)>0) and (FPath[length(FPath)]<>'\') then FPath:=FPath+'\';
  76.  
  77.   try
  78.    //Zlikviduj predany seznam serveru a udelej novy
  79.    x:=SvrNames;
  80.    while x<>nil do
  81.    begin
  82.       //neexistuje uz?
  83.       tmp:=FSvrNames;
  84.       while tmp<>nil do
  85.       begin
  86.          if tmp^.svrname=x^.svrname then break;
  87.          tmp:=tmp^.next;
  88.       end;
  89.       if not ((tmp<>nil) and (tmp^.svrname=x^.svrname)) then
  90.       begin //neni tam
  91.          GetMem(n,sizeof(TMySvrNames));
  92.          n^.svrname:=x^.svrname;
  93.          if n^.svrname='*' then DefSvr:=n;
  94.          n^.prefix:=n^.svrname;
  95.          for m:=1 to length(n^.prefix) do
  96.            if n^.prefix[m] in ['.',',','-',' '] then n^.prefix[m]:='_';
  97.          if n^.prefix='*' then n^.prefix:=''
  98.            else n^.prefix:=n^.prefix+'_';
  99.          n^.ac_buffer:=TStringList.Create;
  100.          n^.ref_buffer:=TStringList.Create;
  101.          n^.agent_buffer:=TStringList.Create;
  102.          n^.f_ac:=OpenLogFile(FPath+n^.prefix+'access.txt',newlog);
  103.          n^.f_ref:=OpenLogFile(FPath+n^.prefix+'referer.txt',newlog);
  104.          n^.f_agent:=OpenLogFile(FPath+n^.prefix+'agent.txt',newlog);
  105.          n^.next:=FSvrNames;
  106.          FSvrNames:=n;
  107.       end;
  108.       x:=x^.next;
  109.    end;
  110.    //ted jeste soubor na chyby
  111.    ErrorFile:=OpenLogFile(FPath+'error.txt',newlog);
  112.    ErrorBuf:=TStringList.Create;
  113.   except
  114.    //Chyba, vypadneme s FALSE a server spadne
  115.    Exit;
  116.   end;
  117.  
  118.    result:=true;
  119. end;
  120.  
  121. //Prida zaznam pristupu do logu
  122. { Vyznam polozek:
  123.                  svrname   - jmeno serveru, ktereho se to tyka
  124.                  from_ip   - z jake IP adresy uzivatel prisel
  125.                  auth_user - jak se prihlasil, pokud byl soubor zabespecen
  126.                  gmt_date  - datum a cas ve formatu GMT
  127.                  request   - prvni radek pozadavku "GET / HTTP/1.0"
  128.                  referer   - odkud prisel
  129.                  agent     - co pouzil za prohlizec
  130.                  code      - kod, kterym odpovedel server (200-OK, 404-Not Found,..)
  131.                  bytes     - kolik dat bylo preneseno, nebo -1, pokud to nelze zjistit
  132. //Vraci TRUE, pokud se povedlo         }
  133. function LogDllAddAccess(svrname,from_ip,auth_user,gmt_date,request,
  134.                          referer,agent:ShortString;code,bytes:Integer):boolean; stdcall;
  135. var tmp:PMySvrNames;
  136.     s:string;
  137.  
  138.   procedure WriteLogBuf;
  139.   begin
  140.      if auth_user='' then auth_user:='-';
  141.      if bytes>=0 then s:=IntToStr(bytes)
  142.                  else s:='-';
  143.      tmp^.ac_buffer.Add(from_ip+' '+auth_user+' - '+gmt_date+' "'+request+
  144.                         '" '+IntToStr(code)+' '+s);
  145.      if length(referer)>2 then
  146.      begin
  147.         s:=request;
  148.         s:=Copy(s,pos(' ',s),length(s));
  149.         Delete(s,pos(' HTTP/',s),length(s));
  150.         tmp^.ref_buffer.add(referer+' ->'+s);
  151.      end;
  152.      tmp^.agent_buffer.add(agent);
  153.   end;
  154.  
  155. begin
  156.    result:=false;
  157.  
  158.    tmp:=FSvrNames;
  159.    while tmp<>nil do
  160.    begin
  161.       if UpperCase(tmp^.svrname)=UpperCase(svrname) then
  162.       begin
  163.          WriteLogBuf;
  164.          result:=true;
  165.          exit;
  166.       end;
  167.       tmp:=tmp^.next;
  168.    end;
  169.    if DefSvr<>nil then
  170.    begin
  171.       tmp:=DefSvr;
  172.       WriteLogBuf;
  173.       result:=true;
  174.    end;
  175. end;
  176.  
  177. //Prida zaznam chyby do logu
  178. { Vyznam polozek:
  179.                  msg       - chybova hlaska, ktera se ma zaznamenat
  180.                  gmt_date  - datum a cas ve formatu GMT
  181. //Vraci TRUE, pokud se povedlo         }
  182. function LogDllAddError(msg,gmt_date:ShortString):boolean; stdcall;
  183. begin
  184.    result:=true;
  185.    ErrorBuf.Add(gmt_date+' '+msg);
  186. end;
  187.  
  188. //Pokud si Funkce LOGDLLINIT vyzadala casovac, bude volana
  189. //tato funkce pro ulozeni zaznamu na disk. Je nutne, aby ukladani
  190. //na disk bylo nezavisle na zbylych funkcich, ktere jsou volany
  191. //nezavisle a asynchrone. Je tedy mozne zavolat vsechny funkce naraz
  192. //Vraci TRUE, pokud se povedlo
  193. function LogDllTimer:boolean; stdcall;
  194. var tmp:PMySvrNames;
  195.     s:string;
  196. begin
  197.    result:=false;
  198.  
  199.    //zapis chybove hlasky
  200.    try
  201.       s:=ErrorBuf.text;
  202.       if length(s)>0 then ErrorFile.Write(s[1],length(s));
  203.       ErrorBuf.Clear;
  204.    except
  205.       Exit;
  206.    end;
  207.  
  208.    tmp:=FSvrNames;
  209.    while tmp<>nil do
  210.    begin
  211.       // Pridej nove radky do LOGu
  212.       try
  213.          s:=tmp^.ac_buffer.text;
  214.          if length(s)>0 then tmp^.f_ac.Write(s[1],length(s));
  215.          tmp^.ac_buffer.Clear;
  216.  
  217.          s:=tmp^.ref_buffer.text;
  218.          if length(s)>0 then tmp^.f_ref.Write(s[1],length(s));
  219.          tmp^.ref_buffer.Clear;
  220.  
  221.          s:=tmp^.agent_buffer.text;
  222.          if length(s)>0 then tmp^.f_agent.Write(s[1],length(s));
  223.          tmp^.agent_buffer.Clear;
  224.       except
  225.          Exit;
  226.       end;
  227.       tmp:=tmp^.next;
  228.    end;
  229.    result:=true;
  230. end;
  231.  
  232. //Ukonci logovaci knihovnu. Nelze odlozit, knihovna se musi ukoncit hned
  233. procedure LogDllDone; stdcall;
  234. var x:PMySvrNames;
  235.     y:PSvrNames;
  236. begin
  237.    //Uloz posledni zkytky v pameti
  238.    LogDllTimer;
  239.  
  240.    //Zlikviduj seznam serveru
  241.    while FSvrNames<>nil do
  242.    begin
  243.       FSvrNames^.ac_buffer.Free;
  244.       FSvrNames^.ref_buffer.Free;
  245.       FSvrNames^.agent_buffer.Free;
  246.       FSvrNames^.f_ac.Free;
  247.       FSvrNames^.f_ref.Free;
  248.       FSvrNames^.f_agent.Free;
  249.       x:=FSvrNames^.next;
  250.       FreeMem(FSvrNames,sizeof(TMySvrNames));
  251.       FSvrNames:=x;
  252.    end;
  253.  
  254.    //a jeste stary
  255.    while FOldNames<>nil do
  256.    begin
  257.       y:=FOldNames^.next;
  258.       FreeMem(FOldNames,sizeof(TSvrNames));
  259.       FOldNames:=y;
  260.    end;
  261.  
  262.    //a jeste chyby
  263.    ErrorFile.Free;
  264.    ErrorBuf.Free;
  265. end;
  266.  
  267.  
  268. //Nejaky info o knihovne a autorovi
  269. function LogDllAbout:ShortString; stdcall;
  270. begin
  271.    result:='<b>LogApache 1.0</b> Copyright ©1999 <a href="mailto:Tomas.Rosa@pinknet.cz">'+
  272.            'Tomas Rosa</a>, <a href="http://ws.pinknet.cz">PinkNet Web Server</a>. '+
  273.            '<i>PNWS log in common log file format</i>';
  274. end;
  275.  
  276. exports
  277.    LogDllAbout,
  278.    LogDllTimer,
  279.    LogDllAddError,
  280.    LogDllAddAccess,
  281.    LogDllDone,
  282.    LogDllInit;
  283.  
  284. end.
  285.