kode
Her er nogle af de ting jeg synes der må være interssante at
dele med verden.
Alt kode her på siden er copyright (c) af mig, og udgivet under
GPL
php / smarty: memcached caching
Da jeg synes det er ganske rart at lave optimeret kode og går op i at det jeg laver kører så hurtigt som overhovedet muligt har jeg lavet en memcached caching funktion til smarty. Jeg ville selv bruge den her på sitet hvis det ikke var fordi at maskinen der køre swag.dk's ram er den gode gamle EDO slags og ikke har en voldsomt stor processor (233 mhz pentium). Grundet de ting lader det ikke til at kunne betale sig for mig at bruge funktionen her.
kode_memcache_smarty_cache.inc.php.txt
/**
* Project: Smarty memcached cache handler function
* Author: Mads Sülau Jørgensen <php at mads dot sulau dot dk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
function memcache_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null, $exp_time=null) {
// ref to the memcache object
$m = $GLOBALS['memcached_res'];
// the key to store cache_ids under, used for clearing
$key = 'smarty_caches';
// check memcache object
if (get_class($m) != 'memcached') {
$smarty_obj->trigger_error('cache_handler: $GLOBALS[\'memcached_res\'] is not a memcached object');
return false;
}
// unique cache id
$cache_id = md5($tpl_file.$cache_id.$compile_id);
switch ($action) {
case 'read':
// grab the key from memcached
$contents = $m->get($cache_id);
// use compression
if($smarty_obj->use_gzip && function_exists("gzuncompress")) {
$cache_content = gzuncompress($contents);
} else {
$cache_content = $contents;
}
$return = true;
break;
case 'write':
// use compression
if($smarty_obj->use_gzip && function_exists("gzcompress")) {
$contents = gzcompress($cache_content);
} else {
$contents = $cache_content;
}
// add the cache_id to the $key string
$caches = $m->get($key);
if (!is_array($caches)) {
$caches = array($cache_id);
$m->set($key, $caches);
} else if (!in_array($cache_id, $caches)) {
array_push($caches, $cache_id);
$m->set($key, $caches);
}
// store the value in memcached
$stored = $m->set($cache_id, $contents);
if(!$stored) {
$smarty_obj->trigger_error("cache_handler: set failed.");
}
$return = true;
break;
case 'clear':
if(empty($cache_id) && empty($compile_id) && empty($tpl_file)) {
// get all cache ids
$caches = $m->get($key);
if (is_array($caches)) {
$len = count($caches);
for ($i=0; $i<$len; $i++) {
// assume no errors
$m->delete($caches[$i]);
}
// delete the cache ids
$m->delete($key);
$result = true;
}
} else {
$result = $m->delete($cache_id);
}
if(!$result) {
$smarty_obj->trigger_error("cache_handler: query failed.");
}
$return = true;
break;
default:
// error, unknown action
$smarty_obj->trigger_error("cache_handler: unknown action \"$action\"");
$return = false;
break;
}
return $return;
}
php: ascii progress bar
Denne lille funktion skrev jeg da jeg lavede et lille konsol script til at opdatere nogle data, og gerne ville holde øje med hvor langt processen var kommet.
kode_ascii_progress_bar.txt
/**
* Ascii progress bar function - draws a progress bar
*
* @param $now number containing what item is beeing processed e.g.: 42
* @param $total number containing the total amount of items e.g.: 101
* @param $text what to put in front of the bar
* [@param $width how many chars the bar is in total, keep it under 80]
*
* @returns void
* @author Mads Jørgensen (php <at> mads <dot> sulau <dot> dk)
*/
function print_progress($now=null, $total=null, $text="Progress", $width=30) {
// where ware we
static $drawn = false;
static $last_precent = 0;
// where are we
$precent = ceil($now/$total*100);
// check for reset
if ($now == null && $total == null || $last_precent > $precent) {
$last_precent = 0;
$drawn = false;
return;
}
if ($precent > 100) {
$precent = 100;
}
if ($now > $total) {
$now = $total;
}
// how much space do we really have
$real_width = $width-strlen($text)-2;
// precent width
$precent_width = $real_width/100;
// draw the bar
if (!$drawn) {
print $text .": ";
print "|";
print str_repeat(".", $real_width+3);
print "|";
$drawn = true;
}
// the fun part
if ($last_precent != $precent) {
print str_repeat(chr(8), $real_width+4);
print str_repeat("-", floor($precent_width*$precent));
if ($precent != 100) {
print str_repeat(".", $real_width-floor($precent_width*$precent)-1);
}
print "| ";
print str_pad($precent, 2, " ");
print "%";
}
// check for done
$last_precent = $precent;
}
for ($i=0; $i<20; $i++) {
print_progress($i, 19, "Progress");
usleep(50 * 1000);
}
print "\n";
print "foo\n";
for ($i=0; $i<10; $i++) {
print_progress($i, 10, "Progress");
usleep(50 * 1000);
}
print "\n";
iptables: forward function
En funktion jeg skrev til at forwarde porte med iptables.
kode_iptables_forward_function.txt
#!/bin/bash
# Disable forwarding while processing rules
echo 0 > /proc/sys/net/ipv4/ip_forward
# defenition of internal / external interface
ext_if="eth0"
int_if="eth1"
# We need sed
SED=`which sed`
#
# Function should be called with the ip to forward to in the first parameter
# and the port (fmt_port) as the second
#
# fmt_port can be either just a regular port eg. 22 to forward all traffic
# from me:22 to forward_ip:22
# it can be written 22(42) to forward all traffic from me:42 to
# forward_ip:22
# or called with a range eg. 42:1042 to forward all traffic from me:42-1024
# to forward_ip:42-1042
#
# Author Mads Slau J¿rgensen dec 2003
#
forward() {
if [ -z "$1" ]; then
echo "forward called without addr param"
return
elif [ -z "$2" ]; then
echo "forward called without ports param"
return
fi
for port in $2; do
# is it a port range (contains a :) or origport(destport) or just a port
case "$port" in
*":"*)
iptables -A INPUT -j ACCEPT -p tcp --dport $port
iptables -A FORWARD -j ACCEPT -p tcp --dport $port
iptables -t nat -A PREROUTING -i $int_if -p tcp --dport $port -j DNAT --to $1
;;
*"("*")")
# get the dest and orig ports, using sed
dest=$(echo -n "$port" | $SED -n -e 's/[^(]*(//' -e 's/)$//p')
orig=$(echo -n "$port" | $SED -n -e 's/(.*//p')
iptables -A INPUT -j ACCEPT -p tcp --dport $orig
iptables -A FORWARD -j ACCEPT -p tcp --dport $orig
iptables -t nat -A PREROUTING -i $int_if -p tcp --dport $orig -j DNAT --to $1:$dest
;;
*)
iptables -A INPUT -j ACCEPT -p tcp --dport $port
iptables -A FORWARD -j ACCEPT -p tcp --dport $port
iptables -t nat -A PREROUTING -i $int_if -p tcp --dport $port -j DNAT --to $1:$port
;;
esac
done
}
# Forward FTP SSH SMTP HTTP POP3 IMAP MYSQL MYSQL4 and a port range
forward "192.168.1.3" "22 25 80 110 143 3306 3307 14000:14999"
# Forward SSH (port 60) and port range
forward "192.168.1.21" "60(22) 15000:15999"
# Enable forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
postfix: script til brugeroprettelse
Et "lille" sh script til at oprette brugere i postfix (levering) og courier's (hentning) userdb
kode_postfix_courier_add_user.txt
#!/bin/sh
# interface to add email address to postfix/courier-imap
# written and copyright by Mads Joergensen (software@mads.sulau.dk)
# a hot summer day in spring 2004
# published under the GPL license (see: gpl.txt)
# Perl would had been a better choise of language tho, but
# the script just evolved out of nowhere
# discard path
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
# configuration options
# home basedir - no tailing slash
MAIL_BASE="/home/vmail"
POSTFIX_VIRTUAL="/usr/local/etc/postfix/virtual"
POSTFIX_VIRTUAL_MAPS="/usr/local/etc/postfix/virtual_mailbox_maps"
COURIER_USERDB="/usr/local/etc/userdb"
MAIL_UID=1003
MAIL_GID=1003
# usage - duh
if [ -z "$1" ]; then
echo "Usage: ${0} <email address>"
exit 1
fi
# split the email adresse - ugly yes couldent figure out how to
# do it another way
USER=`echo "$1" | { IFS=@ read user domain; echo $user; }`
DOMAIN=`echo "$1" | { IFS=@ read user domain; echo $domain; }`
HOME="${MAIL_BASE}/${DOMAIN}/${USER}/"
POSTFIX_HOME="${DOMAIN}\/${USER}\/"
# check that the user does not exist
if [ ! -z "`grep -e "^$USER" $POSTFIX_VIRTUAL`" ]; then
echo "User exists allready"
exit
fi
# add user to postfix virtual
sed -i -e "s/^#$DOMAIN.*---$/&\\
$1 $1/g" $POSTFIX_VIRTUAL
# add user to postfix virtual_mailbox_maps
sed -i -e "s/^#$DOMAIN.*---$/&\\
$1 $POSTFIX_HOME/g" $POSTFIX_VIRTUAL_MAPS
# add user to courier
userdb -f ${COURIER_USERDB} "${1}" set home=$HOME mail=$HOME uid=${MAIL_UID} gid=${MAIL_GID}
# set the password
echo "Setting imap password"
userdbpw | userdb -f ${COURIER_USERDB} "${1}" set imappw
echo "Rebuilding files ..."
makeuserdb
postmap $POSTFIX_VIRTUAL_MAPS
postmap $POSTFIX_VIRTUAL
echo "Reloading postfix"
postfix reload
# send user a mail so postfix can create the user's homedir
echo "Welcome to ${DOMAIN}" | mail -s "welcome to ${DOMAIN}" ${1}
echo "Done"