Month: March 2018

Fedora 26 => 27 & PHP

Since I like to discover major changes by upgrading my server and then realizing something doesn’t work (well “like” might be too strong a word … but I certainly do it) … I randomly upgraded to Fedora 27 without reading any documentation on changes. Aaaand we have PHP! Evidently mod_php has gone away and I’m going to have to figure out how to use FastCGI (php-fpm). Luckily there’s a quick way to switch back to mod_php in the interim:


LoadModule mpm_prefork_module modules/

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See:
#LoadModule mpm_worker_module modules/

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See:
#LoadModule mpm_event_module modules/


<IfModule !mod_php5.c>
<IfModule prefork.c>
LoadModule php7_module modules/

<IfModule !mod_php5.c>
<IfModule !prefork.c>
# ZTS module is not supported, so FPM is preferred
LoadModule php7_module modules/


Pencil Pouch, Part 3

I finished Anya’s pencil pouch last night – she loves it!


With a special surprise:


She put her little toy cat into it to bring to kindergarten. A move that is especially goofy because I used to bring a toy cat to school with me (not my teacher’s favourite thing I did!) too.

When attaching the lining fabric, I left my 5″ gap along one of the hidden gussets. This means the generally visible interior seam is beautifully finished.



While the side gusset hides the hand-stitching in the gap:


Just like Anya’s backpack, I think the piping gives the pouch a finished look.



There’s *ALWAYS* A Worse

I thought James Comey was fired in about the worst way imaginable – giving a speech at a remote office, he sees a TV with a banner announcing her termination and thinks it’s a joke. Which … I know a lot of people with that sense of humor. I remember putting an etc\hosts record to direct someone’s company home page to an internal sandbox web server, cloning over the internal home page project, and editing it to announce the company’s merger with some big competitor and the immediate closing of the HQ office. Screen grabbing CNN, throwing on a new banner, then playing the video back isn’t a stretch.

Then Rex Tillerson, who set out to prove experience negotiating mineral rights contracts is the same as negotiating international political situations where everyone isn’t getting what they want, read his boss’s tweet and learned he was terminated. This is what you get when 48% of voters want a guy whose fame, really, was firing people (in new and dramatic ways) on TV.

Pencil Pouch, Part 2

I finished quilting the pencil case exterior with a light blue thread. This thread from Missouri Star Quilt Company is fantastic. My machine is finicky, and some types of thread result in an ugly snarl on the bobbin thread side. There are a few tricks that help — proper thread tensions, realizing the bobbin thread comes off the right-hand side of the bobbin when it is inserted into the machine — but some threads are basically unusable. These stitches, however, are beautiful on both sides.


Next up – making the piping! If you have bias strips left over from other projects, homemade piping is easy and super cheap. I had about a yard and a half of blue checked double-fold bias tape from a quilt. I unfolded the tape to make a bias strip folded in half length-wise. I then took white 550 paracord (also on-hand from another project, otherwise you can find cotton cord that’s meant to be used in piping) and encased it in the bias strip. I pinned through the top of the cord to secure it to the fabric then used the edging/zipper foot to stitch along the cord, creating a loose piping. I hand-stitched the cord ends (paranoia, mostly … but it would really suck if the cord started to come out of the fabric casing!). The piping fabric shouldn’t be super taut at this point, but there shouldn’t be wrinkles or puckers. When the piping is inserted, the stitching will be closer to the paracord and make a nice firm piping.

Finished in part 3.

Pencil Pouch

We got Anya’s first school list, and it’s got the expected dozen glue sticks and half dozen boxes of crayons. But it also has a pencil pouch for art class. Seems like an opportunity to make something cute and practical. Perusing the Internet for pencil cases, I happened across a pattern for a zippered pencil pouch.

I wanted to use the flower presser foot to stitch flowers around the pouch, but mine doesn’t work! The throw on the sewing machine arm isn’t long enough to advance the ring. I quickly drew out a diamond pattern.

And am stitching it with a blue thread to match the piping fabric.

Continued in part 2.

Unable to ‘send as’ from Outlook With Exchange

