FamousPhil.com -- Home My Calendar Youtube LinkedIn Facebook MySpace Twitter RSS Blog Feed

Blog Navigation

Partners

Latest Activity

MySQL Singleton Classes in PHP and Python

Phil gives the source code for implementing a MySQL singleton class in both PHP and Python.



Posted on: November 21st, 2011 by Famous Phil

Most of the Matthouse infrastructure is running on old Celeron processors and limited RAM, you may laugh at me, but that hardware has been very reliable and has lasted Matthouse for the better part of 3 years, and some of it may continue to power Matthouse well into the future!  But there are some applications out there that require a little more juice to run well, and (unfortunately) Exchange falls into this category.  I say it is unfortunate since the Exchange server hosts a handful (< 10) mailboxes, yet it costs quite a bit to maintain compared to other Mail Transfer Agents (MTA).  So anyways, this blog is dedicated to the procedure that I took to migrate Exchange over to brand new, shiny, fast hardware.

First, I had Server 2008 R2 Datacenter as my operating system on both the existing server (denoted double) and the new server (denoted ruby).  The servers could clearly communicate with each other within the same datacenter as well so that file / data transfers could be effective.  The first thing to adding any server is to give the new server a name and know its network configuration details ahead of time.  I’m not going to go into details about how to install Windows, since it’s pretty simple.  Just make sure that you have the correct drivers installed for your server after the installation completes.

Note about installing Windows: just so that you don’t run into any issues with your system, make sure that your primary hard drive is attached to the first port for your motherboard’s interface, in my case, the first hard drive was connected to SATA 0.  If you don’t do this, you’ll run into a lot of problems and waste a lot of time (like I did!).  In addition, make sure that your BIOS has AHCI enabled prior to installing Windows, this also caused problems in my scenario.  Once Windows is installed, make sure that you can disable write caching on your hard disk without the operating system freezing (in computer management, under storage, right click the disk and optimize for quick removal).  If you followed the above, this shouldn’t cause Windows to hang, and will prevent Active Directory from incapacitating your system during the restart phase of the installation.  In addition, this is a good time to name your computer, join it to some default workgroup, add remote administration features, and change the time zone / clock settings.

Before continuing, I’d also recommend disabling Internet Explorer’s advanced security features; this is done by going to the computer management main screen and scrolling down, finding IE ESC and turning it off (acknowledging all of the warnings).  If you keep them on, you’ll find yourself doing way too much work to download necessary applications, etc.  These features are only useful if you plan on doing general web surfing on the server (which I would not recommend for security reasons).  I also activated windows, ran all the necessary windows updates (several reboots and optional updates as well).  After this all has been done, I ended up rebooting the machine a final time.

At this point, I installed several applications (using IE to get Google Chrome initially).

Tags: , , , , , , ,
Posted in Hosting / Server Administration, Technology
|| No Comments »

Posted on: August 22nd, 2011 by Famous Phil

Anymore, it seems like posting here is a seldom activity because I don’t often deal with server administration issues any longer (although I am working on changing that :D ).  Today, I was asked to reset the password on a Mac Server because the user didn’t remember the password.  Personally, I don’t know how a server oriented password can be lost, but whatever, I guess I’ve seen it all now :)

Mac, like Linux and its BSD roots, has a flaw when you have physical access to the machine.  Basically, passwords are stored as password hashes in a simple file on the server.  To change the password of any user account, you basically have to gain write access to the said password (or shadow) file and change the hash to something that matches the new desired password.  Typically, this is very easy to do for any kind of Linux or BSD operating system.  For all of you Windows fans, Windows stores the passwords encrypted in SAM files (if I recall correctly), and there are also password reset disks available that you boot from and overwrite the administrator account password with your own password.  Once again, resetting a password is very easy to do to gain access to a machine provided you have physical access.  One tiny exception to this rule on every platform, if the encryption feature is enabled on a user account (provided it exists), the files that were encrypted will never be readable again if you change the password using this method.

