havp-0.93/0000755000000000000000000000000013425375455011116 5ustar rootroothavp-0.93/etc/0000755000000000000000000000000013425371670011664 5ustar rootroothavp-0.93/etc/havp/0000755000000000000000000000000013425375424012623 5ustar rootroothavp-0.93/etc/havp/blacklist0000644000000000000000000000105213425374704014514 0ustar rootroot# # This is the blacklist file for HAVP # # All lines starting with a hash (#) or empty lines are ignored. # # Lines can hold URLs with wildcards with following rules: # Line must cointain Domain/Path # Domains can have a wildcard at begin. # Pages can hav a wildcard at begin and end. # URLs without wildcards are exact #e.g # www.havp.org (Only this URL is whitelisted) # www.havp.org/* (Domain is completely whitelisted) # *havp.org/index.html # */*.gif (All .gif are whitelisted) # www.havp.org/novirus* # www.havp.org/*novirus* havp-0.93/etc/havp/whitelist0000644000000000000000000000127513425374742014571 0ustar rootroot# # This is the whitelist file for HAVP # # All lines starting with a hash (#) or empty lines are ignored. # # Lines can hold URLs with wildcards with following rules: # Line must cointain Domain/Path # Domains can have a wildcard at begin. # Pages can hav a wildcard at begin and end. # URLs without wildcards are exact #e.g # www.havp.org (Only this URL is whitelisted) # www.havp.org/* (Domain is completely whitelisted) # *havp.org/index.html # */*.gif (All .gif are whitelisted) # www.havp.org/novirus* # www.havp.org/*novirus* # Whitelist clamav download *.sourceforge.net/*clamav-* # Whitelist Windowsupdate, so RANGE is allowed too *.microsoft.com/* *.windowsupdate.com/* havp-0.93/etc/havp/templates/0000755000000000000000000000000013425371670014620 5ustar rootroothavp-0.93/etc/havp/templates/fr/0000755000000000000000000000000013425374456015234 5ustar rootroothavp-0.93/etc/havp/templates/fr/error.html0000644000000000000000000000230413425374456017252 0ustar rootroot HAVP - Erreur interne
HAVP - Internal error
  HAVP


Une erreur interne est survenue
pendant l'analyse de cette page.






Contactez votre support technique


Votre nom de societé Powered by HAVP
havp-0.93/etc/havp/templates/fr/request.html0000644000000000000000000000210113425374456017604 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/fr/invalid.html0000644000000000000000000000211113425374456017543 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/fr/virus.html0000644000000000000000000000224013425374456017270 0ustar rootroot HAVP - Accès refusé
HAVP - Acces refusé
 
L'accès à cette page vous a été refusé

car ce virus à été détecté :





Votre nom de société Powered by HAVP
havp-0.93/etc/havp/templates/fr/down.html0000644000000000000000000000212613425374456017072 0ustar rootroot HAVP - Serveur inaccessible
HAVP
  HAVP


Le serveur ci-dessous ne répond pas:



Votre nom de société Powered by HAVP
havp-0.93/etc/havp/templates/fr/maxsize.html0000644000000000000000000000224613425374456017606 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/fr/scanner.html0000644000000000000000000000246613425374456017563 0ustar rootroot HAVP - Erreur de l'analyseur de virus
HAVP - Erreur de l'analyseur de virus
 
HAVP


L'analyseur de virus a rencontré un problème
durant son exécution.






Contactez votre support technique


 

Votre nom de société Powered by HAVP
havp-0.93/etc/havp/templates/fr/dns.html0000644000000000000000000000227113425374456016710 0ustar rootroot HAVP - Erreur DNS
HAVP - Erreur DNS
  HAVP


La page demandée ne peut être atteinte
en raison d'une erreur DNS






Contactez votre support technique


Votre nom de société Powered by HAVP
havp-0.93/etc/havp/templates/fr/blacklist.html0000644000000000000000000000224613425374456020076 0ustar rootroot HAVP - Accès Refusé
HAVP - Accès Refusé
 
L'accès à cette page a été

interdit par une décision administrative.





Votre nom de société ici. Powered by HAVP
havp-0.93/etc/havp/templates/it/0000755000000000000000000000000013425374463015237 5ustar rootroothavp-0.93/etc/havp/templates/it/error.html0000644000000000000000000000236413425374463017263 0ustar rootroot HAVP - Errore Interno HAVP
HAVP - Errore Interno
  HAVP


Si e' verificato un errore interno
durante la navigazione






Contattare il personale tecnico per assistenza


La Tua Azienda Powered by HAVP
havp-0.93/etc/havp/templates/it/request.html0000644000000000000000000000210113425374463017607 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/it/invalid.html0000644000000000000000000000211113425374463017546 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/it/virus.html0000644000000000000000000000234413425374463017300 0ustar rootroot HAVP - Accesso Negato
HAVP - Accesso negato
 
L'accesso alla pagina e' stato negato perche'

al suo interno e' stato rilevato il virus





La Tua Azienda Powered by HAVP
havp-0.93/etc/havp/templates/it/down.html0000644000000000000000000000226713425374463017103 0ustar rootroot HAVP - Server non Disponibile
HAVP - Server non Disponibile
  HAVP


Il seguente server non e' disponibile:







Contattare il personale tecnico per assistenza


La Tua Azienda Powered by HAVP
havp-0.93/etc/havp/templates/it/maxsize.html0000644000000000000000000000224613425374463017611 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/it/scanner.html0000644000000000000000000000254713425374463017566 0ustar rootroot HAVP - Errore scanner antivirus
HAVP - Errore scanner antivirus
 
HAVP


Si e' verificato un errore dello scanner
antivirus durante la navigazione






Contattare il personale tecnico per assistenza


 

La Tua Azienda Powered by HAVP
havp-0.93/etc/havp/templates/it/dns.html0000644000000000000000000000234413425374463016714 0ustar rootroot HAVP - Errore DNS
HAVP - Errore DNS
  HAVP


Si e' verificato un errore DNS
durante la navigazione






Contattare il personale tecnico per assistenza


La Tua Azienza Powered by HAVP
havp-0.93/etc/havp/templates/it/blacklist.html0000644000000000000000000000225713425374463020103 0ustar rootroot HAVP - Accesso Negato
HAVP - Accesso Negato
 
L'accesso alla pagina e' stato negato

La seguente pagina risulta inserita nella blacklist





La Tua Azienda Powered by HAVP
havp-0.93/etc/havp/templates/nl/0000755000000000000000000000000013425374466015237 5ustar rootroothavp-0.93/etc/havp/templates/nl/error.html0000644000000000000000000000233213425374466017256 0ustar rootroot HAVP - Interne fout
HAVP - Interner fout
  HAVP


Er is een interne HAVP-fout
opgetreden bij het scannen van de webpagina






Voor vragen neem contact op met uw systeemadministrator


Ihr bedrijfsnaam Powered by HAVP
havp-0.93/etc/havp/templates/nl/request.html0000644000000000000000000000210113425374466017607 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/nl/invalid.html0000644000000000000000000000211113425374466017546 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/nl/virus.html0000644000000000000000000000227113425374466017277 0ustar rootroot HAVP - Toegang geweigerd
HAVP - Toegang geweigerd
 
De toegang tot deze webpagina is geweigerd,

vanwege het bevatten van het volgende virus





Ihr bedrijfsnaam Powered by HAVP
havp-0.93/etc/havp/templates/nl/down.html0000644000000000000000000000213013425374466017070 0ustar rootroot HAVP - Server offline
HAVP - Server offline
  HAVP


De volgende server is offline:



Ihr bedrijfsnaam Powered by HAVP
havp-0.93/etc/havp/templates/nl/maxsize.html0000644000000000000000000000224613425374466017611 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/nl/scanner.html0000644000000000000000000000244513425374466017563 0ustar rootroot HAVP - Vius-scanner fout
HAVP - Virus-scanner fout
 
HAVP


Er is een fout opgetreden
bij het scannen van de webpaginaf






Voor vragen neem contact op met uw systeemadministrator


 

Ihr bedrijfsnaam Powered by HAVP
havp-0.93/etc/havp/templates/nl/dns.html0000644000000000000000000000230513425374466016711 0ustar rootroot HAVP - DNS fout
HAVP - DNS fout
  HAVP


Er is een DNS fout opgetreden
bij het openen van de webpagina






Voor vragen neem contact op met uw systeemadministrator


Ihr bedrijfsnaam Powered by HAVP
havp-0.93/etc/havp/templates/nl/blacklist.html0000644000000000000000000000225313425374466020077 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Accesss to the page has been denied

because the following page is blacklisted





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/ru/0000755000000000000000000000000013425374501015242 5ustar rootroothavp-0.93/etc/havp/templates/ru/error.html0000755000000000000000000000477613425374501017302 0ustar rootroot HAVP - Âíóòðåííÿÿ îøèáêà
HTTP Antivirus Proxy - HAVP
Ïðîèçîøëà âíóòðåííÿÿ îøèáêà
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Ïðîèçîøëà âíóòðåííÿÿ îøèáêà
ïðè ïðîñìîòðå ñòðàíèöû

havp-0.93/etc/havp/templates/ru/request.html0000755000000000000000000000510213425374501017621 0ustar rootroot HAVP - Íåêîððåêòíûé çàïðîñ
HTTP Antivirus Proxy - HAVP
Âàø çàïðîñ íåêîððåêòåí!
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Íå ìîãó îáðàáîòàòü çàïðîñ, òàê êàê îí ÿâëÿåòñÿ
ñèíòàêñè÷åñêè (ëåêñè÷åñêè) íåêîððåêòíûì.
Ïðîâåðüòå ññûëêó!

havp-0.93/etc/havp/templates/ru/invalid.html0000755000000000000000000000472613425374501017572 0ustar rootroot HAVP - Íåâåðíûå äàííûå
HTTP Antivirus Proxy - HAVP
Ïîëó÷åíû íåâåðíûå äàííûå
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Íà çàïðîñ HAVP îò ñåðâåðà áûëè ïîëó÷åíû íåâåðíûå äàííûå

havp-0.93/etc/havp/templates/ru/virus.html0000755000000000000000000000507513425374501017312 0ustar rootroot HAVP - Äîñòóï çàïðåù¸í
HTTP Antivirus Proxy - HAVP
Äîñòóï çàïðåù¸í
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Äîñòóï ê âåá-ñòðàíèöå áûë áëîêèðîâàí ïîòîìó, ÷òî â îòâåòå íà çàïðîñ ê íåé áûë îáíàðóæåí ñëåäóþùèé âèðóñ:

havp-0.93/etc/havp/templates/ru/down.html0000755000000000000000000000502713425374501017106 0ustar rootroot HAVP - Îøèáêà 503
HTTP Antivirus Proxy - HAVP
Ñåðâåð íå îòâå÷àåò
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Ïðåâûøåí èíòåðâàë îæèäàíèÿ îòâåòà óäàë¸ííîé ñèñòåìû.
Ñåðâåð ïåðåãðóæåí èëè íåäîñòóïåí

havp-0.93/etc/havp/templates/ru/maxsize.html0000644000000000000000000000224613425374501017614 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/ru/scanner.html0000755000000000000000000000516313425374501017571 0ustar rootroot HAVP - Îøèáêà àíòèâèðóñíîãî ñêàíåðà
HTTP Antivirus Proxy - HAVP
Îøèáêà àíòèâèðóñíîãî ñêàíåðà
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Îáíàðóæåíà êðèòè÷åñêàÿ îøèáêà ñêàíåðà âèðóñíûõ ñèãíàòóð ïðè îáðàáîòêå ñòðàíèöû

Îáÿçàòåëüíî ïðîêîíñóëüòèðóéòåñü ñî ñâîèì ñåòåâûì (ñèñòåìíûì) àäìèíèñòðàòîðîì!

havp-0.93/etc/havp/templates/ru/dns.html0000755000000000000000000000477313425374501016732 0ustar rootroot HAVP - Îøèáêà DNS
HTTP Antivirus Proxy - HAVP
Îøèáêà ïðè çàïðîñå ñëóæáû äîìåííûõ èì¸í
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Ïðîèçîøëà îøèáêà DNS ïðè ïîïûòêå îòêðûòü ñòðàíèöó

havp-0.93/etc/havp/templates/ru/blacklist.html0000755000000000000000000000503513425374501020106 0ustar rootroot HAVP - Äîñòóï çàïðåù¸í
HTTP Antivirus Proxy - HAVP
Äîñòóï çàïðåù¸í
Çäåñü äîëæíî áûòü íàçâàíèå Âàøåé êîìïàíèè

Äîñòóï ê âåá-ñòðàíèöå áûë áëîêèðîâàí ïîòîìó, ÷òî îíà áûëà çàíåñåíà Âàøèì àäìèíèñòðàòîðîì â ÷¸ðíûé ñïèñîê

havp-0.93/etc/havp/templates/sv/0000755000000000000000000000000013425374504015247 5ustar rootroothavp-0.93/etc/havp/templates/sv/error.html0000644000000000000000000000226613425374504017274 0ustar rootroot HAVP - Internt fel
HAVP - Internt fel
  HAVP


Ett internt fel har uppstått
när sidan skannades






Kontakta teknisk support


Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/request.html0000644000000000000000000000215113425374504017624 0ustar rootroot HAVP - Okänd förfrågan
HAVP
  HAVP


Förfrågan ä okänd:



Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/invalid.html0000644000000000000000000000213613425374504017565 0ustar rootroot HAVP - Server Datat är ogiltigt
HAVP
  HAVP


Server datat är ogiltigt:



Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/virus.html0000644000000000000000000000232413425374504017306 0ustar rootroot HAVP - Tillträde Förbjudet
HAVP - Access Denied
 
Tillträde till sidan har stoppats

på grund av att följande virus har upptäckts





Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/down.html0000644000000000000000000000212613425374504017105 0ustar rootroot HAVP - Server svarar inte
HAVP
  HAVP


Följande server svarar inte:



Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/maxsize.html0000644000000000000000000000224613425374504017621 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/sv/scanner.html0000644000000000000000000000243613425374504017573 0ustar rootroot HAVP - Virus skanner fel
HAVP - Virus skanner fel
 
HAVP


Ett virus skanner fel har uppstått
när följande skannades






Kontakta teknisk support


 

Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/dns.html0000644000000000000000000000225413425374504016724 0ustar rootroot HAVP - DNS fel
HAVP - DNS fel
  HAVP


Ett DNS fel har uppstått
när sidan öppnades






Kontakta teknisk support


Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/sv/blacklist.html0000644000000000000000000000233313425374504020106 0ustar rootroot HAVP - Tillträde Förbjudet
HAVP - Tillträde Förbjudet
 
Tillträde till sidan har nekats

på grund av att sidan är svartlistad





Ert Företag Här Powered by HAVP
havp-0.93/etc/havp/templates/de/0000755000000000000000000000000013425374426015212 5ustar rootroothavp-0.93/etc/havp/templates/de/error.html0000644000000000000000000000230113425374426017225 0ustar rootroot HAVP - Interner Fehler
HAVP - Interner Fehler
  HAVP


Ein interner HAVP-Fehler
trat beim Scannen der Seite auf






Bitte fragen Sie Ihren Systemadministrator


Ihr Firmenname Powered by HAVP
havp-0.93/etc/havp/templates/de/request.html0000644000000000000000000000210113425374426017562 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/de/invalid.html0000644000000000000000000000211113425374426017521 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/de/virus.html0000644000000000000000000000226213425374426017252 0ustar rootroot HAVP - Zugriff verweigert
HAVP - Zugriff verweigert
 
Der Zugriff auf die Seite wurde

verweigert, weil folgender Virus gefunden wurde





Ihr Firmenname Powered by HAVP
havp-0.93/etc/havp/templates/de/down.html0000644000000000000000000000211613425374426017047 0ustar rootroot HAVP - Server Down
HAVP- Server Down
  HAVP


Der folgende Server ist down:



Ihr Firmenname Powered by HAVP
havp-0.93/etc/havp/templates/de/maxsize.html0000644000000000000000000000224613425374426017564 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/de/scanner.html0000644000000000000000000000243113425374426017531 0ustar rootroot HAVP - Viren-Scanner Fehler
HAVP - Viren-Scanner Fehler
 
HAVP


Während des Scannens trat ein
Fehler im Viren-Scanner auf






Bitte fragen Sie Ihren Systemadministrator


 

Ihr Firmenname Powered by HAVP
havp-0.93/etc/havp/templates/de/dns.html0000644000000000000000000000226213425374426016666 0ustar rootroot HAVP - DNS Fehler
HAVP - DNS Fehler
  HAVP


Ein DNS Fehler trat während
des Öffnens der Seite auf






Bitte fragen Sie Ihren Systemadministrator


Ihr Firmenname Powered by HAVP
havp-0.93/etc/havp/templates/de/blacklist.html0000644000000000000000000000227413425374426020055 0ustar rootroot HAVP - Access Denied
HAVP - Zugriff Verweigert!
 
Der Zugriff auf diese Seite wurde verweigert!

Die folgende Seite steht auf der Blacklist





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/es/0000755000000000000000000000000013425374441015226 5ustar rootroothavp-0.93/etc/havp/templates/es/error.html0000644000000000000000000000234513425374441017251 0ustar rootroot HAVP - Internal error
HAVP - Error interno
  HAVP


Ha ocurrido un error interno
al escanear la página






Por favor, contacte a su soporte técnico


Su compañía aquí Powered by HAVP
havp-0.93/etc/havp/templates/es/request.html0000644000000000000000000000210113425374441017576 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/es/invalid.html0000644000000000000000000000211113425374441017535 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/es/virus.html0000644000000000000000000000231613425374441017266 0ustar rootroot HAVP - Access Denied
HAVP - Acceso denegado
 
El acceso a la pagina ha sido denegado

porque se encontró el virus siguiente





Su compañía aquí Powered by HAVP
havp-0.93/etc/havp/templates/es/down.html0000644000000000000000000000216213425374441017064 0ustar rootroot HAVP - Server Down
HAVP
  HAVP


El servidor siguiente está caido:



Su compañía aquí Powered by HAVP
havp-0.93/etc/havp/templates/es/maxsize.html0000644000000000000000000000224613425374441017600 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/es/scanner.html0000644000000000000000000000252413425374441017550 0ustar rootroot HAVP - Virus scanner error
HAVP - Error del escaner de virus
 
HAVP


Ha ocurrido un error en el escaner de virus
al escanear la página






Por favor, contacte a su soporte técnico


 

Su  compañía aquí Powered by HAVP
havp-0.93/etc/havp/templates/es/dns.html0000644000000000000000000000233213425374441016700 0ustar rootroot HAVP - DNS error
HAVP - Error de DNS
  HAVP


A ocurrido un error de DNS
al abrir la página






Por favor, contacte a su soporte técnico


Su compañía aquí Powered by HAVP
havp-0.93/etc/havp/templates/es/blacklist.html0000644000000000000000000000225313425374441020066 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Accesss to the page has been denied

because the following page is blacklisted





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/0000755000000000000000000000000013425374400015215 5ustar rootroothavp-0.93/etc/havp/templates/br/error.html0000644000000000000000000000225513425374370017246 0ustar rootroot HAVP - Erro interno
HAVP - Erro interno
  HAVP


Um erro interno ocorreu
enquanto escaneava a pagina






Entre em contato com o suporte


Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/request.html0000644000000000000000000000210113425374370017573 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/invalid.html0000644000000000000000000000211113425374370017532 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/virus.html0000644000000000000000000000224313425374370017262 0ustar rootroot HAVP - Acesso negado
HAVP - Acesso negado
 
O acesso a esta pagina foi negado

pois o seguinte virus foi detectado





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/down.html0000644000000000000000000000212013425374370017053 0ustar rootroot HAVP - Servidor offline
HAVP
  HAVP


O seguinte servidor está inacessivel:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/maxsize.html0000644000000000000000000000224613425374370017575 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/scanner.html0000644000000000000000000000240313425374370017541 0ustar rootroot HAVP - Erro no antivirus
HAVP - Erro no antivirus
 
HAVP


Um erro no antivirus ocorreu
enquanto escaneava






Entre em contato com o suporte


 

Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/dns.html0000644000000000000000000000225513425374370016701 0ustar rootroot HAVP - Erro de DNS
HAVP - Erro de DNS
  HAVP


Um erro de DNS ocorreu
enquanto tentava acessar a pagina






Entre em contato com o suporte


Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/br/blacklist.html0000644000000000000000000000225013425374370020060 0ustar rootroot HAVP - Acesso negado
HAVP - Acesso negado
 
O acesso a esta pagina foi negado

pois ela esta na lista-negra do servidor





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/0000755000000000000000000000000013425374434015223 5ustar rootroothavp-0.93/etc/havp/templates/en/error.html0000644000000000000000000000226213425374434017244 0ustar rootroot HAVP - Internal error
HAVP - Internal error
  HAVP


An internal error occurred
while scanning the page






Please contact your tech support


Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/request.html0000644000000000000000000000210113425374434017573 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/invalid.html0000644000000000000000000000211113425374434017532 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/virus.html0000644000000000000000000000225113425374434017261 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following virus was detected





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/down.html0000644000000000000000000000210313425374434017054 0ustar rootroot HAVP - Server Down
HAVP
  HAVP


The following server is down:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/maxsize.html0000644000000000000000000000224613425374434017575 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/scanner.html0000644000000000000000000000240613425374434017544 0ustar rootroot HAVP - Virus scanner error
HAVP - Virus scanner error
 
HAVP


A virus scanner error occurred
while scanning






Please contact your tech support


 

Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/dns.html0000644000000000000000000000223613425374434016700 0ustar rootroot HAVP - DNS error
HAVP - DNS error
  HAVP


A DNS error occurred
while opening the page






Please contact your tech support


Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/en/blacklist.html0000644000000000000000000000225213425374434020062 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is blacklisted





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pf/0000755000000000000000000000000013425374472015230 5ustar rootroothavp-0.93/etc/havp/templates/pf/error.html0000644000000000000000000000235113425374472017250 0ustar rootroot HAVP - innedrinn kaputt
HAVP - innedrinn kaputt
  HAVP


E innerer HAVP-Fehler is
beim Scanne vunn de Seit ufgeträte. So e Schlamperei!






Froh denne Trottel der fer die Compjuter zustännig is!

De Name vunn eierm Lade Powered by HAVP
havp-0.93/etc/havp/templates/pf/request.html0000644000000000000000000000210113425374472017600 0ustar rootroot HAVP - Unknown Request
HAVP
  HAVP


The request is unknown:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pf/invalid.html0000644000000000000000000000211113425374472017537 0ustar rootroot HAVP - Server Data Invalid
HAVP
  HAVP


The server data is invalid:



Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pf/virus.html0000644000000000000000000000227613425374472017275 0ustar rootroot HAVP - loss die Finger weck
HAVP - loss die Finger weck
 
Uff die Seit haschte kä Zugriff,

weil so e Krankheitserrecher gefunn worr is





De Name vunn eierm Lade Powered by HAVP
havp-0.93/etc/havp/templates/pf/down.html0000644000000000000000000000212713425374471017066 0ustar rootroot HAVP - Server unne
HAVP - Server unne
  HAVP


De folchende Server ist unne:



De Name vunn eierm Lade Powered by HAVP
havp-0.93/etc/havp/templates/pf/maxsize.html0000644000000000000000000000224613425374472017602 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pf/scanner.html0000644000000000000000000000246313425374472017554 0ustar rootroot HAVP - de Vire-Scanner is kaputt
HAVP - Vire-Scanner is kaputt
 
HAVP


Währemd Scanne is de
Vire-Scanner kaputt gegange. Na, so was.






Froh denne Trottel der fer die Compjuter zustännig is!

 

De Name vunn eierm Lade Powered by HAVP
havp-0.93/etc/havp/templates/pf/dns.html0000644000000000000000000000232613425374471016704 0ustar rootroot HAVP - DNS Fehler
HAVP - DNS Fehler
  HAVP


E DNS (Domän Näm Servis) Fähler is uffgeträt währemd
Öffne vunde Seit






Froh denne Trottel der fer die Compjuter zustännig is!


De Name vunn eierm Lade Powered by HAVP
havp-0.93/etc/havp/templates/pf/blacklist.html0000644000000000000000000000225313425374471020067 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Accesss to the page has been denied

because the following page is blacklisted





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pl/0000755000000000000000000000000013425374475015241 5ustar rootroothavp-0.93/etc/havp/templates/pl/error.html0000644000000000000000000000242513425374475017263 0ustar rootroot HAVP - B³±d wewnêtrzny
HAVP - B³±d wewnêtrzny
  HAVP


Wyst±pi³ b³±d wewnêtrzny
podczas skanowania poni¿szej strony






Proszê skontaktowaæ siê z pomoc± techniczn±


Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/request.html0000644000000000000000000000221413425374475017616 0ustar rootroot HAVP - Nieznane zapytanie
HAVP
  HAVP


Nieznane zapytanie:



Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/invalid.html0000644000000000000000000000223513425374475017557 0ustar rootroot HAVP - B³±d danych serwera
HAVP
  HAVP


B³êdne dane przes³ane przez serwer:



Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/virus.html0000644000000000000000000000237713425374475017310 0ustar rootroot HAVP - Dostêp zablokowany
HAVP - Dostêp zablokowany
 
Dostêp do tej strony zosta³ zablokowany

poniewa¿ znaleziono na niej wirusa





Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/down.html0000644000000000000000000000223113425374475017074 0ustar rootroot HAVP - Serwer nie odpowiada
HAVP
  HAVP


Poni¿szy serwer nie odpowiada:



Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/maxsize.html0000644000000000000000000000224613425374475017613 0ustar rootroot HAVP - Access Denied
HAVP - Access Denied
 
Access to the page has been denied

because the following page is to large





Your Company Here Powered by HAVP
havp-0.93/etc/havp/templates/pl/scanner.html0000644000000000000000000000256713425374475017572 0ustar rootroot HAVP - B³±d skanera antywirusowego
HAVP - B³±d skanera antywirusowego
 
HAVP


Wyst±pi³ b³±d skanera antywirusowego
podczas skanowania






Proszê skontaktowaæ siê z pomoc± techniczn±


 

Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/dns.html0000644000000000000000000000236413425374475016720 0ustar rootroot HAVP - B³±d DNS
HAVP - b³±d DNS
  HAVP


Wyst±pi³ b³±d DNS
w czasie otwierania strony






Prosze skontaktowaæ siê z pomoc± techniczn±


Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/pl/blacklist.html0000644000000000000000000000241013425374475020074 0ustar rootroot HAVP - Dostêp zablokowany
HAVP - Dostêp zablokowany
 
Dostêp do tej strony zosta³ zablokowany

poniewa¿ znajduje siê ona na czarnej li¶cie