I’ve had a confounding problem — we have sendmail magicing up millions of e-mail addresses for us, but occasionally we need to be able to send from one of these addresses too. I’ve got a web form that allows text-based messages (html or plain text), but I don’t want to figure out how to upload and attach images via a web form. Until I get around to updating the web form, I just set up a new Exchange mailbox and grant myself full access (which includes send as permission)

Except ever since we got always updating Office 2016, I’ve gotten nondelivery reports when I subsequently try to send from this new mailbox that claim I don’t have permission to send as the user in question. And I’ve verified my access three times. Even added explicit send-as in addition to full mailbox access.

I’ve finally discovered why I get this false error. The ‘from’ in Outlook allows free-form text which then may or may not resolve against an Exchange mailbox. And based on the permissions of the mailbox (or the lack of permissions of the non-resolved mailbox), it may or may not work. So I don’t have permission to send from newmailbox@ourdomain.ccTLD, I do have permission to send from the Exchange mailbox that happens to have that as its primary SMTP address. Sigh!.

When you use offline mode / cached Exchange mode, and an offline address list, the SMTP address doesn’t resolve out to that mailbox. And Exchange quite properly reports an error. To get the whole thing to work (assuming “wait until tomorrow” isn’t a good answer):

First, the offline address needs to be updated (either wait or hit the powershell management console on the server)

Update-OfflineAddressBook -Identity "Default Offline Address Book"

Secondly, Outlook needs to retrieve the updated address book. Within the Outlook client, use send/receive to update the address lists. Then you can send as the mailbox to which you have perfectly configured access.

WordPress Pages With Custom Info (SEO-type stuff)

I happened across a business who wanted to create several hundred unique WordPress pages so a long list of cities would have a “customized” page offering the service in that area. Makes sense, especially as an SEO endeavor since I search for ‘service city state’ fairly often when it is something I specifically want to obtain locally. Thing is, they were looking to pay someone to duplicate the post & manually edit each duplicate to use the individual locations. There’s a much easier way – the wp_insert_post function. Now it requires that you be able to execute PHP code either from the server’s command line (i.e. it’s your OS) or upload custom code (can be a WordPress plug-in, but it is easier if the code can be installed next to WordPress and called from its URL).

You need a variable for the template text – I wanted to include the location information in both the page title and page content, so I have a title variable as well. Include in the text some string that would never appear in your template (here, I used VARCSZ for variable containing city, state, and zip). Iterate through an array of locations and use str_replace to insert the individual locations into the title and content. Then create the page. Voila, 350 pages posted in a few minutes.

To create a single-column page (although different types of pages can be created by altering the $strContent variable):


$strTitle = 'Service Offered In VARCSZ';
$strContent = '<section id="builder-section-text_11" class="builder-section-first builder-section builder-section-text builder-section-last builder-text-columns-1" style="background-size: cover; background-repeat: no-repeat;background-position: center center;">
     <div class="builder-section-content">
     <div class="builder-text-row">
     <div class="builder-text-column builder-text-column-1" id="builder-section-text_11-column-1">
     <div class="builder-text-content">
     <p><b>Service Offered In VARCSZ</b></p>
     <p>And here is where we provide some information about the service we are offering, why you want this service, and what we do that is super awesome. </P>
     <p><b>More about our service in VARCSZ</b></p>
     <p>Info about our company and the service we provide in VARCSZ</p>
     <p><b>Call NOW for our service in VARCSZ</b></p>
     <p>For this service in VARCSZ, call us.</p>
     <p><b>Call 800-555-1212</b></p>