Since this is resetting the password of a Mac, I’m only going to cover the Mac OS.  Mac, like Linux and BSD, has something called single user mode which is basically a recovery environment built into the operating system.  When something doesn’t work properly, this environment typically boots and gives the local user (on the console) a command prompt that is running as the root user (or superuser).  Typically in single user mode, the local hard disk is read only, but because you are root, you can simply change that to write mode.  Afterwards, its a matter of changing the password.  If you aren’t a single user mode fan, Mac even puts a reset password link in the utilities menu of their installation disk that does the work manually.

So, using the single user mode shell, here is the procedure to resetting the password of your mac:

  1. Shut down the computer
  2. While holding the command (apple) key and S simultaneously, power the computer on
  3. The command line will come up shortly
  4. Type in “/sbin/mount -wu /” without the quotes, this enables writing to the root operating system directory
  5. type in “passwd <user>”, where <user> is the username whose password needs to be reset
  6. type in “reboot”
  7. Login as the user that you reset the password for, using the new password you set.
I’d like to mention that many other tutorials mention a lot of other commands that are required, these aren’t necessary since they’re checks on the operating system.  There is also a command called nidump which will give you the password hash to a user, this is useful if you want to spend the time cracking the password.  In my case, that was simply a waste of time.
Hopefully this helps someone else out.

Tags: , , , ,
Posted in Hosting / Server Administration, Technology
|| No Comments »

Posted on: July 4th, 2011 by Famous Phil

This blog is something that I know like the back of my hand, but I realize that others may not be as fluent in using crons.  This blog is meant to be a reference to those individuals.  Cron is a unix (and solaris,  BSD) utility that runs tasks automatically in the background at regular intervals, its very similar to the Windows Task Scheduler.  Cron can be referenced as a cron job, or cron tab (cron table).  For simplicity, I will simply call it a cron.

Restrictions: Crons can be ran if your username is in the cron.allow file, the location of this file varies across different systems.  If the cron.allow file does not exist, and your username does not exist in cron.deny, you can use crons.  The format of each file is one username per line.

Commands: The most common command I use is “crontab -e” which means edit the crons that run under your user account.  This command opens up the default editor of your system to do this.  The “l” flag means display the crons that are configured under the user’s account.  The “r” flag removes the current crons under a user’s account.   Finally, the “v” tag shows the last modification time of the cron configuration for a user account, note that this command is not available on all systems.

Syntax: The cron file is set up with a certain syntax.

The first line can configure a default email address to email the completion (any script output) to or it can immediately start with cron jobs, using the default email address of the account (defined in the .forward file or a local mail queue usually).

Defining an email address on the first line:

#Don't email anything by default
MAILTO=""
#email all cron job completions to admin@example.com by default
MAILTO="admin@example.com"

Each subsequent line looks like the following

* * * * * <command>
- - - - -
| | | | |
| | | | +----- day of week (0 - 6) (Sunday=0)
| | | +------- month (1 - 12)
| | +--------- day of month (1 - 31)
| +----------- hour (0 - 23)
+------------- minute (0 - 59)

In the above, if you enter * (the wildcard character), the job will run for all possible points of the value.  For example, if you do * for the minute value, this script will run at every minute.  If you want to run a job every second (not recommended), you can specify the minute value as ” */60 ” meaning run at every 60th of a minute.  This is not always supported, but for the majority of systems I use, it is.

The section is the command you would run via command line, for example, if you want to update the spam assassin rules every night at midnight, the command is “/usr/bin/sa-update“.  The crontab entry to do this nightly would be ” 0 0 * * * /usr/bin/sa-update “.

Emails: Finally, if you want a certain command to not email you regardless of completion, you can do the following (using the above example):

0 0 * * * /usr/bin/sa-update  > /dev/null 2>&amp;1

