outlier_lynn: (Default)

January 2015

181920 21222324

Most Popular Tags

Expand Cut Tags

No cut tags
outlier_lynn: (Default)
Thursday, November 20th, 2014 09:14 am
I work with xslt and formatting objects even though I really would rather chew off my own leg.

I'm working with xml that has a node "Person" which is a child of "Subject". "Person" has many children, two of which are "PersonName" and "PersionBirthDate".

There is another node called "PersonAlias". This node has two children: "PersonName" and "PersonBirthDate".

Looks something like this:

I created a template that was suppose to create a string: "Alias(es): alias1, alias2, ..."
What I got was "Alias(es): alias1, ,Dob: dateAlias2, , Dob: date ..."

When I apply-templates select="PersonAlias", it gave me the dob even though I had not asked for it. Two hours later, I noticed that my PersonAlias template WAS NOT a match template, but, rather, an name template.

I learned something new. If a apply-templates does not find a corresponding match, it goes for the children of the node. And I have match templates for PersonName and PersonBirthDate.

outlier_lynn: (Default)
Monday, March 10th, 2014 07:59 am
A humming bird flew into the house last night when we opened the front door to head out for dinner. It immediately flew up to the skylight. No chance to get it. So we turn out all the lights, left the back sliding door open and hoped for the best. When we got back from dinner, we discovered our plan almost worked. When it got dark, the bird abandoned the skylight, but went for the high window over the front door. The overly bright street light shines in that window. We tried various things that had no chance of working and gave up. When we went into our room and turned on the light, the bird flew in. This is good. We have low ceilings. And the poor thing was exhausted. After a couple of tries, I managed to scoop it up in a towel. I left it outside on the towel near water and blooming flowers. I pretty much that it was going to die of exhaustion and fear. Apparently not. This morning I found the towel just like I left it and the bird gone. Since the towel was not disturbed, I'm figuring the bird is off telling the story of getting away.

This morning, I dragged myself out of bed in the dark (I had switching to and from DST) and got myself to work nice and early. Locked out of the building. It is a card entry building and nobodies' cards worked. Thought it might be because of DST, so I waited the 20 minutes 'til the building thought it was time to unlock the doors. Nope. Waited another 30 minutes until "management" showed up and did some hocus-pocus to open the doors. Not a good start for the day.
outlier_lynn: (Default)
Wednesday, February 26th, 2014 08:22 am
My mail server is dying. I've been putting off doing something about it because I really want to redesign mail handling. I even have the new machines ready and I've been playing with them. They are nearly ready for production. I've been waiting on dbmail. There have been been a few pernicious bugs in dbmail or in the libraries used by dbmail that out smarted every attempt at fix them.

Finally, it seemed that the most worrisome issues were dealt with. At least, the one's I cared about. The remaining issues were with parts of dbmail I will not be using. So, time to go!

Yesterday, at 3pm, I downloaded version 3.1.10 which was released on January 22nd. I applied several important patches. Then I fussed with it to get it to compile including getting a few libraries I didn't have (lost at an distribution upgrade). After a couple of hours, I was ready to test.

This morning, I was looking through my mailing lists mail and to my surprise I see 3.1.11 has been released. Sometimes a stitch in time means duplicating work. :)
outlier_lynn: (Default)
Thursday, February 13th, 2014 09:56 am
This morning, a client using FireFox 27, submitted a form at our website. What we got was each form element three times! I'm not talking about the form being submitted multiple times, but each element being bundled up three times within a single POST operation.

I've upped my logging to watch for this to make sure I'm really getting the data three times and it isn't something I'm doing. I can't see how it is something I'm doing, though.

It didn't really affect much. I sanitize pretty carefully. We only noticed because a couple of the elements allow multiple values and the same value showed up three times rather than three different values.

This one is new to me!
outlier_lynn: (Default)
Thursday, August 22nd, 2013 10:33 am
I'm using several bits and pieces for my email server that use postgresql for storage. I really don't want several different databases, though. If I put them all in the same database, there is a slight -- as in no -- chance of a name collision for table names, etc.

I just spent an hour looking at the code for the grey listing daemon to see what it would take to have it use a specific schema in the email database. Turns out that it is very simple for any code that links to libpg. The connection string (conninfo) can include parameters such as "search_path." I could add a search_path configuration option to that code very easily. Great.