$strArrayOfLocations = array('Abington, PA 19001', 'Ambler, PA 19002', 'Ardmore, PA 19003', 'Bala Cynwyd, PA 19004', 'Huntingdon Valley, PA 19006', 'Bristol, PA 19007', 'Broomall, PA 19008', 'Bryn Athyn, PA 19009', 'Bryn Mawr, PA 19010', 'Cheltenham, PA 19012', 'Chester, PA 19013', 'Aston, PA 19014', 'Brookhaven, PA 19015', 'Chester, PA 19016', 'Chester Heights, PA 19017', 'Clifton Heights, PA 19018', 'Philadelphia, PA 19019', 'Bensalem, PA 19020', 'Croydon, PA 19021', 'Crum Lynne, PA 19022', 'Darby, PA 19023', 'Dresher, PA 19025', 'Drexel Hill, PA 19026', 'Elkins Park, PA 19027', 'Edgemont, PA 19028', 'Essington, PA 19029', 'Fairless Hills, PA 19030', 'Flourtown, PA 19031', 'Folcroft, PA 19032', 'Folsom, PA 19033', 'Fort Washington, PA 19034', 'Gladwyne, PA 19035', 'Glenolden, PA 19036', 'Glen Riddle, PA 19037', 'Glenside, PA 19038', 'Gradyville, PA 19039', 'Hatboro, PA 19040', 'Haverford, PA 19041', 'Holmes, PA 19043', 'Horsham, PA 19044', 'Jenkintown, PA 19046', 'Langhorne, PA 19047', 'Fort Washington, PA 19048', 'Fort Washington, PA 19049', 'Lansdowne, PA 19050', 'Lenni, PA 19052', 'Feasterville, PA 19053', 'Levittown, PA 19054', 'Levittown, PA 19055', 'Levittown, PA 19056', 'Levittown, PA 19057', 'Levittown, PA 19058', 'Garnet Valley, PA 19060', 'Marcus Hook, PA 19061', 'Media, PA 19063', 'Springfield, PA 19064', 'Media, PA 19065', 'Merion Station, PA 19066', 'Morrisville, PA 19067', 'Morton, PA 19070', 'Narberth, PA 19072', 'Newtown Square, PA 19073', 'Norwood, PA 19074', 'Oreland, PA 19075', 'Prospect Park, PA 19076', 'Ridley Park, PA 19078', 'Sharon Hill, PA 19079', 'Wayne, PA 19080', 'Swarthmore, PA 19081', 'Upper Darby, PA 19082', 'Havertown, PA 19083', 'Villanova, PA 19085', 'Wallingford, PA 19086', 'Wayne, PA 19087', 'Radnor, PA 19088', 'Radnor, PA 19089', 'Willow Grove, PA 19090', 'Media , PA 19091', 'Philadelphia , PA 19092', 'Philadelphia , PA 19093', 'Woodlyn, PA 19094', 'Wyncote, PA 19095', 'Wynnewood, PA 19096', 'Holmes , PA 19098', 'Philadelphia , PA 19099', 'Philadelphia, PA 19101', 'Philadelphia, PA 19102', 'Philadelphia, PA 19103', 'Philadelphia, PA 19104', 'Philadelphia, PA 19105', 'Philadelphia, PA 19106', 'Philadelphia, PA 19107', 'Philadelphia, PA 19108', 'Philadelphia, PA 19109', 'Philadelphia, PA 19110', 'Philadelphia, PA 19111', 'Philadelphia, PA 19112', 'Philadelphia, PA 19113', 'Philadelphia, PA 19114', 'Philadelphia, PA 19115', 'Philadelphia, PA 19116', 'Philadelphia, PA 19118', 'Philadelphia, PA 19119', 'Philadelphia, PA 19120', 'Philadelphia, PA 19121', 'Philadelphia, PA 19122', 'Philadelphia, PA 19123', 'Philadelphia, PA 19124', 'Philadelphia, PA 19125', 'Philadelphia, PA 19126', 'Philadelphia, PA 19127', 'Philadelphia, PA 19128', 'Philadelphia, PA 19129', 'Philadelphia, PA 19130', 'Philadelphia, PA 19131', 'Philadelphia, PA 19132', 'Philadelphia, PA 19133', 'Philadelphia, PA 19134', 'Philadelphia, PA 19135', 'Philadelphia, PA 19136', 'Philadelphia, PA 19137', 'Philadelphia, PA 19138', 'Philadelphia, PA 19139', 'Philadelphia, PA 19140', 'Philadelphia, PA 19141', 'Philadelphia, PA 19142', 'Philadelphia, PA 19143', 'Philadelphia, PA 19144', 'Philadelphia, PA 19145', 'Philadelphia, PA 19146', 'Philadelphia, PA 19147', 'Philadelphia, PA 19148', 'Philadelphia, PA 19149', 'Philadelphia, PA 19150', 'Philadelphia, PA 19151', 'Philadelphia, PA 19152', 'Philadelphia, PA 19153', 'Philadelphia, PA 19154', 'Philadelphia, PA 19155', 'Philadelphia, PA 19160', 'Philadelphia, PA 19161', 'Philadelphia, PA 19162', 'Philadelphia, PA 19170', 'Philadelphia, PA 19171', 'Philadelphia, PA 19172', 'Philadelphia, PA 19173', 'Philadelphia, PA 19175', 'Philadelphia, PA 19176', 'Philadelphia, PA 19177', 'Philadelphia, PA 19178', 'Philadelphia, PA 19179', 'Philadelphia, PA 19181', 'Philadelphia, PA 19182', 'Philadelphia, PA 19183', 'Philadelphia, PA 19184', 'Philadelphia, PA 19185', 'Philadelphia, PA 19187', 'Philadelphia, PA 19188', 'Philadelphia, PA 19190', 'Philadelphia, PA 19191', 'Philadelphia, PA 19192', 'Philadelphia, PA 19193', 'Philadelphia , PA 19194', 'Philadelphia , PA 19195', 'Philadelphia, PA 19196', 'Philadelphia, PA 19197', 'Philadelphia , PA 19244', 'Philadelphia , PA 19255', 'Paoli, PA 19301', 'Atglen, PA 19310', 'Avondale, PA 19311', 'Berwyn, PA 19312', 'Brandamore, PA 19316', 'Chadds Ford, PA 19317', 'Chatham, PA 19318', 'Cheyney, PA 19319', 'Coatesville, PA 19320', 'Cochranville, PA 19330', 'Concordville, PA 19331', 'Devon, PA 19333', 'Downingtown, PA 19335', 'Concordville , PA 19339', 'Concordville , PA 19340', 'Exton, PA 19341', 'Glen Mills, PA 19342', 'Glenmoore, PA 19343', 'Honey Brook, PA 19344', 'Immaculata, PA 19345', 'Kelton, PA 19346', 'Kemblesville, PA 19347', 'Kennett Square, PA 19348', 'Landenberg, PA 19350', 'Lewisville, PA 19351', 'Lincoln University, PA 19352', 'Lionville, PA 19353', 'Lyndell, PA 19354', 'Malvern, PA 19355', 'Mendenhall, PA 19357', 'Modena, PA 19358', 'New London, PA 19360', 'Nottingham, PA 19362', 'Oxford, PA 19363', 'Parkesburg, PA 19365', 'Pocopson, PA 19366', 'Pomeroy, PA 19367', 'Sadsburyville, PA 19369', 'Suplee, PA 19371', 'Thorndale, PA 19372', 'Thornton, PA 19373', 'Toughkenamon, PA 19374', 'Unionville, PA 19375', 'Wagontown, PA 19376', 'West Chester, PA 19380', 'West Chester, PA 19381', 'West Chester, PA 19382', 'West Chester, PA 19383', 'West Chester, PA 19388', 'West Grove, PA 19390', 'Westtown, PA 19395', 'Southeastern, PA 19397', 'Southeastern, PA 19398', 'Southeastern, PA 19399', 'Norristown, PA 19401', 'Norristown, PA 19403', 'Norristown, PA 19404', 'Bridgeport, PA 19405', 'King Of Prussia, PA 19406', 'Audubon, PA 19407', 'Eagleville, PA 19408', 'Fairview Village, PA 19409', 'Eagleville , PA 19415', 'Arcola, PA 19420', 'Birchrunville, PA 19421', 'Blue Bell, PA 19422', 'Cedars, PA 19423', 'Blue Bell , PA 19424', 'Chester Springs, PA 19425', 'Collegeville, PA 19426', 'Conshohocken, PA 19428', 'Conshohocken , PA 19429', 'Creamery, PA 19430', 'Devault, PA 19432', 'Frederick, PA 19435', 'Gwynedd, PA 19436', 'Gwynedd Valley, PA 19437', 'Harleysville, PA 19438', 'Hatfield, PA 19440', 'Harleysville , PA 19441', 'Kimberton, PA 19442', 'Kulpsville, PA 19443', 'Lafayette Hill, PA 19444', 'Lansdale, PA 19446', 'Lederach, PA 19450', 'Mainland, PA 19451', 'Mont Clare, PA 19453', 'North Wales, PA 19454', 'North Wales , PA 19455', 'Oaks, PA 19456', 'Parker Ford, PA 19457', 'Phoenixville, PA 19460', 'Plymouth Meeting, PA 19462', 'Pottstown, PA 19464', 'Pottstown, PA 19465', 'Royersford, PA 19468', 'Saint Peters, PA 19470', 'Sassamansville, PA 19472', 'Schwenksville, PA 19473', 'Skippack, PA 19474', 'Spring City, PA 19475', 'Spring House, PA 19477', 'Spring Mount, PA 19478', 'Uwchland, PA 19480', 'Valley Forge, PA 19481', 'Valley Forge, PA 19482', 'Valley Forge , PA 19483', 'Valley Forge, PA 19484', 'Valley Forge, PA 19485', 'West Point, PA 19486', 'King Of Prussia, PA 19487', 'Norristown, PA 19488', 'Norristown, PA 19489', 'Worcester, PA 19490', 'Zieglerville, PA 19492', 'Valley Forge , PA 19493', 'Valley Forge , PA 19494', 'Valley Forge , PA 19495', 'Valley Forge , PA 19496', 'Adamstown, PA 19501', 'Bally, PA 19503', 'Barto, PA 19504', 'Bechtelsville, PA 19505', 'Bernville, PA 19506', 'Bethel, PA 19507', 'Birdsboro, PA 19508', 'Blandon, PA 19510', 'Bowers, PA 19511', 'Boyertown, PA 19512', 'Centerport, PA 19516', 'Douglassville, PA 19518', 'Earlville, PA 19519', 'Elverson, PA 19520', 'Fleetwood, PA 19522', 'Geigertown, PA 19523', 'Gilbertsville, PA 19525', 'Hamburg, PA 19526', 'Kempton, PA 19529', 'Kutztown, PA 19530', 'Leesport, PA 19533', 'Lenhartsville, PA 19534', 'Limekiln, PA 19535', 'Lyon Station, PA 19536', 'Maxatawny, PA 19538', 'Mertztown, PA 19539', 'Mohnton, PA 19540', 'Mohrsville, PA 19541', 'Monocacy Station, PA 19542', 'Morgantown, PA 19543', 'Mount Aetna, PA 19544', 'New Berlinville, PA 19545', 'Oley, PA 19547', 'Pine Forge, PA 19548', 'Port Clinton, PA 19549', 'Rehrersburg, PA 19550', 'Robesonia, PA 19551', 'Shartlesville, PA 19554', 'Shoemakersville, PA 19555', 'Strausstown, PA 19559', 'Temple, PA 19560', 'Topton, PA 19562', 'Virginville, PA 19564', 'Wernersville, PA 19565', 'Womelsdorf, PA 19567', 'Reading, PA 19601', 'Reading, PA 19602', 'Reading, PA 19603', 'Reading, PA 19604', 'Reading, PA 19605', 'Reading, PA 19606', 'Reading, PA 19607', 'Reading, PA 19608', 'Reading, PA 19609', 'Reading, PA 19610', 'Reading, PA 19611', 'Reading, PA 19612', 'Reading, PA 19640');