Adding ” > /dev/null 2>&1 ” to the end of the command redirects the output of the script running to the null device (/dev/null), which is a special file that discards all data that is written to it.  Essentially /dev/null is the trash can.  The > symbol is a unix pipe symbol that redirects the output of the left side to a file descriptor (or device) located on the right side.  the “2>&1″ at the end says pipe the standard error output (device 2) to the standard output device (device 1), so this essentially unifies all error and regular messages from the program so that they both can be sent to /dev/null.  In case you’re wondering, device 0 is standard input from the command line.  You can understand this a lot more thoroughly by looking at Linux file descriptors and pipes.

Path: Cron usually invokes commands using (/bin/sh) which is the default shell on most systems, it typically starts in the user’s home directory with a very simplified PATH.  If you believe your cron isn’t working properly, try using absolute paths in your commands from /.

Credit: I’d like to finally credit http://adminschoice.com/crontab-quick-reference in helping me make my reference more comprehensive, I didn’t want to completely write this from my own experience.

Tags: , , ,
Posted in Hosting / Server Administration
|| No Comments »

Posted on: July 3rd, 2011 by Famous Phil

Over the past couple of months, I’ve found that the script that I posted at http://famousphil.com/blog/2011/01/a-decent-backup-strategy-for-exchange-2010-sp1/ hasn’t been working perfectly for my needs.  This relatively short blog is kind of a back track blog to explain the issues and provide some fixes for them.

The original script I posted does not verify that the backups actually completed.  The emails I got were simply gibberish.  I was willing to accept that for a while until during monthly maintenance when I manually verify backups, I was finding that backups didn’t always complete.  I’ve tracked this down in the error logs and found that the memory in the server isn’t enough for the backups at times which has them fail at certain times.  Due to the lack of user base on my server (4 light users), I can’t justify adding more ram (I currently have 4GB) because I’d have to upgrade the entire server.  So instead, I did some RAM optimization and re-wrote the backup script to email me the actual backup names that completed successfully.

First for the tips.  I recently learned that Active Directory can be modified from the backend, so using this, I modified the Information Store service (store.exe) in Exchange to only use at most 512MB of ram.  I used the information at http://terrytlslau.blogspot.com/2011/03/limiting-exchange-server-2007-and-2010.html for doing this, I briefly repeat the procedure here in the even that this link is no longer reachable.

1. At Domain Controller, login as a Domain Administrator.
2. Click "Start", enter "adsiedit.msc" into the search box, hit enter.
3. Right-click "ADSI Edit", select "Connect to".
4. Enable the Naming Context view, click ok to connect
4. Under the "Naming Context" menu, select "Configuration".
6. Expand to "Configuration > Services > Microsoft Exchange >  > Administrative Groups > Exchnage Administrative Group > Servers >  > InformationStore".
7. Right-click "InformationStore", select "Properties".
8. Select "msExchESEParamCacheSizeMax".
9. This value is set in pages, in Exchange 2010 the size is 32KB/page; Exchange 2007 is 8KB/page.  Simply figure out the number of pages for the amount of ram you want to limit store.exe to using.

For instance, if you want to limit the Database Cache to 4 GB of an Exchange 2010 server, set msExchESEParamCacheSizeMax to 131072 (4 GB = 4.194.304 KB / 32 KB). If you want to limit the Database Cache to 2 GB of an Exchange 2007 server, set msExchESEParamCacheSizeMax to 262144 (2 GB = 2.097.152 KB / 8KB).
10. Ok everything and restart the Information Store service (possibly the server)

After limiting the Exchange Information Store service, I simply restarted the Information Store service and that seems to have fixed the gouging memory issue.

As a second optimization procedure, I started tackling the IIS Worker Processes.  Exchange has several application pools that it uses, you can think of an application pool in IIS as a separate instance of Tomcat or Apache for each website.  Application Pools isolate websites to that they can’t affect each other.  On the downside, application pools also hog a great amount of memory and for the features of Exchange that you may not use often (e.g. powershell, calendar, exchange control panel), it takes some time for these features to load initially (for me, its about 30 seconds).  My solution was to limit Exchange to two application pools.  For anything service related, I used the Exchange Service Pool (e.g. EWS, Powershell, Autodiscover), and anything client site based (e.g. OWA, Calendar, ECP, ActiveSync) in the OWA pool.  I still do not know if any update to Exchange may reverse this or break this, but I do keep it in mind during updates.  The result of doing this is that not only is memory consumption reduced significantly, but Outlook Web Access, Exchange’s Calendar display (for the public), and Exchange Control Panel all load much faster now since the overhead in IIS is already loaded.  Of course, I wouldn’t recommend doing this unless you can’t easily upgrade the amount of memory in your server.