But one of the bits -- the second biggest bit -- uses a third party library that knows how to talk to several different databases. Suddenly it is hard to tell that bit to use a schema. Foiled again in my great plan.

Postgresql to the rescue. The default search_path is "$USER",public. Ah-ha! If each bit and piece connects with its own username, I can have a schema for each bit by naming the schema after the bit or piece. Simple. And it is what I shall do.

In any event, if a program is written as a adjunct to other programs and it only talks to postgresql, it should damn well offer up some options about how to talk to the database! It is not that hard.
outlier_lynn: (Default)
Wednesday, August 14th, 2013 02:05 pm
There is a philosophy adopted my many open source projects and, probably, all the big ones that it is good to work on as many platforms as possible. I generally agree with this.

I don't agree with it when the project must dumb down to make sure it works everywhere. Like when it must compromise by not using native features on one platform because it doesn't exist on another. It is a problem when you want to work on OSX, MS whatever, and Linux.

But a bigger problem in my world is when a project wants to be use many different storage systems. For instance, if a project is going to use an sql database, and it won't pick ONE, it must be no smarter than the dumbest one in the offering and that is usually pretty damn dumb!
outlier_lynn: (Default)
Wednesday, July 31st, 2013 05:01 pm
But sometimes, with friends like these....

I think, given time, I could learn to like systemd better than System V. Once one gets past the knee in the curve of "what the hell is this?"

I'm setting up a replacement mail server using many programs not packaged for openSuSE. And openSuSE is double-timing down the trail of systemd. So, as the last step of getting all the daemons playing together correctly, I need to make sure they all get starting on boot and in the right order. Three of the daemons don't behave nicely when the database is off line. (A bug I might decide to try my hand at fixing at some point.)

Here I sit staring man pages and web pages and source code. Slowly the systemd concepts are sinking in and the path to various bits and pieces are visible.

And today, I wrote my first four unit scripts. They work albiet clumsily. Tomorrow, I refine the things and read the manuals in more depth.

I think I finally have all the pieces to make the new server work. It was a good day.
outlier_lynn: (Default)
Wednesday, July 17th, 2013 10:57 am
I am getting ready to replace the production email server at work with a new one using a different set of components. Right now, I handle virtual domains and virtual users in a hard-to-maintain fashion using courier-auth and courier-imapd and some hocus-pocus involving flat files.

I want to put as much as possible in postgresql. To that end I'm using DBmail with a few of my own database extensions.

I have a test server running. And while troubleshooting a delivery problem I turned up verbosity on all bits of postfix. And a warning appeared in the logs. A warning on a piece I thought was settled long ago. It seems postfix thought the localhost domain was in mydestinations and virtual_mailbox_domains. Well, I knew for a fact (and double checked) that localhost was not in the virtual tables anywhere.

When postfix is looking to see if we accept mail for a given domain, it checks a bunch of places. One of the last is the virtual_mailbox_domains list. Postfix is not asking for a yes/no response from the database; rather, it is counting the NUMBER OF ROWS returned by the database query which will be 0 or 1. I'm sure there must be a good reason for this. I suspect it allows the same code to be used to support a lot of ways of storing this information and some can't return boolean.

I wrote a series of functions in postgresql so that the postfix queries call my functions. And that is the rub. If you have a function foo(domain text) that looks like this:

CREATE FUNCTION foo (domain text) RETURNS text AS $$ SELECT domain FROM allowed_domains WHERE domain = $1 $$ LANGUAGE sql

And you call this function like this:

SELECT foo('');

You will always get one row returned and it doesn't matter if is in the database or not. That row will either be "" or "NULL". foo() returns no rows or 1 row, but the select that calls it returns the result of foo or null. Postfix counts rows and it doesn't care that the value of the row is unassigned.

It has also been suggested that returning arbitrary text might be an issue for postfix. I have seen no evidence of that, but returning a "1" when there is a match seems safer. That means that I could do something like this:

SELECT 1 FROM (select domain from foo('%s') where domain is not null) x

Postfix substitutes the necessary key value for the '%s'. This call to my function returns one row with a value of 1 if the domain is found and returns no rows if the domain is not found.

But this is a bit clunky looking. The answer is a view.

CREATE VIEW allowed_domain AS
SELECT domain FROM allowed_domains
WHERE domain <> 'specialname' AND
domain <> 'otherspecialname';

