Never been to TextSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

« Newer Snippets
Older Snippets »
4 total  XML / RSS feed 

Compile ClamAV from source on Mac OS X

The following instructions for compiling & installing the ClamAV virus scanner on Mac OS X require an admin user account and Xcode. Works despite some compiler warnings. Use at your own risk!

1. disable an already installed ClamAV system

clamconf      # get your ClamAV configuration
clamconf -n
clamconf | grep DatabaseOwner


# the following applies to the already installed ClamAV system of user clamavadmin at /private/var/clamavadmin
# cf. Run ClamAV from a system service agent account, http://textsnippets.com/posts/show/1406
# cf. Automated virus scanning with ClamAV on Mac OS X 10.4, http://textsnippets.com/posts/show/1357


# view clamd.log in another Terminal window
open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/clamd.log

# SHUTDOWN clamd 
# cf. man clamd
(sleep 3; echo PING; sleep 3; echo exit) | telnet -u /private/var/clamavadmin/tmp/clamd
(sleep 3; echo SHUTDOWN; sleep 3; echo exit) | telnet -u /private/var/clamavadmin/tmp/clamd

# alternative: sudo /opt/local/bin/port install socat
echo PING | /opt/local/bin/socat - /private/var/clamavadmin/tmp/clamd     
echo SHUTDOWN | /opt/local/bin/socat - /private/var/clamavadmin/tmp/clamd  

# alternative
function clamd_local_socket() {

   local_socket="$(/usr/local/bin/clamconf -n | awk -F '"' '/LocalSocket/ {print $2}')"

   if [[ -z "$local_socket" ]] || [[ ! -S "$local_socket" ]]; then    # cf. help test
      printf "No such local unix socket: $local_socket \n"
      return 1
   fi

   #printf -- "$@\x00$local_socket" | /usr/bin/sudo ruby -rsocket -n -e '
   printf -- "$@\x00$local_socket" | ruby -rsocket -n -e '
      args = $_.split(/\000/, 2)
      unix_socket = UNIXSocket::open(args.last)
      unix_socket.send(args.first, 0)
      print unix_socket.recvfrom(1000).first
      unix_socket.close
   '

return 0
}

clamd_local_socket PING
clamd_local_socket SHUTDOWN


function clamavadmin_perms() {

   if [[ -d "/private/var/clamavadmin" ]]; then
      printf '\nSetting permissions in the clamavadmin directory: /private/var/clamavadmin\n\n'
   else
      printf '\nNo clamavadmin directory at: /private/var/clamavadmin\n\n'
      return 1
   fi

   declare sudo=/usr/bin/sudo

   $sudo /bin/mkdir -p /private/var/clamavadmin/log
   $sudo /bin/mkdir -p /private/var/clamavadmin/tmp
   $sudo /bin/mkdir -p /private/var/clamavadmin/share/clamav   # ClamAV database directory
   $sudo /usr/bin/touch /private/var/clamavadmin/log/clamd.log 
   $sudo /usr/bin/touch /private/var/clamavadmin/log/freshclam.log

   $sudo /usr/sbin/chown -R clamavadmin:clamavadmin /private/var/clamavadmin
   $sudo /bin/chmod -R 0750 /private/var/clamavadmin 
   #$sudo /bin/chmod -R 0770 /private/var/clamavadmin   # for debugging only
   $sudo /bin/chmod 0777 /private/var/clamavadmin/tmp/clamd 2>/dev/null  # local unix socket file
   $sudo /usr/bin/find /private/var/clamavadmin -print0 | /usr/bin/xargs -0 $sudo /bin/ls -ldG
   return 0
}


# restart clamd after SHUTDOWN (socket file removed)
#if [[ -e "/private/var/clamavadmin/tmp/clamd" ]]; then sudo /bin/rm -f "/private/var/clamavadmin/tmp/clamd" ; fi
#sudo "$(/usr/bin/which clamd)" -c /private/var/clamavadmin/clamd.conf
#clamavadmin_perms


# get running clamav launchd services
launchctl list | grep -i clam
sudo launchctl list | grep -i clam

launchctl unload -w ~/Library/LaunchAgents/net.clamav.dirwatcher.plist 2>/dev/null
sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.dirwatcherd.plist 2>/dev/null
sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null
sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null

# check for: Disabled
open -e ~/Library/LaunchAgents/net.clamav.dirwatcher.plist
sudo nano /Library/LaunchDaemons/net.clamav.dirwatcherd.plist
sudo nano /Library/LaunchDaemons/net.clamav.clamd.plist
sudo nano /Library/LaunchDaemons/net.clamav.update.clamd.db.plist


sudo reboot

export PATH=/usr/local/bin:/usr/local/sbin:/usr/local/lib:/usr/local/include:/usr/bin:/bin:/usr/sbin:/sbin


2. compile & install gawk on Mac OS X

# http://www.gnu.org/software/gawk/
cd ~/Desktop
curl -L -O http://ftp.gnu.org/pub/gnu/gawk/gawk-3.1.6.tar.gz
tar -xzf gawk-3.1.6.tar.gz
cd gawk-3.1.6
./configure --help
./configure --disable-nls --prefix=/usr/local
make
sudo make install
/usr/local/bin/gawk --version


3. compile & install the GNU Multiple Precision Arithmetic Library

# http://gmplib.org
# http://gmplib.org/macos.html

cd ~/Desktop
curl -L -O ftp://ftp.gnu.org/gnu/gmp/gmp-4.2.2.tar.gz   # cf. fwftp, http://textsnippets.com/posts/show/1284
tar -xzf gmp-4.2.2.tar.gz
cd gmp-4.2.2

./configure --help
./configure

make
make check
sudo make install

# test
sudo find /usr/local -iregex ".*gmp.*" -print0 | xargs -0 sudo ls -ldG
otool -Lv /usr/local/lib/libgmp.3.4.2.dylib


4. create ClamAV user & group

# to set up a ClamAV user & group run the first script from: http://textsnippets.com/posts/show/1405

#--------------------------------------------------

You are going to create a system service agent account!