Finally, I will leave you with an improved export script that replaces the script in my previous blog at http://famousphil.com/blog/2011/01/a-decent-backup-strategy-for-exchange-2010-sp1/.  This script verifies that all of the users were actually uploaded and emails the complete report to you (instead of some garble).  I’ve found it to be very helpful in determining if a mailbox was failing to export to a PST without having to login to the file server and check.  As always, use this script at your own risk, I am willing to provide limited support as time permits.

# Exchange 2010 SP1 Mailbox Export Script
# Originally from Steve Goodman.
# Modified by Philip Matuskiewicz for Matthouse.us / famousphil.com 1/2/11 FIXED *7/2/11*

#define information here
$server = "host.example.com" #server hostname
$users = @("Joe", "Mary", "Phil") #users to archive
$destination = "localhostpstbackups" #network share to backup to
$emailfrom = "server@yourdomain.com"
$emailto = "you@yourdomain.com"
#define some internal variables
$output = ""
$error = 0
$date = Get-Date

#check for errors
if (!(Get-ExchangeServer $server -ErrorAction SilentlyContinue)){
    $output += "Exchange Server $server not found`n";
	$error = 1
}
if (!(Get-MailboxDatabase -Server $server -ErrorAction SilentlyContinue)){
    $output += "Exchange Server $server does not have mailbox databases";
	$error = 1
}

#create a batch job if the above tests succeeded
if ($error -ne 1){

	$jobname = "Export_$($date.Year)-$($date.Month)-$($date.Day)_$($date.Hour)-$($date.Minute)-$($date.Second)"
	$output += "Job title is: '$($jobname)' `n"
	Write-Output "Job title is: '$($jobname)' "

	foreach ($mailbox in $users){
		#remove existing PST file
		if (Get-Item "$($destination)$($mailbox).PST" -ErrorAction SilentlyContinue){
			Remove-Item "$($destination)$($mailbox).PST" -Confirm:$false
			$output += "Existing PST was deleted (Normal): '$($mailbox)' `n"
			Write-Output "Existing PST was deleted (Normal): '$($mailbox)' "
		} # end if

		#request a backup of the mailbox, Exclude the recoverable items / deleted items
		$mailboxjobname = "$($mailbox)-$($jobname)"
		New-MailboxExportRequest -BatchName $jobname -Mailbox $($mailbox) -FilePath "$($destination)$($mailbox).PST" -ExcludeDumpster -Name $mailboxjobname
		$output += "Mailbox Queued: '$($mailbox)' `n"
		Write-Output "Mailbox Queued: '$($mailbox)' "

	} #end foreach
} #end $error -ne 1

#wait for the jobs to complete
$time = 0;
while ((Get-MailboxExportRequest -BatchName $jobname | Where {$_.Status -eq "Queued" -or $_.Status -eq "InProgress"})){
	Write-Output "Waiting on backup, it has been $($time) seconds"
	$output += "Waiting on backup, it has been $($time) seconds `n"
	sleep 600 #10 minutes
	$time = $time + 720;
} #end while

#check for any jobs that didn't complete
$incomplete = Get-MailboxExportRequest -BatchName $jobname | Where {$_.Status -ne "Completed"} | Get-MailboxExportRequestStatistics | Format-List
$complete = Get-MailboxExportRequest -BatchName $jobname | Where {$_.Status -eq "Completed"} | Get-MailboxExportRequestStatistics | Format-List

if($incomplete){
	Write-Output "ERROR: Something didn't complete, output is '$($incomplete)'"
	$output += "ERROR: Something didn't complete, output is '$($incomplete)' `n"
}

