A blast from the past…(so to speak)

I’m not posting because I’ve been thrown into a bit of a panic. I’ll post the reason later tonight.

But I was looking through the humor folder at work for something a friend asked me to find for him, and I stumbled across this…

I don’t know whether this falls under a joke, a time capsule, irony, satire, political commentary, proof against revisionists, or what…

The President is meeting with Saddam Hussein regarding the recent
crisis. They are meeting in Hussein’s Baghdad capital, and halfway
through the meeting Hussein hits a button on his armrest. A fake arm
flies out and hits Clinton in the face.

A little while later he hits another button and Clinton ducks, only to
be kicked in the butt. A while later, this happens again. Clinton is
angry, calls a break, and they decide to meet again later, in
Washington.

When Hussein comes to DC, they sit in Clinton’s office. A few minutes
into the discussions, Clinton hits a button, Hussein ducks, but
nothing happens. A few minutes later, Clinton hits another button, Hussein
ducks again, but still nothing happens. This happens a third time, and
Hussein, by this point, is angry and paranoid.

He gets up and shouts “Enough of this! I’m going back to Baghdad!”

Clinton looks up and displays a funny-looking smirk to the Iraqi
leader. Then quite calmly replies, “What Baghdad?”

Please include your work to support the answer…

Cindy’s comment on my last post reminded me that I did not show any of the routines I tried while trying to figure out how to get the full raw email from the built in PHP imap_ routines.

So, here it is… It is obviously scrap work, but some one might find it useful to have all in one place. Just save this as a php file on your server (some place not shared since you’ll have your email password in it in raw text) and then change the mail server, username and password references (3 of them) to your own. As is, this routine will display a VERY simple webmail reader. It displays a list of messages in your box and the contents of 1 message.

It should give you the groundworks for building something more complex.

However, what it does not include is any part of the TRUE header which is what I pointed out here that I really need.

BTW this routine is OBVIOUSLY NOT safe html. If you display an email that has an embedded code that does nasty stuff, this testing routine will not protect you from it. It is JUST test code. Use it wisely.

[php]
This is just an example of how I research a topic.
‘);
print(‘Therefore it is not fully documented or clean.
It contains code fragments of my own making and those found on the web, who knows where.

‘);
print(‘There are THREE places where you must put in your email server, email username and email password.
‘);
print(‘Otherwise, you will get very limited results.

‘);

function list_emails(){
$MAILSERVER=”{imap.1and1.com:143}”;
// or $MAILSERVER=”{pop.1and1.com:110}”;
// or $MAILSERVER=”{localhost:143}”;
$PHP_AUTH_USER = “YourAddrHere@thecodecave.com”;
$PHP_AUTH_PW = “YOUR_PW_HERE”;

$mbox=imap_open($MAILSERVER,
$PHP_AUTH_USER,
$PHP_AUTH_PW);

print(‘


‘);
print(‘
THIS SECTION REPORTS ON THE FULL MAIL BOX

‘);

echo “Number of Total Emails: ”
.imap_num_msg($mbox);
echo ” Number of Recent Emails: ”
.imap_num_recent($mbox).”

“;
$headers=imap_headers($mbox);
for($x=0; $x < count($headers); $x++) { $idx=($x+1); echo $idx."
$headers[$x]

“;
}
imap_close($mbox);
}