Enter first name: clamavadmin

Note: The last name is optional and defaults to "agent" if you just press <return>!
Enter last name: 

Note: The user shell is optional and defaults to "/usr/bin/false" if you just press <return>!
Enter user shell: /bin/bash

Note: The home directory is optional and defaults to "/private/var/empty" if you just press <return>!
Enter home directory: /private/var/clamavadmin

System service agent account:  clamavadmin  successfully created!

#--------------------------------------------------


sudo mkdir -p /private/var/clamavadmin/log
sudo touch /private/var/clamavadmin/log/clamd.log 
sudo touch /private/var/clamavadmin/log/freshclam.log
sudo mkdir -p /private/var/clamavadmin/tmp

# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


# add clamavadmin to group admin and group $(logname)
# add $(logname) to group clamavadmin
sudo dscl . -append /Groups/admin GroupMembership clamavadmin
sudo dscl . -append /Groups/$(logname) GroupMembership clamavadmin
sudo dscl . -append /Groups/clamavadmin GroupMembership $(logname)

#sudo dscl . -delete /Groups/admin GroupMembership clamavadmin 
#sudo dscl . -delete /Groups/$(logname) GroupMembership clamavadmin  
#sudo dscl . -delete /Groups/clamavadmin GroupMembership $(logname)   

# test
dscl . -list /Users  | grep -i clamav
dscl . -list /Groups  | grep -i clamav

dscl . -read  /Users/clamavadmin uid
dscl . -read  /Groups/clamavadmin gid

dscl . -search /Groups GroupMembership clamavadmin
printf -- "$(dscl . -search /Groups GroupMembership clamavadmin | awk '{print $1}' | tr '\n' ' ')\n"
id -Gn clamavadmin


5. compile & install ClamAV

# http://wiki.clamav.net/Main/InstallFromSource
# http://downloads.topicdesk.com/docs/Updating_clamav_on_OS_X_Server.pdf
# http://downloads.topicdesk.com/docs/clamav_extras.tar.gz

cd ~/Desktop
open http://freshmeat.net/projects/clamav/
curl -L -O http://freshmeat.net/redir/clamav/29355/url_tgz/clamav-0.92.1.tar.gz
tar -xzf clamav-0.92.1.tar.gz
cd clamav-0.92.1

./configure --help

# Compile bug for clamav 0.92 with latest xcode 
# http://discussions.apple.com/thread.jspa?messageID=6190171
# http://www.mail-archive.com/[email protected]/msg28420.html

CFLAGS="-O0" ./configure \
--prefix=/usr/local --mandir=/usr/local/share/man --sysconfdir=/private/var/clamavadmin \
--with-dbdir=/private/var/clamavadmin/share/clamav --with-datadir=/private/var/clamavadmin/share/clamav \
--with-user=clamavadmin --with-group=clamavadmin \
--enable-bigstack --enable-static --disable-shared

make

sudo make install


# test
man -w    # show directories searched for man pages
man -aW clamd 2>/dev/null
man -aW clamdscan 2>/dev/null
man -aW clamscan 2>/dev/null
man -aW freshclam 2>/dev/null
man -aW clamconf 2>/dev/null


# get an overview of your ClamAV file & folder permissions in /usr/local
sudo find /usr/local -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG
#sudo find /usr/local \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG

# set ClamAV file & folder permissions in /usr/local
# note: you may not need: -not -name "*.png"
sudo find /usr/local -not -name "*.png" -iregex ".*clam.*" -print0 | xargs -0 sudo chown clamavadmin:clamavadmin
sudo find /usr/local -not -name "*.png" -iregex ".*clam.*" -print0 | xargs -0 sudo chmod 0750

# reset permissions in /usr/local
# note: you may not need: -not -name "*.png"
#sudo find /usr/local  -not -name "*.png" -iregex ".*clam.*" -print0 | xargs -0 sudo chown root:wheel  
#sudo find /usr/local  -not -name "*.png" -iregex ".*clam.*" -print0 | xargs -0 sudo chmod 0755



# /private/var/clamavadmin/clamd.conf

sudo cp -p /private/var/clamavadmin/clamd.conf /private/var/clamavadmin/clamd.conf.orig

sudo sh -c '
cat << EOF > /private/var/clamavadmin/clamd.conf

LogFileMaxSize 10M
LogTime yes
FixStaleSocket yes
TCPAddr 127.0.0.1
MaxConnectionQueueLength 30
MaxThreads 20
ExitOnOOM yes
ScanOLE2 yes  # Microsoft Office documents and .msi files
ScanPDF yes
ArchiveMaxFileSize 100M
ArchiveMaxCompressionRatio 0
#VirusEvent echo virus: %v >> /path/to/file.txt

DatabaseDirectory /private/var/clamavadmin/share/clamav    # hardcoded
LogFile /private/var/clamavadmin/log/clamd.log
TemporaryDirectory /private/var/clamavadmin/tmp
LocalSocket /private/var/clamavadmin/tmp/clamd

EOF
'

sudo nano /private/var/clamavadmin/clamd.conf


# /private/var/clamavadmin/freshclam.conf

sudo cp -p /private/var/clamavadmin/freshclam.conf /private/var/clamavadmin/freshclam.conf.orig 

sudo sh -c '
cat << EOF > /private/var/clamavadmin/freshclam.conf

UpdateLogFile /private/var/clamavadmin/log/freshclam.log
LogFileMaxSize 2M
LogTime yes
LogVerbose yes
DatabaseOwner clamavadmin
Debug yes
NotifyClamd /private/var/clamavadmin/clamd.conf   # send the RELOAD command to clamd
DatabaseDirectory /private/var/clamavadmin/share/clamav    # hardcoded
DatabaseMirror database.clamav.net

#Checks 24   # number of database checks per day
#OnUpdateExecute command
#OnErrorExecute command
#OnOutdatedExecute command   # run command when freshclam reports outdated version
#ConnectTimeout 60
#ReceiveTimeout 60

EOF
'

sudo nano /private/var/clamavadmin/freshclam.conf


