Linux Mail Forwarding
If you want to forward mail on a linux machine that you happen to have an account on, follow these simple steps.
touch ~/.forward chmod 644 ~/.forward vi ~/.forward
Contents of ~/.forward should be a comma or newline separated list of email addresses to forward mail to. The following are correctly formatted: .forward files and a brief description of each.
Forward all local email to email@example.com:
email@example.com
Forward all local email to both email@example.com and alternate@domain.com:
email@example.com, alternate@domain.com
Use the local mail spool, keep a copy in the user’s ~/archive/mail file, and forward a copy to email@example.com:
\user, "/home/user/archive/mail", email@example.com
The permissions of the .forward file must be read-only for group and other. Failure to secure your .forward file will cause sendmail to ignore its existence.
GOTCHA!
When a Domain is Blocked by Filtering Software
Can’t access your favorite websites because some stupid ISP or access point is using DNS-level filtering?
Set your DNS to use Google’s DNS:
8.8.8.8 and 8.8.4.4
Then flush the existing DNS cache and register the new DNS.
In Windows 7, you’ll need elevated privileges to changes to the DNS. Make sure you start cmd.exe as Administrator.
- Press the window Key
- Type “cmd”
- Right click the cmd.exe that’s found.
- Select “Run as administrator”
- Type
ipconfig /flushdns - Then type
ipconfig /registerdns
Now you’re free to roam the internet.
On Credit Worthiness and Dependability
Every banker knows that if he has to prove that he is worthy of credit, however good may be his arguments, in fact his credit is gone
Walter Bagehot
Big MySQL Table? Watch the keyfile Length
I made some large tables (around 3-4 billion records each) and then tried to create indexes on one column in each of them. I found that MySQL stopped at a seemingly arbitrary maximum index file size (.MYI file) for both of them. When I tried to open either table, I received an error message “ERROR 1016 (HY000): Can’t open file: ‘mytable.MYI’ (errno: 144)” indicating that the index file was crashed.
CHECK TABLE mytable QUICK reported ‘warning : Keyfile is almost full, 17179867136 of 17179867136 used’ Then myisamchk -dv mytable reported similar information under ‘Max keyfile length,” and reported “Keyfile pointer (bytes): 3′
After a little digging around, I realized that a 3-byte keyfile pointer only allows the index file to hold 2^24 blocks (about 16 million blocks of 1024 bytes each). My index file was holding about 110 keys per block (e.g., each record needed 4 bytes for the key value, plus 4 bytes for the datafile pointer, and maybe one byte for null/housekeeping, and then each block kept a little more empty space). So the 3-byte keyfile pointer only allowed MySQL to index about 1.8 billion records. Then it gave up, leaving a corrupted index file.
I have found no documentation for how MySQL decides how big a keyfile pointer to use in the .MYI file. I had no trouble adding 3-4 billion records to the MYD file, so it didn’t occur to me that there would be a problem with the MAX_ROWS clause of the CREATE TABLE command (which I hadn’t specified). But that turned out to be the problem.
I recovered my data table without the index file, then issued ALTER TABLE and now it looks like everything will be OK.
Here’s how I got my table back, without the index file (similar to what’s described above):
- make a backup of the data file (mytable.myd), just in case
- create a new empty table with the same structure as the existing table, but no index keys.
- copy the .FRM and .MYI files from the new (empty) table over the existing mytable.frm and mytable.myi files.
- issue
REPAIR TABLE mytable USE_FRM;It is very important to include the USE_FRM clause. That way, MySQL knows to make a new (empty) .MYI file that matches the .MYD file, rather than truncating the .MYD file to match the .MYI file. You will eventually get a message along the lines of “Number of rows changed from 0 to xxxx”. - Now you have a working table, with no indexes. Then you can set MAX_ROWS to something appropriate, and try again to make the indexes.
Files Ending in .php.html Unexpectedly Being Processed by the PHP Engine
Apache/2.2.3 (Red Hat), PHP 5.1.6 and phpDocumentor v1.4.3 weren’t getting along. phpDocumentor was generating HTML with filenames of the form script.php.html. Apache’s mod_php wanted to interpret script.php.html as a PHP script and was throwing errors about improper formatting:
PHP Parse error: syntax error, unexpected T_STRING in /var/www/default/docs/out/lib/lib/_php---obj---FFT.php.html on line 1, referer:...
I wanted script.php.html to be treated as an HTML file and not be processed by the php engine. This double-extension was causing me grief. The docs claimed that only files ending in the extension will be handled by the AddHandler command. I was incredulous of this claim, especially in light of Apache’s ability to do content negotiation with those .var language files.
Q: Why was this happening? I first guessed it may have been due to mod_mime, but quickly ruled that out. I then guessed it was the MultiView option… Maybe, this is one mechanism that governs content negotiation… The documentation claims:
# The index.html.var file (a type-map) is used to deliver content- # negotiated documents. The MultiViews Option can be used for the # same purpose, but it is much slower.
This statement lead me to suspect that my problem may actually be caused by an issue with the AddHandler option, since an AddHandler command must be executed to associate type-map with that .var extension.
Ah me, time is money, and in the end, I actually didn’t diagnose the problem, but I did discover (by trial and error) a workaround.
In file /etc/httpd/conf.d/php.conf, I surrounded
AddHandler php5-script .php AddType text/html .php
with
<Files ~ "\.php$"> AddHandler php5-script .php AddType text/html .php </Files>
Now, only files explicitly ending in “.php” will be treated as a php5-script. Take that!
Fast Hash Function for Strings
Pre-condition: str is null terminated.
int hash(const void * str) { int val = 0; const char *ptr; int tmp; while (*ptr != '\0') { val = (val << 4) + (*ptr); if (tmp = (val & 0xf0000000)) { val = val ^ (tmp >> 24); val = val ^ tmp; } } ptr++; return val; }
Or in PHP:
function hash($str) { var $val = 0; for($i=0,$n=strlen($str); $i<$n; $i++) { $val = ($val<<4) + ord($str{$i}); if( $tmp = ($val & 0xf0000000) ) { $val = $val ^ ($tmp>>24); $val = $val ^ $tmp; } } return $val; }
Now all you have to do is mod the returned value by the size of the hash table and you have the target address for the first pass of a hash table with double-hashing.