function view_message_num($num){
$MAILSERVER=”{imap.1and1.com:143}”;
// or $MAILSERVER=”{pop.1and1.com:110}”;
// or $MAILSERVER=”{localhost:143}”;
$PHP_AUTH_USER = “YourAddrHere@thecodecave.com”;
$PHP_AUTH_PW = “YOUR_PW_HERE”;

$mbox=imap_open($MAILSERVER,
$PHP_AUTH_USER,
$PHP_AUTH_PW);
$header=imap_headerinfo($mbox,
$num,
180, 180);
print(‘


‘);
print(‘
This is a print_r of the header contents.

‘);
print_r($header);
print(‘


‘);
print(‘
This is a print_r of only the header->from contents.
I wanted to ensure the print_r contained all the info from the subarrays. This text should also be found above.

‘);
print_r($header->from);
print(‘


‘);
print(‘
This is the header info parsed out

‘);
$from = $header->from;
$udate=$header->udate;
$date=Date(“F j, Y, g:i a”, $udate);
echo “Message Number: “. $num.”
“;
$subject= $header->fetchsubject;
if (is_array($from)){
while(list($key, $val) = each($from)) {
echo “From Address: “;
echo $fromaddr=sprintf(“%s@%s”,
$from[0]->mailbox,
$from[0]->host).

“;
echo “Personal : “.
$from[0]->personal.

“;
echo “Adl : “.
$from[0]->adl.

“;
echo “Mailbox : “.
$from[0]->mailbox.

“;
echo “Host : “.
$from[0]->host.

“;
echo “Subject : “.
$subject.

“;
echo “Date : “.
$date.

“;
echo “To Address : “.
$header->toaddress.



“;
}
}

print(‘


‘);
print(‘
This is a print_r of the results of a fetchstructure

‘);
$mid = $num;
$struct = imap_fetchstructure($mbox, $mid);
print_r($struct);
$parts = $struct->parts;
$i = 0;

if (!$parts)
{
/* Simple message, only 1 piece */
$attachment = array(); /* No attachments */
$content = imap_body($mbox, $mid);
}
else
{
/* Complicated message, multiple parts */

$endwhile = false;

$stack = array(); /* Stack while parsing message */
$content = “”; /* Content of message */
$attachment = array(); /* Attachments */

while (!$endwhile)
{
if (!$parts[$i])
{
if (count($stack) > 0)
{
$parts = $stack[count($stack)-1][“p”];
$i = $stack[count($stack)-1][“i”] + 1;
array_pop($stack);
}
else
{
$endwhile = true;
}
}

if (!$endwhile)
{
/* Create message part first (example ‘1.2.3’) */
$partstring = “”;
foreach ($stack as $s)
{
$partstring .= ($s[“i”]+1) . “.”;
}
$partstring .= ($i+1);

if (strtoupper($parts[$i]->disposition) == “ATTACHMENT”) { /* Attachment */
$attachment[] = array(“filename” => $parts[$i]->parameters[0]->value,
“filedata” => imap_fetchbody($mbox, $mid, $partstring));
}
elseif (strtoupper($parts[$i]->subtype) == “PLAIN”)
{ /* Message */
$content .= imap_fetchbody($mbox, $mid, $partstring);
}
}

if ($parts[$i]->parts)
{
$stack[] = array(“p” => $parts, “i” => $i);
$parts = $parts[$i]->parts;
$i = 0;
}
else
{
$i++;
}
} /* while */
} /* complicated message */

print(‘


‘);
print(‘
This is a print_r of the results of the entire content of the email turned into an array as offered by RJ
NOTE: THIS MIGHT NOT BE SAFE HTML

‘);
print_r($content);

print(‘


‘);
print(‘
This is a print_r of the body in text format. This in theory should be included above, but this is quote protected.

‘);
$Body_text = quoted_printable_decode($content);
print_r($Body_text);

imap_close($mbox);
}

/*********************************************************************************/
/* Calling routines */
/*********************************************************************************/
list_emails();
if (!isset($num)) {
$num =1;
}
view_message_num($num);
?>



type!=0){
//DECODE PART
//decode if base64
if ($p->encoding==3)$part=base64_decode($part);
//decode if quoted printable
if ($p->encoding==4)$part=quoted_printable_decode($part);
//no need to decode binary or 8bit!

//get filename of attachment if present
$filename=”;
// if there are any dparameters present in this part
if (count($p->dparameters)>0){
foreach ($p->dparameters as $dparam){
if ((strtoupper($dparam->attribute)==’NAME’) ||(strtoupper($dparam->attribute)==’FILENAME’)) $filename=$dparam->value;
}
}
//if no filename found
if ($filename==”){
// if there are any parameters present in this part
if (count($p->parameters)>0){
foreach ($p->parameters as $param){
if ((strtoupper($param->attribute)==’NAME’) ||(strtoupper($param->attribute)==’FILENAME’)) $filename=$param->value;
}
}
}
//write to disk and set partsarray variable
if ($filename!=”){
$partsarray[$i][attachment] = array(‘filename’=>$filename,’binary’=>$part);
$fp=fopen($filestore.$filename,”w+”);
fwrite($fp,$part);
fclose($fp);
}
//end if type!=0
}

