SO, I decided to turn my little script that I had written to send myself our local weather forecast into a plugin and post it so other people can use it. This script is a plugin that can be added and maintained via the SAC tools so you can daily email any html document to users or groups. It works by using wget to download the page, store it temporarily, then attach it to an email using mutt. It can work (and has been tested with) a few (2) restricted html pages, several html pages from ftp, and even a few text files from ftp. Also, LOTS and i mean LOTS of general web pages have been done as well. For instance, daily I get a forecast from accuweather.com via this plugin. Secondly, I download several text status & error logs from our ftp servers. And lastly I daily get emails outlining changes in the discover channel's website ( I like watching their videos).
So I know it works....but I still have to say "use at your own risk". So far this hasn't caused any problems whatsoever.
Pay attention to the setup and the notes comments in the script. (Yes, I use bash.... why not!?

Each report is called a "program".... think of it like a newsletter or magazine but you control where it's content comes from. Basically, once installed as a plugin, you can add, delete, list, or run the "programs". I would recommend following the setup exactly. Then, when you run the plugin, select the action from add, del, list, or run. Warning.... if you run it.... it will send email!!!
The only requirements are you have to have wget and mutt..... but seeing as how they are so common (I run fedora 5 with Scalix 11 and used "yum install mutt" to add the mutt program and viola.... oh and wget is almost 99.9% always there on linux... anyway)
that shouldn't be a problem.
Enjoy!
/opt/scalix/daily
Code: Select all
#!/bin/bash
#
# Daily Email Report Scalix Plugin
# Copyright (C) 2007 John A. Mason
#
#
# Requirements:
# wget - command-line tool to retrieve html documents
# mutt - command-line tool to send email with attachments
#
#
# Setup:
#
# 1) Copy this file into (for instance) /opt/scalix/
#
# 2) Set the file as executable. (chmod +x /opt/scalix/daily)
#
# 3) Run sxcfgplugin.py --deploy -l daily -i {instance | all} -u sxadmin
#
# 4) Modify the crontab for the following:
#
# 4a) Either use the direct path for the instance to run every morning
# (ie "30 5 * * 1,2,3,4,5 /var/opt/scalix/##/s/plugin/daily -a run")
# where ## is the instance
#
# 4b) Or use omrealpath to figure it out.
# (ie "30 5 * * 1,2,3,4,5 $(/opt/scalix/bin/omrealpath "~/plugin/daily") -a run"
#
#
# 5) Use the SAC to utilize the plugin. Enjoy!
#
# For more help, use man crontab on parameters for crontab.
#
#
#
# Copyright (C) 2007 John A. Mason
#
######################################################################################3
# NOTES: DO NOT EDIT THIS FILE>...... this file edits itself!!
# - Yes, this is a somewhat security risk... but minimal.
# - Ensure this file can be writable by using a test run. (I use chmod 755)
# - It's either this file edits itself.... or we have to
# do fun stuff with a database to keep the attributes!
# (the manual says you can't add or delete files... so
# let's just edit ourself and we aren't doing that!)
#
######################################################################################3
help() {
echo ""
echo ""
echo "VERSION:"
echo "1.0"
echo ""
echo "NAME:"
echo "Daily Email Report"
echo ""
echo "DESCRIPTION:"
echo ""
echo "Allows for wget to retrieve an HTML page (including images) to send using mutt each day."
echo "For example, go to accuweather.com and lookup your local forecast. Then, copy the url "
echo "and use it to send your local forecast to a new group called weather@your.domain.com!! "
echo "Then your users can receive their local forecast just by their membership in that group!"
echo "PARAMETERS:"
echo "-a Action string single 'add', 'del', 'list', 'run'"
echo "-n Name (No SPACES) string single Unique name for this report __NO SPACES__"
echo "-e Email Address string single Email address to receive report"
echo "-u Target URL string single URL of html page to send"
echo "-s Subject string single Subject line of email"
echo "--help Help \"\" \"\" \"\" Usage Information"
echo ""
echo "OUTPUT:"
echo ""
echo "text/plain"
}
headme() {
tmpstart=$(grep -E -n "#func\) ${name}$" ${myself} | awk -F: '{print $1}')
head -$(echo "${tmpstart} - 1" | bc) ${myself}
}
headme2() {
tmpstart=$(grep -E -n "#call\) ${name}$" ${myself} | awk -F: '{print $1}')
head -$(echo "${tmpstart} - 1" | bc) ${myself}
}
headme3() {
runner=runSystem
tmpstart=$(grep -E -n "#calls\) ${runner}$" ${myself} | awk -F: '{print $1}')
head -$(echo "${tmpstart} - 1" | bc) ${myself}
}
headme4() {
runner=runSystem
tmpstart=$(grep -E -n "#calls\) ${runner}$" ${myself} | awk -F: '{print $1}')
head -$(echo "${tmpstart} + 2" | bc) ${myself}
}
tailme() {
tmplen=$(cat ${myself} | wc -l)
tmpend=$(grep -E -n "#endfunc\) ${name}$" ${myself} | awk -F: '{print $1}')
tmpstart=$(grep -E -n "#func\) ${name}$" ${myself} | awk -F: '{print $1}')
tail -$(echo "${tmplen} - ${tmpstart} - (${tmpend} - ${tmpstart})" | bc) ${myself}
}
tailme2() {
tmplen=$(cat ${myself} | wc -l)
tmpend=$(grep -E -n "#endcall\) ${name}$" ${myself} | awk -F: '{print $1}')
tmpstart=$(grep -E -n "#call\) ${name}$" ${myself} | awk -F: '{print $1}')
tail -$(echo "${tmplen} - ${tmpstart} - (${tmpend} - ${tmpstart})" | bc) ${myself}
}
tailme3() {
runner=runSystem
tmplen=$(cat ${myself} | wc -l)
tmpstart=$(grep -E -n "#calls\) ${runner}$" ${myself} | awk -F: '{print $1}')
tail -$(echo "${tmplen} - ${tmpstart} + 1" | bc) ${myself}
}
tailme4() {
runner=runSystem
tmplen=$(cat ${myself} | wc -l)
tmpstart=$(grep -E -n "#calls\) ${runner}$" ${myself} | awk -F: '{print $1}')
tail -$(echo "${tmplen} - ${tmpstart} - 2" | bc) ${myself}
}
add() {
if [ -z "$name" ] || [ -z "$emailaddress" ] || [ -z "$subject" ] || [ -z "$url" ]; then
echo "Error: Missing parameter. All fields must be present (name, email, subject, url)" 1>&2;
echo "Error: Missing parameter. All fields must be present (name, email, subject, url)";
exit 10
fi
grep -E "^#func\) ${name}$" ${myself} > /dev/null 2>&1
if [ $? -eq 0 ] || [ "${name}" = "runSystem" ]; then
echo "Error: Name already exists. Names must be unique." 1>&2
echo "Error: Name already exists. Names must be unique."
exit 20
fi
echo "$(headme3)
#func) ${name}
${name}() {
NAME=\"${name}\"
SUBJECT=\"${subject}\"
EMAIL=\"${emailaddress}\"
URL=\"${url}\"
wget \"\${URL}\" -o /dev/null -O /tmp/\${NAME}.html
echo \"\" | mutt -s \"\${SUBJECT}\" -a /tmp/\${NAME}.html \${EMAIL}
rm -f /tmp/\${NAME}.html
}
#endfunc) ${name}
$(tailme3)" > ${myself}
echo "$(headme4)
#call) ${name}
${name};
#endcall) ${name}
$(tailme4)" > ${myself}
echo "${name} added successfully."
}
list() {
echo "Current Daily Programs:"
grep -e "^#func)" ${myself} | grep -v "runSystem" | grep -v "\${name}" | awk '{print " "$2}'
echo ""
exit 0
}
del() {
if [ -z "$name" ]; then
echo "Error: Missing parameter. Name is required." 1>&2;
echo "Error: Missing parameter. Name is required.";
exit 10
fi
grep -E "^#func\) ${name}$" ${myself} > /dev/null 2>&1
if [ $? -eq 1 ] || [ "${name}" = "runSystem" ]; then
echo "Error: Name does not exist. Use the list action to see available programs." 1>&2
echo "Error: Name does not exist. Use the list action to see available programs."
exit 40
fi
echo "$(headme)
$(tailme)" > ${myself}
echo "$(headme2)
$(tailme2)" > ${myself}
echo "${name} removed successfully."
}
###########################FUNCTIONS###############################################
#
# To remove a daily option, just delete the function call in the run function.
# You can, but don't have to delete the function itself
#
###################################################################################
#func) Google
Google() {
NAME="Google"
SUBJECT="Your Daily Google Forecast"
EMAIL="sxadmin@mydomain.com"
URL="http://www.google.com"
wget "${URL}" -o /dev/null -O /tmp/${NAME}.html
echo "" | mutt -s "${SUBJECT}" -a /tmp/${NAME}.html ${EMAIL}
rm -f /tmp/${NAME}.html
}
#endfunc) Google
#calls) runSystem
run() {
echo "Running.... be patient...";
#call) Google
Google;
#endcall) Google
echo "Completed...";
}
#
# main script
#
declare myself
declare action
declare name
declare emailaddress
declare subject
declare url
myself=$0
action=""
name=""
subject=""
emailaddress=""
url=""
while [ "$1" != "" ]; do
case "$1" in
--help) help;
exit 0
shift;;
-a) action="$2";
shift;;
-e) emailaddress="$2";
shift;;
-s) subject="$2";
shift;;
-u) url="$2";
shift;;
-n) name="$2";
shift;;
*) echo "Error: Invalid parameter" 1>&2;
echo "Error: Invalid parameter";
help;
exit 10
shift;;
esac
shift
done
case "$action" in
add) add;
exit 0;;
del) del;
exit 0;;
list) list;
exit 0;;
run) run;
exit 0;;
*) echo "Error: no action given" 1>&2;
echo "Error: no action given";
help;
exit 30;;
esac
exit 0
If you want an explanation of what is going on (to verify agains malicious code, etc...) then read further:
First off, the help outlines the options. The action option determines what to do with the others. For instance, 'list' doesn't need any options... it lists the names of the programs that are currently in the script.
Next, 'add' will add a new program. First, it makes sure that you have a name, email address, subject line, and a url. If those requirements are met (and the name isn't a duplicate of another) then it literally looks for the "runSystem" tags. It then replaces it's script code with what's before the runSystem tags, then adds a new function with the same name as the name provided, and then puts the rest of the script back together. In other words, it just inserts a new function in the right spot that has the same name as the name you provide so it can then add a function call into the run function.
You'll notice the "-a run" parameters in the crontab setup.... that's because the 'run' action will just run the "run" function... which calls the other functions (called programs) and boom.... it works!
The 'del' action will of course delete the program with the same name you provide. Other than that the only complicated thing is the headme and tailme functions.
So here's how they work.... using the utilities head and tail of course! (and bc - the basic calculator... hopefully people have that... and I haven't ever NOT seen it on a unix/linux system... so here's hoping)
Basically, i grep to find the line I need, then use awk to get the line number from the grep command. THEN, i feed that into bc to compute how many lines from the top to output or how many lines from the bottom to output. When I get the output I want from head or tail, I can use echo to insert more program code... OR just make sure i head and tail with a gap to delete code. It's really simple even though it looks really complicated.
Again, I just read in the manual (pg 80 in Scalix Administration Guide v. 11.0.2) where "Plugins cannot remove or delete anything from the Scalix system's file system".... so i figured since it doesn't mention 'editing' that I would just use the script file I'm already in!!! Then a cronjob can have direct access to wget and then attach an html document to send via email!!!
Oh... and don't ask.... if you want to access restricted content with this you are crazy!!! FTP files can be done via: ftp://username:password@url.url.com as the url. Same thing with some restricted http locations. BUT if it is a server-script (like PHP) that is securing the url... then good luck. You just have to deal with some weird parameters and hope you can pass the username and password via normal http request parameters!
Good luck!