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 »
95 total  XML / RSS feed 

Notifications from shell scripts with CocoaDialog


cd ~/Desktop
curl -L -O http://prdownloads.sourceforge.net/cocoadialog/CocoaDialog-2.1.1.dmg
hdiutil mount CocoaDialog-2.1.1.dmg
sudo mkdir -p /usr/local/bin
sudo ditto -rsrc /Volumes/CocoaDialog/CocoaDialog.app /usr/local/bin/CocoaDialog.app
sudo chown -R root:wheel /usr/local/bin/CocoaDialog.app
sudo chmod -R 0755 /usr/local/bin/CocoaDialog.app
hdiutil unmount /Volumes/CocoaDialog


alias cocoadialog=/usr/local/bin/CocoaDialog.app/Contents/MacOS/CocoaDialog

# cf. http://cocoadialog.sourceforge.net/examples/bubble.sh.txt
cocoadialog bubble --no-timeout --x-placement center --y-placement center --background-top "FF0000" --background-bottom "FF0066"  \
                   --icon-file /usr/local/bin/CocoaDialog.app/Contents/Resources/info.icns --title "News" --text ''



Further information:

- CocoaDialog Documentation
- CocoaDialog Examples
- growlnotify
- Pashua
- man automator

Progress indicator snippet for man find