//if part is text
else if($p->type==0){
//decode text
//if QUOTED-PRINTABLE
if ($p->encoding==4) $part=quoted_printable_decode($part);
//if base 64
if ($p->encoding==3) $part=base64_decode($part);

//OPTIONAL PROCESSING e.g. nl2br for plain text
//if plain text

if (strtoupper($p->subtype)==’PLAIN’)1;
//if HTML
else if (strtoupper($p->subtype)==’HTML’)1;
$partsarray[$i][text] = array(‘type’=>$p->subtype,’string’=>$part);
}

//if subparts… recurse into function and parse them too!
if (count($p->parts)>0){
foreach ($p->parts as $pno=>$parr){
parsepart($parr,($i.’.’.($pno+1)));
}
}
return;
}

//open resource
$MAILSERVER=”{imap.1and1.com:143}”;
// or $MAILSERVER=”{pop.1and1.com:110}”;
// or $MAILSERVER=”{localhost:143}”;
$PHP_AUTH_USER = “YourAddrHere@thecodecave.com”;
$PHP_AUTH_PW = “YOUR_PW_HERE”;

$link=imap_open($MAILSERVER,
$PHP_AUTH_USER,
$PHP_AUTH_PW);

$msgid = 2;
//fetch structure of message
$s=imap_fetchstructure($link, $msgid);
print_r($s);
die();
//see if there are any parts
if (count($s->parts)>0){
foreach ($s->parts as $partno=>$partarr){
//parse parts of email
parsepart($partarr,$partno + 1);
}
}

//for not multipart messages
else{
//get body of message
$text=imap_body($link,$msgid);
//decode if quoted-printable
if ($s->encoding==4) $text=quoted_printable_decode($text);
//OPTIONAL PROCESSING
if (strtoupper($s->subtype)==’PLAIN’) $text=$text;
if (strtoupper($s->subtype)==’HTML’) $text=$text;

$partsarray[‘not multipart’][text]=array(‘type’=>$s->subtype,’string’=>$text);
}
print(‘


‘);
print(‘
This is a print_r of another method of getting the complete parts of the email. This is the parts array.

‘);
print_r($partsarray);
?>
[/php]

I’m still here and working on new plugins…

It’s been nutso at work since I got back and I’ve been researching a new idea too. So, I’ve not had time for posting. But I will share with you some of what’s caught my attention.

I have two plug-ins I am working on. One is in the EARLY testing phase. It’s called No-More-404. It allows all of the permalink structures you used before to be handled and not present 404 errors. I would like it to present 301 (moved/redirect) messages and point you to the correct structure, but right now I haven’t found an elegant way of doing that. The plugin is toooo top heavy if I build in all of the routines I would need to use using the method I have right now. So, it looks like version 1 of the plugin will simply allow multiple permalink structures for the initial link to your site. Google frowns on that, but it is better than everyone getting 404 errors. After they click (or crawl)on another link, the new structure will be used. But it would be better if I could force it to the official structure.

I am also working on a DNSBL routine that may become a WP plugin or maybe a VB plugin as well. Basically it will block spams based up on the IP address used to send the message. It would be strange to have WP manage your spam, but as long as both VBulletin and WordPress have Cron ablities, it will work for someone that does not have shell access to their host.

But I ran across a technical problem yesterday and it vexed me. I think I have it solved though. Some of you may find this interesting so, I’ll provide part of the conversation I’ve had over at http://www.codingforums.com/showthread.php?t=89994. Besites I am soooo light on words lately…