if($complete){
	Write-Output "Completed Successfully, output is '$($complete)'"
	$output += "Completed Successfully, output is '$($complete)' `n"
}

# Remove Requests and clean up
Write-Output "Cleaning up requests that were part of the job '$($jobname)'"
$output += "Cleaning up requests that were part of the job '$($jobname)' `n"
Get-MailboxExportRequest -BatchName $jobname | Remove-MailboxExportRequest -Confirm:$false

#verify that all the PST files were created...
foreach ($mailbox in $users){
		#remove existing PST file
		if (Get-Item "$($destination)$($mailbox).PST" -ErrorAction SilentlyContinue){
			$output += "PST FOUND!!!: '$($mailbox)' `n"
			Write-Output "PST FOUND!!!: '$($mailbox)' "
		}else{
			$output += "ERROR: PST NOT FOUND: '$($mailbox)' `n"
			Write-Output "ERROR: PST NOT FOUND: '$($mailbox)' "
		}
}

$SmtpClient = new-object system.net.mail.smtpClient("double.matthouse.org")
$msg = new-object Net.Mail.MailMessage
$msg.From = "$($emailfrom)"
$msg.To.Add("$($emailto)")
$msg.Subject = "EXCHANGE EMAIL BACKUP DETAILS"
$msg.Body = $output
$SmtpClient.Send($msg)

Write-Output "Script complete!"

Tags: , , , ,
Posted in Hosting / Server Administration, Technology
|| 2 Comments »

Posted on: July 2nd, 2011 by Famous Phil

Last night, I was tasked with moving 25,000 files (3GB worth) between two of my Linux systems.  Traditionally, I use tar and gunzip (tar czf file.tar.gz directory/) to archive files for network transfer, but for whatever reason, I used the zip utility that is bundled with most Linux distributions (zip -r file.zip directory/).

The zip process went through fine and created a zip archive of the directory, but this is because the zip was done on a 64 bit build of CentOS Linux (where zip is compiled for large file support).  I transferred the archive to the destination server (32 bit build of CentOS Linux).  As any decent admin does, I verified that the checksum (openssl md5 file.zip) matched on both ends (to check for corruption).  The md5 checksums matched, so I proceeded to unzip the file (unzip file.zip).  Below is the error I received:

End-of-central-directory signature not found. Either this file is nota zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive.

unzip: cannot find zipfile directory in one of file.zip or
file.zip.zip, and cannot find file.zip.ZIP, period.

It turns out that the 32 bit version of CentOS includes the zip utility that isn’t compiled with large file support.  To rectify this, we must download the zip source code and recompile with large file support.  The instructions that I used are at http://www.stevenbarre.com/blog/2007/03/04/how-to-unzip-large-files-greater-than-2-gb/

1. install zlib and zlib_devel using yum if you don’t already have them.

2. Download the source code of unzip from http://www.info-zip.org/.

wget http://sourceforge.net/projects/infozip/files/UnZip%205.x%20and%20earlier/5.52/unzip552.tar.gz/download

3. Extract the source code and move the appropriate make file to the main directory

tar xzf unzip552.tar.gz
cd unzip-5.52/
mv unix/Makefile ./

4. Modify the MakeFile to enable large file support

Find:

CF="-O3 -Wall -I. -DASM_CRC $(LOC)"

Replace With:

CF="-O3 -Wall -I. -DASM_CRC -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(LOC)"

5. Compile unzip

make linux

6. Use the executable unzip to extract file.zip

#assume file.zip is at /root/test/file.zip
mv unzip /root/test
cd ..
#clean up the directory, remove unzip's source code
rm -Rf unzip-5.52
rm unzip552.tar.gz
#unzip the file
cd /root/test
./unzip file.zip

Tags: , , , , ,
Posted in Hosting / Server Administration, Programming, Technology
|| No Comments »

Posted on: July 1st, 2011 by Famous Phil