/usr/local/bin/clamconf
/usr/local/bin/clamconf -n


# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


# view clamd.log in another Terminal window
open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/clamd.log

# view freshclam.log in another Terminal window
open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/freshclam.log


# test
sudo /usr/local/bin/freshclam -u clamavadmin   # update virus database
sudo /usr/local/bin/clamscan ~/Desktop/clamav-0.92.1/test/*
sudo /usr/local/bin/clamdscan ~/Desktop/clamav-0.92.1/test/*

# now start clamd
if [[ -e "/private/var/clamavadmin/tmp/clamd" ]]; then sudo /bin/rm -f "/private/var/clamavadmin/tmp/clamd" ; fi
sudo /usr/local/sbin/clamd -c /private/var/clamavadmin/clamd.conf

# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


#--------------------------------------------------


# set up ClamAV launchd items

sudo nano /Library/LaunchDaemons/net.clamav.clamd.plist

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>GroupNamekey>
        clamavadmin</string>
        <key>Labelkey>
        net.clamav.clamd</string>
        <key>ProgramArgumentskey>
        
                /usr/local/sbin/clamdstring>
                -c</string>
                <string>/private/var/clamavadmin/clamd.confstring>
        </array>
        <key>RunAtLoadkey>
        />
        <key>UserNamekey>
        clamavadmin</string>
dict>
</plist>

if [[ -e "/private/var/clamavadmin/tmp/clamd" ]]; then sudo /bin/rm -f "/private/var/clamavadmin/tmp/clamd" ; fi
sudo launchctl load -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null
#sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null

# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


#--------------------------------------------------


sudo nano /Library/LaunchDaemons/net.clamav.update.clamd.db.plist

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>GroupNamekey>
        clamavadmin</string>
        <key>Labelkey>
        net.clamav.update.clamd.db</string>
        <key>ProgramArgumentskey>
        
                /private/var/clamavadmin/update_clamd_db.shstring>
        </array>
        <key>RunAtLoadkey>
        />
        <key>StartIntervalkey>
        20000</integer>
        <key>UserNamekey>
        clamavadmin</string>
dict>
</plist>

sudo launchctl load -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null
#sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null

# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


#--------------------------------------------------


sudo nano /private/var/clamavadmin/update_clamd_db.sh

#!/bin/bash

/bin/sleep 120

exec >/dev/console 2>&1   # write stdout & stderr to console.log

/usr/bin/curl -I -L -s --max-time 15 database.clamav.net 1>/dev/null

if [[ $? -eq 0 ]]; then 

   /bin/sleep 3

   /usr/local/bin/freshclam -u clamavadmin

   /bin/sleep 3

   # cf. /private/var/clamavadmin/freshclam.conf above:
   # NotifyClamd /private/var/clamavadmin/clamd.conf   # send the RELOAD command to clamd

   #echo RELOAD | /opt/local/bin/socat - /private/var/clamavadmin/tmp/clamd
   #/bin/sleep 3
   #echo PING | /opt/local/bin/socat - /private/var/clamavadmin/tmp/clamd
   #/bin/sleep 3

   echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): clamd virus database successfully updated\n"
   exit 0

else

   echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): updating the clamd virus database failed; no internet connection to database.clamav.net established\n"
   exit 0   # leave launchd item /Library/LaunchDaemons/net.clamav.update.clamd.db.plist undisturbed

fi


#--------------------------------------------------


# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above


#--------------------------------------------------


# cf. http://textsnippets.com/posts/show/1357

sudo nano ~/Documents/ClamAV/watchdirs.sh     

# ...

find=/usr/bin/find
clamdscan=/usr/local/bin/clamdscan
clamscan=/usr/local/bin/clamscan

#clamdscan=/opt/local/bin/clamdscan
#clamscan=/opt/local/bin/clamscan

# ...


#--------------------------------------------------


# cf. http://textsnippets.com/posts/show/1400
open ~/Library/Workflows/Applications/Finder/virusscan.workflow

/usr/local/bin/clamdscan --quiet "$f" 2>/dev/null
#/opt/local/bin/clamdscan --quiet "$f" 2>/dev/null


#--------------------------------------------------

launchctl load -w ~/Library/LaunchAgents/net.clamav.dirwatcher.plist 2>/dev/null
#sudo launchctl load -w /Library/LaunchDaemons/net.clamav.dirwatcherd.plist 2>/dev/null
sudo launchctl load -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null
sudo launchctl load -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null


sudo reboot


open -a Console

open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/clamd.log

open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/freshclam.log

# make sure permissions are set correctly in /private/var/clamavadmin
clamavadmin_perms   # see function above

sudo find /private/var/clamavadmin -print0 | xargs -0 sudo ls -ldG
sudo find /usr/local -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG

Run ClamAV from a system service agent account

The following instructions on how to run ClamAV from a system service agent account (non-root) require an admin user account, a ClamAV setup as described here and the creation of a clamavadmin system service agent account as described here.

Use at your own risk!


First uncomment the following lines of code in the first script at http://textsnippets.com/posts/show/1405:

# create further subdirectories if necessary
...
#fi
#
#fi


Then save the file, start the script and enter the following:

You are going to create a system service agent account!

Enter first name: clamavadmin

Note: The last name is optional and defaults to "agent" if you just press <return>!
Enter last name: 

Note: The user shell is optional and defaults to "/usr/bin/false" if you just press <return>!
Enter user shell: /bin/bash

Note: The home directory is optional and defaults to "/private/var/empty" if you just press <return>!
Enter home directory: /private/var/clamavadmin

System service agent account:  clamavadmin  successfully created!



# test
dscl . -read /Users/clamavadmin
dscl . -read /Groups/clamavadmin
dscl . list /Groups GroupMembership
dscl . read /Groups/clamavadmin GroupMembership
dscl . -search /Groups GroupMembership clamavadmin
echo $(dscl . -search /Groups GroupMembership clamavadmin | awk '{print $1}' | tr '\n' ' ')
printf -- "$(dscl . -search /Groups GroupMembership clamavadmin | awk '{print $1}' | tr '\n' ' ')\n"

sudo ls -ld /private/var/clamavadmin
sudo ls -l /private/var/clamavadmin/log/clamd.log
sudo ls -ld /private/var/clamavadmin/tmp
#sudo ls -l /private/var/clamavadmin/tmp/clamd   # will be created later by man clamd
sudo find /private/var/clamavadmin \( -type f -or -type d -or -type s \) -print0 | xargs -0 sudo ls -ldG



# add clamavadmin to group admin and group $(logname)
# add $(logname) to group clamavadmin
sudo dscl . -append /Groups/admin GroupMembership clamavadmin
sudo dscl . -append /Groups/$(logname) GroupMembership clamavadmin
sudo dscl . -append /Groups/clamavadmin GroupMembership $(logname)

#sudo dscl . -delete /Groups/admin GroupMembership clamavadmin 
#sudo dscl . -delete /Groups/$(logname) GroupMembership clamavadmin  
#sudo dscl . -delete /Groups/clamavadmin GroupMembership $(logname)   

# cf. http://textsnippets.com/posts/show/1402
dirmodes ~/Documents/ClamAV/Downloads/QueueDirectory


# copy update_clamd_db.sh
sudo cp /usr/local/sbin/update_clamd_db.sh /private/var/clamavadmin/update_clamd_db.sh
sudo chown clamavadmin:clamavadmin /private/var/clamavadmin/update_clamd_db.sh
sudo chmod 0750 /private/var/clamavadmin/update_clamd_db.sh
ls -l /private/var/clamavadmin/update_clamd_db.sh

# then change the following line in sudo nano  /private/var/clamavadmin/update_clamd_db.sh
/opt/local/bin/freshclam -u root
# ... to read ...
/opt/local/bin/freshclam -u clamavadmin


# get an overview of your ClamAV file & folder permissions in /opt
sudo find /opt \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG

# set new ClamAV file & folder permissions
sudo find /opt  \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo chown clamavadmin:clamavadmin
sudo find /opt  \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo chmod 0750

# reset permissions
#sudo find /opt  \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo chown root:wheel  
#sudo find /opt  \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo chmod 0755


# test
sudo find /opt \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG
sudo find /opt -not -user clamavadmin \( -type f -or -type d \) -iregex ".*clam.*" -print0 | xargs -0 sudo ls -ldG


# then modify clamd.conf
sudo nano /opt/local/etc/clamd.conf

LogFileMaxSize 10M
LogTime yes
FixStaleSocket yes
TCPAddr 127.0.0.1
MaxConnectionQueueLength 30
MaxThreads 20
ExitOnOOM yes
ScanOLE2 yes  # Microsoft Office documents and .msi files
ScanPDF yes
ArchiveMaxFileSize 100M
ArchiveMaxCompressionRatio 0
#VirusEvent echo virus: %v >> /path/to/file.txt

DatabaseDirectory /opt/local/share/clamav    # hardcoded
#LogFile /private/var/log/clamd.log
#TemporaryDirectory /private/var/tmp
#DatabaseDirectory /opt/local/share/clamav
#LocalSocket /tmp/clamd

#DatabaseDirectory /private/var/clamavadmin/share/clamav
LogFile /private/var/clamavadmin/log/clamd.log
TemporaryDirectory /private/var/clamavadmin/tmp
LocalSocket /private/var/clamavadmin/tmp/clamd



# modify net.clamav.clamd.plist

sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null
sudo cp -p /Library/LaunchDaemons/net.clamav.clamd.plist /Library/LaunchDaemons/net.clamav.clamd.root-wheel

sudo nano /Library/LaunchDaemons/net.clamav.clamd.plist

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.$
"1.0">

        Disabled
        
        GroupName
        clamavadmin
        Label
        net.clamav.clamd
        ProgramArguments
        
                /opt/local/sbin/clamd
                -c
                /opt/local/etc/clamd.conf
        
        RunAtLoad
        
        UserName
        clamavadmin


sudo launchctl load -w /Library/LaunchDaemons/net.clamav.clamd.plist 2>/dev/null



# modify net.clamav.update.clamd.db.plist

sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null
sudo cp -p /Library/LaunchDaemons/net.clamav.update.clamd.db.plist /Library/LaunchDaemons/net.clamav.update.clamd.db.plist.root-wheel

sudo nano /Library/LaunchDaemons/net.clamav.update.clamd.db.plist

"1.0" encoding="UTF-8"?>
"-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.$
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>GroupNamekey>
        clamavadmin</string>
        <key>Labelkey>
        net.clamav.update.clamd.db</string>
        <key>ProgramArgumentskey>
        
                /private/var/clamavadmin/update_clamd_db.shstring>
        </array>
        <key>RunAtLoadkey>
        />
        <key>StartIntervalkey>
        20000</integer>
        <key>UserNamekey>
        clamavadmin</string>
dict>


sudo launchctl load -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist 2>/dev/null



# watch clamd.log in a second Terminal window
open /bin/bash
sudo tail -n 50 -f /private/var/clamavadmin/log/clamd.log


# now restart clamd
if [[ -e "/private/var/clamavadmin/tmp/clamd" ]]; then sudo /bin/rm -f "/private/var/clamavadmin/tmp/clamd" ; fi
sudo /opt/local/sbin/clamd -c /opt/local/etc/clamd.conf


# test
(sleep 3; echo PING; sleep 3; echo exit) | sudo telnet -u /private/var/clamavadmin/tmp/clamd
echo PING | /opt/local/bin/socat - /private/var/clamavadmin/tmp/clamd    # requires: sudo port install socat
sudo find /private/var/clamavadmin \( -type f -or -type d -or -type s \) -print0 | xargs -0 sudo ls -ldG   # /private/var/clamavadmin/tmp/clamd

virusscan contextual menu item with Automator

Right-click on a file or folder and select Automator -> virusscan to scan the selected Finder item for viruses.
Requires Automator (Mac OS X 10.4 or later), ClamAV (man clamdscan) and CocoaDialog (for the notification pop-up).


# get the ClamAV icon
cd ~/Desktop
curl -L -O http://freshmeat.net/redir/clamav/29355/url_tgz/clamav-0.92.tar.gz
tar -xzf clamav-0.92.tar.gz
cd clamav-0.92
sudo cp ~/Desktop/clamav-0.92/docs/html/img2.png /usr/local/bin/CocoaDialog.app/Contents/Resources/clamav.png
#sudo sips -i /usr/local/bin/CocoaDialog.app/Contents/Resources/clamav.png
sudo chown -R root:wheel /usr/local/bin/CocoaDialog.app
sudo chmod -R 0755 /usr/local/bin/CocoaDialog.app


open -a Automator


#----------------------------------------------------


Drag or add actions here to build your workflow:
Library: Finder -> Action: Get Selected Finder Items
Library: Automator -> Action: Run Shell Script
                                 - Shell: /bin/bash
                                 - Pass input: as arguments

cocoadialog="/usr/local/bin/CocoaDialog.app/Contents/MacOS/CocoaDialog"
CD_Resources="/usr/local/bin/CocoaDialog.app/Contents/Resources"

for f in "$@"; do

   /opt/local/bin/clamdscan --quiet "$f" 2>/dev/null

   return_code=$?

   if [[ $return_code -eq 0 ]]; then
 
      /usr/bin/say OK

      $cocoadialog bubble --no-timeout --x-placement center --y-placement center --background-top "00FF00" \
          --background-bottom "00FF99" --icon-file $CD_Resources/clamav.png --title "Scanned item is OK!" \
          --text "$f"

   elif [[ $return_code -eq 1 ]]; then

      /usr/bin/say "virus alert"

      $cocoadialog bubble --no-timeout --x-placement center --y-placement center --background-top "FF0000" \
          --background-bottom "FF0066" --icon-file $CD_Resources/clamav.png --title "WARNING: VIRUS ALERT!!!" \
          --text "$f"

   else

      $cocoadialog bubble --no-timeout --x-placement center --y-placement center --background-top "FFCC00" \
          --background-bottom "FFCC33" --icon-file $CD_Resources/clamav.png --title "ClamAV virus scan failed!" \
          --text "Please, check your ClamAV setup! Return code of man clamdscan: $return_code"

      exit 1

   fi

done

exit 0


#----------------------------------------------------


# save the virusscan Automator workflow as a contextual menu item
Automator -> File -> Save As Plug-in ... -> Save Plug-in As: virusscan -> Plug-in for: Finder -> Save

open ~/Library/Workflows/Applications/Finder/virusscan.workflow

# test some files in ...
open ~/Desktop/clamav-0.92/test

Automated virus scanning with ClamAV on Mac OS X 10.4

Author: jv
License: The MIT License, Copyright (c) 2008 jv
Description: basic setup to scan files added to specified directories automatically for viruses using ClamAV; for instructions on how to run ClamAV from a system service agent account (non-root) see here; use at your own risk
Platform: Mac OS X 10.4.11 Client
Requirements: sudo port install clamav (after installing MacPorts); to fix the command search path, insert the following statement at the end of your ~/.bash_login file: export PATH="/opt/local/bin:/opt/local/sbin:$PATH" and then: source ~/.bash_login



# download ClamAV
sudo port install clamav      # requires open firewall port 873
#sudo port uninstall clamav

man clamd
man clamd.conf
man clamdscan
man clamscan
man freshclam


# configure /opt/local/etc/freshclam.conf

sudo cp -p /opt/local/etc/example-freshclam.conf /opt/local/etc/freshclam.conf
sudo sed -i "" -e 's/^Example/#Example/' /opt/local/etc/freshclam.conf              # comment out 'Example' line
#sudo sed -i "" -e 's/^#Example/Example/' /opt/local/etc/freshclam.conf              # uncomment 'Example' line
sudo nano /opt/local/etc/freshclam.conf


# make sure you are a member of the wheel and admin group
id -G -n $(whoami) | grep -Eo 'wheel|admin'
dseditgroup -o checkmember -m $(whoami) wheel; echo $?
dseditgroup $(whoami)
dseditgroup wheel
dseditgroup admin

sudo dscl . -append /Groups/wheel GroupMembership $(whoami)      # add user to group if necessary
#sudo dseditgroup -o edit -a $(whoami) -t user wheel             # add user to group
#sudo dscl . -delete /Groups/wheel GroupMembership $(whoami)     # delete user from group
#sudo dseditgroup -o edit -d $(whoami) -t user wheel             # delete user from group


sudo chown -R root:wheel /opt/local/share/clamav  
sudo chmod -R 0770 /opt/local/share/clamav

freshclam       # update virus database

# test some clamav commands
clamscan /path/to/file
sudo clamscan -r /tmp
sudo clamscan -r /private/var/tmp
clamscan -r ~/Library/Caches
clamscan -r ~/Library/Caches/java
sudo clamscan -r ~/Library/Mail
clamscan -r ~/Library


# configure /opt/local/etc/clamd.conf
# open /opt/local/etc
# sudo nano /opt/local/etc/clamd.conf
# cf. http://www.silvester.org.uk/OSX/configuring_clamd.html

sudo cp -p /opt/local/etc/clamd.conf /opt/local/etc/clamd.conf.orig

sudo sh -c '
cat << EOF > /opt/local/etc/clamd.conf
LogFile /private/var/log/clamd.log
LogFileMaxSize 10M
LogTime yes
TemporaryDirectory /private/var/tmp
DatabaseDirectory /opt/local/share/clamav
LocalSocket /tmp/clamd
FixStaleSocket yes
TCPAddr 127.0.0.1
MaxConnectionQueueLength 30
MaxThreads 20
ExitOnOOM yes
ScanOLE2 yes  # Microsoft Office documents and .msi files
ScanPDF yes
ArchiveMaxFileSize 100M
ArchiveMaxCompressionRatio 0
#VirusEvent echo virus: %v >> /path/to/file.txt
EOF
'

sudo chown root:wheel /opt/local/etc/clamd.conf
sudo chmod 750 /opt/local/etc/clamd.conf



Create the launchd item /Library/LaunchDaemons/net.clamav.clamd.plist


sudo nano /Library/LaunchDaemons/net.clamav.clamd.plist

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
   <dict>
        <key>Disabledkey>
        />
        <key>Labelkey>
        net.clamav.clamd</string>
        <key>ProgramArgumentskey>
        
                /opt/local/sbin/clamdstring>
                -c</string>
                <string>/opt/local/etc/clamd.confstring>
        </array>
        <key>RunAtLoadkey>
        />
        <key>UserNamekey>
        root</string>
   dict>
</plist>


sudo chown root:wheel /Library/LaunchDaemons/net.clamav.clamd.plist
sudo chmod 0644 /Library/LaunchDaemons/net.clamav.clamd.plist

sudo launchctl load -w /Library/LaunchDaemons/net.clamav.clamd.plist
#sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.clamd.plist



Create watchdirs.sh


# create ClamAV directories
mkdir -p "$HOME/Documents/ClamAV/Quarantine"
mkdir -p "$HOME/Documents/ClamAV/Downloads"           # Safari -> Preferences ... -> Save downloaded files to: 
mkdir -p "$HOME/Documents/ClamAV/EmailAttachments"
sudo chown -R $(whoami):wheel "$HOME/Documents/ClamAV"
sudo chmod -R 770 "$HOME/Documents/ClamAV"

# create a timestamp file
touch ~/.clamav_ timestamp
sudo chown $(whoami):wheel "$HOME/.clamav_timestamp"
sudo chmod 400 "$HOME/.clamav_timestamp"
stat -x $HOME/.clamav_timestamp


#---------------------------------


# Create a BASH script that will - controlled by ~/Library/LaunchAgents/net.clamav.dirwatcher.plist below - run 
# a clamdscan or clamscan command on files that have been changed or modified in the specified directories

# nano $HOME/Documents/ClamAV/watchdirs.sh

#!/bin/bash

exec >/dev/console 2>&1   # write stdout & stderr to console.log in /Library/Logs/Console/

echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): ... WATCHDIRS.SH for ClamAV ... STARTED ...\n"


# All files added to the watched directories during the specified sleep period (in seconds) will be scanned for viruses.
# Files added to the directories while a virus scan is being done may not be included in the current virus scan, but
# they will get scanned next time a virus scan is scheduled to run which can, for example, be determined by the launch agent 
# variable StartInterval. Increase the value of the specified sleep period (in seconds) if you expect large files or 
# directories to be copied or downloaded to the watched directories.

/bin/sleep 60


SCANDIR1="$HOME/Documents/ClamAV/Downloads" 
SCANDIR2="$HOME/Documents/ClamAV/EmailAttachments"
QUARANTINEDIR="$HOME/Documents/ClamAV/Quarantine"
TOUCHFILE="$HOME/.clamav_timestamp"

find=/usr/bin/find
clamdscan=/opt/local/bin/clamdscan
clamscan=/opt/local/bin/clamscan

if [[ ! -e "$TOUCHFILE" ]]; then 
   /usr/bin/touch -afm "$TOUCHFILE"
   /usr/sbin/chown $(whoami):$(whoami) "$TOUCHFILE"
   /bin/chmod 400 "$TOUCHFILE"
   $clamdscan --copy="$QUARANTINEDIR" "$SCANDIR1" || $clamscan -i --copy="$QUARANTINEDIR" -r "$SCANDIR1"
   $clamdscan --copy="$QUARANTINEDIR" "$SCANDIR2" || $clamscan -i --copy="$QUARANTINEDIR" -r "$SCANDIR2"
   exit 0
fi


timestamp=$(/bin/date "+%Y%m%d%H%M.%S")    # store timestamp before starting the virus scan


if /bin/ps -ax | /usr/bin/grep clamd | /usr/bin/grep -v grep > /dev/null; then        

   # run clamdscan
   # scan all files that have been changed or modified after the $TOUCHFILE timestamp of the last virus scan
   # optional: $find -x "$SCANDIR1" "$SCANDIR2" -type f ... (but mind the 'sysctl kern.argmax' limit for xargs!)
   # optional: to exclude .DS_Store files add: \! -name ".DS_Store"

   # alternative: first find changed or modified directories
   # find -x "$SCANDIR1" "$SCANDIR2" -type d \( -newercm "$TOUCHFILE" -or -newermm "$TOUCHFILE" \) -print0 | while read -d $'\0' scandir; do echo "find -x $scandir -maxdepth 1 -type f ..."; done

   $find -x "$SCANDIR1" -type f \( -newercm "$TOUCHFILE" -or -newermm "$TOUCHFILE" \) -print0 | xargs -0 $clamdscan --copy="$QUARANTINEDIR"
   $find -x "$SCANDIR2" -type f \( -newercm "$TOUCHFILE" -or -newermm "$TOUCHFILE" \) -print0 | xargs -0 $clamdscan --copy="$QUARANTINEDIR"

else 

   # run clamscan
   $find -x "$SCANDIR1" -type f \( -newercm "$TOUCHFILE" -or -newermm "$TOUCHFILE" \) -print0 | xargs -0 $clamscan -i --copy="$QUARANTINEDIR"
   $find -x "$SCANDIR2" -type f \( -newercm "$TOUCHFILE" -or -newermm "$TOUCHFILE" \) -print0 | xargs -0 $clamscan -i --copy="$QUARANTINEDIR"

fi


# update the $TOUCHFILE timestamp with the pre-scan $timestamp
/usr/bin/touch -f -t $timestamp "$TOUCHFILE"    

echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): ... WATCHDIRS.SH for ClamAV ... DONE ...\n"

exit 0


#---------------------------------


sudo chown root:wheel ~/Documents/ClamAV/watchdirs.sh 
sudo chmod 0770 ~/Documents/ClamAV/watchdirs.sh



Create the ~/Library/LaunchAgents/net.clamav.dirwatcher.plist launch agent


# nano ~/Library/LaunchAgents/net.clamav.dirwatcher.plist
# open -e ~/Library/LaunchAgents/net.clamav.dirwatcher.plist


# Note: Don't use $HOME or any other variables in the file paths you have to specify in the .plist files below! 
#       Use the full file paths without any variables!


# WatchPaths virus scanner launch agent (combined with StartInterval)
# scan the directories specified the same in watchdirs.sh and this .plist file when they are modified or after a specified time interval respectively

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>Labelkey>
        net.clamav.dirwatcher</string>
        <key>LowPriorityIOkey>
        />
        <key>OnDemandkey>
        />
        <key>ProgramArgumentskey>
        
                /full/path/to/Documents/ClamAV/watchdirs.shstring>
        </array>
        <key>StartIntervalkey>
        1800</integer>
        <key>WatchPathskey>
        
                /full/path/to/Documents/ClamAV/Downloadsstring>
                /full/path/to/Documents/ClamAV/EmailAttachmentsstring>
        </array>
        
        
dict>
</plist>


#--------------------------------------------------------------------------------


# StartInterval virus scanner launch agent
# scan the directories specified in watchdirs.sh at the specified time intervals (given in seconds)

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>Labelkey>
        net.clamav.dirwatcher</string>
        <key>LowPriorityIOkey>
        />
        <key>ProgramArgumentskey>
        
                /full/path/to/Documents/ClamAV/watchdirs.shstring>
        </array>
        <key>StartIntervalkey>
        7200</integer>
        
        
dict>
</plist>


#--------------------------------------------------------------------------------


# StartCalendarInterval virus scanner launch agent
# scan the directories specified in watchdirs.sh at the specified times of the day

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
        <key>Labelkey>
        net.clamav.dirwatcher</string>
        <key>LowPriorityIOkey>
        />
        <key>ProgramArgumentskey>
        
                /full/path/to/Documents/ClamAV/watchdirs.shstring>
        </array>
        <key>StartCalendarIntervalkey>
        
                Hour</key>
                <integer>7integer>
                Minute</key>
                <integer>45integer>
        </dict>
        <key>StartCalendarIntervalkey>
        
                Hour</key>
                <integer>12integer>
                Minute</key>
                <integer>30integer>
        </dict>
        
        
dict>
</plist>


#--------------------------------------------------------------------------------


sudo chown root:wheel ~/Library/LaunchAgents/net.clamav.dirwatcher.plist 
sudo chmod 0770 ~/Library/LaunchAgents/net.clamav.dirwatcher.plist
ls -l ~/Library/LaunchAgents/net.clamav.dirwatcher.plist

launchctl load -w ~/Library/LaunchAgents/net.clamav.dirwatcher.plist
#launchctl unload -w ~/Library/LaunchAgents/net.clamav.dirwatcher.plist

sudo reboot

open -a Console

# update clamd virus database
freshclam; sleep 5; sudo clamd RELOAD



Alternative watchdirs.sh for a QueueDirectories virus scanner launch agent


# nano $HOME/Documents/ClamAV/watchdirs.sh

#!/bin/bash

# check downloaded files or directories in the specified $QueueDirectory for viruses and then move them to $MoveDir
# rename the files or folders to be moved to $MoveDir if necessary
# remove anything else from the $QueueDirectory

exec >/dev/console 2>&1   # write stdout & stderr to console.log in /Library/Logs/Console/

echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"):  ... WATCHDIRS.SH for ClamAV ... STARTED ...\n"

/bin/sleep 5

QUARANTINEDIR="$HOME/Documents/ClamAV/Quarantine"
TOUCHFILE="$HOME/.clamav_timestamp"

QueueDirectory="$HOME/Documents/ClamAV/Downloads/QueueDirectory"    # Safari -> Preferences ... -> Save downloaded files to: 
/bin/mkdir -p "$QueueDirectory"

MoveDir="$HOME/Documents/ClamAV/Downloads"
/bin/mkdir -p "$MoveDir"

find=/usr/bin/find
clamdscan=/opt/local/bin/clamdscan
clamscan=/opt/local/bin/clamscan

if [[ -f "$QueueDirectory"/.DS_Store ]]; then /bin/rm -f "$QueueDirectory"/.DS_Store; fi


# alternative to $TOUCHFILE time stamp
#/usr/bin/touch ~/Desktop/test.txt
#t1=$(/bin/date +%s)
#/bin/sleep 1
#/usr/bin/touch -f -am ~/Desktop/test.txt   # ... file is being downloaded ...
#t2=$(/usr/bin/stat -f %m ~/Desktop/test.txt)
#echo $(($t1 - $t2))
#if [[ $t1 -lt $t2 ]]; then echo "file was modified"; else echo "file was not modified"; fi


# directory test
DirTest="$($find -x "$QueueDirectory" -type d -maxdepth 1 -not -regex "^$QueueDirectory$")"

if [[ -n "$DirTest" ]]; then           # download is directory

   $find -x "$QueueDirectory" -type d -maxdepth 1 -not -regex "^$QueueDirectory$" -print0 | while read -d $'\0' dir; do

      /usr/bin/touch -f -am "$TOUCHFILE"
      /bin/sleep 3

      unset -v file_modified
      file_modified=0                      # check if a file within $dir has been modified
      while read -d $'\0' file; do  
         # set file_modified to 1 if at least one file has been modified
         if [[ "$TOUCHFILE" -ot "$file" ]]; then file_modified=1; break; fi     
      done < <($find -x "$dir" -type f -print0 2>/dev/null)

      if [[ -d "$dir" ]] && [[ "$TOUCHFILE" -nt "$dir" ]] && [[ $file_modified -eq 0 ]]; then
         $clamdscan --no-summary --copy="$QUARANTINEDIR" "$dir" || $clamscan -i -r --no-summary --copy="$QUARANTINEDIR" "$dir"
         bname="$(/usr/bin/basename "$dir")"
         if [[ ! -d "$MoveDir/$bname" ]]; then
            /bin/mv "$dir" "$MoveDir" 
         else
            newMoveDir="$MoveDir/$(/bin/date "+%Y-%m-%d-%H%M.%S")-$bname"
            /bin/mv "$dir" "$newMoveDir" 
         fi  
      fi

   done

else           

   $find -x "$QueueDirectory" -type f -maxdepth 1 -print0 | while read -d $'\0' file; do      # download is file

      /usr/bin/touch -f -am "$TOUCHFILE"
      /bin/sleep 3

      if [[ -f "$file" ]] && [[ "$TOUCHFILE" -nt "$file" ]]; then
         $clamdscan --no-summary --copy="$QUARANTINEDIR" "$file" || $clamscan -i --no-summary --copy="$QUARANTINEDIR" "$file"
         # the mv command preserves metadata and resource forks of files on Extended HFS volumes (Mac OS X 10.4)

         bname="$(/usr/bin/basename "$file")"
         if [[ ! -f "$MoveDir/$bname" ]]; then
            /bin/mv "$file" "$MoveDir" 
         else
            newMoveDir="$MoveDir/$(/bin/date "+%Y-%m-%d-%H%M.%S")-$bname"
            /bin/mv "$file" "$newMoveDir" 
         fi  
      fi

   done

fi


if [[ -f "$QueueDirectory"/.DS_Store ]]; then /bin/rm -f "$QueueDirectory"/.DS_Store; fi

$find -x "$QueueDirectory" -not -type f -not -type d -print0 | while read -d $'\0' item; do /bin/rm -f "$item"; done

echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"):  ... WATCHDIRS.SH for ClamAV ... DONE ...\n"

exit 0


#------------------------------------

# nano ~/Library/LaunchAgents/net.clamav.dirwatcher.plist





        Disabled
        
        Label
        net.clamav.dirwatcher
        ProgramArguments
        
                /full/path/to/Documents/ClamAV/watchdirs.sh
        
        QueueDirectories
        
                /full/path/to/Documents/ClamAV/Downloads/QueueDirectory
        





Update clamd virus database automatically


# set permissions
#sudo chown -R root:wheel /opt
#sudo chmod -R 755  /opt
#sudo chown -R root:wheel /opt/local/share/clamav  
#sudo chmod -R 0770 /opt/local/share/clamav


# bash script to update the clamd virus database
# sudo nano /usr/local/sbin/update_clamd_db.sh

#!/bin/bash

/bin/sleep 120

# write stdout & stderr to console.log
exec >/dev/console 2>&1   

# check if internet connection is alive and database.clamav.net is reachable
/usr/bin/curl -I -L -s --max-time 15 database.clamav.net 1>/dev/null   


if [[ $(echo $?) -eq 0 ]]; then

   /opt/local/bin/freshclam -u root

   /bin/sleep 3

   #if [[ -e "/tmp/clamd" ]]; then /bin/rm -f /tmp/clamd; fi
   #/opt/local/sbin/clamd -c /opt/local/etc/clamd.conf     # recreates the local socket file /tmp/clamd as specified in /opt/local/etc/clamd.conf above

   (/bin/sleep 3; echo RELOAD; /bin/sleep 3; echo "exit") | /usr/bin/telnet -u /tmp/clamd >/dev/null 2>&1
   #echo RELOAD | /opt/local/bin/socat - /tmp/clamd         # an alternative that requires: sudo port install socat

   /bin/sleep 3

   echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): clamd virus database successfully updated\n"
   exit 0

else

   echo -e "\n$(/bin/date "+%Y-%m-%d %H:%M:%S %Z"): updating the clamd virus database failed; no internet connection to database.clamav.net established\n"
   exit 0     # leave launchd undisturbed

fi


# set permissions
sudo chown root:wheel /usr/local/sbin/update_clamd_db.sh
sudo chmod 0770 /usr/local/sbin/update_clamd_db.sh


#------------------------


# launchd item to update the clamd virus database using /usr/local/sbin/update_clamd_db.sh
# sudo nano /Library/LaunchDaemons/net.clamav.update.clamd.db.plist

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Disabledkey>
        />
       <key>Labelkey>
        net.clamav.update.clamd.db</string>
        <key>ProgramArgumentskey>
        
                /usr/local/sbin/update_clamd_db.shstring>
        </array>
        <key>RunAtLoadkey>
        />
        <key>StartIntervalkey>
        10800</integer>
        <key>UserNamekey>
        root</string>
        <key>GroupNamekey>
        wheel</string>
dict>
</plist>


sudo chown root:wheel /Library/LaunchDaemons/net.clamav.update.clamd.db.plist
sudo chmod 0644 /Library/LaunchDaemons/net.clamav.update.clamd.db.plist

sudo launchctl load -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist
#sudo launchctl unload -w /Library/LaunchDaemons/net.clamav.update.clamd.db.plist

sudo reboot


# simple shell script syntax check
# for more see Debugging Bash scripts, http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html
bash -n $HOME/Documents/ClamAV/watchdirs.sh
bash -n /usr/local/sbin/update_clamd_db.sh

# optional: convert XML .plist files to binary format
sudo plutil -convert binary1 -- /Library/LaunchDaemons/net.clamav.clamd.plist \
~/Library/LaunchAgents/net.clamav.dirwatcher.plist \
/Library/LaunchDaemons/net.clamav.update.clamd.db.plist

# check .plist file syntax
plutil -- /Library/LaunchDaemons/net.clamav.clamd.plist \
~/Library/LaunchAgents/net.clamav.dirwatcher.plist \
/Library/LaunchDaemons/net.clamav.update.clamd.db.plist


# list virus signatures
sigtool -l | grep -Ei 'adware|spy' | nl
sigtool -l | grep -i phish | nl



Further information:

- Run ClamAV from a system service agent account
- ClamAV an open-source anti-virus toolkit
- Configuring Clamav's clamd for enhanced virus-scanning performance
- Updating ClamAV on OS X Server 10.4.7-10.4.11
- Using Open Source Tools to Filter Email on Mac OS X Server
- The Anti-Virus Or Anti-Malware Test File
- Mac OS X Unix Tutorial: Part 4 - Managing Permissions
- launchd

« Newer Snippets
Older Snippets »
4 total  XML / RSS feed