Tu wpisz nazwê firmy Powered by HAVP
havp-0.93/etc/havp/templates/css2/0000755000000000000000000000000013425374415015472 5ustar rootroothavp-0.93/etc/havp/templates/css2/havp.css0000644000000000000000000000323513425374415017145 0ustar rootroot havp-0.93/etc/havp/havp.config.in0000644000000000000000000003652013425374704015363 0ustar rootroot# # This is the configuration file for HAVP # # All lines starting with a hash (#) or empty lines are ignored. # Uncomment parameters you want to change! # # All parameters configurable in this file are explained and their default # values are shown. If no default value is defined "NONE" is specified. # # General syntax: Parameter Value # Value can be: true/false, number, or path # # Extra spaces and tabs are ignored. # # This line must me remove or a comment for HAVP to start. # Hint: You must enable some scanner! Find them in the end.. # ClamAV is enabled by default. So maybe you don't need to change this file. # REMOVETHISLINE deleteme # # For reasons of security it is recommended to run a proxy program # without root rights. It is recommended to create user that is not # used by any other program. # # Default: # USER havp # GROUP havp # If this is true HAVP is running as daemon in background. # For testing you may run HAVP at your text console. # # Default: # DAEMON true # # Process id (PID) of the main HAVP process is written to this file. # Be sure that it is writeable by the user under which HAVP is running. # /etc/init.d/havp script requires this to work. # # Default: # PIDFILE @localstatedir@/run/havp/havp.pid # # For performance reasons several instances of HAVP have to run. # Specify how many servers (child processes) are simultaneously # listening on port PORT for a connection. Minimum value should be # the peak requests-per-second expected + 5 for headroom. For best # performance, you should have atleast 1 CPU core per 16 processes. # # For single user home use, 8 should be minimum. # For 500+ users corporate use, start at 40. # # Value can and should be higher than recommended. Memory and # CPU usage is only affected by the number of concurrent requests. # # More childs are automatically created when needed, up to MAXSERVERS. # # Default: # SERVERNUMBER 8 # MAXSERVERS 100 # # Files where to log requests and info/errors. # Needs to have write permission for HAVP user. # # Default: # ACCESSLOG @localstatedir@/log/havp/access.log # ERRORLOG @localstatedir@/log/havp/havp.log # VIRUSLOG (same as ACCESSLOG) # # Format for timestamps in logfile messages. # See: man strftime # # Default: # TIMEFORMAT %d/%m/%Y %H:%M:%S # # Syslog can be used instead of logging to file. # For facilities and levels, see "man syslog". # # Default: # USESYSLOG false # SYSLOGNAME havp # SYSLOGFACILITY daemon # SYSLOGLEVEL info # SYSLOGVIRUSLEVEL warning # # true: Log every request to access log # false: Log only viruses to access log # # Default: # LOG_OKS true # # Level of HAVP logging # 0 = Only serious errors and information # 1 = Less interesting information is included # # Default: # LOGLEVEL 0 # # Temporary scan file. # This file must reside on a partition for which mandatory # locking is enabled. For Linux, use "-o mand" in mount command. # See "man mount" for details. Solaris does not need any special # steps, it works directly. # # Specify absolute path to a file which name must contain "XXXXXX". # These characters are used by system to create unique named files. # # Default: # SCANTEMPFILE /var/spool/havp/havp-XXXXXX # # Directory for ClamAV and other scanner created tempfiles. # Needs to be writable by HAVP user. Use ramdisk for best performance. # # Default: # TEMPDIR /var/tmp # # HAVP reloads scanners virus database by receiving a signal # (send SIGHUP to PID from PIDFILE, see "man kill") or after # a specified period of time. Specify here the number of # minutes to wait for reloading. # # This only affects library scanners (clamlib, trophie). # Other scanners must be updated manually. # # Default: # DBRELOAD 60 # # Run HAVP as transparent Proxy? # # If you don't know what this means read the mini-howto # TransparentProxy written by Daniel Kiracofe. # (e.g.: http://www.tldp.org/HOWTO/TransparentProxy.html) # Definitely you have more to do than setting this to true. # You are warned! # # Default: # TRANSPARENT false # # Specify a parent proxy (e.g. Squid) HAVP should use. # If needed, user and password authentication can be used, # but only Basic-authentication scheme is supported. # # Default: NONE # PARENTPROXY localhost # PARENTPORT 3128 # PARENTUSER username # PARENTPASSWORD password # # Write X-Forwarded-For: to log instead of connecters IP? # # If HAVP is used as parent proxy by some other proxy, this allows # to write the real users IP to log, instead of proxy IP. # # Default: # FORWARDED_IP false # # Send X-Forwarded-For: header to servers? # # If client sent this header, FORWARDED_IP setting defines the value, # then it is passed on. You might want to keep this disabled for security # reasons. Enable this if you use your own parent proxy after HAVP, so it # will see the original client IP. # # Disabling this also disables Via: header generation. # # Default: # X_FORWARDED_FOR false # # Port HAVP is listening on. # # Default: # PORT 8080 # # IP address that HAVP listens on. # Let it be undefined to bind all addresses. # # Default: NONE # BIND_ADDRESS 127.0.0.1 # # IP address used for sending outbound packets. # Let it be undefined if you want OS to handle right address. # # Default: NONE # SOURCE_ADDRESS 1.2.3.4 # SSLTIMEOUT - Number of seconds to wait for SSL timeout # # Default: 20 # SSLTIMEOUT 20 # # Path to template files. # # Default: # TEMPLATEPATH @sysconfdir@/havp/templates/en # # Set to true if you want to prefer Whitelist. # If URL is Whitelisted, then Blacklist is ignored. # Otherwise Blacklist is preferred. # # Default: # WHITELISTFIRST true # # List of URLs not to scan. # # Default: # WHITELIST @sysconfdir@/havp/whitelist # # List of URLs that are denied access. # # Default: # BLACKLIST @sysconfdir@/havp/blacklist # # Is scanner error fatal? # # For example, archive types that are not supported by scanner # may return error. Also if scanner has invalid pattern files etc. # # true: User gets error page # false: No error is reported (viruses might not be detected) # # Default: # FAILSCANERROR true # # When scanning takes longer than this, it will be aborted. # Timer is started after HAVP has fully received all data. # If set too low, complex files/archives might produce timeout. # Timeout is always a fatal error regardless of FAILSCANERROR. # # Time in minutes! # # Default: # SCANNERTIMEOUT 10 # # Allow HTTP Range requests? # # false: Broken downloads can NOT be resumed # true: Broken downloads can be resumed # # Allowing Range is a security risk, because partial # HTTP requests may not be properly scanned. # # Whitelisted sites are allowed to use Range in any case. # # Default: # RANGE false # # Allow HTTP Range request to get the ZIP header first? # # This allows (partial) scanning of ZIP files that are bigger than # MAXSCANSIZE. Scanning is done up to that many bytes into the file. # # Default: # PRELOADZIPHEADER true # # If you really need more performance, you can disable scanning of # JPG, GIF and PNG files. These are probably the most common files # around, so it will save lots of CPU. But be warned, image exploits # exist and more could be found. Think twice if you want to disable! # # In addition of checking Content-Type: image/*, this setting uses # file magic to make sure the file is really image. # # Also see SCANMIME/SKIPMIME settings to control scanning based # on just the Content-Type header. # # Default: # SCANIMAGES true # # What MIME types NOT to scan. For performance reasons, you could # exclude all media types. # # Based on Content-Type: header as given by the HTTP server. # Note that it is easy to forge and should not be trusted. # # Basic wildcard match supported. # # Default: NONE # SKIPMIME image/* video/* audio/* # # If set, then ONLY these MIME types will be scanned. # # Based on Content-Type: header as given by the HTTP server. # Note that it is easy to forge and should not be trusted. # # Basic wildcard match supported. # # Default: NONE # SCANMIME application/* # # Temporary file will grow only up to this size. This means scanner # will scan data until this limit is reached. # # There are two sides to this setting. By limiting the size, you gain # performance, less waiting for big files and less needed temporary space. # But there is slightly higher chance of virus slipping through (though # scanning large archives should not be gateways function, HAVP is more # geared towards small exploit detection etc). # # VALUE IN BYTES NOT KB OR MB!!!! # 0 = No size limit # # Default: # MAXSCANSIZE 5000000 # # Amount of data going to browser that is held back, until it # is scanned. When we know file is clean, this held back data # can be sent to browser. You can safely set bigger value, only # thing you will notice is some "delay" in beginning of download. # Virus found in files bigger than this might not produce HAVP # error page, but result in a "broken" download. # # VALUE IN BYTES NOT KB OR MB!!!! # # Default: # KEEPBACKBUFFER 200000 # # This setting complements KEEPBACKBUFFER. It tells how many Seconds to # initially receive data from server, before sending anything to client. # Even trickling is not done before this time elapses. This way files that # are received fast are more secure and user can get virus report page for # files bigger than KEEPBACKBUFFER. # # Setting to 0 will disable this, and only KEEPBACKBUFFER is used. # # Default: # KEEPBACKTIME 5 # # After Trickling Time (seconds), some bytes are sent to browser # to keep the connection alive. Trickling is not needed if timeouts # are not expected for files smaller than KEEPBACKBUFFER, but it is # recommended to set anyway. # # 0 = No Trickling # # Default: # TRICKLING 30 # # Send this many bytes to browser every TRICKLING seconds, see above # # Default: # TRICKLINGBYTES 1 # # Downloads larger than MAXDOWNLOADSIZE will be blocked. # Only if not Whitelisted! # # VALUE IN BYTES NOT KB OR MB!!!! # 0 = Unlimited Downloads # # Default: # MAXDOWNLOADSIZE 0 # # Space separated list of strings to partially match User-Agent: header. # These are used for streaming content, so scanning is generally not needed # and tempfiles grow unnecessary. Remember when enabled, that user could # fake header and pass some scanning. HTTP Range requests are allowed for # these, so players can seek content. # # You can uncomment here a list of most popular players. # # Default: NONE # STREAMUSERAGENT Player Winamp iTunes QuickTime Audio RMA/ MAD/ Foobar2000 XMMS # # Bytes to scan from beginning of streams. # When set to 0, STREAMUSERAGENT scanning will be completely disabled. # It is not recommended as there are some exploits for players. # # Default: # STREAMSCANSIZE 20000 # # Disable mandatory locking (dynamic scanning) for certain file types. # This is intended for fixing cases where a scanner forces use of mmap() # call. Mandatory locking might not allow this, so you could get errors # regarding memory allocation or I/O. You can test the "None" option # anyway, as it might even work depending on your OS (some Linux seems # to allow mand+mmap). # # Allowed values: # None # ClamAV:BinHex (mmap forced in versions older than 0.96) # ClamAV:PDF (mmap forced in versions older than 0.96) # ClamAV:ZIP (mmap forced in 0.93.x, should work in 0.94) # AVG:ALL (AVG 8.5 does not work, uses mmap MAP_SHARED) # # Default: # DISABLELOCKINGFOR AVG:ALL # # Whitelist specific viruses by case-insensitive substring match. # For example, "Oversized." and "Encrypted." are good candidates, # if you can't disable those checks any other way. # # Default: NONE # IGNOREVIRUS Oversized. Encrypted. Phishing. ##### ##### ClamAV Library Scanner (libclamav) ##### ENABLECLAMLIB true # HAVP uses libclamav hardcoded pattern directory, which usually is # /usr/share/clamav. You only need to set CLAMDBDIR, if you are # using non-default DatabaseDirectory setting in clamd.conf. # # Default: NONE # CLAMDBDIR /var/lib/clamav # Should we block broken executables? # # Default: # CLAMBLOCKBROKEN false # Should we block encrypted archives? # # Default: # CLAMBLOCKENCRYPTED false # Should we block files that go over maximum archive limits? # # Default: # CLAMBLOCKMAX false # Scanning limits? # You can find some additional info from documentation or clamd.conf # # Stop when this many total bytes scanned (MB) # CLAMMAXSCANSIZE 20 # # Stop when this many files have been scanned # CLAMMAXFILES 50 # # Don't scan files over this size (MB) # CLAMMAXFILESIZE 100 # # Maximum archive recursion # CLAMMAXRECURSION 8 ##### ##### ClamAV Socket Scanner (clamd) ##### ##### NOTE: ClamAV Library Scanner should be preferred (less overhead) ##### ENABLECLAMD false # Path to clamd socket # # Default: # CLAMDSOCKET /var/run/clamav/clamd.ctl # ..OR if you use clamd TCP socket, uncomment to enable use # # Clamd daemon needs to run on the same server as HAVP # # Default: NONE # CLAMDSERVER 127.0.0.1 # CLAMDPORT 3310 ##### ##### F-Prot Socket Scanner ##### ENABLEFPROT false # F-Prot daemon needs to run on same server as HAVP # # Default: # FPROTSERVER 127.0.0.1 # FPROTPORT 10200 # F-Prot options (only for version 6+ !) # # See "fpscand-client.sh --help" for possible options. # # At the moment: # --scanlevel= Which scanlevel to use, 0-4 (2). # --heurlevel= How aggressive heuristics should be used, 0-4 (2). # --archive= Scan inside supported archives n levels deep 1-99 (5). # --adware Instructs the daemon to flag adware. # --applications Instructs the daemon to flag potentially unwanted applications. # # Default: NONE # FPROTOPTIONS --scanlevel=2 --heurlevel=2 ##### ##### AVG Socket Scanner ##### ENABLEAVG false # AVG daemon needs to run on the same server as HAVP # # Default: # AVGSERVER 127.0.0.1 # AVGPORT 55555 ##### ##### Kaspersky Socket Scanner ##### ENABLEAVESERVER false # Path to aveserver socket # # Default: # AVESOCKET /var/run/aveserver ##### ##### Sophos Scanner (Sophie) ##### ENABLESOPHIE false # Path to sophie socket # # Default: # SOPHIESOCKET /var/run/sophie ##### ##### Trend Micro Library Scanner (Trophie) ##### ENABLETROPHIE false # Scanning limits inside archives (filesize = MB): # # Default: # TROPHIEMAXFILES 50 # TROPHIEMAXFILESIZE 10 # TROPHIEMAXRATIO 250 ##### ##### NOD32 Socket Scanner ##### ENABLENOD32 false # Path to nod32d socket # # For 3.0+ version, try /tmp/esets.sock # # Default: # NOD32SOCKET /tmp/nod32d.sock # Used NOD32 Version # # 30 = 3.0+ # 25 = 2.5+ # 21 = 2.x (very old) # # Default: # NOD32VERSION 25 ##### ##### Avast! Socket Scanner ##### ENABLEAVAST false # Path to avastd socket # # Default: # AVASTSOCKET /var/run/avast4/local.sock # ..OR if you use avastd TCP socket, uncomment to enable use # # Avast daemon needs to run on the same server as HAVP # # Default: NONE # AVASTSERVER 127.0.0.1 # AVASTPORT 5036 ##### ##### Arcavir Socket Scanner ##### ENABLEARCAVIR false # Path to arcavird socket # # For version 2008, default socket is /var/run/arcad.ctl # # Default: # ARCAVIRSOCKET /var/run/arcavird.socket # Used Arcavir version # 2007 = Version 2007 and earlier # 2008 = Version 2008 and later # # Default: # ARCAVIRVERSION 2007 ##### ##### DrWeb Socket Scanner ##### ENABLEDRWEB false # Enable heuristic scanning? # # Default: # DRWEBHEURISTIC true # Enable malware detection? # (Adware, Dialer, Joke, Riskware, Hacktool) # # Default: # DRWEBMALWARE true # Path to drwebd socket # # Default: # DRWEBSOCKET /var/drweb/run/.daemon # ..OR if you use drwebd TCP socket, uncomment to enable use # # DrWeb daemon needs to run on the same server as HAVP # # Default: NONE # DRWEBSERVER 127.0.0.1 # DRWEBPORT 3000 havp-0.93/etc/init.d/0000755000000000000000000000000013425371670013051 5ustar rootroothavp-0.93/etc/init.d/havp0000755000000000000000000000446413425371670013745 0ustar rootroot#!/bin/sh # # #### # This init-script tries to be LSB conform but platform independent. # # Therefore check the following two variables to fit to your requests: # HAVP_BIN HAVP_CONFIG PIDFILE # Any configuration of HAVP is done in havp.config # Type havp --help for help and read havp.config you should have received. HAVP_BIN=/usr/local/sbin/havp HAVP_CONFIG=/usr/local/etc/havp/havp.config PIDFILE=/var/run/havp/havp.pid # Return values acc. to LSB for all commands but status: # 1 generic or unspecified error (current practice) # 2 invalid or excess argument(s) # 3 unimplemented feature (for example, "reload") # 4 user had insufficient privilege # 5 program is not installed # 6 program is not configured # 7 program is not running # 8-99 reserved for future LSB use # 100-149 reserved for distribution use # 150-199 reserved for application use # 200-254 reserved # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signaling is not supported) are # considered a success. reload_havp() { echo "Reloading HAVP ..." PID="`cat $PIDFILE`" if [ "$PID" != "" ]; then kill -HUP "$PID" >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: HAVP not running" exit 1 fi else echo "Error: HAVP not running or PIDFILE not readable" exit 1 fi exit 0 } case "$1" in start) echo "Starting HAVP ..." if [ ! -f $HAVP_BIN ]; then echo "Error: $HAVP_BIN not found" exit 5 fi $HAVP_BIN -c $HAVP_CONFIG exit $? ;; stop) echo "Shutting down HAVP ..." if [ ! -f "$PIDFILE" ]; then echo "Error: HAVP not running or PIDFILE unreadable" exit 1 fi PID="`cat $PIDFILE`" if [ "$PID" != "" ]; then kill -TERM "$PID" >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: HAVP not running" exit 1 fi else echo "Error: HAVP not running or PIDFILE unreadable" exit 1 fi sleep 2 exit 0 ;; restart) echo "Shutting down HAVP ..." $0 stop >/dev/null 2>&1 $0 start exit $? ;; reload-lists) reload_havp ;; force-reload) reload_havp ;; reload) reload_havp ;; status) echo "Checking for service HAVP ..." exit 4 ;; *) echo "Usage: $0 {start|stop|status|restart|force-reload|reload|reload-lists}" exit 0 ;; esac havp-0.93/update-conf0000755000000000000000000000157413425371670013253 0ustar rootroot#!/bin/sh # # This script copies havp.config.default to havp.config, # while keeping user set values # # Command: update-conf /usr/local/etc/havp/havp.config # # Default config must be found: /usr/local/etc/havp/havp.config.default # if [ ! -f "$1" ]; then exit 0; fi if [ ! -f "$1.default" ]; then exit 0; fi cp "$1" "$1.old" perl -e ' open(OLDCONF, "$ARGV[0]") or die; while () { chomp; unless ( /^\s*?#/ || /^\s*$/ ) { if ( /\s*?(\S+?)\s+?(.+)\s*$/ ) { $conf{$1} = $2; } } } close(OLDCONF); open(NEWCONF, "$ARGV[0].default") or die; open(REPCONF, ">$ARGV[0].tmp") or die; while () { foreach $key (keys %conf) { if ( /^(\# )?$key / ) { print REPCONF "$key $conf{$key}\n" or die; goto END; } } print REPCONF $_ or die; END: } close(REPCONF); close(NEWCONF); rename("$ARGV[0].tmp", "$ARGV[0]") or die; ' $1 havp-0.93/configure.in0000644000000000000000000001117213425371670013424 0ustar rootroot AC_INIT(havp) dnl This ksh/zsh feature conflicts with `cd blah ; pwd` unset CDPATH AC_PROG_CXX AC_PREFIX_DEFAULT(/usr/local) AC_CONFIG_HEADER(havp/_default.h) AC_ARG_ENABLE(locking,[ --disable-locking Disable mandatory locking (not needed on Linux/Solaris system)], enable_locking=$enableval, enable_locking=yes) AC_ARG_ENABLE(ssl-tunnel,[ --enable-ssl-tunnel Enable SSL proxying (not scanned, only forwarded!)], enable_ssl_tunnel=$enableval, enable_ssl_tunnel=no) AC_ARG_ENABLE(clamav,[ --disable-clamav Disable ClamAV libclamav support (clamd is supported anyway)], enable_clamav=$enableval, enable_clamav=yes) AC_ARG_ENABLE(trophie,[ --disable-trophie Disable Trend Micro Library (Trophie) support], enable_trophie=$enableval, enable_trophie=yes) AC_CHECK_PROG(AR, ar, ar, no) if test "$AR" = "no"; then AC_MSG_ERROR([ar not found in PATH]) fi AC_CHECK_PROG(PERL, perl, perl, no) AC_SYS_LARGEFILE AC_CHECK_FUNCS(initgroups setgroups) if test "$PERL" = "no"; then AC_MSG_ERROR([perl not found in PATH]) fi AC_MSG_CHECKING(OS) os="`uname`" case $os in Linux*) AC_MSG_RESULT(Linux) mandatory=yes ;; SunOS*) AC_MSG_RESULT(Solaris) mandatory=yes OSLIBS="-lsocket -lresolv -lnsl" ;; *) AC_MSG_RESULT($os) mandatory=no ;; esac AC_MSG_CHECKING(for mandatory locking support) if test "$enable_locking" = "no" then AC_MSG_RESULT([disabled, no dynamic scanning!]) AC_DEFINE(NOMAND, 1, [Do not use mandatory locking]) else if test "$mandatory" = "yes" then AC_MSG_RESULT([OS supported]) else AC_MSG_RESULT([OS not supported]) echo "" echo " Mandatory locking only works on Linux and Solaris." echo "" echo " You are running $os, so you must rerun configure" echo " with --disable-locking option." echo "" echo " This means you cannot use dynamic scanning features" echo " like KEEPBACKBUFFER. Everything is downloaded fully" echo " and only then sent to client." echo "" exit 1 fi fi if test "$enable_ssl_tunnel" = "yes" then AC_DEFINE(SSLTUNNEL, 1, [Use SSL tunnel]) fi AC_MSG_CHECKING(for ClamAV scanner library) if test "$enable_clamav" = "yes" then clamprefix="`clamav-config --prefix 2>/dev/null`" clamversion="`clamav-config --version 2>/dev/null`" if test "x$clamprefix" = "x" then AC_MSG_RESULT([clamav-config not found]) echo "" echo " Error finding ClamAV installation!" echo " Add ClamAV binaries path to PATH and run configure again." echo "" echo " To disable ClamAV library support, use --disable-clamav." echo "" exit 1 fi for cl in `clamav-config --cflags 2>/dev/null`; do if test "x`echo $cl | perl -ne 'print if (/^-I/)' 2>/dev/null`" != "x" then CFLAGS="$CFLAGS $cl" fi done for cl in `clamav-config --libs 2>/dev/null`; do if test "x`echo $cl | perl -ne 'print if (/(^-L|thread|c_r)/)' 2>/dev/null`" != "x" then LDFLAGS="$LDFLAGS $cl" fi done LDFLAGS="$LDFLAGS -lclamav" SCANNEROBJECTS="clamlibscanner.o" AC_DEFINE(USECLAMLIB, 1, [Have clamav scanner]) AC_MSG_RESULT([found $clamversion in $clamprefix]) else AC_MSG_RESULT([disabled :-(]) fi AC_MSG_CHECKING(for Trend Micro scanner) if test "$enable_trophie" = "yes" then if test -f "/etc/iscan/libvsapi.so" then AC_MSG_RESULT([/etc/iscan/libvsapi.so found]) SCANNEROBJECTS="$SCANNEROBJECTS trophiescanner.o" LDFLAGS="-L/etc/iscan -lvsapi $LDFLAGS" AC_DEFINE(USETROPHIE, 1, [Use trophie scanner]) else AC_MSG_RESULT([/etc/iscan/libvsapi.so not found, disabled]) fi else AC_MSG_RESULT([disabled]) fi LDFLAGS="$LDFLAGS $OSLIBS" CFLAGS="$CFLAGS -Wall -g -O2" test "$prefix" = "NONE" && prefix=/usr/local test "$localstatedir" = '${prefix}/var' && localstatedir=/var || localstatedir=$localstatedir sysconfdir=`eval echo $sysconfdir | $PERL -pe 's#/havp/?$##'` localstatedir=`eval echo $localstatedir` AC_DEFINE_UNQUOTED(CONFIGFILE, "$sysconfdir/havp/havp.config", [Location of the conig file]) AC_DEFINE_UNQUOTED(WHITELISTFILE, "$sysconfdir/havp/whitelist", [Location of the whitelist file]) AC_DEFINE_UNQUOTED(BLACKLISTFILE, "$sysconfdir/havp/blacklist", [Location of the blacklist file]) AC_DEFINE_UNQUOTED(TEMPLATEPATH, "$sysconfdir/havp/templates/en", [Path to templates]) AC_DEFINE_UNQUOTED(ACCESSLOG, "$localstatedir/log/havp/access.log", [Location of the access log file]) AC_DEFINE_UNQUOTED(ERRORLOG, "$localstatedir/log/havp/error.log", [Location of the error log file]) AC_DEFINE_UNQUOTED(SCANTEMPFILE, "$localstatedir/tmp/havp/havp-XXXXXX", [Temporary scan path]) AC_DEFINE_UNQUOTED(PIDFILE, "$localstatedir/run/havp/havp.pid", [Location of the PID file]) AC_SUBST(SCANNEROBJECTS) AC_SUBST(CFLAGS) AC_OUTPUT(Makefile havp/Makefile havp/scanners/Makefile etc/havp/havp.config) havp-0.93/configure0000755000000000000000000041335713425372640013033 0ustar rootroot#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="havp" ac_default_prefix=/usr/local ac_subst_vars='LTLIBOBJS LIBOBJS SCANNEROBJECTS ac_ct_CC CFLAGS CC PERL AR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_locking enable_ssl_tunnel enable_clamav enable_trophie enable_largefile ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-locking Disable mandatory locking (not needed on Linux/Solaris system) --enable-ssl-tunnel Enable SSL proxying (not scanned, only forwarded!) --disable-clamav Disable ClamAV libclamav support (clamd is supported anyway) --disable-trophie Disable Trend Micro Library (Trophie) support --disable-largefile omit support for large files Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu unset CDPATH ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers havp/_default.h" # Check whether --enable-locking was given. if test "${enable_locking+set}" = set; then : enableval=$enable_locking; enable_locking=$enableval else enable_locking=yes fi # Check whether --enable-ssl-tunnel was given. if test "${enable_ssl_tunnel+set}" = set; then : enableval=$enable_ssl_tunnel; enable_ssl_tunnel=$enableval else enable_ssl_tunnel=no fi # Check whether --enable-clamav was given. if test "${enable_clamav+set}" = set; then : enableval=$enable_clamav; enable_clamav=$enableval else enable_clamav=yes fi # Check whether --enable-trophie was given. if test "${enable_trophie+set}" = set; then : enableval=$enable_trophie; enable_trophie=$enableval else enable_trophie=yes fi # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="no" fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$AR" = "no"; then as_fn_error $? "ar not found in PATH" "$LINENO" 5 fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_PERL" && ac_cv_prog_PERL="no" fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi for ac_func in initgroups setgroups do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "$PERL" = "no"; then as_fn_error $? "perl not found in PATH" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking OS" >&5 $as_echo_n "checking OS... " >&6; } os="`uname`" case $os in Linux*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Linux" >&5 $as_echo "Linux" >&6; } mandatory=yes ;; SunOS*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: Solaris" >&5 $as_echo "Solaris" >&6; } mandatory=yes OSLIBS="-lsocket -lresolv -lnsl" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $os" >&5 $as_echo "$os" >&6; } mandatory=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mandatory locking support" >&5 $as_echo_n "checking for mandatory locking support... " >&6; } if test "$enable_locking" = "no" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled, no dynamic scanning!" >&5 $as_echo "disabled, no dynamic scanning!" >&6; } $as_echo "#define NOMAND 1" >>confdefs.h else if test "$mandatory" = "yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: OS supported" >&5 $as_echo "OS supported" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: OS not supported" >&5 $as_echo "OS not supported" >&6; } echo "" echo " Mandatory locking only works on Linux and Solaris." echo "" echo " You are running $os, so you must rerun configure" echo " with --disable-locking option." echo "" echo " This means you cannot use dynamic scanning features" echo " like KEEPBACKBUFFER. Everything is downloaded fully" echo " and only then sent to client." echo "" exit 1 fi fi if test "$enable_ssl_tunnel" = "yes" then $as_echo "#define SSLTUNNEL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ClamAV scanner library" >&5 $as_echo_n "checking for ClamAV scanner library... " >&6; } if test "$enable_clamav" = "yes" then clamprefix="`clamav-config --prefix 2>/dev/null`" clamversion="`clamav-config --version 2>/dev/null`" if test "x$clamprefix" = "x" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: clamav-config not found" >&5 $as_echo "clamav-config not found" >&6; } echo "" echo " Error finding ClamAV installation!" echo " Add ClamAV binaries path to PATH and run configure again." echo "" echo " To disable ClamAV library support, use --disable-clamav." echo "" exit 1 fi for cl in `clamav-config --cflags 2>/dev/null`; do if test "x`echo $cl | perl -ne 'print if (/^-I/)' 2>/dev/null`" != "x" then CFLAGS="$CFLAGS $cl" fi done for cl in `clamav-config --libs 2>/dev/null`; do if test "x`echo $cl | perl -ne 'print if (/(^-L|thread|c_r)/)' 2>/dev/null`" != "x" then LDFLAGS="$LDFLAGS $cl" fi done LDFLAGS="$LDFLAGS -lclamav" SCANNEROBJECTS="clamlibscanner.o" $as_echo "#define USECLAMLIB 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $clamversion in $clamprefix" >&5 $as_echo "found $clamversion in $clamprefix" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled :-(" >&5 $as_echo "disabled :-(" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Trend Micro scanner" >&5 $as_echo_n "checking for Trend Micro scanner... " >&6; } if test "$enable_trophie" = "yes" then if test -f "/etc/iscan/libvsapi.so" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: /etc/iscan/libvsapi.so found" >&5 $as_echo "/etc/iscan/libvsapi.so found" >&6; } SCANNEROBJECTS="$SCANNEROBJECTS trophiescanner.o" LDFLAGS="-L/etc/iscan -lvsapi $LDFLAGS" $as_echo "#define USETROPHIE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: /etc/iscan/libvsapi.so not found, disabled" >&5 $as_echo "/etc/iscan/libvsapi.so not found, disabled" >&6; } fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } fi LDFLAGS="$LDFLAGS $OSLIBS" CFLAGS="$CFLAGS -Wall -g -O2" test "$prefix" = "NONE" && prefix=/usr/local test "$localstatedir" = '${prefix}/var' && localstatedir=/var || localstatedir=$localstatedir sysconfdir=`eval echo $sysconfdir | $PERL -pe 's#/havp/?$##'` localstatedir=`eval echo $localstatedir` cat >>confdefs.h <<_ACEOF #define CONFIGFILE "$sysconfdir/havp/havp.config" _ACEOF cat >>confdefs.h <<_ACEOF #define WHITELISTFILE "$sysconfdir/havp/whitelist" _ACEOF cat >>confdefs.h <<_ACEOF #define BLACKLISTFILE "$sysconfdir/havp/blacklist" _ACEOF cat >>confdefs.h <<_ACEOF #define TEMPLATEPATH "$sysconfdir/havp/templates/en" _ACEOF cat >>confdefs.h <<_ACEOF #define ACCESSLOG "$localstatedir/log/havp/access.log" _ACEOF cat >>confdefs.h <<_ACEOF #define ERRORLOG "$localstatedir/log/havp/error.log" _ACEOF cat >>confdefs.h <<_ACEOF #define SCANTEMPFILE "$localstatedir/tmp/havp/havp-XXXXXX" _ACEOF cat >>confdefs.h <<_ACEOF #define PIDFILE "$localstatedir/run/havp/havp.pid" _ACEOF ac_config_files="$ac_config_files Makefile havp/Makefile havp/scanners/Makefile etc/havp/havp.config" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "havp/_default.h") CONFIG_HEADERS="$CONFIG_HEADERS havp/_default.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "havp/Makefile") CONFIG_FILES="$CONFIG_FILES havp/Makefile" ;; "havp/scanners/Makefile") CONFIG_FILES="$CONFIG_FILES havp/scanners/Makefile" ;; "etc/havp/havp.config") CONFIG_FILES="$CONFIG_FILES etc/havp/havp.config" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi havp-0.93/install-sh0000755000000000000000000002202113425371670013112 0ustar rootroot#!/bin/sh # install - install a program, script, or datafile scriptversion=2005-05-14.22 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= dstarg= no_target_directory= usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: -c (ignored) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -c) shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit $?;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t) dstarg=$2 shift shift continue;; -T) no_target_directory=true shift continue;; --version) echo "$0 $scriptversion"; exit $?;; *) # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. test -n "$dir_arg$dstarg" && break # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dstarg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dstarg" shift # fnord fi shift # arg dstarg=$arg done break;; esac done if test -z "$1"; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi for src do # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then mkdircmd=: chmodcmd= else mkdircmd=$mkdirprog fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dstarg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dstarg # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dstarg: Is a directory" >&2 exit 1 fi dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` shift IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift if test ! -d "$pathcomp"; then $mkdirprog "$pathcomp" # mkdir can fail with a `File exist' error in case several # install-sh are creating the directory concurrently. This # is OK. test -d "$pathcomp" || exit fi pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $mkdircmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap '(exit $?); exit' 1 2 13 15 # Copy the file name to the temp name. $doit $cpprog "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now rename the file to the real destination. { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ || { # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit 1 } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" } } fi || { (exit 1); exit 1; } done # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit 0 } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: havp-0.93/COPYING0000644000000000000000000004313113425371670012146 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. havp-0.93/havp/0000755000000000000000000000000013425376265012054 5ustar rootroothavp-0.93/havp/connectiontohttp.h0000644000000000000000000000321113425375263015621 0ustar rootroot/*************************************************************************** connectiontohttp.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CONNECTIONTOHTTP_H #define CONNECTIONTOHTTP_H #include "httphandler.h" class ConnectionToHTTP : public HTTPHandler { private: int HTMLResponse; long long ContentLength; string ContentType; bool IsKeepAlive; bool IsImage; bool IsChunked; vector ScanMimes; vector SkipMimes; int AnalyseFirstHeaderLine( string &RequestT ); int AnalyseHeaderLine( string &RequestT ); public: string PrepareHeaderForBrowser(); int GetResponse(); long long GetContentLength(); bool IsScannableMime(); bool IsItKeepAlive(); bool IsItImage(); bool IsItChunked(); void ClearVars(); ConnectionToHTTP(); ~ConnectionToHTTP(); }; #endif havp-0.93/havp/utils.cpp0000644000000000000000000001360713425375265013726 0ustar rootroot/*************************************************************************** utils.cpp - description ------------------- begin : Sa M� 5 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "utils.h" #include #include #include #include #include string UpperCase( string CaseString ) { string::const_iterator si = CaseString.begin(); string::size_type j = 0; string::size_type e = CaseString.size(); while ( j < e ) { CaseString[j++] = toupper(*si++); } return CaseString; } void SearchReplace( string &source, string search, string replace ) { string::size_type position = source.find(search); while (position != string::npos) { source.replace(position, search.size(), replace); position = source.find(search); } } int select_eintr( int fds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout ) { if ( timeout->tv_sec == 0 ) { return select(fds, readfds, writefds, errorfds, timeout); } int ret; #ifndef __linux__ time_t start = time(NULL); time_t now; int orig_timeout = timeout->tv_sec; #endif while ((ret = select(fds, readfds, writefds, errorfds, timeout)) < 0 && errno == EINTR) { #ifndef __linux__ now = time(NULL); if ((now - start) < orig_timeout) { timeout->tv_sec = orig_timeout - (now - start); timeout->tv_usec = 0; } #endif } return ret; } bool MatchBegin(string &hay, const char *needle, int needlelength) { return ( strncmp(hay.c_str(), needle, needlelength) == 0 ) ? true : false; } bool MatchSubstr(string &hay, const char *needle, int startpos) { if (startpos == -1) { return ( strstr(hay.c_str(), needle) != NULL ) ? true : false; } else { return ( strstr(hay.c_str(), needle) == hay.c_str() + startpos ) ? true : false; } } bool MatchWild(const char *str, const char *pat) { int i, star; if (!str || !pat) return false; new_segment: star = 0; if (*pat == '*') { star = 1; do { pat++; } while (*pat == '*'); } test_match: for (i = 0; pat[i] && (pat[i] != '*'); i++) { if (toupper(str[i]) != toupper(pat[i])) { if (!str[i]) return false; if (pat[i] == '?') continue; if (!star) return false; str++; goto test_match; } } if (pat[i] == '*') { str += i; pat += i; goto new_segment; } if (!str[i]) return true; if (i && pat[i - 1] == '*') return true; if (!star) return false; str++; goto test_match; } void Tokenize(const string& str, vector& tokens) { string::size_type lastPos = str.find_first_not_of(" ", 0); string::size_type pos = str.find_first_of(" ", lastPos); while (string::npos != pos || string::npos != lastPos) { tokens.push_back(str.substr(lastPos, pos - lastPos)); lastPos = str.find_first_not_of(" ", pos); pos = str.find_first_of(" ", lastPos); } } /* The base64 implementation below is licensed according to: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* ** Translation Table as described in RFC1113 */ static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* ** encodeblock ** ** encode 3 8-bit binary bytes as 4 '6-bit' characters */ void encodeblock( unsigned char in[3], unsigned char out[4], int len ) { out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); } string base64_encode(string input) { string base64 = ""; unsigned char result[5]; memset(result, 0x00, 5); for(unsigned int i = 0; i < input.length(); i += 3) { string block = input.substr(i,3); encodeblock((unsigned char*)block.c_str(), result, block.length()); base64.append((const char*)result); } return base64; } havp-0.93/havp/httphandler.cpp0000644000000000000000000002044113425375265015075 0ustar rootroot/*************************************************************************** httphandler.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "httphandler.h" #include "logfile.h" #include "utils.h" #include "default.h" #include //Read header bool HTTPHandler::ReadHeader( string &headerT ) { headerT = ""; string tempheader; ssize_t read; int received = 0; string::size_type position; //Read initial header, ignore whitespace from beginning for(;;) { read = SocketHandler::Recv( tempheader, false, -1 ); if ( read < 1 ) { return false; } received += read; if ( (position = tempheader.find_first_not_of("\r\n\t ")) != string::npos ) { if ( position > 0 ) { tempheader.erase( 0, position ); read -= position; string ws; SocketHandler::RecvLength( ws, position ); } //Jump to header processing break; } if ( received > MAXHTTPHEADERLENGTH ) { LogFile::ErrorMessage("Too large header received (>%d)\n", MAXHTTPHEADERLENGTH); return false; } SocketHandler::RecvLength( tempheader, read ); tempheader = ""; } bool WrongHeader = false; int poscount = 0; while ( (position = tempheader.find("\r\n\r\n")) == string::npos ) { //Maybe we should also look for \n\n (19.3 RFC 1945 - Tolerant Applications) if ( (position = tempheader.find("\n\n")) != string::npos ) { WrongHeader = true; break; } //Header not yet found //Read and delete part of header containing no \r\n\r\n if ( SocketHandler::RecvLength( headerT, read ) == false ) { return false; } poscount += read; received += read; //Too big header if ( received > MAXHTTPHEADERLENGTH ) { LogFile::ErrorMessage("Too large header received (>%d)\n", MAXHTTPHEADERLENGTH); return false; } if ( (read = SocketHandler::Recv( tempheader, false, -1 )) < 1 ) { //Did not receive last empty line? if ( read == 0 && ( headerT.find_last_of( "\r\n" ) == headerT.size() - 1 ) ) { return true; } return false; } } //Read last part of header if ( SocketHandler::RecvLength( headerT, position - poscount + 2 ) == false ) { return false; } if ( WrongHeader == false ) { //Read last \r\n if ( SocketHandler::RecvLength( tempheader, 2 ) == false ) { return false; } } return true; } //Split header to tokens int HTTPHandler::AnalyseHeader( string &linesT ) { //Delete header tokens tokens.clear(); string::size_type lastposition = 0; //Do "Tolerant Applications" - RFC 1945 - Hypertext Transfer Protocol -- HTTP/1.0 while ( (lastposition = linesT.find( "\r", lastposition )) != string::npos ) { linesT.replace( lastposition, 1, "" ); } lastposition = 0; string::size_type length = linesT.length(); string::size_type position, positiontmp; if ( (position = linesT.find( "\n", 0 )) == string::npos ) { return -201; } int ret; string tempToken, headerbase; //Read first line with AnalyseFirstHeaderLine bool First = true; //Loop through headers while ( position != string::npos && lastposition != length ) { tempToken = linesT.substr( lastposition, position - lastposition ); if ( (lastposition = tempToken.find_last_not_of("\t ")) != string::npos ) { tempToken = tempToken.substr( 0, lastposition + 1 ); if ( First == true ) { //Analyse request header if ( (ret = AnalyseFirstHeaderLine( tempToken )) < 0 ) { return ret; } First = false; } else { if ( (positiontmp = tempToken.find(":")) != string::npos ) { headerbase = tempToken.substr(0, positiontmp + 1); headerbase += " "; //Make sure we have "Header:value" if ( (positiontmp = tempToken.find_first_not_of(" ", positiontmp + 1)) != string::npos ) { tempToken = headerbase + tempToken.substr(positiontmp); if ( (ret = AnalyseHeaderLine( tempToken )) < 0 ) { return ret; } } } } //Add header to send queue tokens.push_back( tempToken ); } lastposition = position + 1; position = linesT.find( "\n", lastposition ); } return 0; } //Read part of Body ssize_t HTTPHandler::ReadBodyPart( string &bodyT, bool Chunked ) { bodyT = ""; ssize_t count; if ( Chunked == false ) { if ( (count = SocketHandler::Recv( bodyT, true, -1 )) < 0) { return -1; } return count; } // Handle Chunked encoding, return one chunk string Temp = ""; int received = 0; int read; unsigned int csize; string::size_type position, hpos; // Read header for(;;) { read = SocketHandler::Recv( Temp, false, -1 ); if ( read < 1 ) return -1; if ( (position = Temp.find("\r\n")) != string::npos ) { if ( position == 0 ) { SocketHandler::RecvLength( Temp, 2 ); Temp = ""; continue; } string UTemp = UpperCase(Temp); hpos = UTemp.find_first_not_of("0123456789ABCDEF"); // Read max 8 hex = 4gb if ( hpos == string::npos || hpos < 1 || hpos > 7 ) { LogFile::ErrorMessage("Invalid Chunked-header received\n"); return -1; } if ( sscanf( UTemp.substr(0, hpos).c_str(), "%x", &csize ) != 1 ) { LogFile::ErrorMessage("Invalid Chunked-header received\n"); return -1; } SocketHandler::RecvLength( Temp, position + 2 ); break; } received += read; if ( received > 256 ) { LogFile::ErrorMessage("Too large Chunked-header received (>256)\n"); return -1; } } // All chunks received? if ( csize == 0 ) return 0; // Does someone send over 1MB chunks? if ( csize > 1048576 ) { LogFile::ErrorMessage("Too large Chunked-body size received (>1MB)\n"); return -1; } if ( RecvLength( bodyT, csize ) == false ) return -1; return csize; } //Send Header bool HTTPHandler::SendHeader( string header, bool ConnectionClose ) { if ( ProxyConnection ) header += "Proxy-"; if ( ConnectionClose ) { header += "Connection: close\r\n\r\n"; } else { header += "Connection: keep-alive\r\n\r\n"; } if ( SocketHandler::Send( header ) == false ) { return false; } return true; } //Constructor HTTPHandler::HTTPHandler() { } //Destructor HTTPHandler::~HTTPHandler() { } havp-0.93/havp/whitelist.cpp0000644000000000000000000001511613425375265014577 0ustar rootroot/*************************************************************************** whitelist.cpp - description ------------------- begin : Don Aug 18 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "whitelist.h" #include "logfile.h" #include #include using namespace std; bool URLList::CreateURLList(string URLListFileT) { string::size_type i1, i2; ifstream Input; string Line; string Start; string URL; string Domain; struct PathStruct AnalysedURL; // string::size_type ToplevelCounter; Input.open( URLListFileT.c_str()); if(!Input) { LogFile::ErrorMessage("Cannot open URLList: %s\n", URLListFileT.c_str()); return false; } while(Input) { getline(Input,Line); Start = Line.substr(0,1); i1 = Line.find_first_not_of(" \t"); if(Start != "#" && i1 != Line.npos ) { i2 = Line.find_last_of(" \t"); URL = Line.substr(i1,i2-i1); if (AnalyseURL( URL, &Domain, &AnalysedURL.ExactDomain, &AnalysedURL.Path, &AnalysedURL.ExactPath ) == false ) { return false; } //cout << URL << endl << Domain << endl << AnalysedURL.ExactDomain << endl << AnalysedURL.Path << endl << AnalysedURL.ExactPath << endl << "--" << endl; URLLists[Domain].push_back( AnalysedURL ); } } Input.close(); return true; } bool URLList::ReloadURLList( string URLListFileT ) { map >::iterator URLListsEnum; for(URLListsEnum = URLLists.begin(); URLListsEnum != URLLists.end(); URLListsEnum++) { (*URLListsEnum).second.clear(); } URLLists.clear(); return CreateURLList( URLListFileT ); return true; } bool URLList::AnalyseURL( string UrlT, string *DomainT, char *ExactDomainT, string *PathT, char *ExactPathT ) { *DomainT = ""; *PathT = ""; string::size_type i1; if ((i1 = UrlT.find("/")) != string::npos ) { *DomainT = UrlT.substr(0,i1); *PathT = UrlT.substr(i1+1, UrlT.size()-i1-1); } else { *DomainT = UrlT; if( UrlT == "") { LogFile::ErrorMessage("URLList invalid Domain\n"); } *PathT = ""; } *ExactDomainT = CheckItem( DomainT ); if ( (*ExactDomainT != 'l') && (*ExactDomainT != 'n') ) { LogFile::ErrorMessage("URLList invalid Domain: %s\n", DomainT->c_str() ); return false; } *ExactPathT = CheckItem( PathT ); if (*ExactPathT == 'e') { LogFile::ErrorMessage("URLList invalid Path: %s\n", PathT->c_str() ); return false; } return true; } char URLList::CheckItem ( string *ItemT ) { char position='n'; string character; if ( ItemT->size() == 0 ) return position; character = ItemT->substr(0,1); if( character == "*" ){ ItemT->erase(0,1); position = 'l'; } if ( ItemT->size() == 0 ) return position; character = ItemT->substr(ItemT->size()-1,1); if( character == "*" ){ ItemT->erase(ItemT->size()-1,1); if ( position == 'l' ){ position = 'b'; } else { position = 'r'; } } if (ItemT->find("*") != string::npos ){ LogFile::ErrorMessage("URLList - Too many wildcards in %s\n", ItemT->c_str()); position = 'e'; } return position; } void URLList::DisplayURLList( ) { /* vector::iterator ToplevelI; vector::iterator DomainI; vector::iterator PathI; cout << "URLList:" << endl; //cout << "Toplevel - Domain - Path" << endl; for(ToplevelI = URLListDB.begin(); ToplevelI != URLListDB.end(); ToplevelI++) { if ( ToplevelI->Toplevel == "" ){ cout << " - " << "*" << endl; } else { cout << " - " << ToplevelI->Toplevel << endl; } for(DomainI = ToplevelI->Domain.begin(); DomainI != ToplevelI->Domain.end(); DomainI++) { cout << " - " << DisplayLine(DomainI->Domain, DomainI->exact) << endl; for(PathI = DomainI->Path.begin(); PathI != DomainI->Path.end(); PathI++) { cout << " - " << DisplayLine(PathI->Path, PathI->exact) << endl; } } } */ } string URLList::DisplayLine( string LineT, char positionT ) { string Newline = LineT; if ( positionT == 'r' ){ Newline = LineT + "*"; } else if ( positionT == 'l' ){ Newline = "*" +LineT; } else if ( positionT == 'b' ){ Newline = "*" + LineT + "*"; } return Newline; } bool URLList::Search ( string *DomainT, char ExactDomainT, string *PathT ) { vector::iterator PathI; vector *List = &URLLists[*DomainT]; if ( List == NULL ){ return false; } for(PathI = List->begin(); PathI != List->end(); PathI++) { if ( ( ExactDomainT != 'n' ) && (PathI->ExactDomain != ExactDomainT )){ continue; } if( FindString( &PathI->Path, PathT, PathI->ExactPath ) == true) { return true; } } return false; } bool URLList::URLFound ( string DomainT, string PathT ) { string::size_type pos; //Delete / add Path PathT.erase(0,1); if ( Search ( &DomainT, 'n', &PathT ) == true){ return true; } while ( (pos = DomainT.find(".")) != string::npos){ DomainT.erase(0, pos); if ( Search ( &DomainT, 'l', &PathT ) == true){ return true; } DomainT.erase(0, 1); if ( Search ( &DomainT, 'l', &PathT ) == true){ return true; } } DomainT=""; if ( Search ( &DomainT, 'l', &PathT ) == true){ return true; } return false; } bool URLList::FindString( string *SearchT, string *LineT, char positionT ) { if ( positionT == 'l' ){ //cout << LineT.rfind( SearchT ) << " " << (LineT.size() - SearchT.size()) << endl; //Check if SearchT string is larger than LineT if (SearchT->size() <= LineT->size() ) if ( LineT->rfind( *SearchT ) == (LineT->size() - SearchT->size()) ){ return true; } } else if ( positionT == 'r' ){ if ( LineT->find( *SearchT ) == 0 ){ return true; } } else if ( positionT == 'b' ){ if ( LineT->find( *SearchT ) != string::npos ){ return true; } } else if ( positionT == 'n' ){ if ( *LineT == *SearchT ){ return true; } } return false; } URLList::URLList(){ } URLList::~URLList(){ } havp-0.93/havp/sockethandler.h0000644000000000000000000000457213425375263015060 0ustar rootroot/*************************************************************************** sockethandler.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SOCKETHANDLER_H #define SOCKETHANDLER_H #include "default.h" #include #include #include #include #include #include #include #include using namespace std; class SocketHandler { private: struct sockaddr_un my_u_addr; struct sockaddr_in l_addr; struct sockaddr_in peer_addr; struct hostent *server; struct timeval Timeout; socklen_t addr_len; int ip_count; int ips; fd_set checkfd, wset; string source_address; string RecvBuf; string LastHost; protected: struct sockaddr_in my_s_addr; public: int sock_fd; bool CreateServer( int portT, in_addr_t bind_addrT = INADDR_ANY ); bool CreateServer( int portT, string bind_addrT ); bool AcceptClient( SocketHandler &accept_socketT ); bool ConnectToServer(); bool ConnectToSocket( string SocketPath, int retry ); bool Send( const char *sock_outT, int len ); bool Send( string &sock_outT ); ssize_t Recv( string &sock_inT, bool sock_delT, int timeout ); bool RecvLength( string &sock_inT, unsigned int sock_lengthT ); bool GetLine( string &lineT, string separator, int timeout ); bool SetDomainAndPort( string domainT, int portT ); int IPCount(); string GetIP(); bool CheckForData( int timeout ); void Close(); #ifdef SSLTUNNEL int CheckForSSLData( int sockBrowser, int sockServer ); #endif SocketHandler(); ~SocketHandler(); }; #endif havp-0.93/havp/scannerhandler.cpp0000644000000000000000000006672413425375265015565 0ustar rootroot/*************************************************************************** scannerhandler.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "scannerhandler.h" #include "logfile.h" #include "helper.h" #include "utils.h" //SCANNERS #ifdef USECLAMLIB #include "scanners/clamlibscanner.h" #endif #ifdef USETROPHIE #include "scanners/trophiescanner.h" #endif #include "scanners/kasperskyscanner.h" #include "scanners/avgscanner.h" #include "scanners/f-protscanner.h" #include "scanners/nod32scanner.h" #include "scanners/clamdscanner.h" #include "scanners/sophiescanner.h" #include "scanners/avastscanner.h" #include "scanners/arcavirscanner.h" #include "scanners/drwebscanner.h" #include #include #include #include #include #include #include #include extern char TempFileName[MAXSCANTEMPFILELENGTH+1]; extern int fd_tempfile; //Initialize scanners and load databases bool ScannerHandler::InitScanners() { //SCANNERS if ( Params::GetConfigBool("ENABLECLAMLIB") ) { #ifdef USECLAMLIB VirusScanner.push_back(new ClamLibScanner); #else LogFile::ErrorMessage("ERROR: HAVP not compiled with ClamAV support\n"); return false; #endif } if ( Params::GetConfigBool("ENABLECLAMD") ) { VirusScanner.push_back(new ClamdScanner); } if ( Params::GetConfigBool("ENABLETROPHIE") ) { #ifdef USETROPHIE VirusScanner.push_back(new TrophieScanner); #else LogFile::ErrorMessage("ERROR: HAVP not compiled with Trophie support\n"); return false; #endif } if ( Params::GetConfigBool("ENABLEAVESERVER") ) { VirusScanner.push_back(new KasperskyScanner); } if ( Params::GetConfigBool("ENABLEAVG") ) { VirusScanner.push_back(new AVGScanner); } if ( Params::GetConfigBool("ENABLENOD32") ) { VirusScanner.push_back(new NOD32Scanner); } if ( Params::GetConfigBool("ENABLEFPROT") ) { VirusScanner.push_back(new FProtScanner); } if ( Params::GetConfigBool("ENABLESOPHIE") ) { VirusScanner.push_back(new SophieScanner); } if ( Params::GetConfigBool("ENABLEAVAST") ) { VirusScanner.push_back(new AvastScanner); } if ( Params::GetConfigBool("ENABLEDRWEB") ) { VirusScanner.push_back(new DrwebScanner); } if ( Params::GetConfigBool("ENABLEARCAVIR") ) { VirusScanner.push_back(new ArcavirScanner); } if ( VirusScanner.size() == 0 ) { LogFile::ErrorMessage("ERROR: No scanners are enabled in config!\n"); return false; } for ( unsigned int i = 0; i < VirusScanner.size(); i++ ) { string Name = VirusScanner[i]->ScannerName; LogFile::ErrorMessage("--- Initializing %s\n", Name.c_str()); if ( VirusScanner[i]->InitDatabase() == false ) { LogFile::ErrorMessage("Error initializing %s!\n", Name.c_str()); return false; } //Test scanner with EICAR data (left to TempFileName from hardlock test!!) string Answer = VirusScanner[i]->Scan( TempFileName ); //Make sure we close scanners persistent socket now, because we fork later! //Only really needed for Kaspersky at the moment.. VirusScanner[i]->CloseSocket(); if ( Answer.substr(0,1) == "1" ) { LogFile::ErrorMessage("%s passed EICAR virus test (%s)\n", Name.c_str(), Answer.substr(1).c_str()); } else { LogFile::ErrorMessage("ERROR: %s failed EICAR virus test! (%s)\n", Name.c_str(), Answer.substr(1).c_str()); return false; } } LogFile::ErrorMessage("--- All scanners initialized\n"); return true; } //Fork all scanners, each gets a pipepair for communication bool ScannerHandler::CreateScanners( SocketHandler &ProxyServerT ) { int ret; for ( unsigned int i = 0; i < VirusScanner.size(); i++ ) { int sh_to_sc[2]; int sc_to_sh[2]; //Create pipes if ((ret = pipe(sh_to_sc)) < 0) { LogFile::ErrorMessage("Scanner pipe creation failed: %s\n", strerror(ret)); return false; } if ((ret = pipe(sc_to_sh)) < 0) { LogFile::ErrorMessage("Scanner pipe creation failed: %s\n", strerror(ret)); return false; } //Fork the scanner pid_t scannerpid = fork(); if ( scannerpid < 0 ) { LogFile::ErrorMessage("Could not fork Scanner: %s\n", strerror(errno)); return false; } else if ( scannerpid == 0 ) //Scanner child { //Install Scanner Signals if (InstallSignal(2) < 0) { LogFile::ErrorMessage("Could not install Scanner signal handler\n"); exit(1); } //Small sanity check if ( fd_tempfile == -1 ) { LogFile::ErrorMessage("Program Error: Scannerchild fd_tempfile == -1\n"); exit(1); } //Close ProxyHandler used socket ProxyServerT.Close(); //We don't need tempfile descriptor here anymore, ProxyHandler uses it while (close(fd_tempfile) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("ScannerHandler could not close() tempfile: %s\n", strerror(errno)); exit(1); } fd_tempfile = -1; //Close pipe ends that are not needed while (close(sh_to_sc[1]) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not close scanner pipe: %s\n", strerror(errno)); exit(1); } while (close(sc_to_sh[0]) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not close scanner pipe: %s\n", strerror(errno)); exit(1); } //Make sure each child has unique random seed, atleast ClamAV needs it srand(getpid() ^ time((time_t *) 0)); //Enter scanning loop, pass used pipe fds and filename VirusScanner[i]->StartScanning( sh_to_sc[0], sc_to_sh[1], TempFileName ); //Finish child exit(1); } else //Parent = ProxyHandler { //Struct to hold pipe fds and connected scanners name and pid scanner_st scanner_info = { sh_to_sc[1], sc_to_sh[0], VirusScanner[i]->ScannerName, VirusScanner[i]->ScannerNameShort, scannerpid }; //Add info to list Scanner.push_back(scanner_info); //Close pipe ends that are not needed while (close(sh_to_sc[0]) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not close scanner pipe: %s\n", strerror(errno)); exit(1); } while (close(sc_to_sh[1]) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not close scanner pipe: %s\n", strerror(errno)); exit(1); } } } //Cache some values totalscanners = Scanner.size(); top_fd = 0; //Get top descriptor for select for ( int i = 0; i < totalscanners; i++ ) { if ( Scanner[i].fromscanner > top_fd ) { top_fd = Scanner[i].fromscanner; } } FD_ZERO(&readfds); FD_ZERO(&origfds); FD_ZERO(&scannerfds); //Set main descriptor list for ( int i = 0; i < totalscanners; i++ ) { FD_SET(Scanner[i].fromscanner,&origfds); } //Set descriptors readfds = scannerfds = origfds; //Cache zero timeout for select memset(&ZeroTimeout, 0, sizeof(ZeroTimeout)); ZeroTimeout.tv_sec = 0; ZeroTimeout.tv_usec = 0; //No scanners responded yet answers = 0; //No virus found yet VirusMsg.clear(); ErrorMsg.clear(); LastRequestURL = ""; CompleteTempFile = false; return true; } //Reload scanner databases //Called from main HAVP process only! int ScannerHandler::ReloadDatabases() { int reloaded = 0; int failed = 0; for ( unsigned int i = 0; i < VirusScanner.size(); i++ ) { int rl = VirusScanner[i]->ReloadDatabase(); if ( rl == 1 ) { reloaded++; } else if ( rl < 0 ) { failed++; } } if ( failed ) return -1; if ( reloaded ) return 1; return 0; } //Tell all scanners to start scanning again bool ScannerHandler::RestartScanners() { if ( DeadScanner ) return false; int ret; for ( int i = 0; i < totalscanners; i++ ) { while ((ret = write(Scanner[i].toscanner, (const char*)"c", 1)) < 0 && errno == EINTR); if (ret <= 0) { LogFile::ErrorMessage("Detected crashed %s process (restart, pid: %d, lasturl: %s)\n", Scanner[i].scanner_name.c_str(), Scanner[i].scanner_pid, LastRequestURL.c_str()); return false; } } //Set descriptors readfds = scannerfds = origfds; //No scanners responded yet answers = 0; //Empty message VirusMsg.clear(); ErrorMsg.clear(); LastRequestURL = ""; CompleteTempFile = false; return true; } //Tell all scanners to exit void ScannerHandler::ExitScanners() { int ret; for ( int i = 0; i < totalscanners; i++ ) { while ((ret = write(Scanner[i].toscanner, (const char*)"q", 1)) < 0 && errno == EINTR); if (ret <= 0) { LogFile::ErrorMessage("Detected crashed %s process (exit, pid: %d, lasturl: %s)\n", Scanner[i].scanner_name.c_str(), Scanner[i].scanner_pid, LastRequestURL.c_str()); } } } #ifndef NOMAND //This check is used only while BodyLoop is running //If we return true here, BodyLoop will call GetAnswer() bool ScannerHandler::HasAnswer() { //Set remaining scanners readfds = scannerfds; //Check if any scanner has answer int ret = select_eintr(top_fd+1, &readfds, NULL, NULL, &ZeroTimeout); //No scanner ready, BodyLoop can continue! if ( ret < 1 ) return false; char buf[100]; //Check all descriptors for answer for ( int i = 0; i < totalscanners; i++ ) { //Check if this scanner has answer if ( FD_ISSET(Scanner[i].fromscanner,&readfds) ) { //We have one answer more! ++answers; //Remove scanner from list of checked fds FD_CLR(Scanner[i].fromscanner,&scannerfds); //Lets be safe memset(&buf, 0, sizeof(buf)); //Read scanner answer while ((ret = read(Scanner[i].fromscanner, buf, 100)) < 0 && errno == EINTR); if (ret <= 0) //Pipe was closed - or some bad error { LogFile::ErrorMessage("Detected crashed %s process (hasanswer, pid: %d, lasturl: %s)\n", Scanner[i].scanner_name.c_str(), Scanner[i].scanner_pid, LastRequestURL.c_str()); DeadScanner = true; ErrorMsg.push_back( Scanner[i].scanner_name_short + ": Scanner crashed" ); //We still need to check other possible answers continue; } //If clean, just check next scanner if ( buf[0] == '0' ) continue; //Virus found? if ( buf[0] == '1' ) { //Set answer message (virusname) string Temp = buf; Temp.erase(0,1); if ( Temp == "" ) Temp = "Unknown"; if ( IgnoredVirus( Temp ) == false ) { VirusMsg.push_back( Scanner[i].scanner_name_short + ": " + Temp ); } //Check next descriptor continue; } else //Any other return code must be error { //Set error message string Temp = buf; Temp.erase(0,1); if ( Temp == "" ) Temp = "Error"; ErrorMsg.push_back( Scanner[i].scanner_name_short + ": " + Temp ); } } //Check next descriptor } //If virus was found or all scanners returned already, BodyLoop must call GetAnswer() if ( answers == totalscanners || VirusMsg.size() ) return true; //Continue BodyLoop return false; } #endif //Wait and read all remaining scanner answers int ScannerHandler::GetAnswer() { int ret; char buf[100]; #ifdef NOMAND //Start scanners for ( int i = 0; i < totalscanners; i++ ) { while ((ret = write(Scanner[i].toscanner, (const char*)"s", 1)) < 0 && errno == EINTR); if (ret <= 0) { LogFile::ErrorMessage("Detected crashed %s process (getanswer, pid: %d, lasturl: %s)\n", Scanner[i].scanner_name.c_str(), Scanner[i].scanner_pid, LastRequestURL.c_str()); DeadScanner = true; for ( int ii = 0; ii < totalscanners; ii++ ) { kill(Scanner[ii].scanner_pid, SIGKILL); } ErrorMsg.push_back( "Detected dead scanner" ); return 3; } } #endif while ( answers < totalscanners ) { //Set descriptors that are left readfds = scannerfds; //Reset timeout ScannersTimeout.tv_sec = ScannerTimeout; ScannersTimeout.tv_usec = 0; //Wait for some scanner to return ret = select_eintr(top_fd+1, &readfds, NULL, NULL, &ScannersTimeout); //If some scanner has timed out, kill them all if ( ret == 0 ) { LogFile::ErrorMessage("Error: Some scanner has timed out! (lasturl: %s)\n", LastRequestURL.c_str()); for ( int i = 0; i < totalscanners; i++ ) { kill(Scanner[i].scanner_pid, SIGKILL); } ErrorMsg.push_back( "Scanner timeout" ); return 3; } //Check all descriptors for answer for ( int i = 0; i < totalscanners; i++ ) { //Check if this scanner has answer if ( FD_ISSET(Scanner[i].fromscanner,&readfds) ) { //We have one answer more! ++answers; //Remove scanner from list of checked fds FD_CLR(Scanner[i].fromscanner,&scannerfds); //Lets be safe memset(&buf, 0, sizeof(buf)); //Read scanner answer while ((ret = read(Scanner[i].fromscanner, buf, 100)) < 0 && errno == EINTR); if (ret <= 0) //Pipe was closed - or some bad error { LogFile::ErrorMessage("Detected crashed %s process (getanswer, pid: %d, lasturl: %s)\n", Scanner[i].scanner_name.c_str(), Scanner[i].scanner_pid, LastRequestURL.c_str()); DeadScanner = true; ErrorMsg.push_back( Scanner[i].scanner_name_short + ": Scanner crashed" ); //We still need to check other possible answers continue; } //If clean, just check next scanner if ( buf[0] == '0' ) continue; //Virus found? if ( buf[0] == '1' ) { //Set answer message (virusname) string Temp = buf; Temp.erase(0,1); if ( Temp == "" ) Temp = "Unknown"; if ( IgnoredVirus( Temp ) == false ) { VirusMsg.push_back( Scanner[i].scanner_name_short + ": " + Temp ); } //Check next descriptor continue; } else //Any other return code must be error { //Set error message string Temp = buf; Temp.erase(0,1); if ( Temp == "" ) Temp = "Error"; ErrorMsg.push_back( Scanner[i].scanner_name_short + ": " + Temp ); } } //Check next descriptor } } //Virus found? if ( VirusMsg.size() ) { return 1; } //Return error only if all scanners had one and we want errors if ( ErrorMsg.size() == (unsigned int)totalscanners ) { string Errors = ErrorMsg[0]; for ( unsigned int i = 1; i < ErrorMsg.size(); ++i ) { Errors += ", " + ErrorMsg[i]; } LogFile::ErrorMessage("Scanner errors: %s (lasturl: %s)\n", Errors.c_str(), LastRequestURL.c_str()); if ( Params::GetConfigBool("FAILSCANERROR") ) { return 2; } } //It's clean.. hopefully return 0; } //Return scanner answer message string ScannerHandler::GetAnswerMessage() { string AnswerMsg = ""; if ( VirusMsg.size() ) { for ( unsigned int i = 0; i < VirusMsg.size(); ++i ) { AnswerMsg += ", " + VirusMsg[i]; } AnswerMsg.erase(0,2); } else if ( ErrorMsg.size() ) { for ( unsigned int i = 0; i < ErrorMsg.size(); ++i ) { AnswerMsg += ", " + ErrorMsg[i]; } AnswerMsg.erase(0,2); } return AnswerMsg; } //Update last requested URL void ScannerHandler::LastURL( string URL ) { LastRequestURL = URL; } //Called if TempFile is fully complete, not cut off with MaxScanSize etc void ScannerHandler::HaveCompleteFile() { CompleteTempFile = true; } //Check if Virus is whitelisted bool ScannerHandler::IgnoredVirus( string VirusName ) { //IGNOREVIRUS? if ( IgnoredViruses.size() > 0 ) { string Virus = UpperCase( VirusName ); for ( vector::iterator IV = IgnoredViruses.begin(); IV != IgnoredViruses.end(); ++IV ) { if ( Virus.find(*IV) != string::npos ) { return true; } } } //CLAMBLOCKBROKEN? Ignore detection from incomplete file if ( VirusName == "Broken.Executable" && CompleteTempFile == false ) { return true; } return false; } //Initialize tempfile bool ScannerHandler::InitTempFile() { TempFileLength = 0; memset(&TempFileName, 0, sizeof(TempFileName)); strncpy(TempFileName, Params::GetConfigString("SCANTEMPFILE").c_str(), MAXSCANTEMPFILELENGTH); if ((fd_tempfile = mkstemp(TempFileName)) < 0) { LogFile::ErrorMessage("Invalid Scannerfile: %s Error: %s\n", TempFileName, strerror(errno)); return false; } #ifndef NOMAND while (write(fd_tempfile, " ", 1) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not write to Scannerfile: %s\n", TempFileName ); return false; } #endif #ifndef NOMAND while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP|S_ISGID) < 0) #else while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP) < 0) #endif { if (errno == EINTR) continue; LogFile::ErrorMessage("InitTempFile fchmod() failed: %s\n", strerror(errno)); return false; } #ifndef NOMAND struct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; // Byte-Offset lock.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR oder SEEK_END lock.l_len = MAXFILELOCKSIZE; // number of bytes; 0 = EOF while (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not lock Scannerfile: %s\n", TempFileName); return false; } #endif if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", TempFileName); return false; } return true; } #ifndef NOMAND //Fully unlock tempfile bool ScannerHandler::UnlockTempFile() { struct flock lock; lock.l_type = F_UNLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; while (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not unlock Scannerfile: %s\n", strerror(errno)); exit(1); } return true; } #endif //Delete tempfile bool ScannerHandler::DeleteTempFile() { if (fd_tempfile > -1) while (close(fd_tempfile) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not close() Scannerfile: %s\n", strerror(errno)); exit(1); } fd_tempfile = -1; while (unlink(TempFileName) < 0) { //File already deleted if (errno == ENOENT) break; //Retry if signal received or file busy if (errno == EINTR || errno == EBUSY) continue; LogFile::ErrorMessage("Could not delete Scannerfile: %s\n", strerror(errno)); exit(1); } return true; } //Reinitialize tempfile bool ScannerHandler::ReinitTempFile() { if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } while (ftruncate(fd_tempfile, 0) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not truncate file: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } #ifndef NOMAND while (write(fd_tempfile, " ", 1) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not write file: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } #endif #ifndef NOMAND while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP|S_ISGID) < 0) #else while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP) < 0) #endif { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not fchmod() Scannerfile: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } TempFileLength = 0; #ifndef NOMAND struct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = MAXFILELOCKSIZE; while (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { if (errno == EINTR) continue; //Some scanner still has tempfile opened if (errno == EAGAIN) { sleep(1); continue; } LogFile::ErrorMessage("Could not lock Scannerfile: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } #endif if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } return true; } //Set tempfile size bool ScannerHandler::SetTempFileSize( long long ContentLengthT ) { if (lseek(fd_tempfile, (off_t)ContentLengthT-1, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", strerror(errno)); return false; } while (write(fd_tempfile, "1", 1) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not write to Scannerfile: %s\n", strerror(errno)); return false; } if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", strerror(errno)); return false; } return true; } //Truncate tempfile to size bool ScannerHandler::TruncateTempFile( long long ContentLengthT ) { if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { LogFile::ErrorMessage("Could not lseek Scannerfile: %s\n", strerror(errno)); return false; } while (ftruncate(fd_tempfile, (off_t)ContentLengthT) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not truncate Scannerfile: %s\n", strerror(errno)); DeleteTempFile(); exit(1); } return true; } //Write data to tempfile bool ScannerHandler::ExpandTempFile( string &dataT, bool unlockT ) { int total_written = 0; int len = dataT.length(); int ret; TempFileLength += len; //Handle partial write if interrupted by signal! while (total_written < len) { while ((ret = write(fd_tempfile, dataT.substr(total_written).c_str(), len - total_written)) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not expand tempfile: %s %s\n", TempFileName, strerror(errno)); return false; } total_written += ret; } #ifndef NOMAND //Should we unlock the written part? if (unlockT == true) { struct flock lock; lock.l_type = F_UNLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = TempFileLength; while (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not unlock file: %s\n", TempFileName); return false; } } #endif return true; } bool ScannerHandler::ExpandTempFileRange( string &dataT, long long offset ) { int total_written = 0; int len = dataT.length(); int ret; //off_t origpos; //if ((origpos = lseek(fd_tempfile, 0, SEEK_CUR)) < 0) return false; if (lseek(fd_tempfile, offset, SEEK_SET) < 0) return false; //Handle partial write if interrupted by signal! while (total_written < len) { while ((ret = write(fd_tempfile, dataT.substr(total_written).c_str(), len - total_written)) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not expand tempfile: %s %s\n", TempFileName, strerror(errno)); return false; } total_written += ret; } //if (lseek(fd_tempfile, origpos, SEEK_SET) < 0) return false; if (lseek(fd_tempfile, 0, SEEK_SET) < 0) return false; #ifndef NOMAND struct flock lock; lock.l_type = F_UNLCK; lock.l_start = offset; // byte-offset lock.l_whence = SEEK_SET; lock.l_len = len; // number of bytes; 0 = EOF //partly unlock if (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { LogFile::ErrorMessage("Could not unlock file: %s\n", TempFileName); return false; } #endif return true; } //Constructor ScannerHandler::ScannerHandler() { //Timeout for scanners if ( Params::GetConfigInt("SCANNERTIMEOUT") > 0 ) { ScannerTimeout = 60 * Params::GetConfigInt("SCANNERTIMEOUT"); } else { //10 minutes as failsafe ScannerTimeout = 600; } //Whitelisted viruses if ( Params::GetConfigString("IGNOREVIRUS") != "" ) { Tokenize( UpperCase(Params::GetConfigString("IGNOREVIRUS")), IgnoredViruses ); } DeadScanner = false; } //Destructor ScannerHandler::~ScannerHandler() { } havp-0.93/havp/proxyhandler.h0000644000000000000000000000513513425375263014745 0ustar rootroot/*************************************************************************** proxyhandler.h - description ------------------- begin : So Feb 20 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PROXYHANDLER_H #define PROXYHANDLER_H #include "default.h" #include "connectiontobrowser.h" #include "connectiontohttp.h" #include "scannerhandler.h" #include using namespace std; class ProxyDetails { private: bool UseParentProxy; string ParentHost; int ParentPort; bool UseParentProxyAuth; string ParentUser; string ParentPassword; public: ProxyDetails(); bool useProxy() {return UseParentProxy;}; bool useProxyAuth() {return UseParentProxyAuth;}; string getHost() {return ParentHost;}; int getPort() {return ParentPort;}; string getUser() {return ParentUser;}; string getPassword() {return ParentPassword;}; }; class ProxyHandler { private: bool HeaderSend; bool BrowserDropped; bool DropBrowser; bool ScannerUsed; bool UnlockDone; bool AnswerDone; bool ReinitDone; bool ServerClosed; bool ServerConnected; bool DropServer; int alivecount; string ConnectedHost; int ConnectedPort; string Header; ConnectionToBrowser ToBrowser; ConnectionToHTTP ToServer; ProxyDetails parentProxy; int MaxDownloadSize; int KeepBackTime; int TricklingTime; unsigned int TricklingBytes; int KeepBackBuffer; int TransferredHeader; long long TransferredBody; bool DontLock; bool DontLockBINHEX; bool DontLockPDF; bool DontLockZIP; bool ProxyMessage( int CommunicationAnswerT, string Answer ); int CommunicationHTTP( ScannerHandler &Scanners, bool ScannerOff ); int CommunicationFTP( ScannerHandler &Scanners, bool ScannerOff ); #ifdef SSLTUNNEL int CommunicationSSL(); #endif public: void Proxy( SocketHandler &ProxyServerT, ScannerHandler &Scanners ); ProxyHandler(); ~ProxyHandler(); }; #endif havp-0.93/havp/connectiontohttp.cpp0000644000000000000000000001340713425375265016166 0ustar rootroot/*************************************************************************** connectiontohttp.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "connectiontohttp.h" #include "logfile.h" #include "utils.h" #include "params.h" #include extern int LL; //LogLevel //Prepare Header for Browser string ConnectionToHTTP::PrepareHeaderForBrowser() { string header; header.reserve(20000); header = ""; vector::iterator itvec; string it; it.reserve(200); //Strip unwanted headers to browser for (itvec = tokens.begin(); itvec != tokens.end(); ++itvec) { //Uppercase for matching it = UpperCase(*itvec); if ( MatchBegin( it, "KEEP-ALIVE", 10 ) ) { continue; } else if ( MatchBegin( it, "CONNECTION", 10 ) ) { continue; } else if ( MatchBegin( it, "PROXY-CONNECTION", 16 ) ) { continue; } else if ( MatchBegin( it, "CONTENT-LENGTH", 14 ) && (ContentLength == -1) ) { //Do not pass invalid Content-Length continue; } else if ( MatchBegin( it, "TRANSFER-ENCODING", 17 ) ) { continue; } header += *itvec; header += "\r\n"; } return header; } int ConnectionToHTTP::AnalyseFirstHeaderLine( string &RequestT ) { string::size_type Space; if ( (Space = RequestT.find( " ", 0 )) > 0 ) { string::size_type DigitPos; if ( (DigitPos = RequestT.find_first_of( "0123456789", Space + 1 )) != string::npos ) { string Response = RequestT.substr( DigitPos, 3 ); if ( sscanf(Response.c_str(), "%d", &HTMLResponse) == 1 ) { return 0; } else { if (LL>0) LogFile::ErrorMessage("Unknown server response: %s\n", RequestT.c_str()); } } } return -230; } int ConnectionToHTTP::AnalyseHeaderLine( string &RequestT ) { //Uppercase for matching string RequestU = UpperCase(RequestT); if ( RequestU.length() > 16 && MatchBegin( RequestU, "CONTENT-LENGTH: ", 16 ) ) { if ( RequestU.find_first_not_of("0123456789", 16) != string::npos ) { //Invalid Content-Length return 0; } string LengthToken = RequestT.substr( 16 ); //Sanity check for invalid huge Content-Length if ( LengthToken.length() > 18 ) return 0; if ( sscanf(LengthToken.c_str(), "%lld", &ContentLength) != 1 ) { ContentLength = -1; } return 0; } if ( MatchSubstr( RequestU, "CONNECTION: KEEP-ALIVE", -1 ) ) { IsKeepAlive = true; return 0; } if ( RequestU.length() > 14 && MatchBegin( RequestU, "CONTENT-TYPE: ", 14 ) ) { string::size_type Start = RequestU.find_first_not_of(" \t", 14); if (Start == string::npos) return 0; string::size_type End = RequestU.find_first_of("; \t", Start); if (End == string::npos) { ContentType = RequestU.substr(Start); } else { ContentType = RequestU.substr(Start, End - Start); } if ( MatchBegin( ContentType, "IMAGE/", 6 ) ) IsImage = true; return 0; } if ( MatchBegin( RequestU, "TRANSFER-ENCODING: CHUNKED", 26 ) ) { IsChunked = true; return 0; } if ( MatchBegin( RequestU, "TRANSFER-ENCODING: ", 19 ) ) { //Not allowed on HTTP/1.0 return -232; } return 0; } bool ConnectionToHTTP::IsScannableMime() { for (vector::iterator Mime = SkipMimes.begin(); Mime != SkipMimes.end(); ++Mime) { if ( MatchWild( ContentType.c_str(), (*Mime).c_str() ) ) return false; } for (vector::iterator Mime = ScanMimes.begin(); Mime != ScanMimes.end(); ++Mime) { if ( MatchWild( ContentType.c_str(), (*Mime).c_str() ) ) return true; } return true; } long long ConnectionToHTTP::GetContentLength() { return ContentLength; } int ConnectionToHTTP::GetResponse() { return HTMLResponse; } bool ConnectionToHTTP::IsItKeepAlive() { return IsKeepAlive; } bool ConnectionToHTTP::IsItImage() { return IsImage; } bool ConnectionToHTTP::IsItChunked() { return IsChunked; } void ConnectionToHTTP::ClearVars() { ContentLength = -1; ContentType = ""; IsKeepAlive = IsImage = IsChunked = false; } //Consturctor ConnectionToHTTP::ConnectionToHTTP() { HTMLResponse = 0; ProxyConnection = false; if (Params::GetConfigString("SCANMIME") != "") { Tokenize( UpperCase(Params::GetConfigString("SCANMIME")), ScanMimes ); } if (Params::GetConfigString("SKIPMIME") != "") { Tokenize( UpperCase(Params::GetConfigString("SKIPMIME")), SkipMimes ); } } //Destructor ConnectionToHTTP::~ConnectionToHTTP() { } havp-0.93/havp/genericscanner.cpp0000644000000000000000000000655713425375265015562 0ustar rootroot/*************************************************************************** genericscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "genericscanner.h" bool GenericScanner::StartScanning( int fromhandler, int tohandler, const char *TempFileName ) { string ScannerAnswer; ScannerAnswer.reserve(100); char buf[100]; int ret; for(;;) { #ifndef NOMAND int fd = open(TempFileName, O_RDONLY); if ( fd < 0 ) { LogFile::ErrorMessage("Could not open tempfile: %s %s\n", TempFileName, strerror(errno)); break; } else { //Wait until file is ready for scanning char Ready[2]; while (read(fd, Ready, 1) < 0 && errno == EINTR); while (close(fd) < 0 && errno == EINTR); } #else //Wait for scanning command while ((ret = read(fromhandler, buf, 1)) < 0) { if (errno == EINTR) continue; break; } if (ret <= 0 || buf[0] != 's') break; #endif //Start scanner and get return code ScannerAnswer = Scan( TempFileName ); memset(&buf, 0, sizeof(buf)); ScannerAnswer.copy(buf, 99); //Send answer to ScannerHandler while ((ret = write(tohandler, buf, 100)) < 0) { if (errno == EINTR) continue; break; } if (ret <= 0) break; //Pipe was closed - or some bad error //Wait for ScannerHandler to finish before we loop again - important while ((ret = read(fromhandler, buf, 1)) < 0) { if (errno == EINTR) continue; break; } if (ret <= 0) break; //Pipe was closed - or some bad error //Continue scanning? if (buf[0] == 'q') break; } //End Scanning loop return false; } bool GenericScanner::InitDatabase() { LogFile::ErrorMessage("Program Error: InitDatabase()\n"); return false; } int GenericScanner::ReloadDatabase() { LogFile::ErrorMessage("Program Error: ReloadDatabase()\n"); return -1; } void GenericScanner::FreeDatabase() { LogFile::ErrorMessage("Program Error: FreeDatabase()\n"); } string GenericScanner::Scan( const char *TempFileName ) { LogFile::ErrorMessage("Program Error: Scan()\n"); return ""; } //Scanner might not have this function, so this is allowed void GenericScanner::CloseSocket() { } //Constructor GenericScanner::GenericScanner() { } //Destructor GenericScanner::~GenericScanner() { } havp-0.93/havp/scannerhandler.h0000644000000000000000000000465313425375263015221 0ustar rootroot/*************************************************************************** scannerhandler.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCANNERHANDLER_H #define SCANNERHANDLER_H #include "default.h" #include "genericscanner.h" #include "sockethandler.h" #include #include using namespace std; class ScannerHandler { private: struct scanner_st { int toscanner; int fromscanner; string scanner_name; string scanner_name_short; pid_t scanner_pid; }; struct timeval ZeroTimeout; struct timeval ScannersTimeout; int ScannerTimeout; fd_set readfds, origfds, scannerfds; int totalscanners, top_fd, answers; vector ErrorMsg; vector VirusMsg; vector IgnoredViruses; vector Scanner; vector VirusScanner; unsigned long TempFileLength; bool DeadScanner; bool CompleteTempFile; string LastRequestURL; bool IgnoredVirus( string VirusName ); public: bool InitScanners(); bool CreateScanners( SocketHandler &ProxyServerT ); int ReloadDatabases(); bool RestartScanners(); void ExitScanners(); #ifndef NOMAND bool HasAnswer(); #endif int GetAnswer(); string GetAnswerMessage(); void LastURL( string URL ); void HaveCompleteFile(); bool InitTempFile(); bool UnlockTempFile(); bool DeleteTempFile(); bool ReinitTempFile(); bool SetTempFileSize( long long ContentLengthT ); bool TruncateTempFile( long long ContentLengthT ); bool ExpandTempFile( string &dataT, bool unlockT ); bool ExpandTempFileRange( string &dataT, long long offset ); ScannerHandler(); ~ScannerHandler(); }; #endif havp-0.93/havp/logfile.h0000644000000000000000000000322713425375263013647 0ustar rootroot/*************************************************************************** logfile.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LOGFILE_H #define LOGFILE_H #include using namespace std; class LogFile { private: static string TimeFormat; static int Error_fd; static int Virus_fd; static int Access_fd; static bool UseSyslog; static int SyslogLevel; static int SyslogVirusLevel; static int GetSyslogLevel(); static int GetSyslogVirusLevel(); static int GetSyslogFacility(); public: static bool InitLogFiles( const char *AccessLogFileT, const char *VirusLogFileT, const char *ErrorLogFileT ); static void AccessMessage( const char *formatT, ... ); static void VirusMessage( const char *formatT, ... ); static void ErrorMessage( const char *formatT, ... ); }; #endif havp-0.93/havp/genericscanner.h0000644000000000000000000000334013425375263015210 0ustar rootroot/*************************************************************************** genericscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GENERICSCANNER_H #define GENERICSCANNER_H #include "default.h" #include "sockethandler.h" #include "logfile.h" #include "params.h" #include "utils.h" #include #include #include #include #include #include #include #include using namespace std; class GenericScanner { public: string ScannerName; string ScannerNameShort; bool StartScanning( int fromhandler, int tohandler, const char *FileName ); virtual bool InitDatabase() = 0; virtual int ReloadDatabase() = 0; virtual void FreeDatabase() = 0; virtual string Scan( const char *FileName ) = 0; virtual void CloseSocket(); GenericScanner(); virtual ~GenericScanner(); }; #endif havp-0.93/havp/havp.cpp0000644000000000000000000002425613425375265013526 0ustar rootroot/*************************************************************************** havp.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "logfile.h" #include "helper.h" #include "scannerhandler.h" #include "sockethandler.h" #include "proxyhandler.h" #include "params.h" #include "whitelist.h" #include #include #include #include #include #include #include #include #include URLList Whitelist; URLList Blacklist; bool rereadall = false; bool childrestart = false; int LL = 0; //LogLevel //Needs to be here so we can delete it from signal handler etc.. char TempFileName[MAXSCANTEMPFILELENGTH+1]; int fd_tempfile = -1; int main(int argc, char *argv[]) { if ( Params::SetParams(argc,argv) == false ) { cout << "Exiting.." << endl; exit(1); } LL = Params::GetConfigInt("LOGLEVEL"); if ( Params::GetConfigBool("DISPLAYINITIALMESSAGES") ) { cout << "Starting HAVP Version: " << VERSION << endl; #ifdef NOMAND cout << "Mandatory locking disabled! KEEPBACK settings not used!" << endl; #endif } //Install signal handlers if ( InstallSignal(0) < 0 ) { cout << "Could not install signal handlers" << endl; cout << "Exiting.." << endl; exit(1); } SocketHandler ProxyServer; //Bind daemon port if ( ProxyServer.CreateServer( Params::GetConfigInt("PORT"), Params::GetConfigString("BIND_ADDRESS") ) == false ) { cout << "Could not create server (already running?)" << endl; cout << "Exiting.." << endl; exit(1); } //Change user/group ID if ( ChangeUserAndGroup(Params::GetConfigString("USER"), Params::GetConfigString("GROUP")) == false ) { cout << "Exiting.." << endl; exit(1); } //Open logs if ( LogFile::InitLogFiles( Params::GetConfigString("ACCESSLOG").c_str(), Params::GetConfigString("VIRUSLOG").c_str(), Params::GetConfigString("ERRORLOG").c_str() ) == false ) { cout << "Could not open logfiles!" << endl; cout << "Invalid permissions? Maybe you need: chown " << GetUser() << " " << Params::GetConfigString("ACCESSLOG").substr(0, Params::GetConfigString("ACCESSLOG").rfind("/")) << endl; cout << "Exiting.." << endl; exit(1); } LogFile::ErrorMessage("=== Starting HAVP Version: %s\n", VERSION); #ifdef NOMAND LogFile::ErrorMessage("=== Mandatory locking disabled! KEEPBACK settings not used!\n"); #endif LogFile::ErrorMessage("Running as user: %s, group: %s\n", GetUser().c_str(), GetGroup().c_str()); //Create lists if ( Whitelist.CreateURLList( Params::GetConfigString("WHITELIST") ) == false ) { cout << "Could not read whitelist!" << endl; cout << "Exiting.." << endl; exit(1); } if ( Blacklist.CreateURLList( Params::GetConfigString("BLACKLIST") ) == false ) { cout << "Could not read blacklist!" << endl; cout << "Exiting.." << endl; exit(1); } if ( Params::GetConfigString("PARENTPROXY") != "" ) { LogFile::ErrorMessage("Use parent proxy: %s:%d\n", Params::GetConfigString("PARENTPROXY").c_str(), Params::GetConfigInt("PARENTPORT")); } if ( Params::GetConfigBool("TRANSPARENT") ) { LogFile::ErrorMessage("Use transparent proxy mode\n"); } //Test that mandatory locking works (this leaves file with EICAR data on disk) if ( HardLockTest() == false ) { if (fd_tempfile > -1) while (close(fd_tempfile) < 0 && errno == EINTR); while (unlink(TempFileName) < 0 && (errno == EINTR || errno == EBUSY)); cout << "Exiting.." << endl; exit(1); } //Tempfile descriptor not needed anymore while (close(fd_tempfile) < 0 && errno == EINTR); fd_tempfile = -1; ScannerHandler Scanners; //Initialize scanners if ( Scanners.InitScanners() == false ) { cout << "One or more scanners failed to initialize!" << endl; cout << "Check errorlog for errors." << endl; cout << "Exiting.." << endl; while (close(fd_tempfile) < 0 && errno == EINTR); while (unlink(TempFileName) < 0 && (errno == EINTR || errno == EBUSY)); exit(1); } //We can remove the hardlock/eicar testfile now while (unlink(TempFileName) < 0 && (errno == EINTR || errno == EBUSY)); if ( Params::GetConfigBool("DAEMON") ) { if ( MakeDaemon() == false ) { cout << "Could not fork daemon" << endl; cout << "Exiting.." << endl; exit(1); } } pid_t pid = getpid(); if ( WritePidFile( pid ) == false ) { LogFile::ErrorMessage("Can not write to PIDFILE!\n"); } LogFile::ErrorMessage("Process ID: %d\n", pid); int maxservers = Params::GetConfigInt("MAXSERVERS"); int servernumber = Params::GetConfigInt("SERVERNUMBER"); int dbreload = Params::GetConfigInt("DBRELOAD"); int Instances = 0; int startchild = 0; int status; time_t LastRefresh = time(NULL); bool restartchilds = false; ProxyHandler Proxy; //Infinite Server Loop for(;;) { if ( rereadall ) //Signal Refresh { rereadall = false; LogFile::ErrorMessage("Signal HUP received, reloading scanners and lists\n"); //Reload databases int rl = Scanners.ReloadDatabases(); if ( rl == 1 ) { restartchilds = true; } else if ( rl < 0 ) { LogFile::ErrorMessage("FATAL: Library Scanners failed reloading databases, Exiting HAVP!"); killpg(getpgid(0), SIGTERM); sleep(10); exit(1); } //Reload lists Whitelist.ReloadURLList( Params::GetConfigString("WHITELIST") ); Blacklist.ReloadURLList( Params::GetConfigString("BLACKLIST") ); //Reopen logs LogFile::InitLogFiles( Params::GetConfigString("ACCESSLOG").c_str(), Params::GetConfigString("VIRUSLOG").c_str(), Params::GetConfigString("ERRORLOG").c_str() ); if ( Params::GetConfigBool("USESYSLOG") == false ) restartchilds = true; LastRefresh = time(NULL); } else if ( time(NULL) > (LastRefresh + dbreload*60) ) //Time Refresh { //Reload databases int rl = Scanners.ReloadDatabases(); if ( rl == 1 ) { restartchilds = true; } else if ( rl < 0 ) { LogFile::ErrorMessage("FATAL: Library Scanners failed database reload, stopping HAVP!"); killpg(getpgid(0), SIGTERM); sleep(10); exit(1); } LastRefresh = time(NULL); } //Send restart signal to childs if needed if ( restartchilds ) { restartchilds = false; killpg(getpgid(0), SIGUSR1); } //Clean proxyhandler zombies while (waitpid(-1, &status, WNOHANG) > 0) { Instances--; } while ((startchild > 0) || (Instances < servernumber)) { if ( (pid = fork()) < 0 ) //Fork Error { //Too many processes or out of memory? LogFile::ErrorMessage("Could not fork proxychild: %s\n", strerror(errno)); //Lets hope the the causing error goes away soon sleep(10); } else if ( pid == 0 ) //Child { //Install ProxyHandler Signals if ( InstallSignal(1) < 0 ) { LogFile::ErrorMessage("Error installing ProxyHandler signals\n"); sleep(10); exit(1); } //Create tempfile for scanning if ( Scanners.InitTempFile() == false ) { Scanners.DeleteTempFile(); sleep(10); exit(1); } //Fork scanner handler process if ( Scanners.CreateScanners( ProxyServer ) == false ) { sleep(10); exit(1); } //Start processing requests Proxy.Proxy( ProxyServer, Scanners ); exit(1); } else //Parent { if ( startchild > 0 ) startchild--; Instances++; } } //Do we need more proxy-processes? if ( Instances >= servernumber ) { bool hangup = ProxyServer.CheckForData(0); sleep(1); if ( (hangup == true) && (Instances < maxservers) ) { //Did a old process take care or is there still data? Create two if needed if ( ProxyServer.CheckForData(0) ) { if (LL>0) LogFile::ErrorMessage("All childs busy, spawning new (now: %d) - SERVERNUMBER might be too low\n", Instances+2); startchild += 2; } } } } return 0; } havp-0.93/havp/proxyhandler.cpp0000644000000000000000000015201013425375265015275 0ustar rootroot/*************************************************************************** proxyhandler.cpp - description ------------------- begin : So Feb 20 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "proxyhandler.h" #include "whitelist.h" #include "utils.h" #include #include #include #include #include extern URLList Whitelist; extern URLList Blacklist; extern int LL; //LogLevel void ProxyHandler::Proxy( SocketHandler &ProxyServerT, ScannerHandler &Scanners ) { extern bool childrestart; int ret, CommunicationAnswer, retries; bool ScannerOff = false; int requests = 0; alivecount = 0; ServerConnected = BrowserDropped = DropBrowser = false; //Wait for first connection while ( ProxyServerT.AcceptClient( ToBrowser ) == false ) sleep(10); //Infinite Processing Loop for(;;) { ++requests; ToBrowser.ClearVars(); ToServer.ClearVars(); Header = ""; ScannerUsed = UnlockDone = AnswerDone = ReinitDone = HeaderSend = DropServer = false; TransferredHeader = TransferredBody = 0; //New connection needed? if ( DropBrowser || BrowserDropped ) { ToBrowser.Close(); ToServer.Close(); ServerConnected = BrowserDropped = DropBrowser = false; alivecount = 0; //Wait for new connection while ( ProxyServerT.AcceptClient( ToBrowser ) == false ) sleep(10); } if ( ++alivecount > 1 ) { //Keep-Alive timeout 10 seconds if ( ToBrowser.CheckForData(10) == false ) { DropBrowser = true; continue; } } if ( ToBrowser.ReadHeader( Header ) == false ) { if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not read browser header\n", ToBrowser.GetIP().c_str()); DropBrowser = true; continue; } if ( (ret = ToBrowser.AnalyseHeader( Header )) < 0 ) { if (LL>0) LogFile::ErrorMessage("(%s) Invalid request from browser\n", ToBrowser.GetIP().c_str()); ProxyMessage( ret, "" ); DropBrowser = true; continue; } if ( ToBrowser.GetHost() == "" || ToBrowser.GetPort() == -1 ) { LogFile::ErrorMessage("(%s) Invalid request from browser (no Host-header?)\n", ToBrowser.GetIP().c_str()); ProxyMessage( -201, "" ); DropBrowser = true; continue; } #ifdef REWRITE ToBrowser.RewriteHost(); #endif #ifdef SSLTUNNEL //Whitelist/blacklist can not be checked on SSL requests if ( ToBrowser.GetRequestProtocol() != "connect" ) { #endif //Whitelisted? ScannerOff = Whitelist.URLFound( ToBrowser.GetHost(), ToBrowser.GetRequest() ); if ( (ScannerOff == false) || (Params::GetConfigBool("WHITELISTFIRST") == false) ) { if ( Blacklist.URLFound( ToBrowser.GetHost(), ToBrowser.GetRequest() ) ) { ToBrowser.PrepareHeaderForServer( false, parentProxy ); ProxyMessage( -45, "" ); DropBrowser = true; continue; } } #ifdef SSLTUNNEL } #endif //Keep-Alive? if ( ToBrowser.IsItKeepAlive() == false || ToBrowser.GetRequestType() != "GET" || ( (alivecount > 99) && (ToBrowser.CheckForData(0) == false) ) ) { DropBrowser = true; } //HTTP REQUEST if ( ToBrowser.GetRequestProtocol() == "http" ) { CommunicationAnswer = CommunicationHTTP( Scanners, ScannerOff ); } //FTP REQUEST else if ( ToBrowser.GetRequestProtocol() == "ftp" ) { if ( parentProxy.useProxy() ) { CommunicationAnswer = CommunicationHTTP( Scanners, ScannerOff ); } else { //TODO: Support ftp even without parentproxy :-) ProxyMessage( -110, "" ); DropBrowser = true; continue; } } #ifdef SSLTUNNEL //SSL CONNECT REQUEST else if ( ToBrowser.GetRequestProtocol() == "connect" ) { //Drop Keep-Alive ToServer.Close(); CommunicationAnswer = CommunicationSSL(); //Close connection ToServer.Close(); ServerConnected = false; if ( CommunicationAnswer != 0 ) ProxyMessage( CommunicationAnswer, "" ); DropBrowser = true; continue; } #endif else { LogFile::ErrorMessage("Program Error: Unsupported RequestProtocol: %s\n", ToBrowser.GetRequestProtocol().c_str()); DropBrowser = true; continue; } //Retry GET connection if ReadHeader error (-80) or Connect error (-60, -61) //Also reconnect if server closed Keep-Alive connection (-60) retries = 0; while ( (CommunicationAnswer == -80 && ToBrowser.GetRequestType() == "GET") || CommunicationAnswer == -60 || CommunicationAnswer == -61 ) { ToServer.Close(); ServerConnected = false; //Sleep second before retry sleep(1); CommunicationAnswer = CommunicationHTTP( Scanners, ScannerOff ); //No need to stop Keep-Alive if retry is clean if ( CommunicationAnswer == 0 ) DropServer = false; //Too many retries? if ( ++retries >= ToServer.IPCount() ) break; } //Make sure server connection is closed if needed if ( DropServer || DropBrowser || BrowserDropped ) { ToServer.Close(); ServerConnected = false; } //Check scanners if ( ScannerUsed ) { #ifndef NOMAND if ( UnlockDone == false ) Scanners.UnlockTempFile(); #endif if ( AnswerDone == false ) Scanners.GetAnswer(); } if ( CommunicationAnswer != 0 ) { //Request not clean ProxyMessage( CommunicationAnswer, Scanners.GetAnswerMessage() ); DropBrowser = true; } else if ( Params::GetConfigBool("LOG_OKS") ) { //Clean request LogFile::AccessMessage("%s %s %d %s %d+%lld OK\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody); } //If some scanner timed out, bail out.. if ( CommunicationAnswer == 3 ) break; //Signal scanners if ( ScannerUsed ) { //Exit processes if restart signaled or maximum reqs reached if ( (DropBrowser || BrowserDropped) && (childrestart || (requests > 1000)) ) { //Kill all scanners Scanners.ExitScanners(); //Exit processing loop break; } //Reinit tempfile if ( ReinitDone == false ) Scanners.ReinitTempFile(); //Signal scanners to get ready again if ( Scanners.RestartScanners() == false ) { //Some scanner did not restart, exit processing loop break; } } } //Make sure browser connection is closed ToBrowser.Close(); //Delete Tempfile Scanners.DeleteTempFile(); //Exit process exit(1); } int ProxyHandler::CommunicationHTTP( ScannerHandler &Scanners, bool ScannerOff ) { string HeaderToServer = ToBrowser.PrepareHeaderForServer( ScannerOff, parentProxy ); long long ContentLengthReference = ToBrowser.GetContentLength(); //Check that POST has Content-Length if ( (ToBrowser.GetRequestType() == "POST") && (ContentLengthReference == -1) ) { BrowserDropped = true; LogFile::ErrorMessage("(%s) Browser POST without Content-Length header\n", ToBrowser.GetIP().c_str()); return -10; } //Make server connection if ( parentProxy.useProxy() ) { if ( ServerConnected == false ) { if ( ToServer.SetDomainAndPort( parentProxy.getHost(), parentProxy.getPort() ) == false ) { LogFile::ErrorMessage("Could not resolve parent proxy (%s)\n", parentProxy.getHost().c_str()); return -51; } if ( ToServer.ConnectToServer() == false ) { LogFile::ErrorMessage("Could not connect to parent proxy (%s/%s:%d)\n", ToServer.GetIP().c_str(), parentProxy.getHost().c_str(), parentProxy.getPort()); return -61; } } } else { //We need to close Keep-Alive connection if host to connect changes if ( ServerConnected && (ToBrowser.GetHost() != ConnectedHost || ToBrowser.GetPort() != ConnectedPort) ) { ToServer.Close(); ServerConnected = false; } if ( ServerConnected == false ) { if ( ToServer.SetDomainAndPort( ToBrowser.GetHost(), ToBrowser.GetPort() ) == false ) { if (LL>0) LogFile::ErrorMessage("Could not resolve hostname (%s)\n", ToBrowser.GetHost().c_str() ); return -50; } if ( ToServer.ConnectToServer() == false ) { if (LL>0) LogFile::ErrorMessage("Could not connect to server (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -60; } ConnectedHost = ToBrowser.GetHost(); ConnectedPort = ToBrowser.GetPort(); } } //We are now connected ServerConnected = true; //Update requested URL to Scannerhandler, we can report it on some errors then Scanners.LastURL( ToBrowser.GetCompleteRequest() ); //Send header to server if ( ToServer.SendHeader( HeaderToServer, DropBrowser ) == false ) { if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to server (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -60; } //Check for client body if ( ContentLengthReference >= 0 ) { //Transfer body if there is some if ( ContentLengthReference > 0 ) { int repeat = int (ContentLengthReference / MAXRECV); string Body; for(int i=0; i <= repeat; i++) { Body = ""; if ( i == repeat ) { int rest = ContentLengthReference - (MAXRECV * repeat); if ( ToBrowser.RecvLength( Body, rest ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not read browser body\n", ToBrowser.GetIP().c_str()); return -10; } } else { if ( ToBrowser.RecvLength( Body, MAXRECV ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not read browser body\n", ToBrowser.GetIP().c_str()); return -10; } } if ( ToServer.Send( Body ) == false ) { if (LL>0) LogFile::ErrorMessage("(%s) Could not send browser body to server (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -76; } } } //Check for extra CRLF (IE Bug or Content-Length: 0) if ( ToBrowser.CheckForData(0) ) { string TempString; if ( ToBrowser.Recv( TempString, true, -1 ) < 0 ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not finish browser body transfer\n", ToBrowser.GetIP().c_str()); return -10; } //It is OK if browser finished (empty) or extra CRLF received if ( TempString.find_first_not_of( "\r\n", 0 ) != string::npos ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Browser body was too long\n", ToBrowser.GetIP().c_str()); return -10; } } } //Get response from server if ( ToServer.ReadHeader( Header ) == false ) { if (LL>0) LogFile::ErrorMessage("(%s) Could not read server header (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -80; } TransferredHeader = Header.size(); //Analyse server headers int ret = ToServer.AnalyseHeader( Header ); if ( ret < 0 ) { if (LL>0) LogFile::ErrorMessage("(%s) Invalid server header received (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return ret; } //Check if server sent partial response when not allowed if ( (ToServer.GetResponse() == 206) && (Params::GetConfigBool("RANGE") == false) ) { //If whitelisted or streaming User-Agent, we do allow partial if ( (ScannerOff == false) && ( ToBrowser.IsItStreamAgent() == false) ) { if (LL>0) LogFile::ErrorMessage("(%s) Server tried to send partial data and RANGE set to false (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -231; } } //Server did not send Keep-Alive header, close after request (we can keep browser open) if ( ToServer.IsItKeepAlive() == false ) DropServer = true; //Get Content-Length ContentLengthReference = ToServer.GetContentLength(); //Chunked workaround? bool ChunkedTransfer = ToServer.IsItChunked(); if ( ContentLengthReference == -1 ) { //No Keep-Alive for unknown length DropBrowser = true; } else if ( ChunkedTransfer ) { // Chunked transfer not allowed with Content-Length LogFile::ErrorMessage("(%s) Invalid server header received, Chunked encoding with Content-Length (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -233; } if ( ChunkedTransfer ) DropBrowser = true; Header = ToServer.PrepareHeaderForBrowser(); //No body expected? Not much to be done then if ( (ToServer.GetResponse() == 304) || (ContentLengthReference == 0) || (ToBrowser.GetRequestType() == "HEAD") || (ToServer.GetResponse() == 204) ) { //Send header to browser if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } //Check for extra CRLF if ( ToServer.CheckForData(0) ) { string BodyTemp; ssize_t BodyLength = ToServer.Recv( BodyTemp, true, -1 ); if ( (BodyLength > 0) && (BodyTemp.find_first_not_of( "\r\n", 0 ) != string::npos) ) { if (LL>0) LogFile::ErrorMessage("(%s) Server tried to send body when not expected (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; } } //Return clean return 0; } if ( (ContentLengthReference > 0) && (ContentLengthReference < 25) ) { //Forget scanning for tiny files ScannerOff = true; } else if ( (MaxDownloadSize != 0) && (ScannerOff == false) && (MaxDownloadSize < ContentLengthReference) ) { //File too large for downloading DropServer = true; return -250; } unsigned int MaxScanSize = Params::GetConfigInt("MAXSCANSIZE"); //For streaming User-Agents, check if we need scanning if ( ToBrowser.IsItStreamAgent() ) { if ( Params::GetConfigInt("STREAMSCANSIZE") > 0 ) { MaxScanSize = Params::GetConfigInt("STREAMSCANSIZE"); } else { ScannerOff = true; } } //Failsafe limit if ( MaxScanSize == 0 ) MaxScanSize = MAXFILELOCKSIZE; //Read first part of body string BodyTemp; ssize_t BodyLength = ToServer.ReadBodyPart( BodyTemp, ChunkedTransfer ); //Server disconnected? if ( BodyLength < 0 ) { DropServer = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not read initial server body (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -74; } //Nothing received? if ( BodyLength == 0 ) { //Lets be safe and close all connections DropBrowser = true; //Send header to browser if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } //Return clean return 0; } // ScanMime / SkipMime ACL if ( ToServer.IsScannableMime() == false ) { ScannerOff = true; } //Scan JPG? GIF? PNG? else if ( Params::GetConfigBool("SCANIMAGES") == false && ToServer.IsItImage() && ( MatchBegin( BodyTemp, "\255\216\255\224", 4 ) || MatchBegin( BodyTemp, "GIF8", 4 ) || MatchBegin( BodyTemp, "\137PNG", 4 ) ) ) { ScannerOff = true; } //If scanning is not needed, use this quick send loop if ( ScannerOff ) { //Send header to browser if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } long long ContentLength = BodyLength; TransferredBody = ContentLength; //Server Body Transfer Loop for(;;) { //If we received more than Content-Length, discard the rest if ( (ContentLengthReference > 0) && (ContentLength > ContentLengthReference) ) { BodyTemp.erase( BodyTemp.size() - (ContentLength - ContentLengthReference) ); ContentLength = ContentLengthReference; if (LL>0) LogFile::ErrorMessage("(%s) Server sent more than Content-Length (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); //Drop server connection (we can keep browser open) DropServer = true; } //Send body to browser if ( ToBrowser.Send( BodyTemp ) == false ) { BrowserDropped = true; if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not send body to browser\n", ToBrowser.GetIP().c_str()); return -10; } //File completely received? if ( ContentLength == ContentLengthReference ) break; //Read more of body if ( (BodyLength = ToServer.ReadBodyPart( BodyTemp, ChunkedTransfer )) < 0 ) { DropServer = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not read server body (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -75; } //Server finished, end loop if ( BodyLength == 0 ) { //If we did not receive all data, close all connections if ( ContentLength < ContentLengthReference ) DropBrowser = true; break; } ContentLength += BodyLength; TransferredBody = ContentLength; //Continue bodyloop.. } //Return clean return 0; } // // Scanning is needed, so lets go.. // //Set initial values long long ContentLength = BodyLength; TransferredBody = ContentLength; long long TransferDataLength = BodyLength; deque BodyQueue; deque ::iterator TransferData; bool PartlyUnlock = false; bool ReScan = false; bool ZipFinished = false; #ifndef NOMAND bool NoKeepBack = false; #endif //Scanner will be used and needs to be reinitialized later ScannerUsed = true; //No scanners answer yet int TempScannerAnswer = -1; //Start trickling/keepbacktime time_t LastTrickling = time(NULL); time_t Now; long long TempLengthReference = 0; //Allocate file fully if we have Content-Length, up to MAXSCANSIZE/MAXFILELOCKSIZE if ( ContentLengthReference > 0 ) { if ( ContentLengthReference > MaxScanSize ) { TempLengthReference = MaxScanSize; } else { TempLengthReference = ContentLengthReference; } if ( Scanners.SetTempFileSize( TempLengthReference ) == false ) { LogFile::ErrorMessage("(%s) Could not create tempfile, check disk space! (%lld bytes from %s/%s:%d)\n", ToServer.GetIP().c_str(), ContentLengthReference, ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -100; } #ifndef NOMAND //Check if we need to work around ClamAV mmap() handling (for example) //These can fail if trying to scan locked file: BinHex, PDF //Also Zip files for 0.93 if ( DontLock || ( (DontLockBINHEX && MatchBegin( BodyTemp, "(This file", 10 )) || (DontLockPDF && MatchBegin( BodyTemp, "%PDF-", 5 )) || (DontLockZIP && (MatchBegin( BodyTemp, "PK\003\004", 4 ) || MatchBegin( BodyTemp, "PK00PK\003\004", 8)) ) ) ) { //No partial unlock PartlyUnlock = false; } else { #endif //Partial unlocking - dynamic scanning PartlyUnlock = true; #ifndef NOMAND } #endif } string Zipheader = ""; //Try to get ZIP header first for large files if ( (Params::GetConfigBool("PRELOADZIPHEADER") == true) && ( ContentLengthReference > 1000000 ) #ifndef NOMAND && ( MaxScanSize == 0 || MaxScanSize > 1000000 ) #else && ( MaxScanSize > 1000000 && MaxScanSize < ContentLengthReference ) #endif && ( MatchBegin( BodyTemp, "PK\003\004", 4 ) || MatchBegin( BodyTemp, "PK00PK\003\004", 8 ) ) ) { string RangeServer; int RangePort; if ( parentProxy.useProxy() ) { RangeServer = parentProxy.getHost(); RangePort = parentProxy.getPort(); } else { RangeServer = ToBrowser.GetHost(); RangePort = ToBrowser.GetPort(); } char templen[21]; memset(&templen, 0, sizeof(templen)); snprintf(templen, 20, "%lld", ContentLengthReference - 131072); string OffsetStart = templen; memset(&templen, 0, sizeof(templen)); snprintf(templen, 20, "%lld", ContentLengthReference); string OffsetEnd = templen; string RangeStr = "Range: bytes=" + OffsetStart + "-" + OffsetEnd; RangeStr += "\r\nConnection: close\r\n\r\n"; string HeaderToSend = HeaderToServer + RangeStr; for(;;) { ConnectionToHTTP RangeRequest; string RangeResponse; if ( RangeRequest.SetDomainAndPort( RangeServer, RangePort ) == false ) { break; } if ( RangeRequest.ConnectToServer() == false ) { RangeRequest.Close(); break; } if ( RangeRequest.Send( HeaderToSend ) == false ) { RangeRequest.Close(); break; } if ( RangeRequest.ReadHeader( RangeResponse ) == false ) { RangeRequest.Close(); break; } if ( RangeResponse.find(" 206", 8) != string::npos ) { ssize_t RangeBodyLength; ssize_t RangeReceived = 0; string RangeBody; while ( (RangeBodyLength = RangeRequest.Recv( RangeBody, true, -1 )) > 0 ) { RangeReceived += RangeBodyLength; if ( RangeReceived >= 131072 ) break; } RangeRequest.Close(); if ( RangeBody.size() != 131072 ) break; if ( RangeBody.find( "PK\005\006", 0 ) == string::npos ) break; if ( Scanners.ExpandTempFileRange( RangeBody, TempLengthReference - 131072 ) == false ) { break; } Zipheader = RangeBody; } break; } } //Body Scanning/Transfer Loop for(;;) { //If we received more than Content-Length, discard the rest if ( (ContentLengthReference > 0) && (ContentLength > ContentLengthReference) ) { BodyTemp.erase( BodyTemp.size() - (ContentLength - ContentLengthReference) ); TransferDataLength -= (ContentLength - ContentLengthReference); TransferredBody -= (ContentLength - ContentLengthReference); ContentLength = ContentLengthReference; if (LL>0) LogFile::ErrorMessage("(%s) Server sent more than Content-Length (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); //Drop server connection (we can keep browser open) DropServer = true; } //If we have ZIP header, don't read it from server again if ( Zipheader.size() ) { //Everything received from server, append ZIP header if ( TransferredBody >= (ContentLengthReference - Zipheader.size()) ) { ToServer.Close(); ServerConnected = false; BodyTemp.erase( (ContentLengthReference - Zipheader.size()) - (TransferredBody - BodyTemp.size()) ); BodyQueue.push_back( BodyTemp ); BodyQueue.push_back( Zipheader ); TransferredBody += Zipheader.size(); Zipheader = ""; if ( Scanners.ExpandTempFile( BodyTemp, PartlyUnlock ) == false ) { LogFile::ErrorMessage("(%s) Could not expand tempfile, check disk space! (%lld bytes from %s/%s:%d)\n", ToServer.GetIP().c_str(), ContentLengthReference, ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -100; } //Exit bodyloop Scanners.HaveCompleteFile(); break; } //Received MAXSCANSIZE, need to finish tempfile else if ( (UnlockDone == false) && (TransferredBody >= (TempLengthReference - Zipheader.size())) ) { string BodyTemp2 = BodyTemp.substr( 0, (TempLengthReference - Zipheader.size()) - (TransferredBody - BodyTemp.size()) ); if ( Scanners.ExpandTempFile( BodyTemp2, PartlyUnlock ) == false ) { LogFile::ErrorMessage("(%s) Could not expand tempfile, check disk space! (%lld bytes from %s/%s:%d)\n", ToServer.GetIP().c_str(), ContentLengthReference, ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -100; } //Keep going bodyloop - check scanner there ZipFinished = true; } } //Add bodypart to send queue BodyQueue.push_back( BodyTemp ); //Check if we have exceeded MAXSCANSIZE if ( UnlockDone == false && (ContentLength > MaxScanSize || ZipFinished) ) { #ifndef NOMAND //Unlock file now so all scanners can finish Scanners.UnlockTempFile(); #endif AnswerDone = UnlockDone = true; //Check scanner results TempScannerAnswer = Scanners.GetAnswer(); //Reinitialize tempfile, it is not needed on disk anymore Scanners.ReinitTempFile(); ReinitDone = true; //Exit bodyloop only if virus found, ignore scanner errors //because incomplete archives might produce them if ( TempScannerAnswer == 1 ) break; TempScannerAnswer = 0; } //Expand file if scanning is not yet finished if ( UnlockDone == false ) { if ( Scanners.ExpandTempFile( BodyTemp, PartlyUnlock ) == false ) { LogFile::ErrorMessage("(%s) Could not expand tempfile, check disk space! (%lld bytes from %s/%s:%d)\n", ToServer.GetIP().c_str(), ContentLengthReference, ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -100; } } //Exit bodyloop because file is complete if ( ContentLength == ContentLengthReference ) { Scanners.HaveCompleteFile(); break; } #ifndef NOMAND //Check if virus was found or all scanners said clean already if ( PartlyUnlock && ReinitDone == false && Scanners.HasAnswer() ) { AnswerDone = true; //Unlock file now so all scanners can finish if ( UnlockDone == false ) { Scanners.UnlockTempFile(); UnlockDone = true; } //Get Answer TempScannerAnswer = Scanners.GetAnswer(); //Exit bodyloop if not clean! if ( TempScannerAnswer != 0 ) break; //Reinitialize tempfile, it is not needed on disk anymore Scanners.ReinitTempFile(); ReinitDone = true; //Continue bodyloop so browser receives all data } #endif Now = time(NULL); #ifdef NOMAND //Send data if scanning was clean if ( TempScannerAnswer == 0 ) { TransferData = BodyQueue.begin(); #else //Wait for KeepBackTime to pass if ( NoKeepBack || (LastTrickling + KeepBackTime < Now) ) { //Dont check KeepBackTime anymore NoKeepBack = true; TransferData = BodyQueue.begin(); //Send data if we have enough in buffer or scanning was clean if ( (TempScannerAnswer == 0) || (KeepBackBuffer < (TransferDataLength - TransferData->size())) ) { #endif //Send header only once if ( HeaderSend == false ) { HeaderSend = true; if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } } BodyTemp = *TransferData; TransferDataLength -= BodyTemp.size(); if ( ToBrowser.Send( BodyTemp ) == false ) { BrowserDropped = true; if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not send body to browser\n", ToBrowser.GetIP().c_str()); return -10; } BodyQueue.erase( TransferData ); } //Else check trickling else if ( TricklingTime > 0 && BodyQueue.size() > 0 && LastTrickling + TricklingTime < Now ) { //Send header only once if ( HeaderSend == false ) { HeaderSend = true; if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } } LastTrickling = Now; string TData = ""; do { TransferData = BodyQueue.begin(); TData += TransferData->substr( 0, TricklingBytes ); TransferData->erase( 0, TricklingBytes ); if ( TransferData->size() == 0 ) BodyQueue.erase( TransferData ); } while ( TData.size() < TricklingBytes && BodyQueue.size() > 0 ); TransferDataLength -= TData.size(); if ( ToBrowser.Send( TData ) == false ) { BrowserDropped = true; if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not send body to browser\n", ToBrowser.GetIP().c_str()); return -10; } } #ifndef NOMAND } #endif //Read more of body if ( (BodyLength = ToServer.ReadBodyPart( BodyTemp, ChunkedTransfer )) < 0 ) { DropServer = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not read server body (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -75; } ContentLength += BodyLength; TransferredBody = ContentLength; TransferDataLength += BodyLength; //Check if file is too large for downloading if ( MaxDownloadSize > 0 && ContentLength > MaxDownloadSize ) { DropServer = true; return -250; } //Server finished, end bodyloop if ( BodyLength == 0 ) { //If we did not receive all data, close all connections if ( ContentLength < ContentLengthReference ) { DropBrowser = true; //We need a rescan if no full unlock done yet if ( AnswerDone == false ) ReScan = true; //Exit bodyloop break; } //Exit bodyloop Scanners.HaveCompleteFile(); break; } //Continue bodyloop.. } //Close connection to server if needed if ( DropServer || DropBrowser ) { ToServer.Close(); ServerConnected = false; } #ifndef NOMAND //Unlock if needed if ( UnlockDone == false ) { Scanners.UnlockTempFile(); UnlockDone = true; } #endif //Get answer if needed if ( AnswerDone == false ) { #ifdef NOMAND //Truncate file to received size if ( ReScan ) Scanners.TruncateTempFile( ContentLength ); #endif TempScannerAnswer = Scanners.GetAnswer(); AnswerDone = true; } #ifndef NOMAND //Rescan tempfile if we didn't receive all Content-Length //It might have confused scanners with wrong filesize if ( ReScan && (TempScannerAnswer != 1) ) { //Truncate file to received size Scanners.TruncateTempFile( ContentLength ); //Tell scanners to start scanning again if ( Scanners.RestartScanners() == false ) { //Bail out on error.. ToBrowser.Close(); Scanners.DeleteTempFile(); exit(1); } //Get new answer TempScannerAnswer = Scanners.GetAnswer(); AnswerDone = true; } #endif //Reinit if needed if ( ReinitDone == false ) { Scanners.ReinitTempFile(); ReinitDone = true; } //Virus or error? if ( TempScannerAnswer != 0 ) return TempScannerAnswer; //Send remaining data to browser if ( HeaderSend == false ) { HeaderSend = true; if ( ToBrowser.SendHeader( Header, DropBrowser ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } } for ( TransferData = BodyQueue.begin(); TransferData != BodyQueue.end(); ++TransferData ) { BodyTemp = *TransferData; if ( ToBrowser.Send( BodyTemp ) == false ) { BrowserDropped = true; if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not send body to browser\n", ToBrowser.GetIP().c_str()); return -10; } } //Return clean return 0; } //Not yet implemented.. int ProxyHandler::CommunicationFTP( ScannerHandler &Scanners, bool ScannerOff ) { return 0; } #ifdef SSLTUNNEL int ProxyHandler::CommunicationSSL() { string BodyTemp; ssize_t BodyLength; Header = ToBrowser.PrepareHeaderForServer( false, parentProxy ); if ( parentProxy.useProxy() ) { if ( ToServer.SetDomainAndPort( parentProxy.getHost(), parentProxy.getPort() ) == false ) { LogFile::ErrorMessage("Could not resolve parent proxy (%s)\n", parentProxy.getHost().c_str() ); return -51; } if ( ToServer.ConnectToServer() == false ) { LogFile::ErrorMessage("Could not connect to parent proxy (%s/%s:%d)\n", ToServer.GetIP().c_str(), parentProxy.getHost().c_str(), parentProxy.getPort()); return -61; } if ( ToServer.SendHeader( Header, true ) == false ) { if (LL>0) LogFile::ErrorMessage("Could not send header to server (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -60; } if ( ToServer.ReadHeader( Header ) == false ) { if (LL>0) LogFile::ErrorMessage("Could not read server header (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); DropServer = true; return -80; } string::size_type Position = Header.find_first_of("0123456789", Header.find(" ")); if ( Position == string::npos ) { if (LL>0) LogFile::ErrorMessage("Invalid HTTP response from parent proxy to SSL tunnel\n"); return -300; } //If response not 200, we have some error from parent proxy if ( Header.substr(Position, 3) != "200" ) { //Send header to browser if ( ToBrowser.SendHeader( Header, true ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send header to browser\n", ToBrowser.GetIP().c_str()); return -10; } long long ContentLengthReference = ToServer.GetContentLength(); //No body expected? if ( ContentLengthReference == 0 ) return 0; long long ContentLength = 0; //Server Body Transfer Loop for(;;) { //Read Body if ( (BodyLength = ToServer.ReadBodyPart( BodyTemp, false )) < 0 ) { if (LL>0) LogFile::ErrorMessage("(%s) Could not read server body (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), parentProxy.getHost().c_str(), parentProxy.getPort()); DropServer = true; return -75; } //If server finished, exit loop if ( BodyLength == 0 ) break; ContentLength += BodyLength; TransferredBody = ContentLength; //If we received more than Content-Length, discard the rest if ( (ContentLengthReference > 0) && (ContentLength > ContentLengthReference) ) { BodyTemp.erase( BodyTemp.size() - (ContentLength - ContentLengthReference) ); ContentLength = ContentLengthReference; if (LL>0) LogFile::ErrorMessage("(%s) Server sent more than Content-Length (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetIP().c_str(), parentProxy.getHost().c_str(), parentProxy.getPort()); } //Send body to browser if ( ToBrowser.Send( BodyTemp ) == false ) { BrowserDropped = true; if (LL>0) if (alivecount==1) LogFile::ErrorMessage("(%s) Could not send body to browser\n", ToBrowser.GetIP().c_str()); return -10; } //File completely received? if ( ContentLength == ContentLengthReference ) break; } if (LL>0) LogFile::ErrorMessage("(%s) SSL tunneling failed through parentproxy (response: %s)\n", ToBrowser.GetIP().c_str(), Header.substr(Position, 3).c_str()); return 0; } } else { if ( ToServer.SetDomainAndPort( ToBrowser.GetHost(), ToBrowser.GetPort() ) == false ) { if (LL>0) LogFile::ErrorMessage("Could not resolve hostname: %s\n", ToBrowser.GetHost().c_str() ); return -50; } if ( ToServer.ConnectToServer() == false ) { if (LL>0) LogFile::ErrorMessage("Could not connect to server (%s/%s:%d)\n", ToServer.GetIP().c_str(), ToBrowser.GetHost().c_str(), ToBrowser.GetPort()); return -60; } } Header = "HTTP/1.0 200 Connection established\r\n"; if ( ToBrowser.SendHeader( Header, true ) == false ) { BrowserDropped = true; if (LL>0) LogFile::ErrorMessage("(%s) Could not send SSL header to browser\n", ToBrowser.GetIP().c_str()); return -10; } int ret; while ( (ret = ToBrowser.CheckForSSLData( ToBrowser.sock_fd, ToServer.sock_fd )) > 0 ) { if ( ret == 2 ) { BodyLength = ToServer.ReadBodyPart( BodyTemp, false ); if ( BodyLength < 1 ) break; if ( ToBrowser.Send( BodyTemp ) == false ) break; continue; } else if ( ret == 1 ) { BodyLength = ToBrowser.ReadBodyPart( BodyTemp, false ); if ( BodyLength < 1 ) break; if ( ToServer.Send( BodyTemp ) == false ) break; continue; } } return 0; } #endif bool ProxyHandler::ProxyMessage( int CommunicationAnswerT, string Answer ) { string filename = ""; string message = ""; switch ( CommunicationAnswerT ) { case -10: //Browser Dropped if ( Params::GetConfigBool("LOG_OKS") ) { LogFile::AccessMessage("%s %s %d %s %d+%lld OK\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody); } break; case -45: LogFile::AccessMessage("%s %s %d %s %d+%lld BLACKLIST\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody); message = ToBrowser.GetCompleteRequest(); filename = ERROR_BLACKLIST; break; case -50: message = ToBrowser.GetHost(); filename = ERROR_DNS; break; case -51: message = "Parentproxy did not resolve"; filename = ERROR_DNS; break; case -60: message = "Connection failed"; filename = ERROR_DOWN; break; case -61: message = "Parentproxy down"; filename = ERROR_DOWN; break; case -74: message = "Zero sized reply"; filename = ERROR_DOWN; break; case -75: message = "Could not read body"; filename = ERROR_DOWN; break; case -76: message = "Could not send body"; filename = ERROR_DOWN; break; case -80: message = "Could not read headers"; filename = ERROR_DOWN; break; case -100: message = "Not enough free space on server"; filename = ERROR_SCANNER; break; case -110: message = "FTP is currently supported only
if PARENTPROXY is used!"; filename = ERROR_REQUEST; break; case -201: message = "Invalid request"; filename = ERROR_REQUEST; break; case -202: message = "Invalid request method"; filename = ERROR_REQUEST; break; case -210: message = "Hostname too long"; filename = ERROR_REQUEST; break; case -211: message = "Port not allowed"; filename = ERROR_REQUEST; break; case -212: message = "Invalid port"; filename = ERROR_REQUEST; break; case -215: message = "Unsupported protocol"; filename = ERROR_REQUEST; break; case -230: message = "Invalid HTTP response from server"; filename = ERROR_REQUEST; break; case -231: message = "Server tried to send partial data
and RANGE is set to false"; filename = ERROR_REQUEST; break; case -232: message = "Server sent forbidden Transfer-Encoding header"; filename = ERROR_REQUEST; break; case -233: message = "Server sent Chunked response with Content-Length"; filename = ERROR_REQUEST; break; case -250: //File larger than MAXDOWNLOADSIZE LogFile::AccessMessage("%s %s %d %s %d+%lld OVERMAXSIZE\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody); message = ToBrowser.GetCompleteRequest(); filename = ERROR_MAXSIZE; break; #ifdef SSLTUNNEL case -300: message = "SSL tunneling failed through parentproxy"; filename = ERROR_REQUEST; break; #endif case 1: //Virus LogFile::VirusMessage("%s %s %d %s %d+%lld VIRUS %s\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody, Answer.c_str()); SearchReplace( Answer, ", ", "
" ); message = Answer; filename = VIRUS_FOUND; break; case 2: //Error case 3: //Scanner timeout LogFile::AccessMessage("%s %s %d %s %d+%lld SCANERROR %s\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody, Answer.c_str()); message = Answer; filename = ERROR_SCANNER; break; default: //Log if we have error not defined above.. all should be there! LogFile::ErrorMessage("Program Error: Unknown Error %d\n", CommunicationAnswerT); char ErrorNumber[11]; snprintf(ErrorNumber, 10, "%d", CommunicationAnswerT); message = ErrorNumber; filename = ERROR_BODY; break; } //Check these here so we have logged possible viruses and errors above if ( BrowserDropped ) return false; //Send report to browser if possible if ( HeaderSend == false ) { string UA = ToBrowser.GetUserAgent(); string Code; //IE and Show friendly HTTP errors :( if ( UA.find("MSIE") != string::npos ) { Code = "200"; } else { Code = "403"; } //Start header string errorheader = "HTTP/1.0 " + Code + " "; //Create header body if ( filename == ERROR_DNS ) { errorheader += "DNS error by HAVP"; } else if ( filename == ERROR_DOWN ) { errorheader += "Server down by HAVP"; } else if ( filename == ERROR_REQUEST ) { errorheader += "Request error by HAVP"; } else if ( filename == VIRUS_FOUND ) { errorheader += "Virus found by HAVP"; } else if ( filename == ERROR_SCANNER ) { errorheader += "Scanner error by HAVP"; } else if ( filename == ERROR_BLACKLIST ) { errorheader += "Blacklisted by HAVP"; } else { errorheader += "Forbidden by HAVP"; } //End header errorheader += "\r\nContent-Type: text/html\r\nProxy-Connection: close\r\nConnection: close\r\n\r\n"; if ( ToBrowser.Send( errorheader ) == false ) { return false; } } //Send report page, but for HEAD request body is not allowed if ( (filename != "") && (ToBrowser.GetRequestType() != "HEAD") ) { string path = Params::GetConfigString("TEMPLATEPATH"); filename = path + "/" + filename; ifstream tfile( filename.c_str() ); if ( !tfile ) { string TemplateError = "HAVP could not open Template! Check errorlog and config!"; if ( ToBrowser.Send( TemplateError ) == false ) BrowserDropped = true; return false; } string Response = ""; string Buffer; while ( getline( tfile, Buffer ) ) { Response += Buffer; } tfile.close(); if ( Response != "" ) { SearchReplace( Response, "", message ); SearchReplace( Response, "", ToBrowser.GetIP() ); SearchReplace( Response, "", ToBrowser.GetCompleteRequest() ); if ( ToBrowser.Send( Response ) == false ) BrowserDropped = true; } } return false; } //Constructor ProxyHandler::ProxyHandler() { MaxDownloadSize = Params::GetConfigInt("MAXDOWNLOADSIZE"); KeepBackTime = Params::GetConfigInt("KEEPBACKTIME"); TricklingTime = Params::GetConfigInt("TRICKLING"); TricklingBytes = Params::GetConfigInt("TRICKLINGBYTES"); KeepBackBuffer = Params::GetConfigInt("KEEPBACKBUFFER"); Header.reserve(20000); string DontLockStr = UpperCase( Params::GetConfigString("DISABLELOCKINGFOR") ); DontLock = DontLockBINHEX = DontLockPDF = DontLockZIP = false; if ( Params::GetConfigBool("ENABLECLAMLIB") || Params::GetConfigBool("ENABLECLAMD") ) { if ( MatchSubstr( DontLockStr, "CLAMAV:BINHEX", -1 ) ) DontLockBINHEX = true; if ( MatchSubstr( DontLockStr, "CLAMAV:PDF", -1 ) ) DontLockPDF = true; if ( MatchSubstr( DontLockStr, "CLAMAV:ZIP", -1 ) ) DontLockZIP = true; } if ( Params::GetConfigBool("ENABLEAVG") ) { if ( MatchSubstr( DontLockStr, "AVG:ALL", -1 ) ) DontLock = true; } } //Destructor ProxyHandler::~ProxyHandler() { } ProxyDetails::ProxyDetails() : UseParentProxy(false), ParentHost(""), ParentPort(-1), UseParentProxyAuth(false), ParentUser(""), ParentPassword("") { if ( Params::GetConfigString("PARENTPROXY") != "" ) { UseParentProxy = true; ParentHost = Params::GetConfigString("PARENTPROXY"); ParentPort = Params::GetConfigInt("PARENTPORT"); } if (UseParentProxy && \ (Params::GetConfigString("PARENTUSER") != "" || \ Params::GetConfigString("PARENTPASSWORD") != "")){ UseParentProxyAuth = true; ParentUser = Params::GetConfigString("PARENTUSER"); ParentPassword = Params::GetConfigString("PARENTPASSWORD"); } } havp-0.93/havp/logfile.cpp0000644000000000000000000001567313425375265014214 0ustar rootroot/*************************************************************************** logfile.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "logfile.h" #include "params.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #define LOGSTRINGLENGTH 1000 string LogFile::TimeFormat; int LogFile::Access_fd = -1; int LogFile::Virus_fd = -1; int LogFile::Error_fd = -1; bool LogFile::UseSyslog = false; int LogFile::SyslogLevel; int LogFile::SyslogVirusLevel; //Open access and error logfiles bool LogFile::InitLogFiles( const char *AccessLogFileT, const char *VirusLogFileT, const char *ErrorLogFileT ) { TimeFormat = Params::GetConfigString("TIMEFORMAT") + " "; if ( Params::GetConfigBool("USESYSLOG") ) { //Already open? if ( UseSyslog ) return true; UseSyslog = true; SyslogLevel = GetSyslogLevel(); SyslogVirusLevel = GetSyslogVirusLevel(); openlog(Params::GetConfigString("SYSLOGNAME").c_str(), LOG_CONS | LOG_PID, GetSyslogFacility()); return true; } if ( Error_fd > -1 ) close(Error_fd); if ( Virus_fd != Access_fd && Virus_fd > -1 ) close(Virus_fd); if ( Access_fd > -1 ) close(Access_fd); if ( (Error_fd = open(ErrorLogFileT, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) { return false; } if ( (Access_fd = open(AccessLogFileT, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) { return false; } if ( strcmp(VirusLogFileT, AccessLogFileT) == 0 || strlen(VirusLogFileT) == 0 ) { Virus_fd = Access_fd; } else if ( (Virus_fd = open(VirusLogFileT, O_WRONLY|O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP)) < 0) { return false; } return true; } //Log access messages void LogFile::AccessMessage( const char *formatT , ... ) { char str[LOGSTRINGLENGTH+1]; va_list args; va_start(args, formatT); vsnprintf(str, LOGSTRINGLENGTH, formatT, args); va_end(args); if ( UseSyslog ) { syslog(SyslogLevel, "%s", str); } else { char strt[LOGSTRINGLENGTH+1]; char tmpdate[51]; time_t now = time(NULL); struct tm TmDate = *localtime(&now); strftime(tmpdate, 50, TimeFormat.c_str(), &TmDate); strncpy(strt, tmpdate, sizeof(tmpdate)); strncat(strt, str, LOGSTRINGLENGTH - sizeof(tmpdate) - 2); write(Access_fd, strt, strlen(strt)); } } //Log virus messages void LogFile::VirusMessage( const char *formatT , ... ) { char str[LOGSTRINGLENGTH+1]; va_list args; va_start(args, formatT); vsnprintf(str, LOGSTRINGLENGTH, formatT, args); va_end(args); if ( UseSyslog ) { syslog(SyslogVirusLevel, "%s", str); } else { char strt[LOGSTRINGLENGTH+1]; char tmpdate[51]; time_t now = time(NULL); struct tm TmDate = *localtime(&now); strftime(tmpdate, 50, TimeFormat.c_str(), &TmDate); strncpy(strt, tmpdate, sizeof(tmpdate)); strncat(strt, str, LOGSTRINGLENGTH - sizeof(tmpdate) - 2); write(Virus_fd, strt, strlen(strt)); } } //Log error messages void LogFile::ErrorMessage( const char *formatT , ... ) { char str[LOGSTRINGLENGTH+1]; va_list args; va_start(args, formatT); vsnprintf(str, LOGSTRINGLENGTH, formatT, args); va_end(args); if ( UseSyslog ) { syslog(SyslogLevel, "%s", str); } else { char strt[LOGSTRINGLENGTH+1]; char tmpdate[51]; time_t now = time(NULL); struct tm TmDate = *localtime(&now); strftime(tmpdate, 50, TimeFormat.c_str(), &TmDate); strncpy(strt, tmpdate, sizeof(tmpdate)); strncat(strt, str, LOGSTRINGLENGTH - sizeof(tmpdate) - 2); write(Error_fd, strt, strlen(strt)); } } int LogFile::GetSyslogLevel() { string Level = UpperCase(Params::GetConfigString("SYSLOGLEVEL")); SearchReplace( Level, "LOG_", "" ); if ( Level == "EMERG") return LOG_EMERG; if ( Level == "ALERT" ) return LOG_ALERT; if ( Level == "CRIT" ) return LOG_CRIT; if ( Level == "ERR" ) return LOG_ERR; if ( Level == "WARNING" ) return LOG_WARNING; if ( Level == "WARN" ) return LOG_WARNING; if ( Level == "NOTICE" ) return LOG_NOTICE; if ( Level == "INFO" ) return LOG_INFO; if ( Level == "DEBUG" ) return LOG_DEBUG; return LOG_INFO; } int LogFile::GetSyslogVirusLevel() { string Level = UpperCase(Params::GetConfigString("SYSLOGVIRUSLEVEL")); SearchReplace( Level, "LOG_", "" ); if ( Level == "EMERG") return LOG_EMERG; if ( Level == "ALERT" ) return LOG_ALERT; if ( Level == "CRIT" ) return LOG_CRIT; if ( Level == "ERR" ) return LOG_ERR; if ( Level == "WARNING" ) return LOG_WARNING; if ( Level == "WARN" ) return LOG_WARNING; if ( Level == "NOTICE" ) return LOG_NOTICE; if ( Level == "INFO" ) return LOG_INFO; if ( Level == "DEBUG" ) return LOG_DEBUG; return LOG_WARNING; } int LogFile::GetSyslogFacility() { string Facility = UpperCase(Params::GetConfigString("SYSLOGFACILITY")); SearchReplace( Facility, "LOG_", "" ); if ( Facility == "AUTH" ) return LOG_AUTH; if ( Facility == "CRON" ) return LOG_CRON; if ( Facility == "DAEMON" ) return LOG_DAEMON; if ( Facility == "KERN" ) return LOG_KERN; if ( Facility == "LOCAL0" ) return LOG_LOCAL0; if ( Facility == "LOCAL1" ) return LOG_LOCAL1; if ( Facility == "LOCAL2" ) return LOG_LOCAL2; if ( Facility == "LOCAL3" ) return LOG_LOCAL3; if ( Facility == "LOCAL4" ) return LOG_LOCAL4; if ( Facility == "LOCAL5" ) return LOG_LOCAL5; if ( Facility == "LOCAL6" ) return LOG_LOCAL6; if ( Facility == "LOCAL7" ) return LOG_LOCAL7; if ( Facility == "LPR" ) return LOG_LPR; if ( Facility == "MAIL" ) return LOG_MAIL; if ( Facility == "NEWS" ) return LOG_NEWS; if ( Facility == "USER" ) return LOG_USER; if ( Facility == "UUCP" ) return LOG_UUCP; return LOG_DAEMON; } havp-0.93/havp/connectiontobrowser.h0000644000000000000000000000443313425375263016334 0ustar rootroot/*************************************************************************** connectiontobrowser.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CONNECTIONTOBROWSER_H #define CONNECTIONTOBROWSER_H #include "default.h" #include "httphandler.h" #include using namespace std; class ProxyDetails; class ConnectionToBrowser : public HTTPHandler { private: string Request; string Host; int Port; string IP; string CompleteRequest; string RequestType; string RequestProtocol; string FtpUser; string FtpPass; string UserAgent; long long ContentLength; bool IsKeepAlive; bool IsStreamAgent; vector Methods; vector StreamUA; bool Transparent; int AnalyseFirstHeaderLine( string &RequestT ); int AnalyseHeaderLine( string &RequestT ); int GetHostAndPortOfRequest( string &RequestT, string::size_type StartPos ); int GetHostAndPortOfHostLine( string &HostLineT ); #ifdef REWRITE map URLRewrite; #endif public: string PrepareHeaderForServer( bool ScannerOff, ProxyDetails &parentProxy ); string GetIP(); const string GetHost(); const string GetRequest(); const string GetCompleteRequest(); const string GetRequestProtocol(); const string GetRequestType(); const string GetUserAgent(); bool IsItKeepAlive(); bool IsItStreamAgent(); long long GetContentLength(); int GetPort(); void ClearVars(); #ifdef REWRITE bool RewriteHost(); #endif ConnectionToBrowser(); ~ConnectionToBrowser(); }; #endif havp-0.93/havp/havp.h0000644000000000000000000000203713425375263013162 0ustar rootroot/*************************************************************************** havp.h - description ------------------- begin : Sa M� 5 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HAVP_H #define HAVP_H #endif havp-0.93/havp/whitelist.h0000644000000000000000000000343713425375263014245 0ustar rootroot/*************************************************************************** whitelist.h - description ------------------- begin : Don Aug 18 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef WHITELIST_H #define WHITELIST_H #include #include #include using namespace std; class URLList { private: struct PathStruct { string Path; char ExactPath; char ExactDomain; }; map > URLLists; char CheckItem( string *ItemT ); bool AnalyseURL( string UrlT, string *DomainT, char *ExactDomainT, string *PathT, char *ExactPathT ); string DisplayLine( string LineT, char positionT ); bool FindString( string *SearchT, string *LineT, char positionT ); bool Search( string *DomainT, char ExactDomainT, string *PathT ); public: bool URLFound( string DomainT, string PathT ); bool CreateURLList( string URLListFileT ); bool ReloadURLList( string URLListFileT ); void DisplayURLList(); URLList(); ~URLList(); }; #endif havp-0.93/havp/httphandler.h0000644000000000000000000000307713425375263014546 0ustar rootroot/*************************************************************************** httphandler.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HTTPHANDLER_H #define HTTPHANDLER_H #include "sockethandler.h" #include using namespace std; class HTTPHandler : public SocketHandler { protected: bool ProxyConnection; vector tokens; virtual int AnalyseFirstHeaderLine( string &RequestT ) = 0; virtual int AnalyseHeaderLine( string &RequestT ) = 0; public: bool ReadHeader( string &headerT ); int AnalyseHeader( string &linesT ); ssize_t ReadBodyPart( string &bodyT, bool Chunked ); bool SendHeader( string header, bool ConnectionClose ); HTTPHandler(); virtual ~HTTPHandler(); }; #endif havp-0.93/havp/scanners/0000755000000000000000000000000013425376504013664 5ustar rootroothavp-0.93/havp/scanners/sophiescanner.cpp0000644000000000000000000001032613425375304017230 0ustar rootroot/*************************************************************************** sophiescanner.cpp - description ------------------- begin : Sa Mar 25 2006 copyright : (C) 2006 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sophiescanner.h" bool SophieScanner::InitDatabase() { return true; } int SophieScanner::ReloadDatabase() { return 0; } string SophieScanner::Scan( const char *FileName ) { if ( Connected == false ) { //Connect if ( SOPHIESocket.ConnectToSocket( Params::GetConfigString("SOPHIESOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Sophie: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } Connected = true; } //Construct command for scanner ScannerCmd = FileName; ScannerCmd += "\n"; //Send command if ( SOPHIESocket.Send( ScannerCmd ) == false ) { SOPHIESocket.Close(); Connected = false; //Try to reconnect if failed sleep(1); if ( SOPHIESocket.ConnectToSocket( Params::GetConfigString("SOPHIESOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Sophie: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Send command.. again if ( SOPHIESocket.Send( ScannerCmd ) == false ) { SOPHIESocket.Close(); LogFile::ErrorMessage("Sophie: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } Connected = true; } string Response; //Get response if ( SOPHIESocket.Recv( Response, true, 600 ) < 0 ) { SOPHIESocket.Close(); LogFile::ErrorMessage("Sophie: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } //Clean? if ( MatchBegin( Response, "0", 1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Virus? if ( MatchBegin( Response, "1", 1 ) ) { ScannerAnswer = "1" + Response.substr( 2 ); return ScannerAnswer; } //Error? if ( MatchBegin( Response, "-1", 2 ) ) { ScannerAnswer = "2" + Response.substr( 3 ); return ScannerAnswer; } //Unknown answer.. LogFile::ErrorMessage("Sophie: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } void SophieScanner::FreeDatabase() { } void SophieScanner::CloseSocket() { SOPHIESocket.Close(); Connected = false; } //Constructor SophieScanner::SophieScanner() { ScannerName = "Sophie Socket Scanner"; ScannerNameShort = "Sophos"; Connected = false; LastError = 0; ScannerAnswer.reserve(100); } //Destructor SophieScanner::~SophieScanner() { } havp-0.93/havp/scanners/kasperskyscanner.h0000644000000000000000000000270713425375304017426 0ustar rootroot/*************************************************************************** kasperskyscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KASPERSKYSCANNER_H #define KASPERSKYSCANNER_H #include "../genericscanner.h" class KasperskyScanner : public GenericScanner { private: string ScannerCmd; bool Connected; SocketHandler AVESocket; time_t LastError; string ScannerAnswer; char Ready[2]; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); void CloseSocket(); KasperskyScanner(); ~KasperskyScanner(); }; #endif havp-0.93/havp/scanners/f-protscanner.h0000644000000000000000000000314513425375304016616 0ustar rootroot/*************************************************************************** FProtScanner.h - description ------------------- begin : Mit Jun 29 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FPROTSCANNER_H #define FPROTSCANNER_H #include "../genericscanner.h" class FProtScanner : public GenericScanner { private: string ServerHost; int ServerPort; string ScannerCmd; SocketHandler Scanner; time_t LastError; string ScannerAnswer; char Ready[2]; bool Connected; int Version; string Opts; string ScanV6( const char *FileName ); string ScanV4( const char *FileName ); int TestVersion(); bool ConnectScanner(); public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); void CloseSocket(); FProtScanner(); ~FProtScanner(); }; #endif havp-0.93/havp/scanners/avastscanner.h0000644000000000000000000000263513425375304016530 0ustar rootroot/*************************************************************************** avastscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AVASTSCANNER_H #define AVASTSCANNER_H #include "../genericscanner.h" class AvastScanner : public GenericScanner { private: bool UseSocket; string ScannerAnswer; char Ready[2]; SocketHandler AvastSocket; time_t LastError; string ScannerCmd; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); AvastScanner(); ~AvastScanner(); }; #endif havp-0.93/havp/scanners/clamdscanner.h0000644000000000000000000000263513425375304016472 0ustar rootroot/*************************************************************************** clamdscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CLAMDSCANNER_H #define CLAMDSCANNER_H #include "../genericscanner.h" class ClamdScanner : public GenericScanner { private: bool UseSocket; string ScannerAnswer; char Ready[2]; SocketHandler CLAMDSocket; time_t LastError; string ScannerCmd; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); ClamdScanner(); ~ClamdScanner(); }; #endif havp-0.93/havp/scanners/avgscanner.cpp0000644000000000000000000001155313425375304016521 0ustar rootroot/*************************************************************************** avgscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "avgscanner.h" bool AVGScanner::InitDatabase() { return true; } int AVGScanner::ReloadDatabase() { return 0; } string AVGScanner::Scan( const char *FileName ) { if ( AVGSocket.ConnectToServer() == false ) { AVGSocket.Close(); //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("AVG: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner"; return ScannerAnswer; } string Response; AVGSocket.Recv( Response, true, 5 ); if ( MatchSubstr( Response, "220 Ready", -1 ) == false ) { AVGSocket.Close(); LogFile::ErrorMessage("AVG: Invalid greeting from scanner (%s)\n", Response.c_str()); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } //Construct command for scanner ScannerCmd = "SCAN "; ScannerCmd += FileName; ScannerCmd += "\r\n"; if ( AVGSocket.Send( ScannerCmd ) == false ) { AVGSocket.Close(); LogFile::ErrorMessage("AVG: Could not connect to scanner\n"); ScannerAnswer = "2Could not call scanner"; return ScannerAnswer; } Response = ""; int ret; ret = AVGSocket.Recv( Response, true, 600 ); if (ret < 0) { AVGSocket.Close(); LogFile::ErrorMessage("AVG: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } string Quit = "QUIT\r\n"; AVGSocket.Send( Quit ); AVGSocket.Recv( Quit, true, 2 ); AVGSocket.Close(); if ( Response.length() < 5 ) { LogFile::ErrorMessage("AVG: Invalid response from scanner, report to developer (%s)\n", Response.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } if ( MatchSubstr( Response, "200 ok", -1 ) || MatchSubstr( Response, "200 OK", -1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } string::size_type Position; if ( ( Position = Response.find( "403 File" )) != string::npos ) { string::size_type PositionEnd, PositionStart; PositionEnd = Response.find("\n", Position + 10); PositionStart = Response.rfind(" ", PositionEnd - 3); string vname = Response.substr( PositionStart + 1, PositionEnd - PositionStart - 2); if (vname.rfind(" ") == vname.length() - 1) vname = vname.substr( 0, vname.length() - 1 ); ScannerAnswer = "1" + vname; return ScannerAnswer; } //If AVG is reloading patterns, it will give error, just skip it if ( MatchSubstr( Response, "406 Error", -1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } // Log errors if ( MatchSubstr( Response, "local error", -1 ) ) { LogFile::ErrorMessage("AVG: Scanner error: %s\n", Response.c_str()); ScannerAnswer = "2Scanner error"; return ScannerAnswer; } //LogFile::ErrorMessage("AVG: Unknown response from scanner, report to developer (%s)\n", Response.c_str()); //ScannerAnswer = "2Unknown response from scanner: " + Response; //return ScannerAnswer; //Just return clean for anything else right now.. ScannerAnswer = "0Clean"; return ScannerAnswer; } void AVGScanner::FreeDatabase() { } //Constructor AVGScanner::AVGScanner() { ScannerName = "AVG Socket Scanner"; ScannerNameShort = "AVG"; LastError = 0; if ( AVGSocket.SetDomainAndPort( Params::GetConfigString("AVGSERVER"), Params::GetConfigInt("AVGPORT") ) == false ) { LogFile::ErrorMessage("AVG: Could not resolve scanner host\n"); } ScannerAnswer.reserve(100); } //Destructor AVGScanner::~AVGScanner() { } havp-0.93/havp/scanners/arcavirscanner.h0000644000000000000000000000306213425375304017034 0ustar rootroot/*************************************************************************** arcavirscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ARCAVIRSCANNER_H #define ARCAVIRSCANNER_H #include "../genericscanner.h" class ArcavirScanner : public GenericScanner { private: string ScannerCmd; SocketHandler Scanner; time_t LastError; string ScannerAnswer; char Ready[2]; bool Connected; int Version; string ScanV2007( const char *FileName ); string ScanV2008( const char *FileName ); bool ConnectScanner(); public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); void CloseSocket(); ArcavirScanner(); ~ArcavirScanner(); }; #endif havp-0.93/havp/scanners/arcavirscanner.cpp0000644000000000000000000001434313425375304017373 0ustar rootroot/*************************************************************************** arcavirscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org Help for Version 2008 received from Anthony Have (a.have@sysun-technologies.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "arcavirscanner.h" bool ArcavirScanner::InitDatabase() { return true; } int ArcavirScanner::ReloadDatabase() { return 0; } string ArcavirScanner::Scan( const char *FileName ) { if ( Connected == false && ConnectScanner() == false ) { ScannerAnswer = "2Could not connect to scanner"; return ScannerAnswer; } if ( Version == 2008 ) return ScanV2008( FileName ); return ScanV2007( FileName ); } string ArcavirScanner::ScanV2008( const char *FileName ) { //Scan command string ScannerCmd = "SCAN "; ScannerCmd += FileName; ScannerCmd += "\n"; //Send command if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); //Retry one time if ( ConnectScanner() == false || Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } } string Response; string VirusName = ""; do { if ( Scanner.GetLine( Response, "\n", 600 ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("Arcavir: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } if ( VirusName != "" ) continue; if ( MatchSubstr( Response, " ERROR", -1 ) ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("Arcavir: %s\n", Response.substr( Response.find(": ") + 2 ).c_str() ); ScannerAnswer = "2Scanner error"; return ScannerAnswer; } if ( MatchSubstr( Response, " FOUND", -1 ) ) { string::size_type Position = Response.find(": ") + 2; string::size_type PositionEnd = Response.find(" ", Position); VirusName = Response.substr( Position, PositionEnd - Position ); } } while ( Response != "" && !MatchSubstr( Response, " END", -1 ) ); if ( VirusName != "" ) { ScannerAnswer = "1" + VirusName; return ScannerAnswer; } ScannerAnswer = "0Clean"; return ScannerAnswer; } string ArcavirScanner::ScanV2007( const char *FileName ) { //Scan command string ScannerCmd = "S "; ScannerCmd += FileName; ScannerCmd += "\n"; //Send command if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } string Response; if ( Scanner.GetLine( Response, "\n", 600 ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("Arcavir: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } Scanner.Close(); Connected = false; //Clean if ( MatchBegin( Response, "OK", 2 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Infected if ( MatchBegin( Response, "VIR", 3 ) ) { ScannerAnswer = "1" + Response.substr( 4, Response.find( " ", 4 ) - 4 ); return ScannerAnswer; } //Error if ( MatchBegin( Response, "ERR", 3 ) ) { ScannerAnswer = "2" + Response.substr( 4, Response.find( " ", 4 ) - 4 ); return ScannerAnswer; } LogFile::ErrorMessage("Arcavir: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Unknown scanner response"; return ScannerAnswer; } bool ArcavirScanner::ConnectScanner() { //Connect if ( Scanner.ConnectToSocket( Params::GetConfigString("ARCAVIRSOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Arcavir: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } return false; } if ( Version == 2008 ) { //Persistent connection for version 2008+ string ScannerCmd = "SESSION\n"; //Send command if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); LogFile::ErrorMessage("Arcavir: Could not write command to scanner\n"); return false; } } Connected = true; return true; } void ArcavirScanner::FreeDatabase() { } //Close persistent connection from HAVP scanner initialization //Needed because it will fork later void ArcavirScanner::CloseSocket() { Scanner.Close(); Connected = false; } //Constructor ArcavirScanner::ArcavirScanner() { ScannerName = "Arcavir Socket Scanner"; ScannerNameShort = "Arcavir"; Connected = false; Version = Params::GetConfigInt("ARCAVIRVERSION"); LastError = 0; ScannerAnswer.reserve(100); } //Destructor ArcavirScanner::~ArcavirScanner() { } havp-0.93/havp/scanners/sophiescanner.h0000644000000000000000000000267313425375304016703 0ustar rootroot/*************************************************************************** kasperskyscanner.h - description ------------------- begin : Sa Mar 25 2006 copyright : (C) 2006 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SOPHIESCANNER_H #define SOPHIESCANNER_H #include "../genericscanner.h" class SophieScanner : public GenericScanner { private: string ScannerCmd; bool Connected; SocketHandler SOPHIESocket; time_t LastError; string ScannerAnswer; char Ready[2]; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); void CloseSocket(); SophieScanner(); ~SophieScanner(); }; #endif havp-0.93/havp/scanners/trophiescanner.cpp0000644000000000000000000001431013425375304017410 0ustar rootroot/*************************************************************************** trophiescanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /************************************************* * Some code taken from Trophie by Vanja Hrustic * * http://www.vanja.com/tools/trophie/ * * Thanks for the engineering! * *************************************************/ #include "trophiescanner.h" char TrophieScanner::VIR_NAME[512]; int TrophieScanner::trophie_scanfile( char *scan_file ) { int ret = VSVirusScanFileWithoutFNFilter(vs_addr, scan_file, -1); /* Lame. Hopefully just a temporary thing */ /* Returned for .bz2 archives, and some MPEG files - not sure why it's -89, but we're not missing viruses */ if (ret == -89) ret = 0; return ret; } int TrophieScanner::vs_callback( char *a, struct callback_type *b, int c, char *d ) { /* Only c == 1 needs to be processed = no idea what for 2nd run is used for (and don't want to know) */ if ( (c == 1) && (b->flag_infected > 0) ) { char *virus_name = (char *)(b->vname+8); strncpy(VIR_NAME, virus_name, sizeof(VIR_NAME)-1); } return 0; } bool TrophieScanner::InitDatabase() { int ret; int vs_ptr = 0; vs_addr = 0; memset(&pattern_info_ex, 0, sizeof(pattern_info_ex)); memset(&trophie_vs, 0, sizeof(trophie_vs_type)); if ((ret = VSInit(getpid(), (const char*)"VSCAN", -1, &vs_addr)) != 0) { LogFile::ErrorMessage("Trophie: VSInit() failed: %d\n", ret); return false; } if ((ret = VSSetExtractPath(vs_addr, Params::GetConfigString("TEMPDIR").c_str())) != 0) { LogFile::ErrorMessage("Trophie: VSSetExtractPath() failed: %d\n", ret); return false; } if ((ret = VSSetTempPath(vs_addr, Params::GetConfigString("TEMPDIR").c_str())) != 0) { LogFile::ErrorMessage("Trophie: VSSetTempPath() failed: %d\n", ret); return false; } if ((ret = VSSetExtractFileCountLimit(vs_addr, Params::GetConfigInt("TROPHIEMAXFILES"))) != 0) { LogFile::ErrorMessage("Trophie: VSSetExtractFileCountLimit() failed: %d\n", ret); return false; } if ( Params::GetConfigInt("TROPHIEMAXFILESIZE") > 0 ) { if ((ret = VSSetExtractFileSizeLimit(vs_addr, 1048576 * Params::GetConfigInt("TROPHIEMAXFILESIZE"))) != 0) { LogFile::ErrorMessage("Trophie: VSSetExtractFileSizeLimit() failed: %d\n", ret); return false; } } if ((ret = VSSetExtractFileRatioLimit(vs_addr, Params::GetConfigInt("TROPHIEMAXRATIO"))) != 0) { LogFile::ErrorMessage("Trophie: VSSetExtractFileRatioLimit() failed: %d\n", ret); return false; } if ((ret = VSReadVirusPattern(vs_addr, -1, 0, (int *) &vs_ptr)) != 0) { LogFile::ErrorMessage("Trophie: VSReadVirusPattern() failed: %d\n", ret); return false; } trophie_vs.handle_addr = vs_addr; trophie_vs.version_string[0] = 0; if ((ret = VSGetVSCInfo(&trophie_vs)) != 0) { LogFile::ErrorMessage("Trophie: VSGetVSCInfo() failed: %d\n", ret); return false; } /* Set the callback function */ if ((ret = VSSetProcessFileCallBackFunc(vs_addr, &TrophieScanner::vs_callback)) != 0) { LogFile::ErrorMessage("Trophie: VSSetProcessFileCallBackFunc() failed: %d\n", ret); return false; } if ((ret = VSGetVirusPatternInfoEx(vs_ptr, (int *) &pattern_info_ex)) != 0) { LogFile::ErrorMessage("Trophie: VSGetVirusPatternInfoEx() failed: %d\n", ret); return false; } //Only show if it changed if (pattern_info_ex.info != cur_patt) { cur_patt = pattern_info_ex.info; //Calculate nicer looking version int major = pattern_info_ex.info / 100000; int number = pattern_info_ex.info / 100 - major * 1000; int version = pattern_info_ex.info - major * 100000 - number * 100; //Get signature count ret = VSGetDetectableVirusNumber(vs_addr); LogFile::ErrorMessage("Trophie: Loaded %d signatures (pattern %d.%.3d.%.2d / engine %s)\n", ret, major, number, version, trophie_vs.version_string); } //Here we will set some params on our own if (VS_PROCESS_ALL_FILES_IN_ARCHIVE) VSSetProcessAllFileInArcFlag(vs_addr, 1); if (VS_PROCESS_ALL_FILES) VSSetProcessAllFileFlag(vs_addr, 1); return true; } int TrophieScanner::ReloadDatabase() { int ret = VSQuit(vs_addr); if ( ret != 0 ) { LogFile::ErrorMessage("Trophie: VSQuit() failed: %d\n", ret); return -1; } if ( InitDatabase() == false ) { LogFile::ErrorMessage("Trophie: Database reload failed\n"); return -1; } return 1; } string TrophieScanner::Scan( const char *FileName ) { int ret = trophie_scanfile( (char *)FileName ); if ( ret ) //Virus Found { string Temp = VIR_NAME; if ( Temp == "" ) Temp = "Unknown"; ScannerAnswer = "1" + Temp; return ScannerAnswer; } ScannerAnswer = "0Clean"; return ScannerAnswer; } void TrophieScanner::FreeDatabase() { VSQuit(vs_addr); } //Constructor TrophieScanner::TrophieScanner() { ScannerName = "Trend Micro Library Scanner"; ScannerNameShort = "Trend"; cur_patt = 0; ScannerAnswer.reserve(100); } //Destructor TrophieScanner::~TrophieScanner() { } havp-0.93/havp/scanners/nod32scanner.cpp0000644000000000000000000003245513425375304016675 0ustar rootroot/*************************************************************************** nod32scanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "nod32scanner.h" bool NOD32Scanner::InitDatabase() { return true; } int NOD32Scanner::ReloadDatabase() { return 0; } string NOD32Scanner::Scan( const char *FileName ) { if ( Version == 25 ) return ScanV25( FileName ); if ( Version == 30 ) return ScanV30( FileName ); return ScanV21( FileName ); } string NOD32Scanner::ScanV30( const char *FileName ) { //Connect if ( NOD32Socket.ConnectToSocket( Params::GetConfigString("NOD32SOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("NOD32: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } string Response; //Get initial response if ( NOD32Socket.GetLine( Response, "\n\n", 600 ) == false ) { NOD32Socket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Check greeting if ( MatchBegin( Response, "200", 3 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } //Send HELO and PARAMS ScannerCmd = "HELO\ncli\nhavp\n\n"; //Send command if ( NOD32Socket.Send( ScannerCmd ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } if ( NOD32Socket.GetLine( Response, "\n\n", 600 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } if ( MatchBegin( Response, "200", 3 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } ScannerCmd = "HOPFR\n"; ScannerCmd += FileName; ScannerCmd += "\n\nQUIT\n\n"; //Send command if ( NOD32Socket.Send( ScannerCmd ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } Response = ""; if ( NOD32Socket.GetLine( Response, "\n\n", 600 ) == false ) { NOD32Socket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } NOD32Socket.Close(); //Clean if ( MatchBegin( Response, "0", 1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Infected if ( MatchBegin( Response, "3", 1 ) ) { string::size_type Position; ScannerAnswer = ""; if ( (Position = Response.find("|")) != string::npos ) { string::size_type PositionEnd; if ( (PositionEnd = Response.find("|", Position + 1)) != string::npos ) { if ( PositionEnd - Position > 1 ) ScannerAnswer = "1" + Response.substr( Position + 1, PositionEnd - Position - 1 ); } } if ( ScannerAnswer == "" ) ScannerAnswer = "1Unknown"; return ScannerAnswer; } LogFile::ErrorMessage("NOD32: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Unknown scanner response"; return ScannerAnswer; } string NOD32Scanner::ScanV25( const char *FileName ) { //Connect if ( NOD32Socket.ConnectToSocket( Params::GetConfigString("NOD32SOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("NOD32: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } string Response; //Get initial response if ( NOD32Socket.GetLine( Response, "\n\n", 600 ) == false ) { NOD32Socket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Check greeting if ( MatchBegin( Response, "200", 3 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } //Send HELO and PARAMS ScannerCmd = "HELO\n"; ScannerCmd += Agent; ScannerCmd += "\nhavp\n\nPSET\nscan_obj_files = yes\nscan_obj_archives = yes\nscan_obj_emails = yes\nscan_obj_sfx = yes\nscan_obj_runtimepackers = yes\nscan_app_adware = yes\nscan_app_unsafe = yes\nscan_pattern = yes\nscan_heur = yes\nscan_adv_heur = yes\nscan_all_files = yes\naction_on_infected = \"reject\"\naction_on_notscanned = \"reject\"\nquarantine = no\ntmp_dir = \""; ScannerCmd += Params::GetConfigString("TEMPDIR"); ScannerCmd += "\"\n\n"; //Send command if ( NOD32Socket.Send( ScannerCmd ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } //Receive responses NOD32Socket.GetLine( Response, "\n\n", 600 ); //If we have NOD32 for Linux File Server, change Agent to pac //We can't get virusnames then :( if ( Agent == "cli" && Response == "401 Access denied for agent cli" ) { LogFile::ErrorMessage("NOD32 for Linux File Server detected, virus names are not shown\n"); Agent = "pac"; NOD32Socket.Close(); return Scan( FileName ); } if ( NOD32Socket.GetLine( Response, "\n\n", 600 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } if ( MatchBegin( Response, "200 OK PSET", 11 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } ScannerCmd = "SCAN\n"; ScannerCmd += FileName; ScannerCmd += "\n\nQUIT\n\n"; //Send command if ( NOD32Socket.Send( ScannerCmd ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } Response = ""; int ret; while ( (ret = NOD32Socket.Recv( Response, true, 600 )) != 0 ) { if (ret < 0) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } } NOD32Socket.Close(); //Clean if ( MatchBegin( Response, "201 CLEAN", 9 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Infected if ( MatchBegin( Response, "501 INFECTED", 12 ) ) { if ( Agent != "cli" ) { ScannerAnswer = "1Unknown"; return ScannerAnswer; } string::size_type Position; ScannerAnswer = ""; if ( (Position = Response.find("||")) != string::npos ) { string::size_type PositionEnd = Position - 1; if ( (Position = Response.rfind("|", PositionEnd)) != string::npos ) { ScannerAnswer = "1" + Response.substr( Position + 1, PositionEnd - Position ); } } if ( ScannerAnswer == "" ) ScannerAnswer = "1Unknown"; return ScannerAnswer; } //Error if ( MatchBegin( Response, "5", 1 ) ) { ScannerAnswer = "2" + Response; return ScannerAnswer; } LogFile::ErrorMessage("NOD32: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Unknown scanner response"; return ScannerAnswer; } string NOD32Scanner::ScanV21( const char *FileName ) { //Connect if ( NOD32Socket.ConnectToSocket( Params::GetConfigString("NOD32SOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("NOD32: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } string Response; //Get initial response if ( NOD32Socket.Recv( Response, true, 30 ) <= 0 ) { NOD32Socket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Check greeting if ( MatchBegin( Response, "200", 3 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } //Send HELO and PARAMS char ScannerCmd[] = "SETU\0SCFI1\0SCAR1\0SCEM1\0SCRT1\0SCSX1\0SCAD1\0SCUS1\0EXSC0\0SCPA1\0SCHE1\0SCHS2\0WREM0\0WRSB0\0WRHD0\0ALLF1\0LOGA0\0ACTI0\0ACTU16\0SNDS0\0\0"; //Send command - doublecheck lenght parameter.. if ( NOD32Socket.Send( ScannerCmd, 121 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } //Receive response Response = ""; if ( NOD32Socket.Recv( Response, true, 600 ) <= 0 ) { NOD32Socket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } if ( MatchBegin( Response, "200", 3 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Invalid response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } //Blah.. char ScanCmd[1024]; ScanCmd[0] = '\0'; strcat(ScanCmd, "SCAN*cli*"); strncat(ScanCmd, FileName, 200); strcat(ScanCmd, "**QUIT*"); int ScanLen = strlen(ScanCmd); for ( int j = 0; j <= ScanLen; j++ ) { if ( ScanCmd[j] == '*' ) ScanCmd[j] = '\0'; } //Send command if ( NOD32Socket.Send( ScanCmd, ScanLen + 1 ) == false ) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } Response = ""; int ret; while ( (ret = NOD32Socket.Recv( Response, true, 600 )) != 0 ) { if (ret < 0) { NOD32Socket.Close(); LogFile::ErrorMessage("NOD32: Could not read scanner response\n"); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } } NOD32Socket.Close(); //Clean or archive error if ( MatchBegin( Response, "200", 3 ) || MatchBegin( Response, "205", 3 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Infected if ( MatchBegin( Response, "201", 3 ) ) { ScannerAnswer = "1Unknown"; return ScannerAnswer; } //Error ScannerAnswer = "2" + Response; return ScannerAnswer; } void NOD32Scanner::FreeDatabase() { } //Constructor NOD32Scanner::NOD32Scanner() { ScannerName = "NOD32 Socket Scanner"; ScannerNameShort = "NOD32"; LastError = 0; //Assume we have NOD32 v2.5+ for Linux Mail Server by default Agent = "cli"; Version = Params::GetConfigInt("NOD32VERSION"); if ( Version != 25 && Version != 21 && Version != 30 ) { Version = 25; } ScannerAnswer.reserve(100); } //Destructor NOD32Scanner::~NOD32Scanner() { } havp-0.93/havp/scanners/README0000644000000000000000000000166013425375304014544 0ustar rootroot Some notes on the code ====================== Scanners _must_ have these public functions: bool InitDatabase(); Return: true .. database successfully initialized Return: false .. loading failed, HAVP will terminate Note: always return true when using a daemon, since we don't handle this int ReloadDatabase(); Return: -1 .. error reloading, HAVP will terminate Return: 0 .. no reloading done, databases are current Return: 1 .. database was reloaded, childs will be restarted Note: always return 0 when using a daemon, since we don't handle this void FreeDatabase(); Note: not actually used right now.. maybe in future string Scan( const char *FileName ); Scanners may have these public functions: void CloseSocket(); Note: if persistent connections to daemon are used, we call Close() here, used when HAVP initially tests scanner and forks. we don't want to pass the open file descriptor. havp-0.93/havp/scanners/avastscanner.cpp0000644000000000000000000001266013425375304017062 0ustar rootroot/*************************************************************************** avastscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "avastscanner.h" bool AvastScanner::InitDatabase() { return true; } int AvastScanner::ReloadDatabase() { return 0; } string AvastScanner::Scan( const char *FileName ) { bool SockAnswer; if ( UseSocket ) { SockAnswer = AvastSocket.ConnectToSocket( Params::GetConfigString("AVASTSOCKET"), 1 ); } else { SockAnswer = AvastSocket.ConnectToServer(); } if ( SockAnswer == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Avast: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Construct command for scanner ScannerCmd = "SCAN "; ScannerCmd += FileName; ScannerCmd += "\r\nQUIT\r\n"; //Send command if ( AvastSocket.Send( ScannerCmd ) == false ) { AvastSocket.Close(); //Try to reconnect after 1 second sleep(1); if ( UseSocket ) { SockAnswer = AvastSocket.ConnectToSocket( Params::GetConfigString("AVASTSOCKET"), 1 ); } else { SockAnswer = AvastSocket.ConnectToServer(); } if ( SockAnswer == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Avast: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } if ( AvastSocket.Send( ScannerCmd ) == false ) { AvastSocket.Close(); LogFile::ErrorMessage("Avast: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } } string Response; Response.reserve(200); if ( AvastSocket.GetLine( Response, "\r\n", 600 ) == false ) { AvastSocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } if ( MatchBegin( Response, "220", 3 ) == false ) { AvastSocket.Close(); LogFile::ErrorMessage("Avast: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } if ( AvastSocket.GetLine( Response, "\r\n", 600 ) == false ) { AvastSocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } if ( MatchBegin( Response, "200 OK", 6 ) == false ) { AvastSocket.Close(); ScannerAnswer = "2" + Response; return ScannerAnswer; } ScannerAnswer = ""; string::size_type Position; do { if ( AvastSocket.GetLine( Response, "\r\n", 600 ) == false ) { AvastSocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } if ( (Position = Response.find("\t[L]\t")) != string::npos ) { if ( (Position = Response.find_first_not_of("\t ", Position + 5)) != string::npos ) { ScannerAnswer = "1" + Response.substr( Position ); break; } } } while ( Response != "" && MatchBegin( Response, "221", 3 ) == false ); //Connection will be closed AvastSocket.Close(); //Clean? if ( ScannerAnswer == "" ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Virus? return ScannerAnswer; } void AvastScanner::FreeDatabase() { } //Constructor AvastScanner::AvastScanner() { ScannerName = "Avast Socket Scanner"; ScannerNameShort = "Avast"; LastError = 0; if ( Params::GetConfigString("AVASTSERVER") != "" ) { UseSocket = false; if ( AvastSocket.SetDomainAndPort( Params::GetConfigString("AVASTSERVER"), Params::GetConfigInt("AVASTPORT") ) == false ) { LogFile::ErrorMessage("Avast: Could not resolve scanner host\n"); } } else { UseSocket = true; } ScannerAnswer.reserve(100); } //Destructor AvastScanner::~AvastScanner() { } havp-0.93/havp/scanners/drwebscanner.cpp0000644000000000000000000003260113425375304017044 0ustar rootroot/*************************************************************************** drwebscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "drwebscanner.h" /* drweb-clients-4.33-sources */ /* -- SCAN_COMMANDS -------------------------------------------------- */ #define DRWEBD_SCAN_CMD (1) /* scan file, buffer or diskfile */ #define DRWEBD_VERSION_CMD (2) /* get daemon version */ #define DRWEBD_BASEINFO_CMD (3) /* get info about viruses bases */ #define DRWEBD_IDSTRING_CMD (4) /* get id-string of daemon */ #define DRWEBD_SCANPART_CMD (5) /* scan part of diskfile */ #define DRWEBD_SPAMCHECK_CMD (6) /* check mail by anti-spam */ #define DRWEBD_GET_UUID_CMD (7) /* get daemon uuid (unique for each customer) */ /* -- SCAN_OPTIONS ---------------------------------------------------- */ #define DRWEBD_RETURN_VIRUSES (1<<0) /* ask daemon return to us viruses names from report */ #define DRWEBD_RETURN_REPORT (1<<1) /* ask daemon return to us return report line */ #define DRWEBD_RETURN_CODES (1<<2) /* ask daemon return to us return codes */ #define DRWEBD_HEURISTIC_ON (1<<3) /* enables heuristic in finding module */ #define DRWEBD_RULE_FILTER_ON (1<<5) /* Unix only: enables FilterRules in daemon */ #define DRWEBD_INFECTED_CURE (1<<6) /* Unix only: try to cure infected files - if fails file decided incureable */ #define DRWEBD_INFECTED_MOVE (1<<7) /* move infected files */ #define DRWEBD_INFECTED_RENAME (1<<8) /* just rename infected files */ #define DRWEBD_INFECTED_DELETE (1<<9) /* delete infected files */ #define DRWEBD_INCURABLE_MOVE (1<<10) /* move incureable files */ #define DRWEBD_INCURABLE_RENAME (1<<11) /* just rename incureable files */ #define DRWEBD_INCURABLE_DELETE (1<<12) /* delete incureable files */ #define DRWEBD_SUSPECTED_MOVE (1<<13) /* move suspicious files */ #define DRWEBD_SUSPECTED_RENAME (1<<14) /* just rename suspicious files */ #define DRWEBD_SUSPECTED_DELETE (1<<15) /* delete suspicious files */ #define DRWEBD_ARCHIVE_MOVE (1<<16) /* move archive with infected/suspected files */ #define DRWEBD_ARCHIVE_RENAME (1<<17) /* rename archive with infected/suspected files */ #define DRWEBD_ARCHIVE_DELETE (1<<18) /* delete archive with infected/suspected files */ #define DRWEBD_IS_MAIL (1<<19) /* Unix only: say to daemon that format is "archive MAIL" */ #define DRWEBD_DONT_CHANGEMAIL (1<<21) /* Unix only: say to daemon that mail file cannot be changed */ #define DRWEBD_RETURN_SHORT_VIRUSES (1<<22) /* ask daemon return to us pairs of virusnames and infection type {K|M|S} */ #define DRWEBD_RETURN_FILTER_RULE (1<<23) /* ask daemon return to us filtering rule that has been altered */ #define DRWEBD_HAVE_ENVELOPE (1<<24) /* say to daemon that filter will send mail envelope */ #define DRWEBD_CHECK_ARX (1<<25) /* Windows only: say to WinEngine scans into archives (RAR,ZIP etc) */ #define DRWEBD_USE_TCPNODELAY (1<<26) /* use TCP_NODELAY option */ #define DRWEBD_HAVE_EXTENDED (1<<31) /* client knows about extended options */ /* -- SCAN_EXTENDED_OPTIONS ------------------------------------------- */ #define DRWEBD_EXT_ADWARE_IGNORE (1<<1) /* ignore adware */ #define DRWEBD_EXT_ADWARE_MOVE (1<<2) /* move adware */ #define DRWEBD_EXT_ADWARE_RENAME (1<<3) /* rename adware */ #define DRWEBD_EXT_ADWARE_DELETE (1<<4) /* delete adware */ #define DRWEBD_EXT_DIALER_IGNORE (1<<5) /* ignore adware */ #define DRWEBD_EXT_DIALER_MOVE (1<<6) /* move adware */ #define DRWEBD_EXT_DIALER_RENAME (1<<7) /* rename adware */ #define DRWEBD_EXT_DIALER_DELETE (1<<8) /* delete adware */ #define DRWEBD_EXT_JOKE_IGNORE (1<<9) /* ignore adware */ #define DRWEBD_EXT_JOKE_MOVE (1<<10) /* move adware */ #define DRWEBD_EXT_JOKE_RENAME (1<<11) /* rename adware */ #define DRWEBD_EXT_JOKE_DELETE (1<<12) /* delete adware */ #define DRWEBD_EXT_RISKWARE_IGNORE (1<<13) /* ignore adware */ #define DRWEBD_EXT_RISKWARE_MOVE (1<<14) /* move adware */ #define DRWEBD_EXT_RISKWARE_RENAME (1<<15) /* rename adware */ #define DRWEBD_EXT_RISKWARE_DELETE (1<<16) /* delete adware */ #define DRWEBD_EXT_HACKTOOL_IGNORE (1<<17) /* ignore adware */ #define DRWEBD_EXT_HACKTOOL_MOVE (1<<18) /* move adware */ #define DRWEBD_EXT_HACKTOOL_RENAME (1<<19) /* rename adware */ #define DRWEBD_EXT_HACKTOOL_DELETE (1<<20) /* delete adware */ /* -- SCAN_RESULT ----------------------------------------------------- */ #define DERR_NOERROR (0) /*= 0x00000000 */ #define DERR_READ_ERR (1<<0) /*= 0x00000001 */ #define DERR_WRITE_ERR (1<<1) /*= 0x00000002 */ #define DERR_NOMEMORY (1<<2) /*= 0x00000004 */ #define DERR_CRC_ERROR (1<<3) /*= 0x00000008 */ #define DERR_READSOCKET (1<<4) /*= 0x00000010 */ #define DERR_KNOWN_VIRUS (1<<5) /*= 0x00000020 */ #define DERR_UNKNOWN_VIRUS (1<<6) /*= 0x00000040 */ #define DERR_VIRUS_MODIFICATION (1<<7) /*= 0x00000080 */ #define DERR_HAVE_CURED (1<<8) /*= 0x00000100 */ #define DERR_TIMEOUT (1<<9) /*= 0x00000200 */ #define DERR_SYMLINK (1<<10) /*= 0x00000400 */ #define DERR_NO_REGFILE (1<<11) /*= 0x00000800 */ #define DERR_SKIPPED (1<<12) /*= 0x00001000 */ #define DERR_TOO_BIG (1<<13) /*= 0x00002000 */ #define DERR_TOO_COMPRESSED (1<<14) /*= 0x00004000 */ #define DERR_BAD_CALL (1<<15) /*= 0x00008000 */ #define DERR_EVAL_KEY (1<<16) /*= 0x00010000 */ #define DERR_FILTER_REJECT (1<<17) /*= 0x00020000 */ #define DERR_ARCHIVE_LEVEL (1<<18) /*= 0x00040000 */ #define DERR_HAVE_DELETED (1<<19) /*= 0x00080000 */ #define DERR_IS_CLEAN (1<<20) /*= 0x00100000 */ #define DERR_LICENSE_ERROR (1<<21) /*= 0x00200000 */ #define DERR_ADWARE (1<<22) /*= 0x00400000 */ #define DERR_DIALER (1<<23) /*= 0x00800000 */ #define DERR_JOKE (1<<24) /*= 0x01000000 */ #define DERR_RISKWARE (1<<25) /*= 0x02000000 */ #define DERR_HACKTOOL (1<<26) /*= 0x04000000 */ #define DERR_MASK (0x0FFFFFFF) #define DERR_NON_DAEMON_ERROR (~DERR_MASK) #define DERR_INFECTED (DERR_KNOWN_VIRUS | DERR_VIRUS_MODIFICATION) #define DERR_SUSPICIOUS (DERR_UNKNOWN_VIRUS) #define DERR_MALWARE (DERR_ADWARE | DERR_DIALER | DERR_JOKE | DERR_RISKWARE | DERR_HACKTOOL) #define DERR_VIRUS_MASK (DERR_INFECTED | DERR_SUSPICIOUS | DERR_MALWARE) #define DERR_SKIP_OBJECT (DERR_SYMLINK | DERR_NO_REGFILE | DERR_SKIPPED | DERR_CRC_ERROR | DERR_TIMEOUT) #define DERR_ARCHIVE_RESTRICTION (DERR_TOO_BIG | DERR_TOO_COMPRESSED | DERR_ARCHIVE_LEVEL) #define DERR_DAEMON_ERROR (DERR_READ_ERR | DERR_WRITE_ERR | DERR_NOMEMORY | DERR_READSOCKET | DERR_BAD_CALL) bool DrwebScanner::InitDatabase() { return true; } int DrwebScanner::ReloadDatabase() { return 0; } string DrwebScanner::Scan( const char *FileName ) { if ( ConnectScanner() == false ) { ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Construct command for scanner int scan_cmd = htonl( DRWEBD_SCAN_CMD ); int scan_flags = htonl( Opts ); int scan_slen = htonl( strlen(FileName) ); int scan_null = htonl( 0x0000 ); if ( Scanner.Send( (const char*)&scan_cmd, sizeof(scan_cmd) ) == false || Scanner.Send( (const char*)&scan_flags, sizeof(scan_flags) ) == false || Scanner.Send( (const char*)&scan_slen, sizeof(scan_slen) ) == false || Scanner.Send( FileName, strlen(FileName) ) == false || Scanner.Send( (const char*)&scan_null, sizeof(scan_null) ) == false ) { Scanner.Close(); LogFile::ErrorMessage("Drweb: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } int scan_rc, scan_vnum; ssize_t read; if ( (read = recv( Scanner.sock_fd, &scan_rc, sizeof(scan_rc), 0 )) != sizeof(scan_rc) ) { Scanner.Close(); LogFile::ErrorMessage("Drweb: Could not read scanner response (rc, read: %d errno: %d)\n", read, errno); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } if ( (read = recv( Scanner.sock_fd, &scan_vnum, sizeof(scan_vnum), 0 )) != sizeof(scan_vnum) ) { Scanner.Close(); LogFile::ErrorMessage("Drweb: Could not read scanner response (vnum, read: %d errno: %d)\n", read, errno); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } scan_rc = ntohl(scan_rc); scan_vnum = ntohl(scan_vnum); if ( scan_rc == DERR_IS_CLEAN || scan_rc & DERR_ARCHIVE_RESTRICTION || scan_rc & DERR_SKIP_OBJECT ) { Scanner.Close(); ScannerAnswer = "0Clean"; return ScannerAnswer; } char code[512]; memset(&code, 0, sizeof(code)); snprintf(code, 500, "%d", scan_rc); string Code = code; if (scan_rc & DERR_INFECTED || scan_rc & DERR_SUSPICIOUS || (Params::GetConfigBool("DRWEBMALWARE") && scan_rc & DERR_MALWARE) ) { ScannerAnswer = "1unknown (" + Code + ")"; string VirusNames = ""; for (int i=0;i 250 ) scan_slen = 250; if ( (read = recv( Scanner.sock_fd, &vname, scan_slen, 0 )) != scan_slen ) { Scanner.Close(); LogFile::ErrorMessage("Drweb: Could not read scanner response (vname, read: %d errno: %d)\n", read, errno); return ScannerAnswer; } string tmp = vname; if (i==0) { VirusNames = tmp; } else { VirusNames += ", " + tmp; } } SearchReplace( VirusNames, "infected with ", "" ); if ( VirusNames != "" ) ScannerAnswer = "1" + VirusNames; } else if (scan_rc & DERR_DAEMON_ERROR) { if (scan_rc & DERR_READ_ERR) { ScannerAnswer = "2Daemon could not read tempfile"; } else { ScannerAnswer = "2Daemon error (" + Code + ")"; } } else { ScannerAnswer = "2Unknown error (" + Code + ")"; } Scanner.Close(); return ScannerAnswer; } void DrwebScanner::FreeDatabase() { } bool DrwebScanner::ConnectScanner() { bool SockAnswer; if ( UseSocket ) { SockAnswer = Scanner.ConnectToSocket( Params::GetConfigString("DRWEBSOCKET"), 1 ); } else { SockAnswer = Scanner.ConnectToServer(); } if ( SockAnswer == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Drweb: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } return false; } return true; } //Constructor DrwebScanner::DrwebScanner() { ScannerName = "Drweb Socket Scanner"; ScannerNameShort = "Drweb"; LastError = 0; if ( Params::GetConfigString("DRWEBSERVER") != "" ) { UseSocket = false; if ( Scanner.SetDomainAndPort( Params::GetConfigString("DRWEBSERVER"), Params::GetConfigInt("DRWEBPORT") ) == false ) { LogFile::ErrorMessage("Drweb: Could not resolve scanner host\n"); } } else { UseSocket = true; } Opts = DRWEBD_RETURN_VIRUSES; if ( Params::GetConfigBool("DRWEBHEURISTIC") == true ) { Opts = Opts | DRWEBD_HEURISTIC_ON; } ScannerAnswer.reserve(100); } //Destructor DrwebScanner::~DrwebScanner() { } havp-0.93/havp/scanners/trophiescanner.h0000644000000000000000000001025213425375304017056 0ustar rootroot/*************************************************************************** trophiescanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TROPHIESCANNER_H #define TROPHIESCANNER_H #include "../genericscanner.h" #define TROPHIE_VERSION "1.12" #define VS_PROCESS_ALL_FILES_IN_ARCHIVE 1 #define VS_PROCESS_ALL_FILES 1 extern "C" { /* --- VSAPI --- */ /* For VSInit() */ struct trophie_vs_type { int handle_addr; int vs_pid; /* PID - getpid() result, which we've given to it */ char vscan_str[9]; /* holds 'VSCAN___' */ char version_string[11]; /* version string */ unsigned short pattern_version; /* pattern version */ unsigned short unknown_1; /* don't care, and don't want to care */ unsigned long pattern_number; /* pettern number (how many viruses it detects - I think :) */ }; /* For callbackup function */ struct callback_type { int flag_infected; /* set to 1 if file is infected */ int flag_archive; /* is the file to be checked actually an archive? */ int so_far_it_was_always_minus_one; /* no idea yet for what this is used */ char *archive_being_scanned; /* The name of the *archive* (filename) being scanned - will be NULL if we're scanning file (not archive) */ char this_is_how_windows_source_code_looks_like[156]; /* this is definitelly not right, but we don't really care for data inside :) */ char *vname; /* This is what we care about - virus name :) */ char *current_filename; /* Filename being checked */ }; /* This structure is passed to VSGetVirusPatternInfoEx and will receive the * extended pattern info */ /* For VSGetVirusPatternInfoEx() */ struct pattern_info_ex_type { unsigned int unknown_1; unsigned int unknown_2; unsigned int unknown_3; unsigned int info; /* As a decimal number: MNNNVV M: major number NNN: pattern number VV: pattern version E.g. 195409 is 1.954.09 */ }; /* trophiescanner.cpp */ extern int VSInit(pid_t, const char *, int, int *); extern int VSReadVirusPattern(int, int, int, int *); extern int VSGetVirusPatternInfoEx(int, int *); extern int VSGetVSCInfo(struct trophie_vs_type *); extern int VSGetCurrentPatternFileVersion(int, int *); extern int VSGetDetectableVirusNumber(int); /* int VSSetProcessFileCallBackFunc(int, XXX); */ extern int VSSetProcessFileCallBackFunc(int, int(*)(char *a, struct callback_type *b, int c, char *d)); extern int VSSetProcessAllFileInArcFlag(int, int); extern int VSSetProcessAllFileFlag(int, int); extern int VSSetExtractFileCountLimit(int, int); extern int VSSetExtractFileRatioLimit(int, int); extern int VSSetExtractFileSizeLimit(int, int); extern int VSSetExtractPath(int, const char *); extern int VSSetTempPath(int, const char*); extern int VSQuit(int); /* trophie_scanfile */ extern int VSVirusScanFileWithoutFNFilter(int, char *, int); }; class TrophieScanner : public GenericScanner { private: string ScannerAnswer; char Ready[2]; struct trophie_vs_type trophie_vs; struct pattern_info_ex_type pattern_info_ex; int trophie_scanfile( char *scan_file ); static int vs_callback( char *a, struct callback_type *b, int c, char *d ); static char VIR_NAME[512]; int vs_addr; unsigned int cur_patt; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); TrophieScanner(); ~TrophieScanner(); }; #endif havp-0.93/havp/scanners/nod32scanner.h0000644000000000000000000000304113425375304016327 0ustar rootroot/*************************************************************************** nod32scanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef NOD32SCANNER_H #define NOD32SCANNER_H #include "../genericscanner.h" class NOD32Scanner : public GenericScanner { private: string Agent; int Version; string ScannerCmd; SocketHandler NOD32Socket; time_t LastError; string ScannerAnswer; char Ready[2]; string ScanV30( const char *FileName ); string ScanV25( const char *FileName ); string ScanV21( const char *FileName ); public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); NOD32Scanner(); ~NOD32Scanner(); }; #endif havp-0.93/havp/scanners/avgscanner.h0000644000000000000000000000257613425375304016173 0ustar rootroot/*************************************************************************** avgscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AVGSCANNER_H #define AVGSCANNER_H #include "../genericscanner.h" class AVGScanner : public GenericScanner { private: string ScannerCmd; SocketHandler AVGSocket; time_t LastError; string ScannerAnswer; char Ready[2]; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); AVGScanner(); ~AVGScanner(); }; #endif havp-0.93/havp/scanners/kasperskyscanner.cpp0000644000000000000000000001426213425375304017760 0ustar rootroot/*************************************************************************** kasperskyscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kasperskyscanner.h" bool KasperskyScanner::InitDatabase() { return true; } int KasperskyScanner::ReloadDatabase() { return 0; } string KasperskyScanner::Scan( const char *FileName ) { string Response; if ( Connected == false ) { //Connect if ( AVESocket.ConnectToSocket( Params::GetConfigString("AVESOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("KAV: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Get initial response if ( AVESocket.GetLine( Response, "\r\n", 600 ) == false ) { AVESocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Check greeting if ( MatchBegin( Response, "201", 3 ) == false ) { AVESocket.Close(); LogFile::ErrorMessage("KAV: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } Connected = true; } //Construct command for scanner ScannerCmd = "SCAN xmQPRSTUWabcdefghi "; ScannerCmd += FileName; ScannerCmd += "\r\n"; //Send command if ( AVESocket.Send( ScannerCmd ) == false ) { AVESocket.Close(); Connected = false; //Try to reconnect if failed sleep(1); if ( AVESocket.ConnectToSocket( Params::GetConfigString("AVESOCKET"), 1 ) == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("KAV: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Get initial response if ( AVESocket.GetLine( Response, "\r\n", 600 ) == false ) { AVESocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Check greeting if ( MatchBegin( Response, "201", 3 ) == false ) { AVESocket.Close(); LogFile::ErrorMessage("KAV: Invalid greeting from scanner\n"); ScannerAnswer = "2Invalid greeting from scanner"; return ScannerAnswer; } //Send command.. again if ( AVESocket.Send( ScannerCmd ) == false ) { AVESocket.Close(); LogFile::ErrorMessage("KAV: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } Connected = true; } ScannerAnswer = ""; //Parse response lines do { if ( AVESocket.GetLine( Response, "\r\n", 600 ) == false ) { AVESocket.Close(); Connected = false; ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Virus name found if ( MatchBegin( Response, "322-", 4 ) ) { string::size_type Position; if ( (Position = Response.find("/", 4)) != string::npos ) { ScannerAnswer = "1" + Response.substr( 4, Position - 5 ); } } } while ( MatchBegin( Response, "3", 1 ) ); //Clean if ( MatchBegin( Response, "220", 3 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Infected else if ( MatchBegin( Response, "230", 3 ) ) { if (ScannerAnswer == "") ScannerAnswer = "1Unknown"; return ScannerAnswer; } //Suspicious else if ( MatchBegin( Response, "232", 3 ) ) { if (ScannerAnswer == "") ScannerAnswer = "1Suspicious"; return ScannerAnswer; } //Scan Error else if ( MatchBegin( Response, "241", 3 ) ) { ScannerAnswer = "2" + Response; return ScannerAnswer; } //Other Error else if ( MatchBegin( Response, "5", 1 ) ) { ScannerAnswer = "2" + Response; return ScannerAnswer; } //Other non-fatal responses else if ( MatchBegin( Response, "2", 1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } LogFile::ErrorMessage("KAV: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Unknown scanner response"; return ScannerAnswer; } void KasperskyScanner::FreeDatabase() { } void KasperskyScanner::CloseSocket() { AVESocket.Close(); Connected = false; } //Constructor KasperskyScanner::KasperskyScanner() { ScannerName = "Kaspersky Socket Scanner"; ScannerNameShort = "KAV"; Connected = false; LastError = 0; ScannerAnswer.reserve(100); } //Destructor KasperskyScanner::~KasperskyScanner() { } havp-0.93/havp/scanners/Makefile.in0000644000000000000000000000067213425375304015733 0ustar rootrootCXX = @CXX@ CFLAGS = @CFLAGS@ DEFINES = @DEFS@ AR = @AR@ OBJECTS = avgscanner.o f-protscanner.o kasperskyscanner.o \ nod32scanner.o clamdscanner.o sophiescanner.o \ avastscanner.o arcavirscanner.o drwebscanner.o \ @SCANNEROBJECTS@ all: scanners scanners: $(OBJECTS) ../default.h rm -f scanners.a $(AR) cr scanners.a $(OBJECTS) %.o: %.cpp %.h $(CXX) $(CFLAGS) $(DEFINES) -c -o $@ $< clean: rm -f *.o *.a havp-0.93/havp/scanners/f-protscanner.cpp0000644000000000000000000002330413425375304017150 0ustar rootroot/*************************************************************************** f-protscanner.cpp - description ------------------- begin : Mit Jun 29 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "f-protscanner.h" bool FProtScanner::InitDatabase() { return true; } int FProtScanner::ReloadDatabase() { return 0; } void FProtScanner::FreeDatabase() { } string FProtScanner::Scan( const char *FileName ) { if ( Connected == false && ConnectScanner() == false ) { ScannerAnswer = "2Could not connect to scanner"; return ScannerAnswer; } if ( Version == 0 ) { Version = TestVersion(); if ( Version == 0 ) { ScannerAnswer = "2Could not connect to scanner"; return ScannerAnswer; } if ( Connected == false && ConnectScanner() == false ) { ScannerAnswer = "2Could not connect to scanner"; return ScannerAnswer; } } if ( Version == 6 ) return ScanV6( FileName ); return ScanV4( FileName ); } string FProtScanner::ScanV6( const char *FileName ) { //Construct command for scanner ScannerCmd = "SCAN "; ScannerCmd += Opts; ScannerCmd += "FILE "; ScannerCmd += FileName; ScannerCmd += "\n"; if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("%s: Could not call scanner\n", ScannerNameShort.c_str()); ScannerAnswer = "2Could not call scanner"; return ScannerAnswer; } string Response; if ( Scanner.GetLine( Response, "\n", 600 ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("%s: Could not read scanner response\n", ScannerNameShort.c_str()); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } if ( MatchBegin( Response, "0 ", 2 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } int status = 0; if ( sscanf(Response.substr(0,4).c_str(), "%d ", &status) != 1 ) status = 0; if ( status & 1 || MatchBegin( Response, "1 ", 2 ) || Response.find("" ); if ( PosEnd != string::npos && PosEnd > 3 ) { VirusName = Response.substr( 3, PosEnd - 3 ); } SearchReplace( VirusName, "contains infected objects: ", "" ); SearchReplace( VirusName, "infected: ", "" ); //Reports "clean" for broken ZIPs with viruses? //Sadly it is the case when MAXSCANSIZE it reached too.. if ( VirusName == "clean" ) VirusName = "virus inside archive"; ScannerAnswer = "1" + VirusName; return ScannerAnswer; } //Code 2 for archive bombs etc //Different codes for encrypted files etc, but they are reported "clean" if ( MatchBegin( Response, "2 ", 2 ) || Response.find("") != string::npos ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } LogFile::ErrorMessage("%s: Error response: %s\n", ScannerNameShort.c_str(), Response.c_str()); ScannerAnswer = "2Scanner error"; return ScannerAnswer; } string FProtScanner::ScanV4( const char *FileName ) { //Construct command for scanner ScannerCmd = "GET "; ScannerCmd += FileName; ScannerCmd += " HTTP/1.0\r\n\r\n"; if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("%s: Could not call scanner\n", ScannerNameShort.c_str()); ScannerAnswer = "2Could not call scanner"; return ScannerAnswer; } string Response; int ret; while ( (ret = Scanner.Recv( Response, true, 600 )) != 0 ) { if ( ret < 0 ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("%s: Could not read scanner response\n", ScannerNameShort.c_str()); ScannerAnswer = "2Could not read scanner response"; return ScannerAnswer; } } Scanner.Close(); Connected = false; string::size_type PositionEnd; if ( (PositionEnd = Response.rfind( "", string::npos )) == string::npos ) { LogFile::ErrorMessage("%s: Invalid response from scanner\n", ScannerNameShort.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } string::size_type Position; if ( (Position = Response.rfind( ">", PositionEnd )) == string::npos ) { LogFile::ErrorMessage("%s: Invalid response from scanner\n", ScannerNameShort.c_str()); ScannerAnswer = "2Invalid response from scanner"; return ScannerAnswer; } string SummaryCode = Response.substr( Position + 1, PositionEnd - (Position + 1) ); if ( SummaryCode == "clean" ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } else if ( SummaryCode == "infected" ) { if ( (PositionEnd = Response.rfind( "
" )) != string::npos ) { if ( (Position = Response.rfind( ">", PositionEnd )) == string::npos ) { ScannerAnswer = "1Unknown"; return ScannerAnswer; } ScannerAnswer = "1" + Response.substr( Position+1, PositionEnd - (Position + 1) ); return ScannerAnswer; } else if ( (PositionEnd = Response.rfind( "" )) != string::npos ) { if ( (Position = Response.rfind( ">", PositionEnd )) == string::npos ) { ScannerAnswer = "1Unknown"; return ScannerAnswer; } ScannerAnswer = "1" + Response.substr( Position+1, PositionEnd - (Position + 1) ); return ScannerAnswer; } else { ScannerAnswer = "1Unknown"; return ScannerAnswer; } } ScannerAnswer = "2Unknown response from scanner"; return ScannerAnswer; } int FProtScanner::TestVersion() { //Construct command for scanner ScannerCmd = "HELP\nQUIT\n"; if ( Scanner.Send( ScannerCmd ) == false ) { Scanner.Close(); Connected = false; LogFile::ErrorMessage("%s: Could not call scanner\n", ScannerNameShort.c_str()); return 0; } string Response; int ret = Scanner.Recv( Response, true, 30 ); Scanner.Close(); Connected = false; if ( ret < 0 ) { LogFile::ErrorMessage("%s: Could not read scanner response\n", ScannerNameShort.c_str()); return 0; } if ( MatchBegin( Response, "FPSCAND:6", 9 ) ) { return 6; } return 4; } bool FProtScanner::ConnectScanner() { if ( Version == 4 ) { if ( Scanner.SetDomainAndPort( ServerHost, ServerPort ) == false ) { LogFile::ErrorMessage("%s: Could not resolve scanner host", ScannerNameShort.c_str()); return false; } } if ( Scanner.ConnectToServer() == false ) { if ( Version == 4 ) { //Old F-Prot version might be updating, try next port.. if ( Scanner.SetDomainAndPort( ServerHost, ServerPort + 1 ) == false ) { LogFile::ErrorMessage("%s: Could not resolve scanner host", ScannerNameShort.c_str()); return false; } } else { sleep(1); } if ( Scanner.ConnectToServer() == false ) { Scanner.Close(); Connected = false; //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("%s: Could not connect to scanner! Scanner down?\n", ScannerNameShort.c_str()); LastError = time(NULL); } return false; } } Connected = true; return true; } //Close persistent connection from HAVP scanner initialization //Needed because it will fork later void FProtScanner::CloseSocket() { Scanner.Close(); Connected = false; } //Constructor FProtScanner::FProtScanner() { ScannerName = "F-Prot Socket Scanner"; ScannerNameShort = "F-Prot"; LastError = 0; Version = 0; Connected = false; ServerHost = Params::GetConfigString("FPROTSERVER"); ServerPort = Params::GetConfigInt("FPROTPORT"); Version = Params::GetConfigInt("FPROTVERSION"); Opts = ""; if ( Params::GetConfigString("FPROTOPTIONS") != "" ) { Opts = Params::GetConfigString("FPROTOPTIONS") + " "; } if ( Scanner.SetDomainAndPort( ServerHost, ServerPort ) == false ) { LogFile::ErrorMessage("%s: Could not resolve scanner host", ScannerNameShort.c_str()); } ScannerAnswer.reserve(100); } //Destructor FProtScanner::~FProtScanner() { } havp-0.93/havp/scanners/drwebscanner.h0000644000000000000000000000267413425375304016520 0ustar rootroot/*************************************************************************** drwebscanner.h - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DRWEBSCANNER_H #define DRWEBSCANNER_H #include "../genericscanner.h" class DrwebScanner : public GenericScanner { private: bool UseSocket; string ScannerAnswer; char Ready[2]; SocketHandler Scanner; time_t LastError; string ScannerCmd; int Opts; bool ConnectScanner(); public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); DrwebScanner(); ~DrwebScanner(); }; #endif havp-0.93/havp/scanners/clamdscanner.cpp0000644000000000000000000001206413425375304017022 0ustar rootroot/*************************************************************************** clamdscanner.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "clamdscanner.h" bool ClamdScanner::InitDatabase() { return true; } int ClamdScanner::ReloadDatabase() { return 0; } string ClamdScanner::Scan( const char *FileName ) { bool SockAnswer; if ( UseSocket ) { SockAnswer = CLAMDSocket.ConnectToSocket( Params::GetConfigString("CLAMDSOCKET"), 1 ); } else { SockAnswer = CLAMDSocket.ConnectToServer(); } if ( SockAnswer == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Clamd: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } //Construct command for scanner ScannerCmd = "SCAN "; ScannerCmd += FileName; ScannerCmd += "\n"; //Send command if ( CLAMDSocket.Send( ScannerCmd ) == false ) { CLAMDSocket.Close(); //Try to reconnect after 1 second sleep(1); if ( UseSocket ) { SockAnswer = CLAMDSocket.ConnectToSocket( Params::GetConfigString("CLAMDSOCKET"), 1 ); } else { SockAnswer = CLAMDSocket.ConnectToServer(); } if ( SockAnswer == false ) { //Prevent log flooding, show error only once per minute if ( (LastError == 0) || (LastError + 60 < time(NULL)) ) { LogFile::ErrorMessage("Clamd: Could not connect to scanner! Scanner down?\n"); LastError = time(NULL); } ScannerAnswer = "2Could not connect to scanner socket"; return ScannerAnswer; } if ( CLAMDSocket.Send( ScannerCmd ) == false ) { CLAMDSocket.Close(); LogFile::ErrorMessage("Clamd: Could not write command to scanner\n"); ScannerAnswer = "2Scanner connection failed"; return ScannerAnswer; } } string Response; //Get response if ( CLAMDSocket.GetLine( Response, "\n", 600 ) == false ) { CLAMDSocket.Close(); ScannerAnswer = "2Could not read from scanner socket"; return ScannerAnswer; } //Connection will be closed CLAMDSocket.Close(); //Clean? if ( MatchSubstr( Response, " OK", -1 ) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } string::size_type Position; //Virus? if ( (Position = Response.find(" FOUND")) != string::npos ) { string::size_type PositionStart = Response.find(": ") + 2; ScannerAnswer = "1" + Response.substr( PositionStart, Position - PositionStart ); return ScannerAnswer; } //Error? if ( (Position = Response.find(" ERROR")) != string::npos ) { //Ignore RAR errors if ( Response.find("RAR module failure") != string::npos ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } string::size_type PositionStart = Response.find(": ") + 2; ScannerAnswer = "2" + Response.substr( PositionStart, Position - PositionStart ); return ScannerAnswer; } //Unknown answer.. LogFile::ErrorMessage("Clamd: Unknown response from scanner: %s\n", Response.c_str()); ScannerAnswer = "2Unknown response from scanner"; return ScannerAnswer; } void ClamdScanner::FreeDatabase() { } //Constructor ClamdScanner::ClamdScanner() { ScannerName = "Clamd Socket Scanner"; ScannerNameShort = "Clamd"; LastError = 0; if ( Params::GetConfigString("CLAMDSERVER") != "" ) { UseSocket = false; if ( CLAMDSocket.SetDomainAndPort( Params::GetConfigString("CLAMDSERVER"), Params::GetConfigInt("CLAMDPORT") ) == false ) { LogFile::ErrorMessage("Clamd: Could not resolve scanner host\n"); } } else { UseSocket = true; } ScannerAnswer.reserve(100); } //Destructor ClamdScanner::~ClamdScanner() { } havp-0.93/havp/scanners/clamlibscanner.h0000644000000000000000000000301613425375304017007 0ustar rootroot/*************************************************************************** clamlibscanner.h - description ------------------- begin : 2005/02/12 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CLAMLIBSCANNER_H #define CLAMLIBSCANNER_H #include "../genericscanner.h" #include using namespace std; class ClamLibScanner : public GenericScanner { private: string ScannerAnswer; char Ready[2]; const char *virname; #ifdef CL_INIT_DEFAULT struct cl_engine *engine; #else struct cl_node *engine; struct cl_limits limits; #endif struct cl_stat dbstat; char dbdir[255]; struct cl_scan_options cl_options; public: bool InitDatabase(); int ReloadDatabase(); void FreeDatabase(); string Scan( const char *FileName ); ClamLibScanner(); ~ClamLibScanner(); }; #endif havp-0.93/havp/scanners/clamlibscanner.cpp0000644000000000000000000002202113425375304017337 0ustar rootroot/*************************************************************************** clamlibscanner.cpp - description ------------------- begin : 2005/02/12 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ extern int LL; #include "clamlibscanner.h" bool ClamLibScanner::InitDatabase() { unsigned int sigs = 0; int ret; if (LL>2) cl_debug(); #ifdef CL_INIT_DEFAULT if ( (ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS ) { printf("ClamAV: cl_init() error: %s\n", cl_strerror(ret)); return false; } if ( !(engine = cl_engine_new()) ) { printf("ClamAV: cl_engine_new() failed\n"); return false; } // Limits if ( (ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, (long long)1048576 * Params::GetConfigInt("CLAMMAXSCANSIZE"))) ) { LogFile::ErrorMessage("ClamAV: set CL_ENGINE_MAX_SCANSIZE failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return false; } if ( (ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILESIZE, (long long)1048576 * Params::GetConfigInt("CLAMMAXFILESIZE"))) ) { LogFile::ErrorMessage("ClamAV: set CL_ENGINE_MAX_FILESIZE failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return false; } if ( (ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILES, (long long)Params::GetConfigInt("CLAMMAXFILES"))) ) { LogFile::ErrorMessage("ClamAV: set CL_ENGINE_MAX_FILES failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return false; } if ( (ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, (long long)Params::GetConfigInt("CLAMMAXRECURSION"))) ) { LogFile::ErrorMessage("ClamAV: set CL_ENGINE_MAX_RECURSION failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return false; } // Tempdir if ( (ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, Params::GetConfigString("TEMPDIR").c_str())) ) { LogFile::ErrorMessage("ClamAV: set CL_ENGINE_TMPDIR failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return false; } #else engine = NULL; cl_settempdir(Params::GetConfigString("TEMPDIR").c_str(), 0); #endif LogFile::ErrorMessage("ClamAV: Using database directory: %s\n", dbdir); #ifdef CL_INIT_DEFAULT if ( (ret = cl_load(dbdir, engine, &sigs, 0)) != CL_SUCCESS ) #else if ( (ret = cl_load(dbdir, &engine, &sigs, 0)) != 0 ) #endif { LogFile::ErrorMessage("ClamAV: Could not load database: %s\n", cl_strerror(ret)); return false; } LogFile::ErrorMessage("ClamAV: Loaded %d signatures (engine %s)\n", sigs, cl_retver()); //Build engine #ifdef CL_INIT_DEFAULT if ( (ret = cl_engine_compile(engine)) != CL_SUCCESS ) #else if ( (ret = cl_build(engine)) != 0 ) #endif { LogFile::ErrorMessage("ClamAV: Database initialization error: %s\n", cl_strerror(ret)); #ifdef CL_INIT_DEFAULT cl_engine_free(engine); #else cl_free(engine); #endif return false; } memset(&dbstat, 0, sizeof(struct cl_stat)); cl_statinidir(dbdir, &dbstat); return true; } int ClamLibScanner::ReloadDatabase() { int ret = cl_statchkdir(&dbstat); if ( ret == 1 ) { unsigned int sigs = 0; struct cl_settings *settings = NULL; #ifdef CL_INIT_DEFAULT if ( engine ) { settings = cl_engine_settings_copy(engine); if ( !settings ) LogFile::ErrorMessage("ClamAV: cl_engine_settings_copy() failed\n"); cl_engine_free(engine); } if ( !(engine = cl_engine_new()) ) { printf("ClamAV: cl_engine_new() failed\n"); return false; } if ( settings ) { if ( (ret = cl_engine_settings_apply(engine, settings)) != CL_SUCCESS ) { LogFile::ErrorMessage("ClamAV: cl_engine_settings_apply() failed: %s\n", cl_strerror(ret)); } cl_engine_settings_free(settings); } #else cl_free(engine); engine = NULL; cl_settempdir(Params::GetConfigString("TEMPDIR").c_str(), 0); #endif #ifdef CL_INIT_DEFAULT if ( (ret = cl_load(dbdir, engine, &sigs, 0)) != CL_SUCCESS ) #else if ( (ret = cl_load(dbdir, &engine, &sigs, 0)) != 0 ) #endif { LogFile::ErrorMessage("ClamAV: Could not reload database: %s\n", cl_strerror(ret)); #ifdef CL_INIT_DEFAULT cl_engine_free(engine); #else cl_free(engine); #endif return -1; } #ifdef CL_INIT_DEFAULT if ( (ret = cl_engine_compile(engine)) != CL_SUCCESS ) #else if ( (ret = cl_build(engine)) != 0 ) #endif { LogFile::ErrorMessage("ClamAV: Database initialization error: %s\n", cl_strerror(ret)); #ifdef CL_INIT_DEFAULT cl_engine_free(engine); #else cl_free(engine); #endif return -1; } LogFile::ErrorMessage("ClamAV: Reloaded %d signatures (engine %s)\n", sigs, cl_retver()); cl_statfree(&dbstat); memset(&dbstat, 0, sizeof(struct cl_stat)); cl_statinidir(dbdir, &dbstat); return 1; } else if ( ret != 0 ) { LogFile::ErrorMessage("ClamAV: Error on database check: %s\n", cl_strerror(ret)); } return 0; } string ClamLibScanner::Scan( const char *FileName ) { #ifdef CL_INIT_DEFAULT int ret = cl_scanfile(FileName, &virname, NULL, engine, &cl_options); #else int ret = cl_scanfile(FileName, &virname, NULL, engine, &limits, scanopts); #endif //Clean? if ( ret == CL_CLEAN ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } //Virus? if ( ret == CL_VIRUS ) { //Ignore Oversized.XXX errors? ClamAV does not honour BLOCKMAX on Ratio if ( (strstr(virname, "Oversized.") != NULL) && (Params::GetConfigBool("CLAMBLOCKMAX") == false) ) { ScannerAnswer = "0Clean"; return ScannerAnswer; } ScannerAnswer = "1"; ScannerAnswer += virname; return ScannerAnswer; } //Error.. ScannerAnswer = "2"; ScannerAnswer += cl_strerror(ret); return ScannerAnswer; } void ClamLibScanner::FreeDatabase() { #ifdef CL_INIT_DEFAULT int ret = cl_engine_free(engine); if ( ret != CL_SUCCESS ) { LogFile::ErrorMessage("ClamAV: cl_engine_free() failed: %s\n", cl_strerror(ret)); } #else cl_free(engine); #endif } //Constructor ClamLibScanner::ClamLibScanner() { ScannerName = cl_retver(); if ( MatchSubstr( ScannerName, "devel", -1 ) ) { ScannerName = "ClamAV Library Scanner (devel)"; } else { ScannerName = "ClamAV Library Scanner"; } ScannerNameShort = "ClamAV"; memset(&dbdir, 0, sizeof(dbdir)); if (Params::GetConfigString("CLAMDBDIR") != "") { strncpy(dbdir, Params::GetConfigString("CLAMDBDIR").c_str(), 254); } else { strncpy(dbdir, cl_retdbdir(), 254); } //Set scanning options memset(&cl_options, 0, sizeof(struct cl_scan_options)); cl_options.general = CL_SCAN_GENERAL_ALLMATCHES; cl_options.parse = ~0; /* scanopts = CL_SCAN_STDOPT; */ if ( Params::GetConfigBool("CLAMBLOCKMAX") ) { /* scanopts = scanopts | CL_SCAN_BLOCKMAX; */ cl_options.heuristic |= CL_SCAN_HEURISTIC_EXCEEDS_MAX; } if ( Params::GetConfigBool("CLAMBLOCKENCRYPTED") ) { /* scanopts = scanopts | CL_SCAN_BLOCKENCRYPTED; */ cl_options.heuristic |= CL_SCAN_HEURISTIC_ENCRYPTED_ARCHIVE; cl_options.heuristic |= CL_SCAN_HEURISTIC_ENCRYPTED_DOC; } if ( Params::GetConfigBool("CLAMBLOCKBROKEN") ) { /* scanopts = scanopts | CL_SCAN_BLOCKBROKEN; */ cl_options.heuristic |= CL_SCAN_HEURISTIC_BROKEN; } if (cl_options.heuristic != 0) cl_options.general |= CL_SCAN_GENERAL_HEURISTICS; //Set up archive limits #ifndef CL_INIT_DEFAULT memset(&limits, 0, sizeof(limits)); limits.maxfiles = Params::GetConfigInt("CLAMMAXFILES"); limits.maxfilesize = 1048576 * Params::GetConfigInt("CLAMMAXFILESIZE"); limits.maxreclevel = Params::GetConfigInt("CLAMMAXRECURSION"); limits.maxscansize = 1048576 * Params::GetConfigInt("CLAMMAXSCANSIZE"); limits.archivememlim = 0; #endif ScannerAnswer.reserve(100); } //Destructor ClamLibScanner::~ClamLibScanner() { } havp-0.93/havp/Makefile.in0000644000000000000000000000375713425375246014133 0ustar rootrootCXX = @CXX@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ DEFINES = @DEFS@ INSTALL = ../install-sh prefix = @prefix@ exec_prefix = $(prefix) sbindir = @sbindir@ sysconfdir = @sysconfdir@ localstatedir = @localstatedir@ OBJECTS = helper.o logfile.o scannerhandler.o connectiontobrowser.o \ genericscanner.o httphandler.o params.o sockethandler.o \ connectiontohttp.o havp.o proxyhandler.o utils.o whitelist.o all: havp havp: $(OBJECTS) cd scanners && $(MAKE) $(CXX) $(CFLAGS) -o havp $(OBJECTS) scanners/scanners.a $(LDFLAGS) %.o: %.cpp %.h default.h $(CXX) $(CFLAGS) $(DEFINES) -c -o $@ $< install: all $(INSTALL) -d $(DESTDIR)$(sbindir) $(INSTALL) -m 755 havp $(DESTDIR)$(sbindir)/havp $(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/log/havp $(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/tmp/havp $(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/run/havp $(INSTALL) -d $(DESTDIR)/etc/init.d $(INSTALL) -m 644 ../etc/havp/havp.config $(DESTDIR)$(sysconfdir)/havp/havp.config.default @if [ ! -f $(DESTDIR)$(sysconfdir)/havp/havp.config ]; then \ echo "$(INSTALL) -m 644 ../etc/havp/havp.config $(DESTDIR)$(sysconfdir)/havp/havp.config"; \ $(INSTALL) -m 644 ../etc/havp/havp.config $(DESTDIR)$(sysconfdir)/havp/havp.config; \ else \ echo "Updating config $(DESTDIR)$(sysconfdir)/havp/havp.config"; \ ../update-conf $(DESTDIR)$(sysconfdir)/havp/havp.config; \ fi @if [ ! -f $(DESTDIR)$(sysconfdir)/havp/whitelist ]; then \ $(INSTALL) -m 644 ../etc/havp/whitelist $(DESTDIR)$(sysconfdir)/havp/whitelist; \ else \ echo "Not overwriting old $(DESTDIR)$(sysconfdir)/havp/whitelist"; \ fi @if [ ! -f $(DESTDIR)$(sysconfdir)/havp/blacklist ]; then \ $(INSTALL) -m 644 ../etc/havp/blacklist $(DESTDIR)$(sysconfdir)/havp/blacklist; \ else \ echo "Not overwriting old $(DESTDIR)$(sysconfdir)/havp/blacklist"; \ fi cp -r ../etc/havp/templates $(DESTDIR)$(sysconfdir)/havp/ chmod -R a+rX $(DESTDIR)$(sysconfdir)/havp/templates clean: cd scanners && $(MAKE) clean rm -f havp *.o havp-0.93/havp/utils.h0000644000000000000000000000321713425375263013365 0ustar rootroot/*************************************************************************** utils.h - description ------------------- begin : Sa M� 5 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef UTILS_H #define UTILS_H #include #include #include #include #include using namespace std; string UpperCase( string CaseString ); void SearchReplace( string &source, string search, string replace ); int select_eintr( int fds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout ); bool MatchSubstr(string &hay, const char* needle, int startpos); bool MatchBegin(string &hay, const char *needle, int needlelength); bool MatchWild(const char *str, const char *pat); void Tokenize(const string& str, vector& tokens); string base64_encode(string input); #endif havp-0.93/havp/params.h0000644000000000000000000000306413425375263013510 0ustar rootroot/*************************************************************************** params.h - description ------------------- begin : So Feb 20 2005 copyright : (C) 2005 by Peter Sebald / Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PARAMS_H #define PARAMS_H #include #include using namespace std; class Params { private: static map params; static bool ReadConfig( string file ); static void ShowConfig( string cfgfile ); static bool TestConfig(); static void Usage(); static void SetDefaults(); public: static bool SetParams( int argcT, char* argv[] ); static void SetConfig( string key, string val ); static bool GetConfigBool( string key ); static string GetConfigString( string key ); static int GetConfigInt( string key ); }; #endif havp-0.93/havp/helper.h0000644000000000000000000000241513425375263013503 0ustar rootroot/*************************************************************************** helper.h - description ------------------- begin : Sa M� 5 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HELPER_H #define HELPER_H #include #include bool MakeDaemon(); bool HardLockTest(); bool ChangeUserAndGroup( string usr, string grp ); string GetUser(); string GetGroup(); bool WritePidFile( pid_t pid ); int InstallSignal( int level ); #endif havp-0.93/havp/params.cpp0000644000000000000000000003144113425375265014045 0ustar rootroot/*************************************************************************** params.cpp - description ------------------- begin : 2005/02/20 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "params.h" #include "utils.h" #include #include #include #include #include #include #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long) -1) #endif map Params::params; void Params::SetDefaults() { SetConfig("DISPLAYINITIALMESSAGES", "true"); SetConfig("USER", "havp"); SetConfig("GROUP", "havp"); SetConfig("DAEMON", "true"); SetConfig("SERVERNUMBER", "8"); SetConfig("MAXSERVERS", "150"); SetConfig("PORT", "8080"); SetConfig("BIND_ADDRESS", ""); SetConfig("SOURCE_ADDRESS", ""); SetConfig("PARENTPROXY", ""); SetConfig("PARENTPORT", "0"); SetConfig("PARENTUSER", ""); SetConfig("PARENTPASSWORD", ""); SetConfig("ACCESSLOG", ACCESSLOG); SetConfig("VIRUSLOG", ""); SetConfig("ERRORLOG", ERRORLOG); SetConfig("TIMEFORMAT", "%d/%m/%Y %H:%M:%S"); SetConfig("LOG_OKS", "true"); SetConfig("LOGLEVEL", "0"); SetConfig("USESYSLOG", "false"); SetConfig("SYSLOGNAME", "havp"); SetConfig("SYSLOGFACILITY", "daemon"); SetConfig("SYSLOGLEVEL", "info"); SetConfig("SYSLOGVIRUSLEVEL","warning"); SetConfig("SCANIMAGES", "true"); SetConfig("SKIPMIME", ""); SetConfig("SCANMIME", ""); SetConfig("MAXSCANSIZE", "5000000"); SetConfig("KEEPBACKBUFFER", "200000"); SetConfig("KEEPBACKTIME", "5"); SetConfig("TRICKLING", "30"); SetConfig("TRICKLINGBYTES", "1"); SetConfig("WHITELISTFIRST", "true"); SetConfig("WHITELIST", WHITELISTFILE); SetConfig("BLACKLIST", BLACKLISTFILE); SetConfig("TEMPLATEPATH", TEMPLATEPATH); SetConfig("TEMPDIR", "/var/spool/havp"); SetConfig("SCANTEMPFILE", "/var/spool/havp/havp-XXXXXX"); SetConfig("PIDFILE", PIDFILE); SetConfig("TRANSPARENT", "false"); SetConfig("RANGE", "false"); SetConfig("PRELOADZIPHEADER","true"); SetConfig("FORWARDED_IP", "false"); SetConfig("X_FORWARDED_FOR","false"); SetConfig("STREAMUSERAGENT",""); SetConfig("STREAMSCANSIZE", "20000"); SetConfig("DBRELOAD", "60"); SetConfig("FAILSCANERROR", "true"); SetConfig("MAXDOWNLOADSIZE","0"); SetConfig("SCANNERTIMEOUT", "10"); SetConfig("IGNOREVIRUS", ""); SetConfig("DISABLELOCKINGFOR","AVG:ALL"); SetConfig("SSLTIMEOUT", "20"); //SCANNERS SetConfig("ENABLECLAMLIB","false"); SetConfig("CLAMDBDIR",""); SetConfig("CLAMBLOCKBROKEN","false"); SetConfig("CLAMBLOCKMAX","false"); SetConfig("CLAMBLOCKENCRYPTED","false"); SetConfig("CLAMMAXSCANSIZE","20"); SetConfig("CLAMMAXFILES","50"); SetConfig("CLAMMAXFILESIZE","100"); SetConfig("CLAMMAXRECURSION","8"); SetConfig("ENABLECLAMD","false"); SetConfig("CLAMDSOCKET","/var/run/clamav/clamd.ctl"); SetConfig("CLAMDSERVER",""); SetConfig("CLAMDPORT","3310"); SetConfig("ENABLEAVG","false"); SetConfig("AVGSERVER","127.0.0.1"); SetConfig("AVGPORT","55555"); SetConfig("ENABLEAVESERVER","false"); SetConfig("AVESOCKET","/var/run/aveserver"); SetConfig("ENABLEFPROT","false"); SetConfig("FPROTPORT","10200"); SetConfig("FPROTSERVER","127.0.0.1"); SetConfig("FPROTOPTIONS",""); SetConfig("ENABLENOD32","false"); SetConfig("NOD32SOCKET","/tmp/nod32d.sock"); SetConfig("NOD32VERSION","25"); SetConfig("ENABLETROPHIE","false"); SetConfig("TROPHIEMAXFILES","50"); SetConfig("TROPHIEMAXFILESIZE","10"); SetConfig("TROPHIEMAXRATIO","250"); SetConfig("ENABLESOPHIE","false"); SetConfig("SOPHIESOCKET","/var/run/sophie"); SetConfig("ENABLEAVAST","false"); SetConfig("AVASTSOCKET","/var/run/avast4/local.sock"); SetConfig("AVASTSERVER",""); SetConfig("AVASTPORT","5036"); SetConfig("ENABLEARCAVIR","false"); SetConfig("ARCAVIRSOCKET","/var/run/arcavird.socket"); SetConfig("ARCAVIRVERSION","2007"); SetConfig("ENABLEDRWEB","false"); SetConfig("DRWEBSOCKET","/var/drweb/run/.daemon"); SetConfig("DRWEBSERVER",""); SetConfig("DRWEBPORT","3000"); SetConfig("DRWEBHEURISTIC","true"); SetConfig("DRWEBMALWARE","true"); } bool Params::ReadConfig( string file ) { ifstream input( file.c_str() ); if ( !input ) { cerr << "Could not open config file: " << file << endl; return false; } string::size_type Position; string line, key, val; while ( input ) { getline( input, line ); //Strip whitespace from beginning and end if ( (Position = line.find_first_not_of(" \t")) != string::npos ) { line = line.substr(Position, (line.find_last_not_of(" \t", string::npos) - Position) + 1); } //Read next if nothing found if ( (Position == string::npos) || (line.size() == 0) ) continue; //Read next if commented if ( line.substr(0, 1) == "#" ) continue; //Find key and value if ( (Position = line.find_first_of(" \t")) != string::npos ) { key = line.substr(0, Position); if ( key == "REMOVETHISLINE" ) { cout << "Configuration is not edited!" << endl; cout << "You must delete REMOVETHISLINE option." << endl; cout << "Review the configuration carefully. :)" << endl; return false; } if ( (Position = line.find_first_not_of(" \t", Position + 1)) == string::npos ) { cout << "Invalid Config Line: " << line << endl; return false; } val = line.substr( Position ); Params::SetConfig( key, val ); } else { cout << "Invalid Config Line: " << line << endl; return false; } } input.close(); return true; } void Params::SetConfig( string param, string value ) { string TempParams[] = {CONFIGPARAMS}; bool ParamFound = false; param = UpperCase(param); for ( unsigned int i = 0; i < sizeof(TempParams)/sizeof(string); i++ ) { if ( param == TempParams[i] ) { ParamFound = true; } } if ( ParamFound ) { if ( UpperCase(value) == "TRUE" || UpperCase(value) == "FALSE" ) { value = UpperCase(value); } params[param] = value; } else { cout << "Unknown Config Parameter: " << param << endl; cout << "Exiting.." << endl; exit(1); } } int Params::GetConfigInt( string param ) { return atoi( params[param].c_str() ); } bool Params::GetConfigBool( string param ) { if ( params[param] == "TRUE" ) { return true; } else { return false; } } string Params::GetConfigString( string param ) { return params[param]; } void Params::ShowConfig( string cfgfile ) { cout << endl << "# Using HAVP config: " << cfgfile << endl << endl; typedef map::const_iterator CI; for(CI p = params.begin(); p != params.end(); ++p) { cout << p->first << "=" << p->second << '\n'; } cout << endl; } void Params::Usage() { cout << endl << "Usage: havp [Options]" << endl << endl; cout << "HAVP Version " << VERSION << endl << endl; cout << "Possible options are:" << endl; cout << "--help | -h This pamphlet" << endl; cout << "--conf-file=FileName | -c Filename Use this Config-File" << endl; cout << "--show-config | -s Show configuration HAVP is using" << endl << endl; } bool Params::SetParams( int argvT, char* argcT[] ) { string option, value; string::size_type i1, i2; string cfgfile = CONFIGFILE; bool showconf = false; SetDefaults(); while ( --argvT ) { value = *++argcT; i1 = value.find_first_not_of("-"); //No GNU options if ( i1 == 1 ) { option = value.substr(i1, 1); if ( option == "c" ) { --argvT; if ( argvT == 0 ) { Usage(); return false; } value = *++argcT; } else if ( option == "s" ) { showconf = true; } else { Usage(); return false; } } //GNU options else if ( i1 == 2 ) { if ( (i2 = value.find("=")) != string::npos ) { option = value.substr(i1, i2 - i1); if ( value.size() > i2 + 1 ) { value = value.substr(i2 + 1); } else { Usage(); return false; } } else { option = value.substr(i1); value = ""; } } else { Usage(); return false; } if ( option == "help" ) { Usage(); return false; } else if ( option == "show-config" ) { showconf = true; } else if ( option == "conf-file" || option == "c" ) { if (value == "") { Usage(); return false; } cfgfile = value; } else if ( showconf == true ) { //Nothing: prevent Usage } else { Usage(); return false; } } if ( ReadConfig( cfgfile ) == false ) { return false; } if ( showconf == true ) { ShowConfig( cfgfile ); return false; } return TestConfig(); } //Test that some options are sane bool Params::TestConfig() { if ( Params::GetConfigInt("SERVERNUMBER") < 1 ) { cout << "Invalid Config: SERVERNUMBER needs to be greater than 0" << endl; return false; } if ( Params::GetConfigString("ACCESSLOG").substr(0,1) != "/" || (Params::GetConfigString("VIRUSLOG") != "" && Params::GetConfigString("VIRUSLOG").substr(0,1) != "/") || Params::GetConfigString("ERRORLOG").substr(0,1) != "/" ) { cout << "Invalid Config: Log paths need to be abolute" << endl; return false; } if ( Params::GetConfigString("SCANTEMPFILE").find("XXXXXX") == string::npos ) { cout << "Invalid Config: SCANTEMPFILE must contain string \"XXXXXX\"" << endl; return false; } if ( Params::GetConfigInt("MAXSERVERS") > 500 ) { cout << "Note: MAXSERVERS is unusually high! You are sure you want this?" << endl; } if ( Params::GetConfigString("BIND_ADDRESS") == "NULL" ) Params::SetConfig("BIND_ADDRESS",""); if ( Params::GetConfigString("BIND_ADDRESS") != "" ) { if ( inet_addr( Params::GetConfigString("BIND_ADDRESS").c_str() ) == INADDR_NONE ) { cout << "Invalid Config: Invalid BIND_ADDRESS" << endl; return false; } } if ( Params::GetConfigString("SOURCE_ADDRESS") == "NULL" ) Params::SetConfig("SOURCE_ADDRESS",""); if ( Params::GetConfigString("SOURCE_ADDRESS") != "" ) { if ( inet_addr( Params::GetConfigString("SOURCE_ADDRESS").c_str() ) == INADDR_NONE ) { cout << "Invalid Config: Invalid SOURCE_ADDRESS" << endl; return false; } } if ( Params::GetConfigString("PARENTPROXY") != "" && Params::GetConfigInt("PARENTPORT") < 1 ) { cout << "Invalid Config: Invalid PARENTPROXY/PARENTPORT" << endl; return false; } if ( Params::GetConfigInt("TRICKLING") > 0 && Params::GetConfigInt("TRICKLINGBYTES") < 1 ) { cout << "Invalid Config: TRICKLINGBYTES needs to be greater than 0" << endl; return false; } return true; } havp-0.93/havp/sockethandler.cpp0000644000000000000000000003445313425375265015416 0ustar rootroot/*************************************************************************** sockethandler.cpp - description ------------------- begin : 2005/02/12 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sockethandler.h" #include "logfile.h" #include "params.h" #include "utils.h" #include #include #include #include #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long) -1) #endif #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif //Create Server Socket bool SocketHandler::CreateServer( int portT, in_addr_t bind_addrT ) { int i = 1; my_s_addr.sin_addr.s_addr = bind_addrT; my_s_addr.sin_port = htons(portT); if ( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { LogFile::ErrorMessage("socket() failed: %s\n", strerror(errno)); return false; } // Enable re-use Socket if ( setsockopt( sock_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i) ) < 0 ) { LogFile::ErrorMessage("setsockopt() failed: %s\n", strerror(errno)); return false; } if ( ::bind( sock_fd, (struct sockaddr *) &my_s_addr, sizeof(my_s_addr) ) < 0 ) { LogFile::ErrorMessage("bind() failed: %s\n", strerror(errno)); return false; } if ( ::listen( sock_fd, MAXCONNECTIONS ) < 0 ) { LogFile::ErrorMessage("listen() failed: %s\n", strerror(errno)); return false; } return true; } //Create Server Socket, convert ASCII address representation into binary one bool SocketHandler::CreateServer( int portT, string bind_addrT ) { if ( bind_addrT == "" ) { return CreateServer( portT, INADDR_ANY ); } else { return CreateServer( portT, inet_addr( Params::GetConfigString("BIND_ADDRESS").c_str() ) ); } } //Connect to Server bool SocketHandler::ConnectToServer() { if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { LogFile::ErrorMessage("ConnectToServer socket() failed: %s\n", strerror(errno)); return false; } if ( source_address != "" ) { if ( ::bind(sock_fd, (struct sockaddr *) &l_addr, sizeof(l_addr)) < 0 ) { LogFile::ErrorMessage("ConnectoToServer bind() failed: %s\n", strerror(errno)); Close(); return false; } } int flags, ret; //Nonblocking connect to get a proper timeout while ( (flags = fcntl(sock_fd, F_GETFL, 0)) < 0 ) { if (errno == EINTR) continue; LogFile::ErrorMessage("ConnectToServer fcntl() get failed: %s\n", strerror(errno)); Close(); return false; } while ( fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) < 0 ) { if (errno == EINTR) continue; LogFile::ErrorMessage("ConnectToServer fcntl() O_NONBLOCK failed: %s\n", strerror(errno)); Close(); return false; } while ( (ret = ::connect(sock_fd, (struct sockaddr *) &my_s_addr, sizeof(my_s_addr))) < 0 ) { if (errno == EINTR) continue; if (errno != EINPROGRESS) { if (errno != EINVAL) LogFile::ErrorMessage("connect() failed: %s\n", strerror(errno)); Close(); return false; } break; } if ( ret != 0 ) { FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); wset = checkfd; Timeout.tv_sec = CONNTIMEOUT; Timeout.tv_usec = 0; ret = select_eintr(sock_fd+1, &checkfd, &wset, NULL, &Timeout); if ( ret <= 0 ) { Close(); return false; } addr_len = sizeof(peer_addr); if ( getpeername(sock_fd, (struct sockaddr *) &peer_addr, (socklen_t *) &addr_len) < 0 ) { Close(); return false; } } while ( fcntl(sock_fd, F_SETFL, flags) < 0 ) { if (errno == EINTR) continue; LogFile::ErrorMessage("ConnectToServer fcntl() set failed: %s\n", strerror(errno)); Close(); return false; } return true; } bool SocketHandler::ConnectToSocket( string SocketPath, int retry ) { strncpy(my_u_addr.sun_path, SocketPath.c_str(), sizeof(my_u_addr.sun_path)-1); if ( (sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0 ) { LogFile::ErrorMessage("ConnectToSocket socket() failed: %s\n", strerror(errno)); return false; } int tries = 0; int ret; for(;;) { while ( (ret = ::connect(sock_fd, (struct sockaddr *) &my_u_addr, sizeof(my_u_addr))) < 0 ) { if (errno == EINTR) continue; if (errno != ENOENT) LogFile::ErrorMessage("ConnectToSocket connect() failed: %s\n", strerror(errno)); break; } //Success? if ( ret == 0 ) return true; //All retried? if ( ++tries > retry ) break; //Try again in one second sleep(1); continue; } Close(); return false; } //Accept Client bool SocketHandler::AcceptClient( SocketHandler &accept_socketT ) { addr_len = sizeof(my_s_addr); while ((accept_socketT.sock_fd = ::accept(sock_fd, (sockaddr *) &my_s_addr, (socklen_t *) &addr_len)) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("accept() failed: %s\n", strerror(errno)); return false; } //Save IP to ToBrowser accept_socketT.my_s_addr = my_s_addr; return true; } //Send String bool SocketHandler::Send( const char *sock_outT, int len ) { int total_sent = 0; int ret, buffer_count; do { Timeout.tv_sec = SENDTIMEOUT; Timeout.tv_usec = 0; FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); ret = select_eintr(sock_fd+1, NULL, &checkfd, NULL, &Timeout); if (ret <= 0) { return false; } while ((buffer_count = ::send(sock_fd, sock_outT + total_sent, len - total_sent, 0)) < 0) { if (errno == EINTR) continue; return false; } if (buffer_count == 0) { return false; } total_sent += buffer_count; } while (total_sent < len); return true; } //Send String bool SocketHandler::Send( string &sock_outT ) { int total_sent = 0; int len = sock_outT.size(); int ret, buffer_count; do { Timeout.tv_sec = SENDTIMEOUT; Timeout.tv_usec = 0; FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); ret = select_eintr(sock_fd+1, NULL, &checkfd, NULL, &Timeout); if (ret <= 0) { return false; } while ((buffer_count = ::send(sock_fd, sock_outT.substr(total_sent).c_str(), len - total_sent, 0)) < 0) { if (errno == EINTR) continue; return false; } if (buffer_count == 0) { return false; } total_sent += buffer_count; } while (total_sent < len); return true; } //Receive String - Maximal MAXRECV //sock_del = false : Do not delete Data from Socket ssize_t SocketHandler::Recv( string &sock_inT, bool sock_delT, int timeout ) { if ( RecvBuf.size() > 0 ) { sock_inT.append( RecvBuf ); if ( sock_delT == true ) { ssize_t tempsize = RecvBuf.size(); RecvBuf = ""; return tempsize; } return RecvBuf.size(); } char buffer[MAXRECV+1]; ssize_t buffer_count; int ret; if ( timeout != -1 ) { Timeout.tv_sec = timeout; } else { Timeout.tv_sec = RECVTIMEOUT; } Timeout.tv_usec = 0; FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout); if (ret <= 0) { return -1; } while ((buffer_count = ::recv(sock_fd, buffer, MAXRECV, 0)) < 0) { if (errno == EINTR) continue; return -1; } if ( sock_delT == false ) { RecvBuf.append( buffer, buffer_count ); } if ( buffer_count == 0 ) { return 0; } sock_inT.append( buffer, buffer_count ); return buffer_count; } //Receive String of length sock_length bool SocketHandler::RecvLength( string &sock_inT, unsigned int sock_lengthT ) { if ( RecvBuf.size() >= sock_lengthT ) { sock_inT.append( RecvBuf.substr( 0, sock_lengthT ) ); RecvBuf.erase( 0, sock_lengthT ); return true; } char buffer[MAXRECV+1]; ssize_t buffer_count; unsigned int received = 0; if ( RecvBuf.size() > 0 ) { sock_inT.append( RecvBuf ); received += RecvBuf.size(); RecvBuf = ""; } for(;;) { Timeout.tv_sec = RECVTIMEOUT; Timeout.tv_usec = 0; FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); int ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout); if ( ret <= 0 ) { return false; } while ((buffer_count = ::recv(sock_fd, buffer, MAXRECV, 0)) < 0 && errno == EINTR); if ( buffer_count < 1 ) { return false; } if ( received + buffer_count >= sock_lengthT ) { string Rest; Rest.append( buffer, buffer_count ); unsigned int needed = sock_lengthT - received; sock_inT.append( Rest.substr( 0, needed ) ); if ( Rest.size() > needed ) RecvBuf.append( Rest.substr( needed ) ); return true; } sock_inT.append( buffer, buffer_count ); received += buffer_count; } return true; } //Wait and get something from socket until separator bool SocketHandler::GetLine( string &lineT, string separator, int timeout ) { lineT = ""; string TempLine; string::size_type Position; do { if ( Recv( TempLine, false, timeout ) == false ) { return false; } } while ( (Position = TempLine.find( separator )) == string::npos ); TempLine = ""; if ( RecvLength( TempLine, Position + separator.size() ) == false ) { return false; } lineT = TempLine.erase( Position ); return true; } //Resolve and set hostname/port for connecting bool SocketHandler::SetDomainAndPort( string domainT, int portT ) { if ( domainT == "" ) return false; if ( portT < 1 || portT > 65536 ) return false; int domlen = domainT.length(); if (domlen > 250) domainT = domainT.substr(0, 250); my_s_addr.sin_port = htons(portT); //IP? if ( domlen >= 7 && domlen <= 15 && domainT.find_first_not_of("0123456789.") == string::npos ) { LastHost = ""; if ( inet_aton( domainT.c_str(), &my_s_addr.sin_addr ) != 0 ) return true; return false; } //Same host as last time, use next IP if ( server && LastHost == domainT ) { if ( ips == 1 ) return true; if ( ++ip_count == ips ) ip_count = 0; memcpy((char *) &my_s_addr.sin_addr.s_addr, server->h_addr_list[ip_count], server->h_length); return true; } //Resolve host if ( (server = gethostbyname( domainT.c_str() )) ) { //Count IPs for ( ips = 0; server->h_addr_list[ips] != NULL && server->h_addrtype == AF_INET && ips != 16; ips++ ); if ( !ips ) return false; memcpy((char *) &my_s_addr.sin_addr.s_addr, server->h_addr_list[0], server->h_length); ip_count = 0; LastHost = domainT; return true; } LastHost = ""; return false; } int SocketHandler::IPCount() { return ips; } string SocketHandler::GetIP() { string ip = inet_ntoa(my_s_addr.sin_addr); return ip; } bool SocketHandler::CheckForData( int timeout ) { if ( RecvBuf.size() > 0 ) { return true; } int ret; Timeout.tv_sec = timeout; Timeout.tv_usec = 0; FD_ZERO(&checkfd); FD_SET(sock_fd,&checkfd); ret = select_eintr(sock_fd+1, &checkfd, NULL, NULL, &Timeout); if (ret <= 0) { return false; } return true; } #ifdef SSLTUNNEL int SocketHandler::CheckForSSLData( int sockBrowser, int sockServer ) { fd_set readfd; int fds; FD_ZERO(&readfd); FD_SET(sockBrowser,&readfd); FD_SET(sockServer,&readfd); if ( sockBrowser > sockServer ) { fds = sockBrowser; } else { fds = sockServer; } Timeout.tv_sec = Timeout.tv_sec = Params::GetConfigInt("SSLTIMEOUT"); Timeout.tv_usec = 0; int ret = select_eintr(fds+1, &readfd, NULL, NULL, &Timeout); if (ret <= 0) return 0; if (FD_ISSET(sockBrowser,&readfd)) return 1; return 2; } #endif void SocketHandler::Close() { //Clear receive buffer RecvBuf = ""; //Check that we have a real fd if ( sock_fd > -1 ) { while ( ::close(sock_fd) < 0 ) { if (errno == EINTR) continue; if (errno == EBADF) break; //IO error? LogFile::ErrorMessage("close() failed: %s\n", strerror(errno)); } //Mark socket unused sock_fd = -1; } } //Constructor SocketHandler::SocketHandler() { memset(&my_s_addr, 0, sizeof(my_s_addr)); my_s_addr.sin_family = AF_INET; memset(&my_u_addr, 0, sizeof(my_u_addr)); my_u_addr.sun_family = AF_LOCAL; ip_count = 0; ips = 0; //No socket exists yet sock_fd = -1; source_address = Params::GetConfigString("SOURCE_ADDRESS"); if ( source_address != "" ) { l_addr.sin_family = AF_INET; l_addr.sin_port = htons(0); l_addr.sin_addr.s_addr = inet_addr( source_address.c_str() ); } RecvBuf.reserve(1500); RecvBuf = ""; } //Destructor SocketHandler::~SocketHandler() { } havp-0.93/havp/connectiontobrowser.cpp0000644000000000000000000004164013425375265016672 0ustar rootroot/*************************************************************************** connectiontobrowser.cpp - description ------------------- begin : Sa Feb 12 2005 copyright : (C) 2005 by Christian Hilgers email : christian@havp.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "default.h" #include "connectiontobrowser.h" #include "params.h" #include "utils.h" #include "proxyhandler.h" #include #include //Prepare Header for Server string ConnectionToBrowser::PrepareHeaderForServer( bool ScannerOff, ProxyDetails &parentProxy ) { string PortString = ""; if ( Port != 80 && Port != 21 ) { char porttemp[21]; snprintf(porttemp, 20, ":%d", Port); PortString = porttemp; } string header; header.reserve(20000); if ( parentProxy.useProxy() ) { //HTTP if ( RequestProtocol == "http" ) { header = RequestType; header += " http://"; header += Host; header += PortString; header += Request; header += " HTTP/1.0\r\n"; /* Use proxy auth if required */ if ( parentProxy.useProxyAuth() ) { header += "Proxy-Authorization: Basic " + \ base64_encode(parentProxy.getUser() + ":" + parentProxy.getPassword()) + "\r\n"; } CompleteRequest = "http://"; CompleteRequest += Host; CompleteRequest += PortString; CompleteRequest += Request; } //FTP else if ( RequestProtocol == "ftp" ) { string AuthString = ""; if ( FtpUser != "" ) { SearchReplace( FtpUser, ":", "%3A" ); SearchReplace( FtpUser, "@", "%40" ); if ( FtpPass != "" ) { SearchReplace( FtpPass, ":", "%3A" ); SearchReplace( FtpPass, "@", "%40" ); AuthString = FtpUser; AuthString += ":"; AuthString += FtpPass; AuthString += "@"; } else { AuthString = FtpUser; AuthString += "@"; } } header = RequestType; header += " ftp://"; header += AuthString; header += Host; header += PortString; header += Request; header += " HTTP/1.0\r\n"; CompleteRequest = "ftp://"; CompleteRequest += Host; CompleteRequest += PortString; CompleteRequest += Request; } #ifdef SSLTUNNEL //CONNECT else if ( RequestProtocol == "connect" ) { header = "CONNECT "; header += Request; header += " HTTP/1.0\r\n"; CompleteRequest = "connect://"; CompleteRequest += Request; } #endif } else { header = RequestType; header += " "; header += Request; header += " HTTP/1.0\r\n"; CompleteRequest = RequestProtocol; CompleteRequest += "://"; CompleteRequest += Host; CompleteRequest += PortString; CompleteRequest += Request; } //Remove parameters from URL string::size_type QMark = CompleteRequest.find( "?" ); if ( QMark != string::npos ) { CompleteRequest = CompleteRequest.substr( 0, QMark + 1 ); } //Strip long URL if (CompleteRequest.length() > 500) { CompleteRequest = CompleteRequest.substr( 0, 500 ); CompleteRequest += "..."; } string via = ""; string it; it.reserve(200); //Skip first token for (vector::iterator itvec = tokens.begin() + 1; itvec != tokens.end(); ++itvec) { //Uppercase for matching it = UpperCase(*itvec); if ( MatchBegin( it, "PROXY", 5 ) ) { //Pass Proxy-Authorization to parent proxy if used if (! (parentProxy.useProxy() && MatchBegin( it, "PROXY-AUTHORIZATION", 19 )) ) { continue; } } else if ( MatchBegin( it, "KEEP-ALIVE", 10 ) ) { continue; } else if ( MatchBegin( it, "VIA", 3 ) ) { string line = *itvec; string::size_type Position = line.find_first_not_of(" ", 4); if ( Position != string::npos ) { via = ", " + line.substr(Position); } continue; } else if ( MatchBegin( it, "CONNECTION", 10 ) ) { continue; } else if ( MatchBegin( it, "X-FORWARD", 9 ) ) { continue; } else if ( MatchBegin( it, "RANGE:", 6 ) || MatchBegin( it, "IF-RANGE", 8 ) ) { //Range allowed when whitelisted or streaming User-Agent if ( Params::GetConfigBool("RANGE") == false && ScannerOff == false && IsStreamAgent == false ) { continue; } } header += *itvec; header += "\r\n"; } if ( Params::GetConfigBool("X_FORWARDED_FOR") ) { header += "X-Forwarded-For: "; header += GetIP(); header += "\r\n"; header += "Via: 1.0 HAVP"; header += via; header += "\r\n"; } // else // { // Version 0.89: Always send Via: header, fixes some IIS problems (e.g. MSNBC) // Sebastian Andrzej Siewior: I haven't noticed anything wrong with a few IIS6 and IIS7 servers google // found for me to test :) // header += "Via: 1.0 PROXY\r\n"; // } return header; } int ConnectionToBrowser::AnalyseFirstHeaderLine( string &RequestT ) { //Uppercase for matching string RequestU = UpperCase(RequestT); //Looking for GET, POST, HEAD, CONNECT etc. for (unsigned int i=0;i < Methods.size(); i++) { if ( RequestU.find( Methods[i] + " ", 0 ) == 0 ) { RequestType = Methods[i]; return GetHostAndPortOfRequest( RequestT, Methods[i].size() + 1 ); } } return -202; } int ConnectionToBrowser::AnalyseHeaderLine( string &RequestT ) { //Uppercase for matching string RequestU = UpperCase(RequestT); if ( MatchBegin( RequestU, "CONTENT-LENGTH: ", 15 ) ) { if ( RequestU.find_first_not_of("0123456789", 16) != string::npos ) { //Invalid Content-Length return 0; } string LengthToken = RequestT.substr( 16 ); //Sanity check for invalid huge Content-Length if ( LengthToken.length() > 18 ) return 0; if ( sscanf(LengthToken.c_str(), "%lld", &ContentLength) != 1 ) { ContentLength = -1; } return 0; } if ( ProxyConnection == false ) { if ( MatchBegin( RequestU, "CONNECTION: ", 12 ) ) { if ( MatchSubstr( RequestU, "KEEP-ALIVE", 12 ) ) { IsKeepAlive = true; } else { IsKeepAlive = false; } return 0; } if ( MatchBegin( RequestU, "PROXY-CONNECTION: ", 18 ) ) { ProxyConnection = true; if ( MatchSubstr( RequestU, "KEEP-ALIVE", 18 ) ) { IsKeepAlive = true; } else { IsKeepAlive = false; } return 0; } } if ( Params::GetConfigBool("FORWARDED_IP") == true ) { if ( MatchBegin( RequestU, "X-FORWARDED-FOR: ", 17 ) ) { IP = RequestT.substr(17); return 0; } } if ( MatchBegin( RequestU, "USER-AGENT: ", 12 ) ) { UserAgent = RequestT.substr(12); if ( StreamUA.size() > 0 ) { for (vector::iterator UAi = StreamUA.begin(); UAi != StreamUA.end(); ++UAi) { if ( RequestU.find(*UAi, 12) != string::npos ) { IsStreamAgent = true; } } } return 0; } //Checks for TRANSPARENT if (Transparent && MatchBegin( RequestU, "HOST: ", 6 ) ) { return GetHostAndPortOfHostLine( RequestT ); } return 0; } //Get host and port int ConnectionToBrowser::GetHostAndPortOfHostLine( string &HostLineT ) { string HostwithPort = HostLineT.substr( 6 ); string::size_type PositionPort; if ( ( PositionPort = HostwithPort.find( ":", 1 )) != string::npos ) { Host = HostwithPort.substr( 0, PositionPort ); if ( Host.length() > 256 ) { return -210; } string PortString = HostwithPort.substr( PositionPort ); if ( PortString.length() > 6 ) { return -212; } if ( sscanf(PortString.c_str(), ":%d", &Port) != 1 ) { return -212; } if ( Port < 1 || Port > 65535 ) { return -212; } return 0; } Host = HostwithPort; Port = 80; return 0; } int ConnectionToBrowser::GetHostAndPortOfRequest( string &RequestT, string::size_type StartPos ) { string::size_type Begin, LastPosition; #ifdef SSLTUNNEL //Handle SSL if (RequestType == "CONNECT") { RequestProtocol = "connect"; if ( (Begin = RequestT.find_first_not_of( " ", 8 )) != string::npos ) { if ( (LastPosition = RequestT.find( " ", Begin )) != string::npos ) { string HostwithPort = RequestT.substr( Begin, LastPosition - Begin ); if ( (Begin = HostwithPort.find( ":", 1 )) != string::npos ) { Host = HostwithPort.substr( 0, Begin ); if (Host.length() > 256) { return -210; } string PortString = HostwithPort.substr( Begin ); if ( sscanf(PortString.c_str(), ":%d", &Port) == 1 ) { Request = HostwithPort; //If you want more control, edit or use Squid in front if ( Port >= 80 && Port <= 65535 ) { return 0; } else { return -211; } } } } } return -201; } #endif //Check for other protocols.. //Uppercase for matching string RequestU = UpperCase(RequestT); //Transparent proxying? if ( Transparent ) { if ( RequestT.find( "/", StartPos ) == StartPos ) { if ( (LastPosition = RequestT.find( " ", StartPos )) != string::npos ) { if ( LastPosition > 4096 ) return -201; if ( RequestU.find( "HTTP/1.1", LastPosition + 1 ) != string::npos ) { //KeepAlive by default for HTTP/1.1 clients IsKeepAlive = true; } RequestProtocol = "http"; Request = RequestT.substr( StartPos, LastPosition - StartPos ); return 0; } } return -201; } //HTTP if ( (Begin = RequestU.find( "HTTP://", StartPos )) == StartPos ) { RequestProtocol = "http"; Begin += 7; } //FTP else if ( (Begin = RequestU.find( "FTP://", StartPos )) == StartPos ) { RequestProtocol = "ftp"; Begin += 6; } //No supported protocol found else { return -201; } //Start parsing request.. if ( (LastPosition = RequestT.find( " ", Begin )) == string::npos ) { return -201; } if ( LastPosition == Begin || LastPosition > 4096 ) { return -201; } if ( RequestU.find( "HTTP/1.1", LastPosition + 1 ) != string::npos ) { //KeepAlive by default for HTTP/1.1 clients IsKeepAlive = true; } //Split domain and path string RequestDomain = RequestT.substr( Begin, LastPosition - Begin ); if ( (LastPosition = RequestDomain.find( "/", 0 )) != string::npos ) { Request = RequestDomain.substr( LastPosition ); RequestDomain = RequestDomain.substr( 0, LastPosition ); } else { Request = "/"; } //Check for login info if ( (LastPosition = RequestDomain.rfind( "@", string::npos )) != string::npos ) { if ( RequestProtocol == "ftp" ) { string UserPass = RequestDomain.substr( 0, LastPosition ); string::size_type Position; if ( (Position = UserPass.find( ":", 0 )) != string::npos ) { FtpUser = UserPass.substr( 0, Position ); FtpPass = UserPass.replace( 0, Position + 1, "" ); } else { FtpUser = UserPass; FtpPass = ""; } } //Strip login info.. also from HTTP because IE does it anyway RequestDomain.replace( 0, LastPosition + 1, "" ); RequestT.replace( Begin, LastPosition + 1, "" ); if ( !RequestDomain.length() ) { return -201; } } //Check for Port and Host if ( (LastPosition = RequestDomain.rfind( ":", string::npos )) != string::npos ) { string PortString = RequestDomain.substr( LastPosition ); if ( PortString.length() > 6 ) { return -212; } if ( sscanf(PortString.c_str(), ":%d", &Port) != 1 ) { return -212; } if ( Port < 1 || Port > 65535 ) { return -212; } Host = RequestDomain.substr( 0, LastPosition ); } else { if ( RequestProtocol == "http" ) { Port = 80; } else if ( RequestProtocol == "ftp" ) { Port = 21; } else { return -215; } Host = RequestDomain; } //Sanity check - TODO: Config variable for allowed ports? if ( Host.length() > 256 ) { return -210; } //if ( RequestProtocol == "http" && Port < 80 ) //{ // return -211; //} return 0; } const string ConnectionToBrowser::GetHost() { return Host; } const string ConnectionToBrowser::GetRequest() { return Request; } const string ConnectionToBrowser::GetCompleteRequest() { return CompleteRequest; } const string ConnectionToBrowser::GetRequestProtocol() { return RequestProtocol; } const string ConnectionToBrowser::GetRequestType() { return RequestType; } const string ConnectionToBrowser::GetUserAgent() { return UserAgent; } long long ConnectionToBrowser::GetContentLength() { return ContentLength; } int ConnectionToBrowser::GetPort() { return Port; } string ConnectionToBrowser::GetIP() { if (IP == "") { IP = inet_ntoa( my_s_addr.sin_addr ); } //Else IP was set by X-Forwarded-For: return IP; } bool ConnectionToBrowser::IsItKeepAlive() { return IsKeepAlive; } bool ConnectionToBrowser::IsItStreamAgent() { return IsStreamAgent; } #ifdef REWRITE bool ConnectionToBrowser::RewriteHost() { if(URLRewrite[Host] != "" ) { Host = URLRewrite[Host]; return true; } return false; } #endif void ConnectionToBrowser::ClearVars() { RequestProtocol = RequestType = Request = Host = IP = FtpUser = FtpPass = UserAgent = CompleteRequest = ""; Port = ContentLength = -1; IsKeepAlive = ProxyConnection = IsStreamAgent = false; } //Constructor ConnectionToBrowser::ConnectionToBrowser() { #ifdef REWRITE REWRITE #endif string TempMethods[] = {METHODS}; for(unsigned int i = 0; i < sizeof(TempMethods)/sizeof(string); i++) { Methods.push_back( TempMethods[i] ); } if (Params::GetConfigString("STREAMUSERAGENT") != "") { Tokenize( UpperCase(Params::GetConfigString("STREAMUSERAGENT")), StreamUA ); } Transparent = Params::GetConfigBool("TRANSPARENT"); } //Destructor ConnectionToBrowser::~ConnectionToBrowser() { } havp-0.93/havp/default.h0000644000000000000000000001014113425375263013643 0ustar rootroot/*************************************************************************** default.h - description ------------------- begin : 2005/02/12 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEFAULT_H #define DEFAULT_H #define VERSION "0.93" //############################################################## //Define if you want to rewrite a URL //#define REWRITE URLRewrite["havp"]="www.havp.org"; URLRewrite["www.havp"]="www.havp.org"; //############################################################## //Parameters in Configurationfile #define CONFIGPARAMS \ "WHITELISTFIRST","TEMPDIR","RANGE", "PRELOADZIPHEADER", "USER","GROUP", \ "SERVERNUMBER","PORT","BIND_ADDRESS","SOURCE_ADDRESS","KEEPBACKBUFFER", \ "KEEPBACKTIME","TRICKLING","TRICKLINGBYTES","MAXSCANSIZE","WHITELIST","BLACKLIST","PIDFILE", \ "DAEMON","TRANSPARENT","LOG_OKS","ACCESSLOG","VIRUSLOG","ERRORLOG","TIMEFORMAT","LOGLEVEL", \ "USESYSLOG","SYSLOGNAME","SYSLOGFACILITY","SYSLOGLEVEL","SYSLOGVIRUSLEVEL","IGNOREVIRUS", \ "DISPLAYINITIALMESSAGES","DBRELOAD","SCANTEMPFILE","TEMPLATEPATH","DISABLELOCKINGFOR", \ "PARENTPROXY","PARENTPORT","MAXSERVERS","FORWARDED_IP","X_FORWARDED_FOR","FAILSCANERROR", \ "SSLTIMEOUT", \ "MAXDOWNLOADSIZE","SCANNERTIMEOUT","STREAMUSERAGENT","STREAMSCANSIZE","SCANIMAGES", \ "SKIPMIME","SCANMIME", \ "ENABLECLAMLIB","CLAMDBDIR","CLAMBLOCKBROKEN","CLAMBLOCKMAX","CLAMBLOCKENCRYPTED", \ "CLAMMAXFILES","CLAMMAXFILESIZE","CLAMMAXRECURSION","CLAMMAXSCANSIZE", \ "ENABLEAVG","AVGSERVER","AVGPORT", \ "ENABLEAVESERVER","AVESOCKET", \ "ENABLEFPROT","FPROTSERVER","FPROTPORT","FPROTOPTIONS", \ "ENABLETROPHIE","TROPHIEMAXFILES","TROPHIEMAXFILESIZE","TROPHIEMAXRATIO", \ "ENABLENOD32","NOD32SOCKET","NOD32VERSION", \ "ENABLECLAMD","CLAMDSOCKET","CLAMDSERVER","CLAMDPORT", \ "ENABLESOPHIE","SOPHIESOCKET", \ "ENABLEAVAST","AVASTSOCKET","AVASTSERVER","AVASTPORT", \ "ENABLEARCAVIR","ARCAVIRSOCKET","ARCAVIRVERSION", \ "ENABLEDRWEB","DRWEBSOCKET","DRWEBSERVER","DRWEBPORT","DRWEBHEURISTIC","DRWEBMALWARE", \ "PARENTUSER", "PARENTPASSWORD" //SCANNERS //############################################################## //Configuration not setable in havp.config //CONNTIMEOUT in seconds #define CONNTIMEOUT 60 //RECVTIMEOUT in seconds #define RECVTIMEOUT 120 //SENDTIMEOUT in seconds #define SENDTIMEOUT 120 //Maximum client connection waiting for accept #define MAXCONNECTIONS 1024 //Maximum bytes received in one request #define MAXRECV 14600 //Maximum logfile line length #define STRINGLENGTH 1000 //Maximum hardlock size - do not change #define MAXFILELOCKSIZE 1000000000 //Valid Methods #define METHODS \ "GET","POST","HEAD","CONNECT","PUT","TRACE","PURGE","OPTIONS","UNLOCK", \ "SEARCH","PROPFIND","BPROPFIND","PROPPATCH","BPROPPATCH","MKCOL","COPY", \ "BCOPY","MOVE","LOCK","BMOVE","DELETE","BDELETE","SUBSCRIBE","UNSUBSCRIBE", \ "POLL","REPORT","ERROR","NONE","MKACTIVITY","CHECKOUT","MERGE" //Maximum length of SCANTEMPFILE #define MAXSCANTEMPFILELENGTH 200 //Maximum length of http headers #define MAXHTTPHEADERLENGTH 65536 // HTML Error String #define ERROR_DNS "dns.html" #define VIRUS_FOUND "virus.html" #define ERROR_SCANNER "scanner.html" #define ERROR_DOWN "down.html" #define ERROR_INVALID "invalid.html" #define ERROR_REQUEST "request.html" #define ERROR_BODY "error.html" #define ERROR_BLACKLIST "blacklist.html" #define ERROR_MAXSIZE "maxsize.html" #include "_default.h" #endif havp-0.93/havp/helper.cpp0000644000000000000000000002376213425375265014050 0ustar rootroot/*************************************************************************** helper.cpp - description ------------------- begin : 2005/02/12 last : 2019/02/02 ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* Fix https://bugs.debian.org/524045 The init script sends a SIGHUP to the main process. The main process sends a SIGUSR1 to all its children. The child process should restart which happens but not immediately. This patch re-opens the logfiles from within the signal handler so the old files (after a rename) are no longer in use. As per signal(7) it is allowed to use open() and close() from within the signal handler. */ #include "default.h" #include "params.h" #include "logfile.h" #include #include #include #include #include #include #include #include #include #include #include #include #include extern char TempFileName[MAXSCANTEMPFILELENGTH+1]; extern int fd_tempfile; static void ChildExited( int SignalNo ) { //Handle with waitpid() in havp.cpp } static void ChildChildExited( int SignalNo ) { int status; while (waitpid(-1, &status, WNOHANG) > 0); } static void RereadAll( int SignalNo ) { extern bool rereadall; rereadall = true; } static void ReopenLogFiles( int SignalNo ) { LogFile::InitLogFiles(Params::GetConfigString("ACCESSLOG").c_str(), Params::GetConfigString("VIRUSLOG").c_str(), Params::GetConfigString("ERRORLOG").c_str()); } static void RestartChild( int SignalNo ) { extern bool childrestart; childrestart = true; ReopenLogFiles(SignalNo); } static void ExitProcess( int SignalNo ) { pid_t pgid = getpgid(0); //PSE: all processes have same pgid! if (getpid() == pgid) { //PSE: only parent, no scan-file to delete!! killpg(pgid,SIGINT); //Delete pidfile while (unlink(Params::GetConfigString("PIDFILE").c_str()) < 0 && (errno == EINTR || errno == EBUSY)); } else { if (fd_tempfile > -1) { //Delete tempfile while (close(fd_tempfile) < 0 && errno == EINTR); while (unlink(TempFileName) < 0 && (errno == EINTR || errno == EBUSY)); } } //End process exit(0); } //Install Signal Handlers for different fork levels int InstallSignal( int level ) { struct sigaction Signal; memset(&Signal, 0, sizeof(Signal)); Signal.sa_flags = 0; //Level 0 = Main Havp Process //Level 1 = ProxyHandler Process //Level 2 = Scanner Process //Signals are inherited from previous level at forking.. if ( level == 0 ) //Main Havp Process { Signal.sa_handler = ExitProcess; if (sigaction(SIGINT, &Signal, NULL) != 0) return -1; if (sigaction(SIGTERM, &Signal, NULL) != 0) return -1; Signal.sa_handler = RereadAll; if (sigaction(SIGHUP, &Signal, NULL) != 0) return -1; //Compatibility for 0.77 and older init-script if (sigaction(SIGUSR2, &Signal, NULL) != 0) return -1; Signal.sa_handler = ChildExited; if (sigaction(SIGCHLD, &Signal, NULL) != 0) return -1; Signal.sa_handler = SIG_IGN; if (sigaction(SIGUSR1, &Signal, NULL) != 0) return -1; if (sigaction(SIGPIPE, &Signal, NULL) != 0) return -1; } else if ( level == 1 ) //ProxyHandler Process { Signal.sa_handler = RestartChild; if (sigaction(SIGUSR1, &Signal, NULL) != 0) return -1; Signal.sa_handler = ChildChildExited; if (sigaction(SIGCHLD, &Signal, NULL) != 0) return -1; Signal.sa_handler = SIG_IGN; if (sigaction(SIGHUP, &Signal, NULL) != 0) return -1; if (sigaction(SIGUSR2, &Signal, NULL) != 0) return -1; } else if ( level == 2 ) //Scanner Process { Signal.sa_handler = ReopenLogFiles; if (sigaction(SIGUSR1, &Signal, NULL) != 0) return -1; } return 0; } bool MakeDaemon() { pid_t daemon = fork(); if ( daemon < 0 ) { return false; } else if (daemon != 0) { //Exit Parent exit(0); } //Child setsid(); chdir("/tmp/"); umask(077); //Close stdin/stdout/stderr close(0); close(1); close(2); return true; } bool HardLockTest() { memset(&TempFileName, 0, sizeof(TempFileName)); strncpy(TempFileName, Params::GetConfigString("SCANTEMPFILE").c_str(), MAXSCANTEMPFILELENGTH); if ((fd_tempfile = mkstemp(TempFileName)) < 0) { string Error = strerror(errno); cout << "Could not open lock testfile " << TempFileName << ": " << Error << endl; string user = Params::GetConfigString("USER"); string scanpath = Params::GetConfigString("SCANTEMPFILE"); cout << "Maybe you need to: chown " << user << " " << scanpath.substr(0, scanpath.rfind("/")) << endl; return false; } #ifndef NOMAND while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP|S_ISGID) < 0) #else while (fchmod(fd_tempfile, S_IRUSR|S_IWUSR|S_IRGRP) < 0) #endif { if (errno == EINTR) continue; string Error = strerror(errno); cout << "Testfile fchmod() failed: " << Error << endl; return false; } char eicardata[] = "a5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*\0"; eicardata[0] = 'X'; while (write(fd_tempfile, eicardata, 68) < 0) { if (errno == EINTR) continue; LogFile::ErrorMessage("Could not write to Scannerfile: %s\n", TempFileName ); return false; } #ifdef NOMAND return true; #else struct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = MAXFILELOCKSIZE; while (fcntl(fd_tempfile, F_SETLK, &lock) < 0) { if (errno == EINTR) continue; string Error = strerror(errno); cout << "Testfile fcntl() failed: " << Error << endl; return false; } if (lseek(fd_tempfile, 0, SEEK_SET) < 0) { string Error = strerror(errno); cout << "Testfile lseek() failed: " << Error << endl; return false; } pid_t testpid = fork(); if (testpid < 0) { string Error = strerror(errno); cout << "Error forking lock test: " << Error << endl; return false; } else if (testpid != 0) { //Parent int status; while ((testpid = wait(&status)) < 0 && errno == EINTR); if (WEXITSTATUS(status) == 1) { return false; } //Descriptor not needed anymore while (close(fd_tempfile) < 0 && errno == EINTR); fd_tempfile = -1; return true; } //Child int fd; if ((fd = open(TempFileName, O_RDONLY)) < 0) { string Error = strerror(errno); cout << "Could not open lock testfile " << TempFileName << ": " << Error << endl; exit(1); } //Set nonblocking while (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { if (errno == EINTR) continue; string Error = strerror(errno); cout << "Testfile fcntl() failed: " << Error << endl; exit(1); } int testread; char tmpread[2]; while ((testread = read(fd, tmpread, 1)) < 0 && errno == EINTR); while (close(fd) < 0 && errno == EINTR); if (testread > 0) { cout << "Filesystem not supporting mandatory locks!" << endl; cout << "On Linux, you need to mount filesystem with \"-o mand\"" << endl; exit(1); } //Success exit(0); #endif } bool ChangeUserAndGroup( string usr, string grp ) { if ( geteuid() != 0 ) return true; if ( usr == "" || grp == "" ) { cout << "You must define User and Group" << endl; return false; } struct passwd *user; struct group *my_group; if ( (user = getpwnam( usr.c_str() )) == NULL ) { cout << "User does not exist: " << usr << endl; cout << "You need to: useradd " << usr << endl; return false; } if ( (my_group = getgrnam( grp.c_str() )) == NULL ) { cout << "Group does not exist: " << grp << endl; cout << "You need to: groupadd " << grp << endl; return false; } #ifdef HAVE_INITGROUPS if ( initgroups( usr.c_str(), user->pw_gid ) ) { cout << "Group initialization failed (initgroups)" << endl; return false; } #else #if HAVE_SETGROUPS if ( setgroups(1, &user->pw_gid) ) { cout << "Group initialization failed (setgroups)" << endl; return false; } #endif #endif if ( setgid( my_group->gr_gid ) < 0 ) { cout << "Could not change group to: " << grp << endl; return false; } if ( setuid( user->pw_uid ) < 0 ) { cout << "Could not change user to: " << usr << endl; return false; } return true; } string GetUser() { struct passwd *user = getpwuid( geteuid() ); if ( user == NULL ) return ""; return (string)user->pw_name; } string GetGroup() { struct group *my_group = getgrgid( getegid() ); if ( my_group == NULL ) return ""; return (string)my_group->gr_name; } bool WritePidFile( pid_t havp_pid ) { ofstream pidf( Params::GetConfigString("PIDFILE").c_str(), ios_base::trunc ); if ( !pidf ) return false; pidf << havp_pid << endl; pidf.close(); return true; } havp-0.93/havp/_default.h.in0000644000000000000000000000041713425375245014414 0ustar rootroot// DONT TOUCH - run configure #undef CONFIGFILE #undef WHITELISTFILE #undef BLACKLISTFILE #undef TEMPLATEPATH #undef ACCESSLOG #undef ERRORLOG #undef PIDFILE #undef NOMAND #undef SSLTUNNEL #undef USECLAMLIB #undef USETROPHIE #undef HAVE_SETGROUPS #undef HAVE_INITGROUPS havp-0.93/Makefile.in0000644000000000000000000000014113425371670013152 0ustar rootrootall: cd havp && $(MAKE) clean: cd havp && $(MAKE) clean install: cd havp && $(MAKE) install havp-0.93/ChangeLog0000644000000000000000000001512313425371670012665 0ustar rootroot*HAVP 0.93 released (2019/02/02) - Add support for clamav 0.101: Sebastian Andrzej Siewior - Enable LFS & fix autoreconf: Sebastian Andrzej Siewior - Add SSLTIMEOUT config option: Rene Mayrhofer, adapted from a patch by Heiko Schlittermann - Fix missing re-opens of logfiles after signal(7): Sebastian Andrzej Siewior - Remove the VIA header completely if disabled: Sebastian Andrzej Siewior - Change default PID file and SCANTEMPFILE location: adapted and cleaned up by Rene Mayrhofer - Change default clamd socket: Scott Kitterman - Update transparent proxy documentation link: Sebastian Andrzej Siewior *HAVP 0.92a - Security Fix - Add missing dot to sourceforge for safety *HAVP 0.92 released - Add SCANMIME and SKIPMIME options - Add TIMEFORMAT option - Add VIRUSLOG option - Add PARENTUSER/PARENTPASSWORD (thanks to James Brotchie) - DISABLELOCKINGFOR default has changed in favor of ClamAV 0.96, it only contains AVG:ALL now *HAVP 0.91 released - Fix possible segfault on dns lookups (thanks Gavin McCullagh) - Fix compiling with gcc 4.4 - Support AVG version 8.5 (default AVGPORT 54322) (thanks Markus Wigge) (note: you may need DISABLELOCKINGFOR AVG:ALL, which is now default) *HAVP 0.90 released - ClamAV library 0.95 support (recompile needed) - Support NOD32 version 3 (set NOD32VERSION 30 in config) - Add PRELOADZIPHEADER config (Squid 3.x might not work if enabled) - Add SYSLOGVIRUSLEVEL config *HAVP 0.89 released - Fix possible retry loop and hang (thanks to Peter Warasin @ endian.it) - Always send Via: header, fixes some IIS problems (e.g. MSNBC) *HAVP 0.88 released - ClamAV library 0.93 support (recompile needed, new option CLAMMAXSCANSIZE) - CLAMMAXFILESIZE default is now 100MB (so 0.93 even starts scanning big files) - Fix random seed issue (ClamAV generated some temporary file errors) - Added DISABLELOCKINGFOR config (fix for ZIP handling in ClamAV 0.93) - Arcavir version 2008 support (set ARCAVIRVERSION) - Log scanner errors to errorlog - Relaxed SSL/CONNECT port limits (It is _not_ recommended to use --enable-ssl-tunnel, you should use Squid) *HAVP 0.87 released - DrWeb scanner support - F-Prot support for v6.0 added (also check FPROTOPTIONS) - If false, X_FORWARDED_FOR drops also Via: header for privacy - Fix Avast and AVG bugs - Templates support and tags - Uses supplementary groups for user if defined - Added TRICKLINGBYTES config - Reduced *MAXFILES settings to 50 for performance - Add missing HTTP methods (MKACTIVITY, CHECKOUT, MERGE) *HAVP 0.86 released - Experimental support for chunked Transfer-Encoding, fixes some broken sites - Added IGNOREVIRUS config for whitelisting virus names - Added CLAMBLOCKBROKEN config - Improve detection with AVG, only Viruses were found, not Trojans etc - HAVP is killed if database reloading fails for Library Scanner - Log URL when crashed scanner process detected, for troubleshooting - Build system updated (--prefix --sbindir --sysconfdir --localstatedir) *HAVP 0.85 released - Added support for ClamAV 0.90 library (once compiled for it, older library versions not supported) *HAVP 0.84 released - Fix bug in tcp buffer, requests could leak to other clients sometimes - Support for Arcavir scanner - Support for multiple IPs in hostnames, all are tried if necessary - Pass Proxy-Authorization header to parent proxy (thanks Mateus) - Ignore scanner errors if MAXSCANSIZE reached (thanks Vittorio) - Build system polished a bit (--prefix supported) - Added support for old NOD32 scanner (set NOD32VERSION in config) - Default for MAXSCANSIZE 5000000, not suggested to be 0 anymore *HAVP 0.83 released - Allow Accept-Encoding header so HTTP compression works - Workaround for some ClamAV mmap() troubles (affected BinHex and PDF) *HAVP 0.82 released - Improved ZIP handling (header pre-fetch, scans ZIPs larger than MAXSCANSIZE) - Added SCANIMAGES config - Ignore RAR errors from clamd - Fixes to HTTP header handling - Added syslog logging option - Signal HUP re-opens logfiles, making rotation possible *HAVP 0.81 released - Fixed binding to low ports (<1024) - Fixed FreeBSD, downloads that took longer than TRICKLING did not work *HAVP 0.80 released - Experimental FreeBSD support (no mandatory locking, KEEPBACK not supported!) - Avast! scanner support - Added MAXDOWNLOADSIZE config - Added X_FORWARD_FOR config to control the header - Added some archive scanning parameters for Trophie - Added TCP support for clamd - Ignore RAR errors from ClamAV (use ClamAV-devel if you want to scan RARv3) - Fixed bug in socket buffer, sometimes caused nasty effects with POST etc. - Fixed KeepAlive for HTTP/1.1 clients, now on by default - Access logging format changed a bit *HAVP 0.79 released - MULTIPLE SCANNER SUPPORT! (see havp.config how to enable scanners) - NOD32, Sophos and Clamd scanner support - Parentproxy error on SSL tunneling is passed to browser - Whitelisted sites can use HTTP Range requests (for Windowsupdate..) - Added STREAMUSERAGENT/STREAMSCANSIZE config to reduce stream scanning - Added SCANNERTIMEOUT option to catch scanners gone wild - Added scanning options for ClamLib - Some HTTP header handling fixes - Init-script updated so it works on Solaris *HAVP 0.78 released - Solaris is now supported too - AVG scanner support - Kaspersky aveserver socket support (faster) - Added TEMPDIR, LOGLEVEL, FAILSCANERROR and WHITELISTFIRST config - KEEPBACKTIME config added to complement KEEPBACKBUFFER setting - Basic HTTP Keep-Alive support, improves network performance - HTTPS/SSL tunneling support (requires configure --enable-ssl-tunnel) - FTP is supported and scanned when FTP supporting parent proxy is used - Default user and group changed to havp - Logging improved - Many important and not so important fixes/optimizations *HAVP 0.77 released - Fix Security Bug - Kaspersky and F-Prot did not catch viruses - Add Trophie (Trend Micro) Scanner - Added RANGE config for improved security - Change some default settings *HAVP 0.76 released - Improve performance - Fix small bug in logfile - Swedish Templates - Polish Templates *HAVP 0.75 - 02/01/2005 - Improve Configfile - Fix Bug in Black/Whitelists *HAVP 0.74 - 12/11/2005 - Add IP to Logfile - Add Templates - Improve Errorhandling - Fix Bug in Serverpool *HAVP 0.73 - 20/10/2005 - Move Pidfile to /var/run/havp/havp.pid - Add Templates - Improve Performance - Rewrite Domains (Check default.h.in) *HAVP 0.72 - 07/10/2005 - Add Kaspersky and F-Prot Scanner - Add Templates - Fix some minor bugs in default.h havp-0.93/INSTALL0000644000000000000000000001330713425372562012147 0ustar rootroot This software is GPL2! This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You MUST check your antivirus licence for the use with HAVP. Maybe you are not allowed to use it with HAVP. We don't take ANY WARRANTY!! UPGRADING ========= Just install HAVP normally. Your config will be preserved, but check havp.config for possible new options. Templates are overwritten, so if you have your own, make sure it is not in any default directory. BASIC INSTALLATION ================== HAVP has been tested only with GCC. Other compilers like Sun Studio have some problems currently. Installation: # ./configure (if you don't want /usr/local, use --prefix=/other/path) # make # make install You can use the following path options in configure: --prefix base directory, default "/usr/local" --sbindir location of havp-binary, default "$prefix/sbin" --sysconfdir location of etc, default "$prefix/etc" (+ /havp) --localstatedir location of pidfile, default "/var" (+ /run/havp) Also "make install DESTDIR=/tmp/havp" is supported for helping in creating packages etc. It is recommended to create a havp user: # groupadd havp # useradd -g havp havp Check the configfile: /usr/local/etc/havp/havp.config If Linux is used, you need to enable mandatory locking for the partition where your tempfiles are located. Solaris supports mandatory locking without these extra steps: The default location for logfiles is /var/spool/havp Don't use mandatory locking for / Using tmpfs might have some problems, make sure you test it properly. Add mand-option to /etc/fstab so it will stay after reboot e.g: echo "none /var/spool/havp tmpfs mand,nodev,nosuid,noexec,nodiratime,size=50M 0 0" >> /etc/fstab NOTE: Mandatory locking could make it possible for evil local accounts to hang the system. You should run HAVP anyway on non-public server. Make sure the directories you are using have correct permissions: # chown havp /var/spool/havp /var/log/havp /var/run/havp # chmod 700 /var/spool/havp /var/log/havp /var/run/havp Start havp: # /usr/local/sbin/havp -c /path/to/config You can also install rc-script to your system from sources etc/init.d. If you have problems check the logfiles: /var/log/havp/havp.log /var/log/havp/access.log More information and help can be found at HAVP forum: http://havp.hege.li/ OS SPECIFIC INSTRUCTIONS ======================== Linux: ------ Use GCC 3.4+. Solaris 9: ---------- You may need lots of swap space if you use library scanners (ClamAV and Trophie). It wants to reserve it even when it is not really used. If there is not enough, you will get fork errors. Worst case formula: (20MB * USEDLIBRARYSCANNERS) * (USEDSCANNERS + 1) * SERVERNUMBER. GCC 3.4.2 from sunfreeware.com is recommended. You may need to fix GCC headers like this: # cd /usr/local/libexec/gcc/*/3.4.2/install-tools # ./mkheaders Solaris 10: ----------- Swap space is not an issue anymore. Use GCC 3.4.x that comes bundled at /usr/sfw/bin/gcc. It is installed from SUNWgcc package. FreeBSD: -------- Use GCC 3.4+ from ports. FreeBSD does not support mandatory locking, which means KEEPBACK settings can not be used (only TRICKLING is supported). This means everything is first downloaded fully and only then sent to client. You need to use --disable-locking option to compile. SCANNER SPECIFIC INSTRUCTIONS ============================= ClamAV ------ Library is used directly, so there is no need for clamd running. If you choose to use clamd (which is not recommended as library support has less overhead), you need to enable AllowSupplementaryGroups in clamd.conf, and add clamav user to havp group. == NOTICE: == You must check your antivirus license before using HAVP with commercial scanners. Usage might not be allowed. We do not give any warranty! Kaspersky --------- Tested with aveserver daemon found in Linux File Server and Linux Mail Server package. You should set ReportLevel=1 at [aveserver.report] section, so log will not fill disk. Trend Micro (Trophie) --------------------- /etc/iscan must point to the directory where libvsapi.so and virus patterns are located. Create link if necessary. Trend library is used directly, so daemon is not required to be running. You should naturally run some pattern update script, if Trend itself is not running. AVG --- Recommended changes to avg.conf (version 7.5): [AvgCommon] heuristicAnalysis = 1 processesArchives = 1 [AvgDaemon] # Raise number of daemons atleast equal to SERVERNUMBER/MAXSERVERS numOfDaemons = xx F-Prot ------ Supported. NOD32 ----- Tested with Linux Mail Server and Linux File Server packages. File Server version can not display virus names. For version 3.0+, see settings in /etc/esets/esets.cfg (num_thrd etc). Also you want to disable syslogging. Sophos (Sophie) --------------- You need to make sure Sophie is working first, you can get it from: http://www.clanfield.info/sophie/ Change user or group to havp user in sophie.cfg, so it can read tempfiles. Also change maxproc value to atleast SERVERNUMBER/MAXSERVERS value! Avast! ------ Linux/Unix Servers version is required. Recommended changes to avastd.conf: # Raise number to atleast equal of SERVERNUMBER daemoncount = XX # Raise number to atleast equal of MAXSERVERS maxdaemoncount = XX archivetype = A testall = 1 testfull = 0 Arcavir ------- Start arcavird with enough processes, like "arcavird 16". DrWeb ----- Recommended changes to drweb32.ini: ; Raise number to atleast equal of SERVERNUMBER MaxChildren = xx PreFork = Yes havp-0.93/config.status0000755000000000000000000006601213425375357013641 0ustar rootroot#! /bin/sh # Generated by configure. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=${CONFIG_SHELL-/bin/sh} export SHELL ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " # Files that config.status was made for. config_files=" Makefile havp/Makefile havp/scanners/Makefile etc/havp/havp.config" config_headers=" havp/_default.h" ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." ac_cs_config="'clean' 'build_alias=clean' 'host_alias=clean' 'target_alias=clean'" ac_cs_version="\ config.status configured by ./configure, generated by GNU Autoconf 2.69, with options \"$ac_cs_config\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='/root/software/havp/havp-0.93' srcdir='.' test -n "$AWK" || AWK=awk # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi if $ac_cs_recheck; then set X /bin/sh './configure' 'clean' 'build_alias=clean' 'host_alias=clean' 'target_alias=clean' $ac_configure_extra_args --no-create --no-recursion shift $as_echo "running CONFIG_SHELL=/bin/sh $*" >&6 CONFIG_SHELL='/bin/sh' export CONFIG_SHELL exec "$@" fi exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "havp/_default.h") CONFIG_HEADERS="$CONFIG_HEADERS havp/_default.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "havp/Makefile") CONFIG_FILES="$CONFIG_FILES havp/Makefile" ;; "havp/scanners/Makefile") CONFIG_FILES="$CONFIG_FILES havp/scanners/Makefile" ;; "etc/havp/havp.config") CONFIG_FILES="$CONFIG_FILES etc/havp/havp.config" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && S["LTLIBOBJS"]="" S["LIBOBJS"]="" S["SCANNEROBJECTS"]="clamlibscanner.o" S["ac_ct_CC"]="gcc" S["CFLAGS"]="-g -O2 -Wall -g -O2" S["CC"]="gcc" S["PERL"]="perl" S["AR"]="ar" S["OBJEXT"]="o" S["EXEEXT"]="" S["ac_ct_CXX"]="g++" S["CPPFLAGS"]="" S["LDFLAGS"]=" -lclamav " S["CXXFLAGS"]="-g -O2" S["CXX"]="g++" S["target_alias"]="clean" S["host_alias"]="clean" S["build_alias"]="clean" S["LIBS"]="" S["ECHO_T"]="" S["ECHO_N"]="-n" S["ECHO_C"]="" S["DEFS"]="-DHAVE_CONFIG_H" S["mandir"]="${datarootdir}/man" S["localedir"]="${datarootdir}/locale" S["libdir"]="${exec_prefix}/lib" S["psdir"]="${docdir}" S["pdfdir"]="${docdir}" S["dvidir"]="${docdir}" S["htmldir"]="${docdir}" S["infodir"]="${datarootdir}/info" S["docdir"]="${datarootdir}/doc/${PACKAGE}" S["oldincludedir"]="/usr/include" S["includedir"]="${prefix}/include" S["localstatedir"]="/var" S["sharedstatedir"]="${prefix}/com" S["sysconfdir"]="/usr/local/etc" S["datadir"]="${datarootdir}" S["datarootdir"]="${prefix}/share" S["libexecdir"]="${exec_prefix}/libexec" S["sbindir"]="${exec_prefix}/sbin" S["bindir"]="${exec_prefix}/bin" S["program_transform_name"]="s,x,x," S["prefix"]="/usr/local" S["exec_prefix"]="${prefix}" S["PACKAGE_URL"]="" S["PACKAGE_BUGREPORT"]="" S["PACKAGE_STRING"]="" S["PACKAGE_VERSION"]="" S["PACKAGE_TARNAME"]="" S["PACKAGE_NAME"]="" S["PATH_SEPARATOR"]=":" S["SHELL"]="/bin/sh" _ACAWK cat >>"$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { D["PACKAGE_NAME"]=" \"\"" D["PACKAGE_TARNAME"]=" \"\"" D["PACKAGE_VERSION"]=" \"\"" D["PACKAGE_STRING"]=" \"\"" D["PACKAGE_BUGREPORT"]=" \"\"" D["PACKAGE_URL"]=" \"\"" D["HAVE_INITGROUPS"]=" 1" D["HAVE_SETGROUPS"]=" 1" D["USECLAMLIB"]=" 1" D["CONFIGFILE"]=" \"/usr/local/etc/havp/havp.config\"" D["WHITELISTFILE"]=" \"/usr/local/etc/havp/whitelist\"" D["BLACKLISTFILE"]=" \"/usr/local/etc/havp/blacklist\"" D["TEMPLATEPATH"]=" \"/usr/local/etc/havp/templates/en\"" D["ACCESSLOG"]=" \"/var/log/havp/access.log\"" D["ERRORLOG"]=" \"/var/log/havp/error.log\"" D["SCANTEMPFILE"]=" \"/var/tmp/havp/havp-XXXXXX\"" D["PIDFILE"]=" \"/var/run/havp/havp.pid\"" for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { line = $ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} ac_datarootdir_hack=' s&@datadir@&${datarootdir}&g s&@docdir@&${datarootdir}/doc/${PACKAGE}&g s&@infodir@&${datarootdir}/info&g s&@localedir@&${datarootdir}/locale&g s&@mandir@&${datarootdir}/man&g s&\${datarootdir}&${prefix}/share&g' ;; esac ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// } :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 havp-0.93/autom4te.cache/0000755000000000000000000000000013425375466013724 5ustar rootroot