Often times, I find myself working in a remote Linux terminal window. The other day, I had the need to share what I was doing with a friend, but I didn’t want to share my entire local desktop because sharing a full desktop is slow and laggy. So I quickly looked into sharing a screen session with him so he’d only see the command line window that I was in, and I know I will need it again, so its going up here.  For those of you who have a Mac or Linux, you might know that you can have multiple desktops and go through them by some key combination (usually ctrl-alt-arrow).  In a very simplified nutshell, screen basically allows for the user to exploit multiple desktops.

Here is how you share a screen session:

#User 1, initiator of the screen session
screen -R sessionName

#User 2, connecting to an existing session
screen -x -R sessionName

The -R flag means try to reattach to an existing session, if the existing session does not exist, create a new session and attach to that.  The -x flag means to connect to an already attached session, which allows for session sharing.

I ran into a problem as a non-root user (that I normally run as) when I first started using shared screen sessions.  The error is as follows:

Cannot open your terminal '/dev/pts/0' - please check.

There are several terminal devices that screen can use under the /dev/pts directory, starting with 0.  Only root can traditionally access these terminal devices, therefore, we need to modify each necessary device to allow normal users access.  I didn’t research the security implications that the following fix has, so use this at your own risk.  The server that I was using has only trusted users on it, so I was not concerned about possible risks.

#run this as root, or as sudo
#this gives others read and write access to the device
chmod o+rw /dev/pts/0

Finally, up until last week, I could never get myself out of a screen session safely without completely closing my putty terminal window.  Here is the proper key sequence to detach from a screen session.

ctrl-A  followed by  ctrl-D

To terminate a session in screen, simply type exit.

Tags: , , ,
Posted in Hosting / Server Administration, Programming, Technology
|| 1 Comment »

Posted on: June 18th, 2011 by Famous Phil

This is a topic that I should have blogged about a long time ago (when I actually did it), but I was busy at the time and stuff gets pushed onto a back burner (or even the freezer) when I don’t have the time.  Oh well, this article is better late than never.  I will also provide a script that powers https://www.matthouse.us/status.php.

Nagios is a server monitoring solution that can monitor entire systems and services running on those systems.  For Matthouse, Nagios runs on a reliable virtual private server that has a SLA to be up all of the time, the provider I choose has complete redundancy so that this VPS will not go down due to localized hardware, network, or power failures.  Nagios also runs on a system that is completely off-site from all of my other servers, so it can see if a datacenter goes down and notify me properly.  If you’re going to host Nagios yourself, I’d strongly suggest getting a similar setup since you don’t want your monitoring system to fail with everything else!

So let’s get into the actual installation of Nagios. (THIS WAS UPDATED 6/23/11) Read the rest of this entry »

Tags: , , , ,
Posted in Hosting / Server Administration, Technology
|| 2 Comments »

Posted on: June 13th, 2011 by Famous Phil

I bring you a guest post from Jason who is associated with the subtext project which is a blog written in ASP.net!  Disclaimer… I do not guarantee (or verify) the accuracy of guest posts.

A webmaster has many things to think about from choosing the right host to making sure everything is running smoothly on the backend servers. Fortunately, different tools, applications and developments exist that can help us simplify the process of running a website. Subtext skins can help designers more effectively and efficiently create the styles used for personal blogs on their website.

While you can always decrease your workload by choosing options like managed hosting, if you are responsible for web design then you should look into the many advantages of Subtext skins for blogging.

What is a Subtext skin?
Subtext is a blogging platform offered as open source software under the BSD license. The whole concept behind Subtext was to create a very simplified blogging engine that allows bloggers to concentrate on creating actual blog content rather than trying to figure out how to use the blogging software.

Almost all websites these days have their own blogs. In addition, many sites offer blogging as a service to their users who can sign up to create their own personal blogs. You can use Subtext both for the site’s own blog and to offer blogs to site members.

A Subtext skin refers to the styling and layout of the blog page. Skins are versatile as they allow you to create page formats and designs without coding from scratch. A Subtext skin is actually made up of five separate style sheets that can be used to format different elements on the page like divs, spans, boxes, headers, footers, sidebars and forms.