Then the postfix query can look like this:

SELECT 1 FROM allowed_domain WHERE domain = '%s';

Better. Much, much better. It is an error to return more than one row to postfix. The table allowed_domains is not allowed to have duplicate entries so we will "never" return more than 1 row and now we can return 0 rows.
outlier_lynn: (Default)
Monday, June 17th, 2013 08:36 am
Just writing to let you know how nice your Customer Care Representative (CCR) was on our call about my recent problem with your product. He was personable and seemed genuinely interested in my issues and concerns. I felt like there was a personal connection. You have done a wonderful job in hiring and training empathetic CCRs. It felt like I had spoken to my father or older brother.

And, like my father or older brother, your CCR didn't know a damn thing about your product specifically or the software industry in general. Might as well have been talking to a wall. If every question I ask has to be kicked up two or three levels of support, you really need to just give me a goddamn rep who can deal with the issues on the first call.

If I ask a question that deviates at all from the scripts in the pleasant fellows notebook (or online triage matrix), he becomes pleasantly confused and sweetly confusing.

I don't need a friend to call when my phones go dead or I need a question answered about some little used configuration options, I need an expert on the product. He can curse me for my stupidity for all I care as long as my problem is resolved quickly.

I don't need someone who cannot help unless I boot up a Windows machine and give your rep remote access through it to my entire internal network. JUST ANSWER MY QUESTION. Yes, I'm talking to you,

outlier_lynn: (Default)
Tuesday, March 5th, 2013 03:04 pm
Last Sunday night after 8:30 pm, our offices were broken into. A small window in my office was smashed in. My monitor and my laptop was taken. Petty cash was taken. A small travel case with a cheap digital camera was taken. The feeling is this: it was the local druggie youth in our area. The druggie youth we know thinks this, too.

The good news is that we recently installed cameras and a DVR. The bad news is that I didn't set it up quite right and it didn't record anything. sigh.

It also seems that our suite has been hit in the past. Wish someone had told us we had some reasonable likelihood of theft! Well, we are keeping our camera system and installing a monitored alarm system.

I hate being robbed.
outlier_lynn: (Default)
Friday, December 28th, 2012 03:02 pm
I have a pair of mail servers waiting to go into service. I ran into a bug so I delayed swapping out the old mail server. Well, the old one crapped out on Sunday. I put one of the two into service immediately and found my bug again. Fixed it.

So, in the morning of christmas day, mail was mostly working again. Mostly. smtp authentication did not work.

cyrus-sasl seems to have some kind of bug. So I googled my little heart out. This seems to be a known issue in 2005, 2006, 2007, and 2008. And no thread of any search result gave me a solution. Trying to use the sql auxprop plugin fails. At least on SUSE 12.2. I got the source and compiled it. Failed.


So I gave up and installed dovecot today. Like cyrus, it is a imap/pop/auth server. Unlike cyrus, though, it has more than a dozen configuration files and looks a bit like udev. And like cyrus, it is very poor documentation. So, 4 hours of trial and error, I successfully authenticated.

Still have some clean up to do, but right now, I goofing off for awhile.
outlier_lynn: (Default)
Thursday, December 13th, 2012 02:37 pm
I ordered two new computers for work for the firewall/proxy machines. I had two requirements: 1) Run Linux; and, 2) have three Ethernet ports. I picked them up today. To get the three nics, I had to not get the cheapest motherboards. Fine. More horsepower than I need for the work the machines do. Oh well.

Picked them up this afternoon. As I expected, these motherboards do not have ps2 connectors. So they aren't going to get connected to my ps2 KVM switch. Bother. Not the end of the world, but a bother.

As I didn't expect at all, it doesn't have a vga connector, either. REAL BOTHER. It has hdmi, and dvi and something called "display port" with a connector I don't recognize. I know that vga is being phased out. I don't even mind. But it does mean that I am now in the very slow transition period in which I will have machines that aren't easily re-purposed, can't be hooked up to my ps2/vga KVM in the server room, and will be a pain in the ass to maintain.

I just happen to have a monitor (the one I was using before I needed double size) that will work with the new machines. I just don't have cables for it. Guess I need to go to the store.
outlier_lynn: (Default)
Wednesday, October 3rd, 2012 08:34 am
Generating web pages dynamically is relatively easy if one is structuring individual pages using a language like php or ruby. And there are frameworks that make it even simpler.