echo "<ul>\n";
foreach($strArrayOfLocations as $strLocation){
     $strSEOTitle = str_replace(VARCSZ,$strLocation,$strTitle);
     $strSEOContent = str_replace(VARCSZ,$strLocation,$strContent);

     $postObject = array();
     $postObject['post_title'] = $strSEOTitle;
     $postObject['post_content'] = $strSEOContent;
     $postObject['post_status'] = 'publish';
     $postObject['post_author'] = 1;
     $postObject['post_type'] = 'page';
     $postObject['post_category'] = array(0);
     $iPostID = wp_insert_post( $postObject);
     echo "<li>$iPostID created for $strLocation</li>\n";
echo "</ul>\n";

Now if you wanted to get really fancy … add some code to list all of the city/state/zip combos for the country (or subset there-of). And for the other attributes you can set on a post, see

Extracting RPM Packages

I’ve encountered a few scenarios of late where I couldn’t install an RPM package but needed its content. One is the security config at work where I have sudo access for cp but not install rights. Sigh! But more recently, I needed to compare a library from an updated package to the currently installed one. Listing package content confirms it is the same file name and path.

[root@fedora02 tmp]# rpm -q --filesbypkg -p ./mariadb-libs-10.2.13-2.fc27.i686.rpm
mariadb-libs              /etc/my.cnf.d/client.cnf
mariadb-libs              /usr/lib/.build-id
mariadb-libs              /usr/lib/.build-id/7c
mariadb-libs              /usr/lib/.build-id/7c/c8e65deafbdcc28b3089da60f295a6f757cf4f
mariadb-libs              /usr/lib/


Extracting the rpm allowed me to actually compare the files, swap back and forth to see which worked, etc.

[lisa@fedora tmp]# rpm2cpio mariadb-libs-10.2.13-2.fc27.x86_64.rpm | cpio -idmv

Bed for Anya: Dimensions

Still trying to work through the dimensions for Anya’s new bed. A twin bed is like 38”x75” – thinking 80” long with the headboard/footboard. Along the 15.5’ wall, that leaves like 8’ for the stairs, open floor space, fish tank, and door swing. Even if we needed to go a little longer to get the headboard/footboard, it should fit.

It’s the other dimension that worries me. With a 38” bed & another ~3 feet for the desk area, that’s just over 6’ wide … which gives a 3’ walkway between the bed/desk and hearth. But I worry that 3’ for the desk and chair area is going to be cramped – kids desk chairs are about 2’ square, and a 12” desk seems really small. Although L shaped desks end up having a lot of space, and having that second layer for more storage … maybe a 12” desk isn’t bad. I’d make the shorter part of the ‘L’ wider for paperwork and books. But a laptop computer will fit fine on a 12” desk.

The other question is height. I thought about doing the under-bed area as a potential walk-in closet … but the ceiling is only like 8’ high. And you don’t want to hit your head getting into bed every night. So that’s pretty much out. Doing the desk at 42” high and the bed platform at 48” – gives a little 5” platform for the mattress, plus the mattress height. But a 4’ hideaway might seem cramped. I’d rather a 5’ hideaway (desk at like 55”) … but that leaves 3’ from the mattress platform to the ceiling. Mattress itself has depth too. Now I was going to do the mattress platform the same width as the mattress so you’d sit up & swing your legs over to the desk platform to stand up. Which gives you 3’5” and that seems uncomfortable. A 42” platform means there’s 4.5’ to the ceiling. Wondering about a desk platform that is 3’ and pretty much close to square on the vertical wall – with the two tiers, the desk itself is 4’ & there’s a foot between that top desk level and the ceiling. Then 4’ for the hideaway, which gives 4’ for bed/sitting and 5’ to stand up next to the bed. No good for a teenager, but we’re designing a kid’s bed/desk … I’m sure she’ll want something else when she’s older.

I think we’re going to try laying it out in cardboard this weekend to make sure the footprint is reasonable & the platform heights aren’t head-bonking.

Side Job Accounting

Flaws in the MIT ride-share earning calculations aside, I don’t think ride-share or home-share involves a realistic accounting of expenses against income. I used to use my personal car for work quite regularly. The company reimbursed per mile at a fixed rate, and I started off thinking I scored. Paid like 20 bucks for gas and they cut me a cheque for 100 USD. Then I needed to replace my tires *way* before I expected. Turns out the reimbursement rate wasn’t a major boon. If you consider tires, oil changes, brake pads as part of your auto maintenance budget and don’t book some portion of those expenses against your Uber/Lyft income, then the gig looks artificially profitable.

At the time I looked, Lyft had a 2500 USD deductible on their comprehensive/collision insurance (and both Uber and Lyft only covered comp/collision when passengers were in the car). Drivers incur additional expense for supplemental / commercial insurance policies or live with those restrictions. But most people I know didn’t consider their insurance coverage – which means they incurred risk that would offset income. Same with house-rentals (AirBnB, HomeAway) – apart from people who rented properties as a commercial venture (i.e. people who were using the service as advertising for properties they rented anyway, not just renting out their house for a week or two when they were out of town), I don’t find many people who really understood what, say, AirBnB’s host protection insurance covered  / what their homeowners insurance covered / what was uncovered.