The five style sheets used for each Subtext skin are:

• style.css – the default style sheet that determines the basic underlying skin layout.
• secondary style sheet – this file handles the specific Stylesheet attribute of the skin. The secondary style sheet is generally used to create styling contrasts over the style.css file. For example, the web designer may choose to give the header a different border than the sidebars where in the style.css file they use the same border.
• custom.css – this style sheet is used for custom design features set by the blog author. Primarily used to set styles and layout for personal badges or for the actual post content.
• non-attribute css files – generally used for CSS frameworks or for system styles.
• css files with limited attributes – these stylesheets have a title and media attribute, and cannot be merged with other css files. The attributes specify IE version compatibility and that they are applicable only in screen mode or in printing mode.

Packaged and custom Subtext skins
Web designers can choose from a large library of pre-designed skins or they can create their own custom skins. Creating a custom Subtext skin requires some basic knowledge of CSS scripting and also learning the basic Subtext parsing rules.

Fortunately, Subtext is highly simplified to allow users to quickly master the underlying script.

Skin templates are folders that can be used to render different Subtext skins. Each folder actually contains a number of skins that are related in certain attributes and themes. The folders or templates have their own series of controls that are used to render a skin in that template along with associated style sheets.

Once you have a library of packaged and/or custom skins, you will be able to style blogs quickly after learning how to tweak the skins and templates.

Instead of racking your brain each time you need to come up with a new design, you can simply browse through your selection of Subtext skins. Each skin can be modified according to the primary and secondary CSS files associated with the skin. You can easily find the types of skins you are looking for because they will be arranged in skin templates or families according to related attributes. For example, you can have a Rainbow template. a Geometric template and an Origami template – each having multiple skins that express the same theme. The number of templates is only limited by your imagination and willingness to create custom skins.

When using the Subtext blogging software, the skin templates are arranged in folders in an easy to manage directory system. The setup makes it simple to find the skin you are looking for and simply click on the selection to implement it on the Subtext blog.

By using Subtext skins, you can save time and energy creating page designs and layouts for multiple blogs. No need to code style sheets from scratch when you can access an easy-to-use Subtext skin library and quickly find what you need.

Each skin will handle the styling and layout of all page elements including headers, footers, sidebars, text format, boxes and forms.

You can find out more about Subtext and skins at the Subtext Project Site: http://www.subtextproject.com/.

Tags: , , , , , ,
Posted in Hosting / Server Administration, Programming, Student Life, Technology
|| 3 Comments »

Posted on: June 11th, 2011 by Famous Phil

Here is a relatively short blog for a change!  A client came to me today to have PDFLib installed onto the Matthouse CPanel server.  PDFLib allows you to create PDF files programatically (in this case, PHP), so I can see a lot of uses for this extension.  As expected, CPanel wasn’t able to install this extension through PECL without a little help, so below is the procedure that I used.

#get latest pdflib lite 7 from http://www.pdflib.com/download/
#http://www.pdflib.com/download/pdflib-family/pdflib-lite-7/

cd ~
wget http://www.pdflib.com/binaries/PDFlib/705/PDFlib-Lite-7.0.5.tar.gz
tar xzf PDFlib-Lite-7.0.5.tar.gz
cd PDFlib-Lite-7.0.5
#java isn't installed on the server, compile without java
./configure --prefix=/usr/local/pdflib --without-java
make
make install
pecl install pdflib 
#when asked for a path, enter "/usr/local/pdflib" then hit <enter>

I opted to install the lite version of PDFLib since its free and my client didn’t need all of the features that the program includes.  I installed pdflib to its own directory that isn’t included in path since I don’t anticipate anyone actually using this via other languages on the server (besides PHP).  Once PDFLib is installed, we will need to use the command line (as root) to install the pecl extension and tell it where to find the compiled version of pdflib.  Note that CPanel’s PECL installer will not be able to install this extension since there is no way to enter the path (and I’d prefer to not add this to the global PATH variable on my server).  The extension is now installed, in order to test the extension, make a PHP file for the below code and execute it in a web browser, you should see “Hello World” as a PDF document.