PHP Imap_blah function to retrieve full Internet header


I’ll switch over to the pear library if need be, but I CANNOT believe the built in php functions don’t do what I want them to do.

I can use imap_header to get the basic "to" and "from" stuff in emails. They give the "typical end user" level of info about the origin of the email. However, what I want retrieve is the ip address of the smtp server that processed the email. That information is included in EVERY email and is available from IMAP servers (at least it is available to Outlook because you can right click on an email and choose options to see it).

I cannot find an IMAP_BLAHBLAHBLAH function that either returns this info or returns the full raw text of the message. I need the email’s Internet headers. This stuff:

Quote:

Return-Path: <tkuhnel@alushiptechnology.com>
Delivery-Date: Mon, 26 Jun 2006 23:53:47 -0400
Received-SPF: none (mxus6: 74.139.17.40 is neither permitted nor denied by domain of alushiptechnology.com) client-ip=74.139.17.40; envelope-from=tkuhnel@alushiptechnology.com; helo=Laskowski6;
Received: from [74.139.17.40] (helo=Laskowski6)
by mx.perfora.net (node=mxus6) with ESMTP (Nemesis),
id 0MKvMg-1Fv4dv28vt-0006m9 for *@thecodecave.com; Mon, 26 Jun 2006 23:53:47 -0400
From: "Adam Field" <tkuhnel@alushiptechnology.com>
To: <*@thecodecave.com>
Subject: RICARDO examined BENJAMIN of a please
Date: Tue, 27 Jun 2006 03:53:44 +0480
MIME-Version: 1.0
Content-Type: multipart/related;
type="multipart/alternative";
boundary="—-=_NextPart_000_006A_01C69962.9CE1DB50"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.2670
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2670
Message-ID: <0MKvMg-1Fv4dv28vt-0006m9@mx.perfora.net>
Envelope-To: *@thecodecave.com

But all I get from imap_headerinfo is this stuff :
$header=imap_headerinfo($mbox,
$num,
180, 180);
print_r($header);

Quote:

stdClass Object ( [date] => Tue, 27 Jun 2006 03:53:44 +0480 [Date] => Tue, 27 Jun 2006 03:53:44 +0480 [subject] => RICARDO examined BENJAMIN of a please [Subject] => RICARDO examined BENJAMIN of a please [message_id] => <0MKvMg-1Fv4dv28vt-0006m9@mx.perfora.net> [toaddress] => [to] => Array ( [0] => stdClass Object ( [personal] => [mailbox] => brian [host] => thecodecave.com ) ) [fromaddress] => "\"Adam Field\"" [from] => Array ( [0] => stdClass Object ( [personal] => "Adam Field" [mailbox] => tkuhnel [host] => alushiptechnology.com ) ) [reply_toaddress] => "\"Adam Field\"" [reply_to] => Array ( [0] => stdClass Object ( [personal] => "Adam Field" [mailbox] => tkuhnel [host] => alushiptechnology.com ) ) [senderaddress] => "\"Adam Field\"" [sender] => Array ( [0] => stdClass Object ( [personal] => "Adam Field" [mailbox] => tkuhnel [host] => alushiptechnology.com ) ) [Recent] => [Unseen] => [Flagged] => [Answered] => [Deleted] => D [Draft] => [Msgno] => 1 [MailDate] => 27-Jun-2006 03:53:47 +0000 [Size] => 12651 [udate] => 1151380427 [fetchfrom] => "Adam Field" [fetchsubject] => RICARDO examined BENJAMIN of a please )

The imap_body requests provide no more info with the default parameters.

I suspect the quotes I’ve provided here are more info than is needed for anyone that knows the answer, but I wanted to be clear about what I was asking.

So, how do I get that Received-SPF or Recieved info?

If this is not possible, is PEAR my best bet or do I have to go old school on this thing and communicate with it via FTP or telnet?

Input is appreciated!

A reply:

to find the SMTP address, would it not be as easy as extracting the hostname from the sender’s email address, and converting it to an IP address if necessary with gethostbyname() (http://us2.php.net/manual/en/function.gethostbyname.php)?

My Response:

Unfortunately, it is rarely that simple.

Take for example that address on the spam I quoted earlier. tkuhnel@alushiptechnology.com was used as the sender. However, that address is probably some innocent business man that had their email address plastered into several thousand spam emails.

Alushiptechnology.com evaluates to 62.233.142.37. That is very different from the address of the SMTP server that we see in the email 74.139.17.40. Additionally, since shared servers have become more common, it is not at all unusual for the SMTP server to be a common server – say smtp.lunarpages.com and the website url/email address to be on a totally different server like Support@codingforums.com.

So, unfurtunately, all things being equal, gethostbyname() is a good idea that won’t work in this situation. However, if we were to check on the IP address of the SMTP server, we can tell that it is blocked. Here is one of the places I would check: http://www.spamcop.net/w3m?action=ch…=74.139.17.40+

I’ll see if PEAR has a solution for me. But I still find it hard to believe that this info is not available from the built in functions that otherwise seem so robust!

If any of my readers have any other suggestions, your input would be much appreciated too!!!

Tags allowed in WordPress Comments & Posts

There have been some comments on the WP support forum asking what tags are allowed in WP comments.

If you are a user of the editor or author security levels with unfiltered HTML rights, you are technicially allowed to enter any HTML tags.

Otherwise, these are comment tags that are allowed by the filtering engine used by WordPress (KSES):

  • address
  • a
    • href
    • title
    • rel
    • rev
    • name
  • abbr
    • title
  • acronym
    • title
  • b
  • big
  • blockquote
    • cite
  • br
  • button
    • disabled
    • name
    • type
    • value
  • caption
    • align
  • code
  • col
    • align
    • char
    • charoff
    • span
    • valign
    • width
  • del
    • datetime
  • dd
  • div
    • align
  • dl
  • dt
  • em
  • fieldset
  • font
    • color
    • face
    • size
  • form
    • action
    • accept
    • accept-charset
    • enctype
    • method
    • name
    • target
  • h1
    • align
  • h2
    • align
  • h3
    • align
  • h4
    • align
  • h5
    • align
  • h6
    • align
  • hr
    • align
    • noshade
    • size
    • width
  • i
  • img
    • alt
    • align
    • border
    • height
    • hspace
    • longdesc
    • vspace
    • src
    • width
  • ins
    • datetime
    • cite
  • kbd
  • label
    • for
  • legend
    • align
  • li
  • p
    • align
  • pre
    • width
  • q
    • cite
  • s
  • strike
  • strong
  • sub
  • sup
  • table
    • align
    • bgcolor
    • border
    • cellpadding
    • cellspacing
    • rules
    • summary
    • width
  • tbody
    • align
    • char
    • charoff
    • valign
  • td
    • abbr
    • align
    • axis
    • bgcolor
    • char
    • charoff
    • colspan
    • headers
    • height
    • nowrap
    • rowspan
    • scope
    • valign
    • width
  • textarea
    • cols
    • rows
    • disabled
    • name
    • readonly
  • tfoot
    • align
    • char
    • charoff
    • valign
  • th
    • abbr
    • align
    • axis
    • bgcolor
    • char
    • charoff
    • colspan
    • headers
    • height
    • nowrap
    • rowspan
    • scope
    • valign
    • width
  • thead
    • align
    • char
    • charoff
    • valign
  • title
  • tr
    • align
    • bgcolor
    • char
    • charoff
    • valign
  • tt
  • u
  • ul
  • ol
  • var

How to fix error C00D11DA: an error occurred while verifying the license

So, this HUGE thunderstorm rolled through last night and took out the power a bunch of times. The first time the power went out, I had the computer on and was playing a licensed media file.

Upon rebooting the computer, I found that NONE of my licensed media would play. That REALLY stunk. I listen to unabbridged audio books all the time. I have several libary accounts with branches that offer LibaryReserve borrowing through Overdrive Media, the Ohio eBook Project website (http://ohdbks.lib.overdrive.com) and Net Library accounts. Each branch offers different lists of audio books, so I probably have free access to 3000 or so audio books.

So it was a ROYAL pain when none media player could play none of these files. Media Player wouldn’t even do the OverDrive Media Player’s security update task.

When I tried to do anything related to Media Player’s Digital Rights management, I got the error “Windows Media Player cannot play, synchronize, or burn a protected file because an error occurred while verifying the license.” That’s error C00D11DA if you must know… It means that one or more of your license files are corrupt. In my case, it seems all of them were. I could neither do a restore nor a backup of the licenses. Here’s how to fix that…

ATTEMPT 1: Surgical Assualt
The first choice you have, if the problem is with one song or story or whatever, is to delete that wma file, download a new unlicensed one and aquire a new license. That’s the easy fix. But my problem was with ALL licensed media. The Windows Media Player would not even attempt to get a new license for any file.

ATTEMPT 2: Send in the Ground Forces
You might be able to do a license restore and save your self a lot of pain. So try this first.
1. Run media player
2. Choose Tools-> Manage Licenses
3. Click “Restore now”

Hopefully that works. Of course that depends upon you having backed them up before, and who does that? Who even knows that menu entry is there???

Anyway, it didn’t work for me. So, I searched my hard drive and registry for anything related to the licensing. Google revealed nothing until I found a post by a guy that had just paid $35 to MS Support for the fix. (HAH! This morning I can’t find the link, but the very first result is a more detailed blog entry by Cris Lanier describing what I was about to tell you in this post. Oh well, I’ll tell you anyway and turn it into a three step process. If you want to do this process manually, or have some OS other than XP, I recommend that you use the link I provided to Chris’s blog.)

ATTEMPT 3: Throw out the baby with the bath water it’s time for Global Thermonuclear War

Well, that’s it. Now, it is time to quit playing games get serious. Now, to fix your Digital Rights Management problem, we are going to erase everything your computer knows about the DRM licenses you have and tell it to start over. Since this process will delete all licenses you have, after we’re done, you’ll have to redownload the WMA (or whatever they are) and reaquire a new license. Hopefully, that’s not a problem for you, but if it is, there’s really not much else that can be done at this point, as far as I know. A call to MS and a few hundred dollars in support fees might get them to rebuild the license database, but I wouldn’t count on it. In the meantime, the rest of us are gonna give DRM a brain transplant. Or at least we’ll remove the old brain and see if a new one grows back…

SUMMARY:
Delete the C:\Documents and Settings\All Users\DRM directory
Delete these two registry branches:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DRM
HKEY_CURRENT_USER\Software\Microsoft\Windows Media\WMSDK

WindowsXP three step process: (Close all media players first)
1. Click Start->Run paste in the following line, press enter and hit Y if you are sure you did it correctly:
rd /s “C:\Documents and Settings\All Users\DRM”
2. Click Start->Run paste in the following line, press enter and hit Y if you are sure you did it correctly:
reg delete “HKLM\SOFTWARE\Microsoft\DRM”
3. Click Start->Run paste in the following line, press enter and hit Y if you are sure you did it correctly:
reg delete “HKCU\Software\Microsoft\Windows Media\WMSDK”

That’s it. You’re done. Now re-download the files and re-aquire your licenses. You should be in business.

Using Delphi and TWebBrowser to process WordPress’s HTML Source code

I don’t have a lot of time since I am heading off to my brother-in-law’s highschool graduation in upstate NY tomorrow. I might be able to post date a few articles for the Verizon Phone tips category, but this will be the last meaty post for a little while. So, today you get a program that I wrote at the beginning of the month when I wanted to let people know I’d written an article about the release of WordPress 2.03: TrackbackGrabber.

This little routine will go to a WordPress post, grab the source code and isolate all of the track backs for you. It turns them in to seperate lines of <255 characters each that you can paste into your ping back line on your post. Then when you publish an article, you will let everyone on that list know about it. This is somethign I used to do manually and it took forever! IMPORTANT: Don’t abuse this or it will back fire and you’ll quickly be labeled a spammer and will be reported to Akismet, Spam Karma and other spam filtering tools. If that happens none of your comments, trackbacks or manually typed entries, will get through anywhere!

Concepts Demonstrated:


  • Surfing the web using Delphi

  • Using a TWebBrowser Active X control to navigate the DOM structure of a website

  • Retreiving the source code of a webpage

  • The fundamentals of creating a web bot in Delphi

  • Filtering contents of a TMemo

  • How to tell when a page has loaded in the TWebBrowser

That last one was the tricky part. If you access WebBrowser1.Document too soon, you will get an access violation. Sleeps and process messages, no matter how many you use or how long you wait, do NOT consistently work. Pressing the button (calling WebBrowser1.Navitate twice) always worked but I found WebBrowser1.ReadyState in the documentation and checking that seems to be the right way to do it.

Exe: http://www.thecodecave.com/downloads/delphi/TrackbackGrabber.exe
Source Code: http://www.thecodecave.com/downloads/delphi/TrackbackGrabber.zip

Main unit:
[delphi]
// ****************************************************************************
// TrackBackGrabber_Main 06/Jun/2006
// Written by Brian Layman (AKA Capt. Queeg AKA SilverPaladin)
// Visit him at http://www.TheCodeCave.com
//
// WordPress’s Trackback system is a way to connect articles about the same
// topic. If you post something related to a popular article, this tool allows
// you to tell other bloggers that have posted related articles that you have
// additional information on the subject.
//
// Warning: I can’t think of any way that this routine could cause harm to
// your computer, but it could spell the end of your blog if you abuse it.
// Abuse this tool and it WILL back fire. You’ll quickly be labeled a
// spammer and will be reported to Akismet, Spam Karma and other spam
// filtering tools. If that happens, none of your comments, trackbacks or
// manually typed entries, will get through anywhere! It would really stink
// to have every comment you leave on any WordPress blog automaticly
// deleted.
//
// As always, I’ll say it is a good best practice to understand every line
// of new code before you run it. Who knows what could be lurking? Better
// yet, do not run this example at all. You should stop right now and erase
// the files. For if it causes blue smoke to be emitted from your network
// card, if it erases all users from your computer, or if it makes your
// sister break up with her lawyer boyfriend and start dating a caver, it
// is not my fault. (Actually that last one might be an improvement, but
// it is still not my fault.) But the fact of the matter is, computers
// have a mind of their own and we programmers live on the wild side.
//
// Usage: TrackBackGrabber.exe
// Supply an URL to a WordPress post and it will grab all of the track
// back links and then consolidate those to lines 255 characters long.
// Then all you need to do is paste each line into your WordPress post’s
// track back field and hit save. Each site will only be updated once.
//
// Licensing – You can use this source as you will. It’s free for
// commercial, shareware and gpl use as you like. I hope it helps.
// If this program & source really helps you out, please visit
// http://www.thecodecave.com/did-that-help/ and read more.
//
// History:
// 06/Jun/2006 – BL – Created
//
// ****************************************************************************
unit TrackbackGrabber_Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, OleCtrls, SHDocVw, mshtml;

type
TfrmTrackback = class(TForm)
memoResults: TMemo;
btnGather: TButton;
editAddress: TEdit;
WebBrowser1: TWebBrowser;
procedure btnGatherClick(Sender: TObject);
private
{ Private declarations }
procedure ProcessPage;
public
{ Public declarations }
end;

var
frmTrackback: TfrmTrackback;

const
// This defines what to look for.
// In this case it is TrackBacks.
// Deliberate references to this article for.
SEARCH_STR = ‘Trackback from Memo1.Lines.Count)
do begin
S := Memo1.Lines[0] + ‘ ‘ + Memo1.Lines[Loop];
if (Length(S) < 255) then Memo1.Lines[0] := S else begin Memo1.Lines.Insert(0, Memo1.Lines[Loop]); inc(Loop); end; Memo1.Lines.Delete(Loop); end; end; // ProcessPage end. [/delphi]