find -x "$HOME" -type f -print0 2>/dev/null | while read -d $'\0' filename; do 
   if [[ ${#filename} -lt 85 ]]; then
      echo -en "\r\e[0K$(echo -e "$filename" | tr -d '\n\r')"; 
   else
      echo -en "\r\e[0K$(echo -e "$filename" | tr -d '\n\r' | sed -En 's/^(.{40}).*(.{40})$/\1.....\2/p')"; 
   fi
done; echo



find -x "$HOME" -type f -print0 2>/dev/null | while read -d $'\0' filename; do 
   i=$[i+1]
   if [[ ${#filename} -lt 85 ]]; then
      echo -en "\r\e[0K\e[1;32m$i\e[0m $(echo -e "$filename" | tr -d '\n\r')"; 
   else
      echo -en "\r\e[0K\e[1;32m$i\e[0m $(echo -e "$filename" | tr -d '\n\r' | sed -En 's/^(.{40}).*(.{40})$/\1.....\2/p')"; 
   fi
done; echo

shell : remove last char of a string


#!/bin/bash

function removeLastChar {

        s=$1
        stringLength=${#s}
        echo ${s:0:$stringLength-1}
        return
}

echo $(removeLastChar $1)

Create & delete user accounts from the command line on Mac OS X

The following two Bash scripts will interactively prompt for user input to create or delete user accounts on Mac OS X 10.4.11. Use them at your own risk!

1. Create a user account

#!/bin/bash

# cf. Adding a User From the Command Line,
# http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/additionalfeatures/chapter_10_section_9.html

if [[ "$(/usr/bin/whoami)" != "root" ]]; then echo -e "\nMust be run as root!\n"; exit 1; fi

OPATH=$PATH
export PATH=/usr/bin:/usr/sbin:/bin:/sbin

OIFS=$IFS
export IFS=$' \t\n'

echo -en "\e[1mEnter first name\e[m: "
read firstname

# no spaces in names
if [[ -z "$(echo "$firstname" | /usr/bin/grep -Eo "^[^[:space:]]+$")" ]]; then
   echo -e "Don't use spaces! \nPlease, try again!"
   exit 1
fi

# make sure the user name is unique
new_user="$(/usr/bin/dscl . -search /Users name "$firstname" 2>/dev/null)"

if [[ -z "$new_user" ]]; then
  new_user="$firstname"               
else
  echo -e "\nUser name already exists: $firstname \nPlease, modify your name and try it again!\n"
  exit 1
fi 


# make sure the user's primary group name is unique 
# note: the user's primary group name is also based on the first name!

new_group="$(/usr/bin/dscl . -search /Groups name "$firstname")"

if [[ -z "$new_group" ]]; then
  new_group="$firstname"             
else
  echo -e "The user's primary group name already exists: $firstname! \nPlease, try again!"
  exit 1
fi 


# make sure there is no (file or) home directory of the same name already
if [[ -e "/Users/$new_user" ]]; then
  echo -e "User $new_user already exists at /Users/$new_user! \nPlease, try again!"
  exit 1
fi


# last name

echo -en "\e[1mEnter last name\e[m: "
read lastname

# no spaces in names
if [[ -z "$(echo "$lastname" | /usr/bin/grep -Eo "^[^[:space:]]+$")" ]]; then
   echo -e "Don't use spaces! \nPlease, try again!"
   exit 1
fi


# enter password

echo -en "\e[1mEnter password\e[m: "
stty_orig=$(/bin/stty -g) 
pass=''
blank='false'

while [[ "$blank" != "true" ]]; do

   /bin/stty -icanon -echo

   c=$(/bin/dd bs=6 count=1 2> /dev/null)

   # Check for a CR.
   if [[ -z "$(echo "$c" | /usr/bin/tr -d "\r\n")" ]]; then
      blank='true'
   else
      /bin/stty echo
      echo -n "*"
      pass="$pass$c"
      /bin/stty -echo
   fi
done

/bin/stty icanon echo
/bin/stty "$stty_orig"
passwd1="$pass"
echo


# check minimum password length: 6
if [[ -z "$(echo "$passwd1" | /usr/bin/grep -Eo "^([[:alnum:]]|[[:punct:]]){6,}$")" ]]; then
   echo -e "Use at least 6 characters (alphanumeric, punctuational) for your password! \nPlease, try again!"
   exit 1
fi


# confirm password

echo -en "\e[1mConfirm password\e[m: "
stty_orig=$(/bin/stty -g) 
pass=''
blank='false'

while [[ "$blank" != "true" ]]; do

   /bin/stty -icanon -echo

   c=$(/bin/dd bs=6 count=1 2> /dev/null)

   # Check for a CR.
   if [[ -z "$(echo "$c" | /usr/bin/tr -d "\r\n")" ]]; then
      blank='true'
   else
      /bin/stty echo
      echo -n "*"
      pass="$pass$c"
      /bin/stty -echo
   fi
done

/bin/stty icanon echo
/bin/stty "$stty_orig"
passwd2="$pass"
echo


if [[ "$passwd1" != "$passwd2" ]]; then
   echo -e "\nPasswords do not match. \nPlease, try again!\n"
   exit 1
else
   echo -e "\nPassword confirmation was successful!\n"
fi


# get unique id numbers (for uid, gid) by increasing the highest id number already in use by 1
new_uid=$(($(/usr/bin/dscl . -list /Users uid | /usr/bin/awk '{print $NF;}' | /usr/bin/sort -n | /usr/bin/tail -n 1) + 1))
new_gid=$(($(/usr/bin/dscl . -list /Groups gid | /usr/bin/awk '{print $NF;}' | /usr/bin/sort -n | /usr/bin/tail -n 1) + 1))


# make sure $new_uid and $new_gid are equal
if [[ $new_uid -ne $new_gid ]]; then
   if [[ $new_uid -gt $new_gid ]]; then new_gid="$new_uid"; else new_uid=$new_gid; fi
fi


# check once again ...

if [[ $new_uid -eq $new_gid ]] && [[ "$new_user" == "$firstname" ]] && [[ "$new_group" == "$firstname" ]]; then

# create the user's primary group
sudo /usr/sbin/dseditgroup -o create -r "$firstname $lastname" -i $new_gid "$new_group"
sudo /usr/bin/dscl . -append "/Groups/$new_group" passwd "*"

sudo /usr/bin/dscl . -create "/Users/$new_user"
sudo /usr/bin/dscl . -append "/Users/$new_user" RealName "$firstname $lastname"
sudo /usr/bin/dscl . -append "/Users/$new_user" NFSHomeDirectory "/Users/$new_user"
###sudo /usr/bin/dscl . -append "/Users/$new_user" NFSHomeDirectory "/Local/Users/$new_user"
sudo /usr/bin/dscl . -append "/Users/$new_user" UserShell /bin/bash   
sudo /usr/bin/dscl . -append "/Users/$new_user" PrimaryGroupID $new_gid
sudo /usr/bin/dscl . -append "/Users/$new_user" UniqueID $new_uid
sudo /usr/bin/dscl . -append "/Users/$new_user" hint ""
sudo /usr/bin/dscl . -append "/Users/$new_user" comment "user account \"$firstname $lastname\" created: $(/bin/date)"
sudo /usr/bin/dscl . -append "/Users/$new_user" picture "/Library/User Pictures/Animals/Butterfly.tif"
sudo /usr/bin/dscl . -append "/Users/$new_user" sharedDir Public
sudo /usr/bin/dscl . -passwd "/Users/$new_user" "$passwd1"

# add some other properties that are usually set (Mac OS X 10.4)
sudo /usr/bin/dscl . -append "/Users/$new_user" _shadow_passwd ""
sudo /usr/bin/dscl . -append "/Users/$new_user" _writers_hint "$new_user"
sudo /usr/bin/dscl . -append "/Users/$new_user" _writers_real_name "$new_user"

sudo /usr/bin/dscl . -append "/Groups/$new_group" GroupMembership "$new_user"      # add new user to the user's primary group
#sudo /usr/sbin/dseditgroup -o edit -a "$new_group" -t user "$new_user"

sudo /usr/bin/dscl . -append /Groups/staff GroupMembership "$new_user"             # test: add new user to group staff

# add the new user to the admin group (Mac OS X 10.4)
# This should be part of a separate admin user account shell script or 
# at least require an additional user input prompt at the beginning!
#sudo /usr/bin/dscl . -append /Groups/admin GroupMembership "$new_user"
#sudo /usr/bin/dscl . -append /Groups/appserverusr GroupMembership "$new_user"
#sudo /usr/bin/dscl . -append /Groups/appserveradm GroupMembership "$new_user"

# log out after running the script to see the new user account has been created
sudo /usr/sbin/createhomedir -l -u "$new_user"

else

   echo -e "Configuration of user account: $firstname failed!. \nPlease, try again!"
   exit 1

fi


echo -e "\nUser account:  $firstname  successfully created! \nYou can now log in to your new user account!\n"

export IFS=$OIFS
export PATH=$OPATH

exit 0


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


# test
dscl . list /Users
dscl . -read /Users/<firstname>

dscl . list /Groups
dscl . -read /Groups/<firstname>
dscl . list /Groups GroupMembership



2. Delete a user account


#!/bin/bash

# cf. http://www.macos.utah.edu/documentation/authentication/dscl.html

if [[ "$(/usr/bin/whoami)" != "root" ]]; then echo -e "\nMust be run as root!\n"; exit 1; fi

OPATH=$PATH
export PATH=/usr/bin:/usr/sbin:/bin:/sbin

OIFS=$IFS
export IFS=$' \t\n'

echo -en "\e[1mDelete user account\e[m: "
read user

if [[ -z "$user" ]]; then echo -e "\nNo user specified! Please, try again!\n"; exit 1; fi

# make sure the user exists
usertest="$(/usr/bin/dscl . -search /Users name "$user" 2>/dev/null)"

if [[ -z "$usertest" ]]; then echo -e "\nUser does not exist: $user\n"; exit 1; fi 


# get user's group memberships
groups_of_user="$(/usr/bin/id -Gn $user)"

if [[ $? -eq 0 ]]; then 
   # delete the user's group memberships
   for group in $groups_of_user; do
      sudo /usr/bin/dscl . -delete "/Groups/$group"  GroupMembership "$user"
      #sudo /usr/sbin/dseditgroup -o edit -d "$user" -t user "$group"           
   done
fi


# delete the user's primary group
if [[ -n "$(/usr/bin/dscl . -search /Groups name "$user")" ]]; then
   sudo /usr/sbin/dseditgroup -o delete "$user"
fi


# find the GeneratedUID of the user and remove the password hash file 
# from /private/var/db/shadow/hash/
# sudo ls -a /private/var/db/shadow/hash
# sudo ls -l /private/var/db/shadow/hash/

guid="$(/usr/bin/dscl . -read "/Users/$user" GeneratedUID | /usr/bin/awk '{print $NF;}')"

if [[ -f "/private/var/db/shadow/hash/$guid" ]]; then
   sudo /bin/rm -f /private/var/db/shadow/hash/$guid
fi


# delete the user
sudo /usr/bin/dscl . -delete "/Users/$user"

# make a backup
if [[ -d "/Users/$user" ]]; then
   /usr/bin/ditto -rsrc -c -k "/Users/$user" "/Users/${user}-archive-$(/bin/date).zip"
fi

# remove the user's home directory
if [[ -d "/Users/$user" ]]; then
   sudo /bin/rm -rf "/Users/$user"
fi

export IFS=$OIFS
export PATH=$OPATH

exit 0



Bash password prompt

#!/bin/bash

# cf. Creating password prompts using Bash, http://ubuntuforums.org/showthread.php?t=269592

stty_orig=$(stty -g) 

# Init some stuff...
pass=''
blank='false'

# Main loop executed once for each char typed...
while [[ "$blank" != "true" ]]; do
   stty -icanon -echo
   c=$(dd bs=6 count=1 2> /dev/null)

   # Check for a CR.
   if [ -z "$(echo "$c" | tr -d "\r\n")" ]; then
      blank='true'
   else
      stty echo
      echo -n "*"
      pass="$pass$c"
      stty -echo
   fi
done

stty icanon echo

echo
echo "$pass"

stty "$stty_orig"

exit 0

Save & restore file permissions with xattr

Extended attributes make it possible to store (additional) file metadata on a per-file basis. This can, for example, be used to save & restore file permissions.


mkdir -p ~/Desktop/testdir
touch ~/Desktop/testdir/f{1,2,3}.txt
find -x ~/Desktop/testdir -print0 | xargs -0 stat -LF
stat -x ~/Desktop/testdir/f1.txt

which xattr   # /opt/local/bin/xattr; sudo port install xattr (after installing MacPorts, http://www.macports.org/install.php)


# store file permissions as additional Unix file metadata with xattr

find -x ~/Desktop/testdir -print0 | while read -d $'\0' filename; do
#find -x ~/Desktop/testdir -type f -or -type d -print0 | while read -d $'\0' filename; do
   fchmod="$(stat -f %p "$filename")"; \
   fchown="$(stat -f %u:%g "$filename")"; \
   xattr --set fchmod "$fchmod" "$filename"; \
   xattr --set fchown "$fchown" "$filename"; \
   #echo $fchown $fchmod; \
done


find -x ~/Desktop/testdir -print0 | xargs -0 xattr --list
find -x ~/Desktop/testdir -print0 | xargs -0 stat -LF

# change file permissions & ownership
sudo chown -R root:wheel ~/Desktop/testdir
sudo chmod -R 700 ~/Desktop/testdir

sudo find -x ~/Desktop/testdir -print0 | xargs -0 sudo stat -LF
find -x ~/Desktop/testdir -print0 | xargs -0 xattr --list
sudo find -x ~/Desktop/testdir -print0 | xargs -0 sudo xattr --list


# restore file permissions & ownership

sudo find -x ~/Desktop/testdir -print0 | while read -d $'\0' filename; do 
   fchown="$(sudo xattr --get fchown "$filename" | awk '/fchown/ {print $2}')"; \
   fchmod="$(sudo xattr --get fchmod "$filename" | awk '/fchmod/ {print $2}')"; \
   sudo chown "$fchown" "$filename"; \
   sudo chmod "$fchmod" "$filename"; \
   #echo $fchown $fchmod; \
done


find -x ~/Desktop/testdir -print0 | xargs -0 stat -LF
find -x ~/Desktop/testdir -print0 | xargs -0 xattr --list


Convert chmod file permissions between octal & symbolic notation


# convert from octal to symbolic format

function o2s () { touch ~/.octal2symbolic; chmod -vv "$@" $_;  ls -l $_ | awk '{print $1}'; rm -f ~/.octal2symbolic; }
#function o2s () { touch ~/.octal2symbolic; chmod "$@" $_;  ls -l $_ | awk '{print $1}'; rm -f ~/.octal2symbolic; }

o2s 755
o2s 644
o2s 1744
o2s 0100751      # cf. man 2 stat (st_mode)
o2s 0101751


# Cf. Bash 'umask' builtin doesn't set 'x' permissions?
# http://archives.devshed.com/forums/unix-linux-135/bash-umask-builtin-doesn-t-set-x-permissions-372356.html

UMASKO=$(umask)   # 0022

help umask
umask
umask -p
umask -S

umask 0077
umask
umask -S
o2s 755

umask 0000
umask
umask -S
o2s 654

umask $UMASKO



# convert from symbolic to octal format
# default file permissions of temporary file: chmod 777 ~/.symbolic2octal

function s2o () { touch ~/.symbolic2octal; chmod 777 $_; chmod "$@" $_;  stat -f %p $_; rm -f ~/.symbolic2octal; }

s2o a-x
s2o u=rwx,g=rx,o=x
s2o u=rwx,g=rx,o=x,+t

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; 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)

      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
   /opt/local/sbin/clamd RELOAD
   /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 1

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:

- 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

Tweak your BASH startup files

Depending on whether the BASH shell is started as a login shell or a non-login shell, different BASH startup files are going to be run (see the references below and the Invocation section of man bash for more detailed information). To make sure your customized BASH shell works the way it should you can source /private/etc/bashrc from /private/etc/profile and ~/.bashrc from ~/.bash_login (or alternatives):


# BASH startup files

/private/etc/profile      # login shell
~/.bash_profile
~/.bash_login
~/.profile

/private/etc/bashrc      # non-login shell
~/.bashrc


# list your BASH startup files
ls -a ~ | grep \.bash
ls /private/etc | grep -E "bash|profile"

# backup the existing BASH startup files
sudo cp -p /private/etc/profile /private/etc/profile.orig
sudo cp -p /private/etc/bashrc /private/etc/bashrc.orig
cp -p ~/.bash_profile ~/.bash_profile.orig
cp -p ~/.bash_login ~/.bash_login.orig
cp -p ~/.profile ~/.profile.orig
cp -p ~/.bashrc ~/.bashrc.orig


# /private/etc/profile should contain: 
# if [[ -f /private/etc/bashrc ]]; then source /private/etc/bashrc; fi 

sudo sh -c 'echo "if [[ -f /private/etc/bashrc ]]; then source /private/etc/bashrc; fi" >> /private/etc/profile'
sudo nano /private/etc/profile


# ~/.bash_profile or ~/.bash_login or ~/.profile should contain: 
# if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi 

echo 'if [[ -f ~/.bashrc ]]; then source ~/.bashrc; fi' >> ~/.bash_login
nano ~/.bash_login


# then add a simple 'echo' command to the existing BASH startup files
sudo sh -c 'echo "echo \"... running /private/etc/profile ...\"" >> /private/etc/profile'
sudo sh -c 'echo "echo \"... running /private/etc/bashrc ...\"" >> /private/etc/bashrc'
echo 'echo "... running ~/.bash_profile ..."' >> ~/.bash_profile
echo 'echo "... running ~/.bash_login ..."' >> ~/.bash_login
echo 'echo "... running ~/.profile ..."' >> ~/.profile
echo 'echo "... running ~/.bashrc ..."' >> ~/.bashrc

# check added lines
sudo nano /private/etc/profile
sudo nano /private/etc/bashrc
nano ~/.bash_profile
nano ~/.bash_login
nano ~/.profile
nano ~/.bashrc

exit

# now relaunch Terminal.app and play around with ...
bash
echo $SHLVL
exec bash
echo $SHLVL
exec bash -$-
exec env -i /bin/bash
exec bash --login
exec bash -l
echo $0
echo $BASH_ENV
exec bash -norc
bash
bash --init-file file
bash --rcfile file
open-x11 xterm
ssh some_other_user@internal_IP_address     # cf. http://textsnippets.com/posts/show/1326
...


Further information:

- Controlling Bash At Startup
- Make X11 Xterm Launch Login Shells
- Initialisation Scripts
- Difference between .bashrc and .bash_profile
- Fun and profit by modifying your Bash startup files in OS X, Linux, and other fine unices
- bash shell aliases
- A Sample .bashrc File
- Theming Bash
- .bash_profile
- .bashrc

Local SOCKS Proxy for Safari

Surfing the web with Safari (3.0.4) on Mac OS X 10.4 can be made a bit more private & secure by setting up a local SOCKS Proxy on an admin user account.
Use the following BASH command-line instructions at your own risk!

I. Setting up a local SOCKS proxy for Safari on a single admin user account


# first enable remote login on your admin user account: System Preferences > Sharing > Services > Remote Login

# test if remote login is enabled
sudo launchctl list | grep com.openssh.sshd                               # com.openssh.sshd
defaults read /System/Library/LaunchDaemons/ssh
netstat -an | awk '/\*\.22[[:space:]]+.*LISTEN$/ {print}'                 # tcp4 ... *.22 ... LISTEN
service --test-if-available ssh; echo $?                                  # 0
service --test-if-configured-on ssh; echo $?                              # 0

# test if sshd daemon supports tcp_wrappers
# cf. http://www.la-samhna.de/library/brutessh.html#5
otool -L /usr/sbin/sshd | grep libwrap                                      

# then make sure you are connected to the internet
ping -c 10 checkip.dyndns.org
curl -L -s --max-time 10 http://checkip.dyndns.org | grep -Eo -m 1 '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}'   


# then set up the local SOCKS Proxy
# cf. http://macapper.com/2007/05/22/advanced-os-x-secure-tunneling-via-ssh

#ssh -q -D 8080 -f -C -N -x $(whoami)@$(ipconfig getifaddr $(route -n get default | awk '/interface:/ { print $2 }') 2>/dev/null)
#ssh -v -D 8080 -f -C -N -x $(whoami)@$(ipconfig getifaddr $(route -n get default | awk '/interface:/ { print $2 }') 2>/dev/null) 

ssh -q -D 8080 -f -C -N -x $(whoami)@127.0.0.1     # cf. AllowUsers $(whoami)@127.0.0.1 below

# ... enter your user account login password


# SSH Without a Password
# http://www.csua.berkeley.edu/~ranga/notes/ssh_nopass.html
# http://homepage.mac.com/kelleherk/iblog/C1901548470/E20061128145420/index.html

# RSA
mkdir -p $HOME/.ssh
chmod -R 0700 $HOME/.ssh
ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -P ''
cp -p $HOME/.ssh/id_rsa.pub $HOME/.ssh/authorized_keys2
chmod 0600 $HOME/.ssh/authorized_keys2
srm -v $HOME/.ssh/id_rsa.pub
#ls -ld $HOME/.ssh
#ls -l $HOME/.ssh/authorized_keys2

# encrypt the known_hosts file
ssh-keygen -H -f $HOME/.ssh/known_hosts 
srm -v $HOME/.ssh/known_hosts.old
chmod 0600 $HOME/.ssh/known_hosts


# securing SSH
# See:
# - man sshd_config
# - sudo nano /private/etc/sshd_config
# - http://switch.richard5.net/2006/09/24/securing-your-ssh-access/ 
# - http://www.mactech.com/articles/mactech/Vol.21/21.02/Security/index.html
# - Mac OS X Security Configuration Guides at http://www.apple.com/server/documentation/

sudo sh -c "
echo '
# added
Protocol 2
PermitRootLogin no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
PubkeyAuthentication yes
AuthorizedKeysFile $HOME/.ssh/authorized_keys2
#KeepAlive yes
MaxAuthTries 3
LoginGraceTime 40
LogLevel INFO     # QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG
#AllowUsers $(whoami)      # add more users if you like: ~  (in Terminal.app) or dscl . -list /Users
AllowUsers $(whoami)@127.0.0.1      # cf. ssh -q -D 8080 -f -C -N -x $(whoami)@127.0.0.1 above
#AllowUsers $(whoami)@$(ipconfig getifaddr $(route -n get default | awk '/interface:/ { print $2 }') 2>/dev/null)   # requires internet connection
#AllowGroups sshusersgroup     # cf. dscl . -list /Groups; groups
' >> /private/etc/sshd_config
"


# then open Safari ...

open -a Safari

# ... and go to:
# Safari > Preferences ... > Advanced > Proxies: Change Settings ... 
# > Select a proxy server to configure: SOCKS Proxy > SOCKS Proxy Server: 127.0.0.1 : 8080 > Apply Now


sudo reboot       # ... or just restart: System Preferences > Sharing > Services > Remote Login

ssh -q -D 8080 -f -C -N -x $(whoami)@127.0.0.1      # should now work without password; cf. man ssh_config for configuring SSH shortcuts


# check local SOCKS Proxy setup

scutil --proxy                   # SOCKSProxy : 127.0.0.1, SOCKSEnable : 1, SOCKSPort : 8080

sudo ln -s "/Applications/Utilities/Network Utility.app/Contents/Resources/stroke" /bin/portscan
portscan localhost 8000 8100     # Open TCP Port:  8080  http-alt

lsof -i :22 -P
lsof -i :8080 -P
lsof -i TCP -P
lsof -U -P             # list UNIX domain socket files
sudo lsof -U -P
netstat -n -f inet


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


# now you can, for example, test if a website can discover your real internal IP address provided your computer
# is behind a DSL router and you have a firewall running (cf. http://textsnippets.com/posts/show/1267)
# cf. http://www.auditmypc.com/internal-ip.html

# first get your internal IP address
ipconfig getifaddr $(route -n get default | awk '/interface:/ { print $2 }')

# note: to run the 'real IP' test you first have to enable Plug-ins, Java & JavaScript in Safari
# Safari > Preferences ... > Security > Enable plug-ins & Enable Java & Enable JavaScript

open -a Safari http://www.auditmypc.com/software_audit.asp



II. Setting up a local SOCKS proxy for Safari using two different user accounts on the same computer


# The following BASH command-line instructions assume you have a regular user account 
# and an admin user account on the same computer!

# First, log in to the regular user account 
regular_user_name="$(whoami)"
regular_user_path="$HOME"
echo $regular_user_name $regular_user_path    

# note down the output from the echo command
# log out from the regular user account

# Then log in to the admin account for the following instructions!

# first make sure you are connected to the internet
ping -c 10 checkip.dyndns.org
curl -L -s --max-time 10 http://checkip.dyndns.org | grep -Eo -m 1 '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}'   

# get internal IP address & set regular user account information
regular_user_name="...insert information from regular user account above..."
regular_user_path="...insert information from regular user account above..."
internal_IP_address=$(ipconfig getifaddr $(route -n get default | awk '/interface:/ { print $2 }'))
echo $internal_IP_address $regular_user_name $regular_user_path

# enable remote login: System Preferences > Sharing > Services > Remote Login

# test if remote login is enabled
service --test-if-available ssh; echo $?               # 0
service --test-if-configured-on ssh; echo $?           # 0


# SSH Without a Password

# admin user account
# RSA
mkdir -p $HOME/.ssh
chmod -R 0700 $HOME/.ssh
ssh-keygen -t rsa -f $HOME/.ssh/id_rsa -P ''
cp -p $HOME/.ssh/id_rsa.pub $HOME/.ssh/authorized_keys2
chmod 0600 $HOME/.ssh/authorized_keys2
srm -v $HOME/.ssh/id_rsa.pub
ls -ld $HOME/.ssh
ls -l $HOME/.ssh

# regular user account
sudo mkdir -p $regular_user_path/.ssh
sudo chmod -R 0700 $regular_user_path/.ssh
sudo cp $HOME/.ssh/authorized_keys2 $regular_user_path/.ssh/authorized_keys2
#scp ~/.ssh/authorized_keys2 $regular_user_name@$internal_IP_address:~/.ssh/authorized_keys2
sudo chown -R $regular_user_name:$regular_user_name $regular_user_path/.ssh
sudo chmod 0600 $regular_user_path/.ssh/authorized_keys2
sudo ls -l $regular_user_path/.ssh
sudo ls -ld $regular_user_path/.ssh

# delete all files in ~/.ssh on both user accounts
#sudo find $regular_user_path/.ssh -type f -exec srm -fv "{}" \;
#find $HOME/.ssh -type f -exec srm -fv "{}" \;


# log in to regular user account via SSH
# enter admin account login password if prompted
ssh -i $HOME/.ssh/id_rsa $regular_user_name@$internal_IP_address     
exit

# encrypt the known_hosts file
ssh-keygen -H -f $HOME/.ssh/known_hosts       
srm -v $HOME/.ssh/known_hosts.old
chmod 0600 $HOME/.ssh/known_hosts

ssh -i $HOME/.ssh/id_rsa $regular_user_name@$internal_IP_address    # test
ls 
exit


# securing SSH
# man sshd_config
# sudo nano /private/etc/sshd_config

sudo sh -c "
echo '
# added
Protocol 2
PermitRootLogin no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
PubkeyAuthentication yes
#AuthorizedKeysFile $regular_user_path/.ssh/authorized_keys2
#KeepAlive yes
MaxAuthTries 3
#PermitUserEnvironment yes     # requires ~/.ssh/environment file; see man ssh and man sshd_config
LoginGraceTime 40
LogLevel INFO     # QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG
#AllowUsers $(whoami) $regular_user_name
AllowUsers $(whoami)@$internal_IP_address $regular_user_name@$internal_IP_address
' >> /private/etc/sshd_config
"


# set up the local SOCKS Proxy
# enter admin account login password if prompted
ssh -q -D 8080 -f -C -N -x $regular_user_name@$internal_IP_address    

open -a Safari

# Safari > Preferences ... > Advanced > Proxies: Change Settings ... 
# > Select a proxy server to configure: SOCKS Proxy > SOCKS Proxy Server: 127.0.0.1 : 8080 > Apply Now

# restart sshd: System Preferences > Sharing > Services > Remote Login

# check local SOCKS Proxy setup
scutil --proxy                    # SOCKSProxy : 127.0.0.1, SOCKSEnable : 1, SOCKSPort : 8080
portscan localhost 8000 8100      # Open TCP Port:  8080  http-alt

ssh -p 22 $regular_user_name@$internal_IP_address ls
ssh -l $regular_user_name $internal_IP_address 'echo hello world; whoami; hostname; logname'

# test privacy of internal IP address
open -a Safari http://www.auditmypc.com/software_audit.asp



Further information on SSH & Mac OS X:

- Getting started with SSH
- Remote Login With SSH
- SSH Without A Password
- Exit Your SSH Session Without Killing Your Job
- SSH on Mac OS X
- SSH
- ssh tunnelling
- ssh X forwarding debugging
- Tutorial: SSH To Alternate Ports and Enabling Multiple SSH Daemons
- Route All Your Internet Traffic Through a Proxy
- SSH Notes
- SSH Host Key Protection
- Setup the SSH server to use keys for authentication
- Auto-closing SSH tunnels
- SSH Tunnelling (Port Forwarding)
- Defending against brute force ssh attacks
- SSH + Screen = Easy Administration
- SSH SOCKS Proxy From Behind a Gateway
- nylon - flexible Unix proxy server with mirror mode; sudo port install nylon
- tsocks - transparent SOCKS proxying library; sudo port install tsocks

portscan


# first create a symbolic link
sudo ln -s "/Applications/Utilities/Network Utility.app/Contents/Resources/stroke" /bin/portscan

# usage: portscan address startPort endPort

portscan localhost 1 5000

portscan $(/usr/sbin/ipconfig getifaddr en0 2>/dev/null || /bin/echo localhost) 1 10000

Show all files in Finder


# just put them into your ~/.bash_login
# and then: source ~/.bash_login 

function showall() { 
   /usr/bin/defaults write com.apple.finder AppleShowAllFiles TRUE
   /bin/sleep 1
   /usr/bin/killall Finder
   return 0
}     


function shownall() { 
   /usr/bin/defaults write com.apple.finder AppleShowAllFiles FALSE
   /bin/sleep 1
   /usr/bin/killall Finder
   return 0
}     

Use md5 to generate website passwords

Use the following command in your shell to generate unique passwords for websites based on a master password. md5 generates a hash of the text string 'SECRET:domain.tld'. awk and cut retrieve first 10 characters of said hash. 'SECRET' would be your master password. 'domain.tld' would be the site in question (eg, textsnippets.com).

/sbin/md5 -s 'SECRET:domain.tld' | awk '{print $4}' | cut -c 1-10

pdftotext


# pdftotext is a command line program that converts PDF files into text files
# first get the pdftotext installer package from http://www.bluem.net/downloads/pdftotext_en/
# pdftotext code written by Glyph & Cog, LLC: http://www.glyphandcog.com/Xpdf.html

which pdftotext     # /usr/local/bin/pdftotext

pdftotext -h
pdftotext example.pdf
pdftotext example.pdf example.txt
pdftotext example.pdf -
pdftotext -layout -eol unix -enc UTF-8 /path/to/file.pdf /path/to/file.txt


Delete WebKit search fields


# defaults read com.apple.Safari | grep -i com.apple.WebKit.searchField:
# open $HOME/Library/Preferences/com.apple.Safari.plist
# put the following function into ~/.bash_login

function dws() { 

if [[ ! -e "$HOME/Library/Preferences/com.apple.Safari.plist" ]]; then
   echo "There is no com.apple.Safari.plist file in $HOME/Library/Preferences!"
   return 1
fi

defaults read com.apple.Safari | sed -En -e "s/^[[:space:]]*\"(com.apple.WebKit.searchField:.*)\" = .*$/\1/p" | while read item; do 
   #echo "$item"
   defaults delete com.apple.Safari "$item" 2>/dev/null
done

return 0

}     


backup files

// create backup copy

#!/bin/bash

filename=$1
date=`date +%Y%m%d`

usage () {
        echo "Usage: `basename $0` filename"
}

if [ -z "$filename" -a ! -f "$filename" ]; then
        usage
        exit 1
fi

rev=0
backup="$filename.$date.$rev"

while [ -f $backup ]; do
        let rev+=1
        backup="$filename.$date.$rev"
done

cp $filename $backup
exit $?

Compressing a directory with rar on Linux

I've been struggling to get this to work for so long that when I finally got it going I had to throw it up here so I wouldn't lose it.
rar a -m5 -R output.rar /etc/

This will create a max compression (not taking into account dictionary sizes and the like) archive of the entire etc directory.

Switching firewall settings from the command line

Provided that you have specified different firewalls in /usr/local/sbin/ (based on customized versions of a basic IPFW ruleset) you can easily switch between different firewall settings from the command line.

First create the different firewall settings & files:
# find /usr/local/sbin -name "*firewall"

/usr/local/sbin/rc.firewall         # default firewall setting
/usr/local/sbin/rc-ftp.firewall     # FTP firewall setting (enable FTP rules)
/usr/local/sbin/rc-ssh.firewall     # SSH firewall setting (enable SSH rules)
/usr/local/sbin/rc-SL.firewall      # Second Life firewall setting (enable Second Life rules)
/usr/local/sbin/rc-r.firewall       # restrictive firewall setting, cf. http://prefetch.net/blog/index.php/2006/08/13/locking-down-the-os-x-firewall/


Then:
# $ cat $HOME/.bash_login

function fwdef() { /usr/bin/sudo  /usr/local/sbin/rc.firewall; }     
function fwftp() { /usr/bin/sudo  /usr/local/sbin/rc-ftp.firewall; } 
function fwssh() { /usr/bin/sudo  /usr/local/sbin/rc-ssh.firewall; } 
function fwsl() { /usr/bin/sudo  /usr/local/sbin/rc-SL.firewall; }   
function fwr() { /usr/bin/sudo  /usr/local/sbin/rc-r.firewall; }     

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

# in Terminal.app

source $HOME/.bash_login 
fwdef
fwftp
fwssh
fwsl
fwr

snippet

Download code snippets (http://textsnippets.com) from the command line and convert them to text files using man textutil (on Mac OS X 10.4).

Usage:
snippet 345
snippet 1268
snippet 1281



# $ cat $HOME/.bash_login

function snippet() {
   mkdir -p $HOME/Desktop/Snippets
   OPWD="$PWD"
   cd $HOME/Desktop/Snippets
   curl -L -O -s --max-time 25 http://textsnippets.com/posts/show/"$1" || exit 1
   file="$HOME/Desktop/Snippets/$(basename $_)"
   textutil -convert txt "$file"
   rm "$file"
   new_file="$file.txt"
   sed -i "" -e '1,5d' -e 's/.See related posts.//' "$new_file"  # delete first 5 lines of file
   sed -i "" -e :a -e '1,6!{P;N;D;};N;ba' "$new_file"            # delete last 6 lines of file
   cd "$OPWD"
   return 0
}


ws - web search from the command line

Author: jv
License: The MIT License, Copyright (c) 2007 jv
Description: search the web from the command line; an example of using cmdparser
Platform: Mac OS X 10.4.11
Requirements: set the character set encoding of Terminal.app to UTF-8; sudo port install libidn (after installing MacPorts)

Usage:
ws -h
ws daily quote
ws -y -p "daily news" sports football
ws -gm California
ws -p "wildlife vacation" India travel visit tiger leopard
ws -t 'Australia holiday vacation ocean desert'
ws -w http://en.wikipedia.org -p "keep it simple"
ws -wp -p "keep it simple"
ws -w en.wikipedia.org -t Africa wildlife
echo "Canada wildlife" | ws -y -w en.wikipedia.org -


Installation:
sudo mkdir -p /usr/local/bin
sudo touch /usr/local/bin/ws
sudo chmod 0755 /usr/local/bin/ws
sudo chown root:wheel /usr/local /usr/local/bin /usr/local/bin/ws
sudo nano /usr/local/bin/ws



# $ sudo cat /usr/local/bin/ws

#!/bin/bash

OPATH=$PATH
export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin

OIFS=$IFS
export IFS=$' \t\n'

declare search="" sed="/usr/bin/sed" open="/usr/bin/open" grep="/usr/bin/grep"

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

# URL encoding
# convert special (UTF-8 encoded) input characters into hexadecimal URL-encoding form 
# For further conversions see:
# http://www.w3schools.com/tags/ref_urlencode.asp (HTML URL-encoding Reference)
# http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
# http://en.wikipedia.org/wiki/Percent-encoding

function url_encoding() {

echo -e "$('s/%/%25/g' -e 's/ /%20/g' -e 's/"/%22/g' -e 's/#/%23/g' \
-e 's/&/%26/g' -e 's//%3E/g' -e 's/{/%7B/g' -e 's/}/%7D/g' -e 's/\|/%7C/g' \
-e 's/\\/%5C/g' -e 's/\^/%5E/g' -e 's/\~/%7E/g' -e 's/\[/%5B/g' -e 's/\]/%5D/g' -e 's/\`/%60/g' \
-e s/$'\342\202\254'/%80/g -e s/$'\303\274'/%FC/g -e s/$'\302\243'/%A3/g -e s/$'\303\266'/%F6/g \
-e s/$'\303\251'/%E9/g -e s/$'\303\244'/%E4/g -e s/$'\303\204'/%C4/g -e s/$'\303\226'/%D6/g \
-e s/$'\303\234'/%DC/g -e s/$'\303\237'/%DF/g -e s/$'\303\240'/%E0/g -e s/$'\303\241'/%E1/g \
-e s/$'\303\242'/%E2/g -e s/$'\303\247'/%E7/g -e s/$'\303\250'/%E8/g -e s/$'\303\252'/%EA/g \
-e s/$'\303\253'/%EB/g -e s/$'\303\254'/%EC/g -e s/$'\303\255'/%ED/g -e s/$'\303\256'/%EE/g \
-e s/$'\303\257'/%EF/g -e s/$'\303\200'/%C0/g -e s/$'\303\201'/%C1/g -e s/$'\303\202'/%C2/g \
-e s/$'\303\207'/%C7/g -e s/$'\303\210'/%C8/g -e s/$'\303\211'/%C9/g -e s/$'\303\212'/%CA/g \
-e s/$'\303\213'/%CB/g -e s/$'\303\214'/%CC/g -e s/$'\303\215'/%CD/g -e s/$'\303\216'/%CE/g \
-e s/$'\303\217'/%CF/g -e s/$'\303\277'/%BF/g -e s/$'\303\203'/%C3/g -e s/$'\303\205'/%C5/g \
-e s/$'\303\206'/%C6/g -e s/$'\303\220'/%D0/g -e s/$'\303\221'/%D1/g -e s/$'\303\245'/%E5/g \
-e s/$'\303\246'/%E6/g -e s/$'\303\261'/%F1/g -e s/$'\303\262'/%F2/g -e s/$'\303\263'/%F3/g \
-e s/$'\303\264'/%F4/g -e s/$'\303\265'/%F5/g -e s/$'\303\267'/%F7/g -e s/$'\303\270'/%F8/g \
-e s/$'\303\271'/%F9/g -e s/$'\303\272'/%FA/g -e s/$'\303\273'/%FB/g -e s/$'\303\275'/%FD/g \
-e s/$'\303\276'/%FE/g -e s/$'\303\277'/%FF/g -e s/$'\303\235'/%DD/g -e s/$'\303\236'/%DE/g \
-e s/$'\305\241'/%9A/g -e s/$'\305\223'/%9C/g -e s/$'\305\276'/%9E/g -e s/$'\305\270'/%9F/g \
-e s/$'\302\265'/%B5/g -e s/$'\305\275'/%8E/g -e s/$'\305\240'/%8C/g -e s/$'\302\241'/%A1/g \
-e s/$'\302\242'/%A2/g -e s/$'\302\245'/%A5/g -e s/$'\303\243'/%E3/g -e s/$'\303\260'/%F0/g \
-e s/$'\303\222'/%D2/g -e s/$'\303\223'/%D3/g -e s/$'\303\224'/%D4/g -e s/$'\303\225'/%D5/g \
-e s/$'\303\230'/%D8/g -e s/$'\303\223'/%D9/g -e s/$'\303\232'/%DA/g -e s/$'\303\233'/%DB/g

}


# check if character set encoding of Terminal.app is set to UTF-8
if [[ "$(/usr/bin/defaults read com.apple.Terminal StringEncoding)" != "4" ]]; then 
   echo "Terminal.app does not use UTF-8 character set encoding!"
   exit 1
fi

# check if libidn is available (optional here; see the same libidn check below)
# http://www.gnu.org/software/libidn/
# http://en.wikipedia.org/wiki/Punycode
# http://en.wikipedia.org/wiki/Internationalized_domain_name

#if [[ ! -e "/opt/local/bin/idn" ]]; then 
#   echo $'You do not have libidn installed at: /opt/local/bin/idn\nPlease install it via MacPorts!\nSee: http://www.macports.org/install.php'
#   exit 1
#fi



#################################################    BEGINNING OF CMDPARSER


# define the names of flags as a regular expression
# flags are command line options that require arguments

# p: phrase
# t: terms
# w: website

flags="(p|t|w)"


# define the names of switches as a regular expression
# switches are command line options that do not take arguments
# make sure multi-char switches precede single-char switches in the regular expression
# note that the regular expression contains neither the special read-from-stdin switch "-" nor the special end-of-options switch "--"

# gm: Google Maps
# h: help
# wp: Wikipedia
# y: Yahoo


switches="(gm|wp|h|y)"

names_of_switches="gm h wp y"

usage="usage: $(/usr/bin/basename "$0") [-h] [-y] [-gm] [-wp] [-p \"a phrase\"] [-w website ] [-t term] [term1 term2 ...]"

declare p s t                            # flags
declare -i gm=0 h=0 wp=0 y=0             # switches

declare optstr flagvar argvar argvar_escaped pipedstr piped
declare -i optid pipedvar pipedvar2

# piped="piped" will be used for variable creation 
# example: piped="piped"; piped2="piped"; pipedstr="piped arg"; eval $piped='"$(echo "$pipedstr")"'; echo "$piped"

piped="piped"

# default value is set to "no pipe"
pipedvar=0
pipedvar2=0

# if /dev/stdin has a size greater than zero ...
if [[ -s /dev/stdin ]]; then pipedstr="$("; else pipedstr=""; fi 

if [[ $# -eq 0 ]] && [[ -z "$pipedstr" ]]; then
  echo "No arguments specified!"
  echo "$usage"
  exit 1
fi 

if [[ $# -eq 0 ]] && [[ -n "$pipedstr" ]]; then
  eval $piped='"$(echo "$pipedstr")"'  
  pipedvar=1
  pipedvar2=1
fi 

# if there are command line arguments ...
if [[ $pipedvar -eq 0 ]] ; then

   optstr=" "  
   optid=0

   while [[ -n "$optstr" ]]; do     

      optstr="$(echo "$1" | $grep -E "^\-\-?$flags$")"
      if [[ -n "$optstr" ]]; then optid=1; fi
      if [[ -z "$optstr" ]]; then optid=2; optstr="$(echo "$1" | $grep -E "^\-\-?$switches$")"; fi
      if [[ -z "$optstr" ]]; then optid=3; optstr="$(echo "$1" | $grep -E "^\-\-?$switches+$")"; fi
      if [[ -z "$optstr" ]]; then optid=4; optstr="$(echo "$1" | $grep -E "^(\-\-?$flags\=.*|\-\-?$flags[^ ]+)$")"; fi
      if [[ -z "$optstr" ]]; then  
         if [[ "$1" = "-" ]] && [[ "$@" = "-" ]]; then  
            optid=5
            optstr="-" 
         fi
      fi

      if [[ -z "$optstr" ]] && ( [[ -n "$(echo "$@" |  $grep -Eo "(^ *| )\-\-?$flags" )" ]] || [[ -n "$(echo "$@" |  $grep -Eo "(^ *| )\-\-?$switches" )" ]] ); then
         optstr="$(echo $1)"
         echo "illegal option removed: $optstr"
         shift
         continue
         #optstr=" "
         #echo "$usage"
         #exit 1
      fi 

      if [[ "$1" = "--" ]]; then shift; break; fi      # -- marks end of options
      if [[ -z "$optstr" ]]; then break; fi

      # flag followed by space (example: -f file)
      if [[ $optid -eq 1 ]]; then 

         if [[ -z "$2" ]]; then
            echo; echo "flag \"$1\" removed: no argument given!"
            shift
            if [[ -n "$(echo "$@")" ]]; then shift; continue; else shift; break; fi
            #echo "$usage"
            #exit 1
         fi 

         # make sure flag $1 is not directly followed by yet another flag or switch
         if [[ "$2" = "-" ]] || [[ "$2" = "--" ]] || [[ -n "$(echo "$2" |  $grep -E "^\-\-?$flags.*$" )" ]] || [[ -n "$(echo "$2" |  $grep -E "^\-\-?$switches+$" )" ]]; then
            echo; echo "flag \"$1\" removed because of illegal argument: \"$2\""
            shift
            continue
            #echo "$usage"
            #exit 1
         fi

         flagvar="$(/bin/expr "$1" : "^\-\{1,2\}\(.*\)$")"
         argvar="$2"
         eval $flagvar='"$(echo "$argvar")"'
         shift 2
         continue

      # single switch (example: -a)
      elif [[ $optid -eq 2 ]]; then
         flagvar="$(/bin/expr "$1" : "^\-\{1,2\}\(.*\)$")"
         eval $flagvar='"$(echo "1")"'
         shift
         continue
  
      # combined switch (example: -abcc)
      elif [[ $optid -eq 3 ]]; then
         flagvar="$(/bin/expr "$1" : "^\-\{1,2\}\(.*\)$")"
         while [[ -n "$flagvar" ]]; do
            char="$(echo "$flagvar" | $sed -E "s/^$switches.*$/\1/")"
            eval $char='"$(echo "1")"'
            flagvar="$(echo "$flagvar" | $sed -E "s/^$switches//")"
         done
         shift
         continue

      # flag without following space (example: -ffile)
      elif [[ $optid -eq 4 ]]; then 
         argvar="$(echo "$1" | $sed -E "s/^\-\-?$flags\=?//")"
         argvar_escaped="$(echo "$argvar" | $sed -E 's/([^[:alnum:]])/\\\1/g')"   # escape special regex metacharacters such as ., ?, *
         #argvar_escaped="$(echo "$argvar" | $sed -E 's/([[:punct:]])/\\\1/g')"     
         #echo "argvar_escaped: $argvar_escaped"
         flagvar="$(echo "$1" | $sed -E -e 's/^-\-?//' -e "s/\=?$argvar_escaped$//")"
         eval $flagvar='"$(echo "$argvar")"'
         shift
         continue

      # the special read-from-stdin switch "-"
      elif [[ $optid -eq 5 ]]; then 
         pipedvar=1
         eval $piped='"$(echo "$pipedstr")"'
         shift
         break
      fi

      shift

   done

fi   # if [[ $pipedvar -eq 0 ]] ; then ...




#################################################    END OF CMDPARSER


if [[ $h -eq 1 ]]; then      #  help message
   echo "$usage"

/bin/cat <<-EOF
Examples:
ws -h
ws daily quote
ws -y -p "daily news" sports football
ws -gm California
ws -p "wildlife vacation" India travel visit tiger leopard
ws -t 'Australia holiday vacation ocean desert'
ws -w http://en.wikipedia.org -p "keep it simple"
ws -wp -p "keep it simple"
ws -w en.wikipedia.org -t Africa wildlife
echo "Canada wildlife" | ws -y -w en.wikipedia.org -
EOF

   exit 0 
fi


# store the contents of $@ in $search
if [[ -n "$@" ]]; then search="$@"; fi

# if there is piped data, $search is set to $pipedstr
if [[ $pipedvar -eq 1 ]]; then search="$piped"; fi 

# if there is piped data without any further flags or switches specified, we just do a Google
if [[ $pipedvar2 -eq 1 ]]; then
   F="$(echo "$search" | url_encoding)"
   $open "http://www.google.com/search?q=$F"
   exit 0
fi

# to open the given URL directly we will store the original URL given by the -w switch in $ow for processing with libidn below
declare ow     

# remove http:// and encode URL
if [[ -n "$w" ]]; then w="$(echo "$w" | $sed -E 's/^( *http:\/\/ *)(.*)$/\2/' )"; ow=$w; w="$(echo "$w" | url_encoding)"; fi 

# If only the -p and/or -t flag is specified or no flags & switches are specified at all we just do a Google.
# If the remaining string stored in $search (which has been $@ above) is not empty and the -p and/or -t flags are specified, 
# the remaining string will be added to the search term(s) or phrase as additional search term(s).

if [[ -z "$w" ]] && [[ $y -eq 0 ]] && [[ $gm -eq 0 ]] && [[ $wp -eq 0 ]]; then 

   if [[ -n "$t" ]] && [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi    # strings in $search will be added as search terms
      F1="$(echo "$t" | url_encoding)"                  # example: ws -p "a phrase" -t "a term" term1 term2 ...
      F2="$(echo "$p" | url_encoding)"
      str='%22'
      F2="$str$F2$str"
      F="$F2%20$F1"
      $open "http://www.google.com/search?q=$F"
      exit 0

   elif [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then            # strings in $search will be added as search terms 
         t="$search"                        
         F1="$(echo "$t" | url_encoding)"
         F2="$(echo "$p" | url_encoding)"
         str='%22'
         F2="$str$F2$str"
         F="$F2%20$F1"
         $open "http://www.google.com/search?q=$F"
         exit 0

      else
         F="$(echo "$p" | url_encoding)"
         str='%22'
         F="$str$F$str"
         $open "http://www.google.com/search?q=$F"
         exit 0
      fi

   elif [[ -n "$t" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi    # strings in $search will be added as search terms 
      F="$(echo "$t" | url_encoding)"
      $open "http://www.google.com/search?q=$F"
      exit 0

   else  
      
      if [[ -z "$search" ]]; then $open "http://www.google.com"; exit 0; fi     # just open the given URL
      F="$(echo "$search" | url_encoding)"
      $open "http://www.google.com/search?q=$F"
      exit 0

   fi

fi


# search a website specified by the -w switch (example: ws -w www.macosxhints.com ...)
if [[ -n "$w" ]] && [[ $y -eq 0 ]]; then 

   if [[ -n "$t" ]] && [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi
      F1="$(echo "$t" | url_encoding)"
      F2="$(echo "$p" | url_encoding)"
      str='%22'
      F2="$str$F2$str"
      F="$F2%20$F1"
      $open "http://www.google.com/search?q=site%3A$w%20$F"
      exit 0

   elif [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then    # strings in $search will be added as search terms
         t="$search"                      
         F1="$(echo "$t" | url_encoding)"
         F2="$(echo "$p" | url_encoding)"
         str='%22'
         F2="$str$F2$str"
         F="$F2%20$F1"
         $open "http://www.google.com/search?q=site%3A$w%20$F"
         exit 0

      else
         F="$(echo "$p" | url_encoding)"
         str='%22'
         F="$str$F$str"
         $open "http://www.google.com/search?q=site%3A$w%20$F"
         exit 0
      fi

   elif [[ -n "$t" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi   
      F="$(echo "$t" | url_encoding)"
      $open "http://www.google.com/search?q=site%3A$w%20$F"
      exit 0

   else

      # if there are no search terms given at all, just open the original URL stored in $ow
      if [[ -z "$search" ]]; then   

         # check if libidn is available
         if [[ ! -e "/opt/local/bin/idn" ]]; then 
            echo $'You do not have libidn installed at: /opt/local/bin/idn\nPlease install it via MacPorts!\nSee: http://www.macports.org/install.php'
            exit 1
         fi

         w="$(echo "$ow" | CHARSET=UTF-8 idn --quiet)"
         $open "http://$w"
         exit 0
      fi

      F="$(echo "$search" | url_encoding)"
      $open "http://www.google.com/search?q=site%3A$w%20$F"
      exit 0

   fi

fi


# Wikipedia
if [[ $wp -eq 1 ]]; then 

   if [[ -n "$t" ]] && [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi
      F1="$(echo "$t" | url_encoding)"
      F2="$(echo "$p" | url_encoding)"
      str='%22'
      F2="$str$F2$str"
      F="$F2%20$F1"
      $open "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=$F&=MediaWiki+search&fulltext=Search"
      exit 0

   elif [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then           
         t="$search"                           # set $t to $search since $t is empty
         F1="$(echo "$t" | url_encoding)"
         F2="$(echo "$p" | url_encoding)"
         str='%22'
         F2="$str$F2$str"
         F="$F2%20$F1"
         $open "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=$F&=MediaWiki+search&fulltext=Search"
         exit 0

      else
         F="$(echo "$p" | url_encoding)"
         str='%22'
         F="$str$F$str"
         $open "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=$F&=MediaWiki+search&fulltext=Search"
         exit 0
      fi

   elif [[ -n "$t" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi   
      F="$(echo "$t" | url_encoding)"
      $open "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=$F&=MediaWiki+search&fulltext=Search"
      exit 0

   else

      if [[ -z "$search" ]]; then $open "http://en.wikipedia.org"; exit 0; fi     # just open the given URL 
      F="$(echo "$search" | url_encoding)"
      $open "http://en.wikipedia.org/w/index.php?title=Special%3ASearch&search=$F&=MediaWiki+search&fulltext=Search"
      exit 0

   fi

fi


# http://www.yahoo.com
if [[ $y -eq 1 ]]; then 

   if [[ -n "$w" ]]; then      # if a website is specified ...

         str="$search"
         if [[ -n "$p" ]]; then str="$str $p"; fi
         if [[ -n "$t" ]]; then str="$str $t"; fi
         F="$(echo "$str" | url_encoding)"
         $open "http://search.yahoo.com/search?p=site%3A$w%20$F"

   elif [[ -n "$t" ]] && [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi
      F1="$(echo "$t" | url_encoding)"
      F2="$(echo "$p" | url_encoding)"
      str='%22'
      F2="$str$F2$str"
      F="$F2%20$F1"
      $open "http://search.yahoo.com/search?p=$F"
      exit 0

   elif [[ -n "$p" ]]; then

      if [[ -n "$search" ]]; then           
         t="$search"                           # set $t to $search since $t is empty
         F1="$(echo "$t" | url_encoding)"
         F2="$(echo "$p" | url_encoding)"
         str='%22'
         F2="$str$F2$str"
         F="$F2%20$F1"
         $open "http://search.yahoo.com/search?p=$F"
         exit 0

      else
         F="$(echo "$p" | url_encoding)"
         str='%22'
         F="$str$F$str"
         $open "http://search.yahoo.com/search?p=$F"
         exit 0
      fi

   elif [[ -n "$t" ]]; then

      if [[ -n "$search" ]]; then t="$t $search"; fi   
      F="$(echo "$t" | url_encoding)"
      $open "http://search.yahoo.com/search?p=$F"
      exit 0

   else

      if [[ -z "$search" ]]; then $open "http://search.yahoo.com"; exit 0; fi    # just open the given URL
      F="$(echo "$search" | url_encoding)"
      $open "http://search.yahoo.com/search?p=$F"
      exit 0

   fi

fi


# Google maps
if [[ $gm -eq 1 ]]; then 
   if [[ -z "$search" ]] && [[ -n "$p" ]] && [[ -n "$t" ]]; then $open "http://maps.google.com"; exit 0; fi    # just open the given URL
   str="$search"
   if [[ -n "$p" ]]; then str="$str $p"; fi
   if [[ -n "$t" ]]; then str="$str $t"; fi
   F="$(echo "$str" | url_encoding)"
   $open "http://maps.google.com/maps?q=$F"
   exit 0
fi


export IFS=$OIFS
export PATH=$OPATH

exit 0

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