It gets more complicated when entire pages come into and go out of existence within a domain., for instance, does not have a single static page even though it looks like it does. There are plenty of pages that end with ".html" If there really were a file "foo.html" in the document root, it would be served, but when there is no foo.html, scripts jump into action to create the page.

It is all easily extensible and very easy to maintain. I am proud of my handiwork in creating this framework.

But a tiny bug can have very large consequences. I altered a four files yesterday in an attempt to trap an intermittent bug which I think is in an xml parser library I'm using. I introduced a new bug. A one line bug that wiped out customer support for one of our products. It was easily found and fixed, but for a few minutes our support team had no access to customer records. They got a perfectly nice web page. It was just a mix of three other pages on which nothing functioned.

It is easier to troubleshoot a single page with 50 lines of code then it is to find a bug in a dynamic system with 200,000 lines of code.
outlier_lynn: (Default)
Thursday, August 30th, 2012 08:43 am
I wrote a small debugging library to use in the business logic at work. It works very, very well but the log files are sometimes a bit cryptic because multiple things are going on at the same time which means the debugging logs have entries from different processes intertwined.

This morning, I finally looked at that library again. Duh. Every process has its own pid, Lynn. Just prefix each log entry with the time stamp and the pid. Done.

Now when I identify the pid of the process I want to follow, I grep the log for it. It provides a beautiful list of just the info I want. Much, much better. I can grep the log for specific user data, for instance, which gives me the pid, then grep the pid. I think I'll write a little script that does the second part for me. Simple enough.
outlier_lynn: (Default)
Monday, August 20th, 2012 10:12 am
I am sitting in front my my brand new 39 inch (tv) computer monitor. I had a brand new 42 inch (tv) monitor but "it didn't work" as advertised so I exchanged it for this one. And it is good. I can read every word on it.

The 42 inch probably worked just fine. The "not supported" message on its screen was not that it did not support a vga input. Rather, it was that my computer monitor configuration was not supported. At least, that was the problem with the 39 inch when I first plugged it in.

Silly boy. Didn't think it through, did you? Nope, you didn't.
outlier_lynn: (Default)
Friday, August 3rd, 2012 05:21 pm
We have had cbeyond as our internet/phone provider for five years. Until a couple of weeks ago, they gave us a pri circuit that fed our own aging pbx. I have been looking for a reason to dump it. It is old, I have very limited control over it and it is a disaster waiting to happen.

I was thinking I would set up buy the necessary cards from digium and run asterisk locally. Just get cbeyond to give me a sip line. They made us a deal for increased internet bandwidth ( from 2 to 3 T-1) plus a hosted asterisk pbx that I would have a great deal of control over. All for $300 a month.

We talked it over and decided to go for it.

We have been on the hosted pbx for a week. It is a fucking disaster. It is asterisk with freepbx on top. We bought the phones they suggested and told them what the initial configuration should be. We changed as part our move to the new office. It took twice as long as the longest time they said and the phones did not work as we asked.

I have been messing with the damn web config tool for a week. And it still does not perform correctly. I have been on the phone with tech support, but they don't know crap about this pbx. Cbeyond bought aretta but their support people are groping along with me for solutions.

One basic routing is to change the call routing when we open in the morning and change it back when we close. I set up a test with a number we don't use and it worked fine. The real numbers however are flaky as hell. For the last two days, it put us into night mode at 2pm instead of 5pm. I think it's a timezone issue. The damn system comes with extensible "feature codes" that allow you to type "*something" to affect the phone status. Logging into or out of the ACD queue, for instance. Doesn't work as advertized. Further, there is no indication whether a phone is logged in or not. What a fucking joke.

I was on the phone for 90 minutes with tier 2 and 3 tech support yesterday. They messed with this and that, remotely reprogrammed one of the phones, found a few work arounds for some issues. And today, it is all crap again.

Well. the old system is sitting in the back room. I think I'm going to hang it on the wall and tell cbeyond what they can do with their hosted pbx.

it might be time to look for a new provider for everything. They have fumbled the ball on every possession in the transition to the new phones and in the move from the old office to here.