<?php

try {
$p = new PDFlib();

/*  open new PDF file; insert a file name to create the PDF on disk */
if ($p->begin_document("", "") == 0) {
die("Error: " . $p->get_errmsg());
}

$p->set_info("Creator", "hello.php");
$p->set_info("Author", "AUTHOR");
$p->set_info("Title", "Hello world (PHP)!");

$p->begin_page_ext(595, 842, "");

$font = $p->load_font("Helvetica-Bold", "winansi", "");

$p->setfont($font, 24.0);
$p->set_text_pos(50, 700);
$p->show("Hello world!");
//$p->continue_text("continue text");
$p->end_page_ext("");

$p->end_document("");

$buf = $p->get_buffer();
$len = strlen($buf);

header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=hello.pdf");
print $buf;
}
catch (PDFlibException $e) {
die("PDFlib exception occurred in hello sample:n". $e->get_errnum() ." " . $e->get_apiname() . " : " .$e->get_errmsg() . "nn");
}
catch (Exception $e) {
die($e);
}
$p = 0;
?>

Source: I used the guide at http://www.supportfacility.com/blog/cpanel/install-pdflib-php-on-cpanel-dedicated-server/ to write an updated version for my blog.  I’d like to thank them for blogging about this topic!

Tags: , , , ,
Posted in Hosting / Server Administration, Programming
|| 2 Comments »

Posted on: June 3rd, 2011 by Famous Phil

There are many reasons why you might be reading this post, but likely, you’re trying to figure out how to install this complex heap of code (that has its root node removed, no doubt, ha ha).  If you didn’t get my last joke, I feel sorry for you, but the show must go on.

Gitorious is an open source repository management system similar to Trac on SVN.  The software looks really nice (gitorious.org), and it has a lot of built in features for managing git repositories.  For those of you who are not familiar with coding, code repositories are often set up to enable many coders to work on the same project simultaneously (different portions of course).  Repositories also enable versioning so that you can easily revert to an older copy of your code base if something breaks along the way.  Repositories are often centralized so that only a single location has to be backed up, in this case Gitorious centralizes git repositories.

Truthfully, there are three memorable software programs that have been notoriously difficult to install and configure in my experience, these are as follows:

  • Shibboleth- I never did successfully install this myself, this was because I was asked to help a friend install it over the phone.  I don’t work well when I can’t see the problem and play with stuff, I test hunches, and doing it with this method would have taken way too long.  From what I’ve seen of Shibboleth, I would rate this as worst of the worst programs to install.
  • Gitorious – This is probably the second worst application I’ve ever installed.  It required a lot of research and resources since it is poorly documented and requires a lot of Ruby Gems to operate successfully.  Of course, I will hopefully document it a little more today!
  • Exchange – I wish I would have documented the install of my Exchange server internally so I could have shared it here.  Exchange isn’t awful to install, but the configuration of Exchange is very tricky and there are many gotchas.  This is why I place it as the best of the worst software programs to install.

With all of the above said, the installation process of gitorious isn’t for the leisure system administrator to install.  This took me approximately 3 days of research to successfully install and understand.  I installed it on a separate system only because I didn’t want it hurting any of my existing production systems.  In the end, I’m glad I did this because I learned that Ruby isn’t very memory efficient and this application easily eats up most of the 1GB of ram allocated to it in a VPS (Virtual Private Server).  And with this said, I invite you to continue reading if you really want to know how to install this software.

Update 6/14: After a few requests, I’ve decided that I will provide a Gitorious installation service on your CentOS server.  I will be happy to install Gitorious and make it work (as described below) for a one time paypal payment of $100.  For details, contact me directly (see my contact page).

LAST UPDATE: 6/8/2011 – Suggestions from Gitorious Discussion Group

Read the rest of this entry »

Tags: , , , , ,
Posted in Hosting / Server Administration, My Site, Programming, Technology
|| 24 Comments »