And they have changed their trouble ticket system. You log into their sight and get a goddamn interactive flash presentation of your trouble tickets. I can't fucking read the tiny ass print they decided to use and I can't re-size it. What kind of fucking anti-ADA is that! (Trustwave has this same issue.)

Really, guys. Really?
outlier_lynn: (Default)
Monday, July 16th, 2012 10:33 am
I notice very recently that firefox stop showing me printers in the print dialog. A bit of sleuthing and I discover that my firefox "upgraded" itself from my ver. 13 64 bit to a 13.0.1 32 bit. Everything worked fine except that it was not happy with the libraries that were used to deal with printers.

Everyone who had similar problems (all the way back to firefox 3) solved the problem by installed the 32 bit libs. To hell with that! I wanted a 64 bit firefox.

And that took some more looking around. If you just use the download button for firefox, it doesn't even bother to check for the bit size, it just hands back 32 bit. Sigh.

With each new version, it is less usable in general and more hassle. The have crossed the knew in the curve. I know had firefox more than I had google chrome.
outlier_lynn: (Default)
Monday, July 9th, 2012 04:11 pm
Well, hell. That's the end of my trying to use archiveopteryx. I've spent a week working out the kinks in the configuration of postfix and archiveopteryx only to find that they don't play with each other all that nicely. I really like the idea of storing email in postgresql which what archiveopteryx is good at.

But to do that, I have to tell postfix to "relay" mail to it over either smtp or lmtp. And all that is fine, too. Except that if I set the mailbox_transport configuration to do that, postfix immediately stops rejecting unlisted recipients. As far as postfix is concerned it is just a mail relay. Okay, I can live with that, too.

But archiveopteryx does not doesn't reject, it bounces, mail for unknown recipients. And that I can't live with. I want mail to unknowns to simple fall into the bit bucket. I am not interested in becoming just another great backsplatter server for spammers to use.

I suppose I could try and modify archiveopteryx source. Hell, I'll go have a look anyway. But, damn that is the hard way.
outlier_lynn: (Default)
Wednesday, June 27th, 2012 03:58 pm
Starting putting openSuSE 12.1 on five old emachines to get them up to date for use as desktops for our agents. All five failed BADLY. I'm not horribly upset, though. I've wanted to ditch the emachines from the first time I saw them. That leaves 3 that are new enough that 12.1 has no trouble running.

In four of the old boxes, I could run 12.1 without the X system (so I might keep them for servers). The other wouldn't load the OS at all. It was the last windows machine for the agents. Some proprietary something that linux couldn't support.

Went to my local computer store and bought two bear bones machines. Loading up 12.1 as I type. All is right with the world. More or less. :)


Installed 12.1 on first machine. All(most) is good. Then I decided to try something I've never done. I made a clone of the disk with dd. What I didn't know was that it would take almost four hours! But it did work. And this morning I have a second machine just like the first. But it won't boot. Oh, yes. SuSE uses disk-by-id to mount partitions. Of course, the grub and fstab files are wrong. Not a big deal. I needed a new live CD anyway. :)

I like using dd to clone an installation. It just means I have to plan far enough in advance for the time it takes and the slight editing it later takes.

I like learning new things like the systemV init system I've grown to love is going to die before I do in favor or systemd. I think I like systemd,

Dr. Dobb's Journal published salaries in the latest issue. I think admins are making enough. :) It is easy to write software than keep all these machines going and I don't have all that many machines.
outlier_lynn: (Default)
Wednesday, February 9th, 2011 10:04 am
As I have written more and more databases within a given PostgreSQL cluster, I have run into a bit of a problem with "version control" of sets of utility domains, types, functions and the like.

Every database created comes with a default schema named public. And anything created in that database is automatically part of the public schema. Although somethings are private to a given database, somethings are not.

Domains and functions in the public schema are available to other databases. If I redefine a function in my new database that has been used in other databases, I've just created a problem in the other databases. Not good.

I've decided, therefore, to create a schema for each database and create everything inside that schema. Then I can change the schema search path to check for the local schema FIRST, then public. Or not check public at all.

I think this works. I'm going to try it for a bit and see if it deals with the issue.

EDIT. It seems that the default search_path starts with "$user" which means that the default schema for everything has the same name as the current user (assuming the schema has been created). I'll just create it that way and make sure that I always connect to a particular database as the user that owns the database. Problem solved.