Friday, August 31, 2007

rsync speedup -- only 2.49

I had to transfer 2.4GB of svn working copy over the internet and I wanted to save as much bandwidth as possible. Just plain rsync of the working copy wouldn't have given me enough bandwidth savings since the duplicated data (not just blocks inside files but actual full files duplicated) are in different files.

I decided to try to take advantage of that duplication detection by creating a tar (not tar-gz) of the working copy. I hypothesized that there would be at least a 2x bandwidth saving because the pristine copies (in .svn/text-base) would be exactly the same as the working copy except where the working copy was modified, and even then only a few lines are typically modified, out of perhaps 500-1500.

There should be even more savings because the reason the working is so large is because there are a few branches (experimental working directories tracked via svnmerge) and 5 or so tags left lying around (older tags are removed and documented in a readme so they can be resurrected by referring to the revision number, but we don't keep everything around since we release very often and the tags are very large).

Because of the tags, I expected a speedup of 10-20. I only got 2.49 though. Which is good, but close to an order of magnitude away from what I expected. I'll play with this some more. I just took another quick look at the rsync technical report and it doesn't seem to invalidate my hypothesis
{alpha} searches through A to find all blocks of length S bytes (at any offset, not just multiples of S) that have the same weak and strong checksum as one of the blocks of B.

Possibly tweaking the block size might help. Blocksize is set according to the size of the file, and I expect it to be directly proportional to the file (to minimize the amount of data to transmit for checksums, probably). Setting it smaller will make sending the checksums larger, but possibly increase the efficiency. I expect to waste quite a lot of time and bandwidth on this :-).

Thursday, August 23, 2007

git-svn again

I'd been having trouble figuring out git-svn and git. I worked at it a bit more this week and I've finally got something working.

mkdir svn-git
git-clone [URL]
cd [directory]

and the files are there. I can do most of the basic things. I haven't yet practiced branching and merging. I'll do that in a week or so. Or tomorrow, as the mood arises. For now, I'm happy that I can remotely mirror a repository (my personal backup of the entire repository, including commit messages). It also makes viewing log messages a lot faster when the svn server is far or my link to it is slow (as happened to me and sol the past three nights, the route to the svn server passed through an ISP in singapore that was experiencing 50% packet loss, it took a few days the upstream ISPs to figure out that they shouldn't go through that lame router).

I had some confusion earlier since I deleted a subdirectory (with just rm -rf) and then couldn't figure out a way to revert. I still don't know how to revert from a "pristine copy", if git has that at all. Instead, what I had to do was a local commit and then a git-revert (which reverts a commit, something that svn doesn't have yet). I don't know if that's the canonical way to do that, but it worked.

I tested git-commit and git-svn dcommit and that worked pretty well. The commit messages are clean, which is my main issue. I'm looking into git-svn partly so that I'll be able to work with version control even if not connected to a repository. I'd previously used svk but wasn't happy with the format of the commit messages pushed into svn when it came time to merge back into svn. That might have improved by now, but then there were problems with speed too. Those won't be fixed except by rewriting in something faster than perl. If I learn, like, and learn to like git, I'll stick with it for disconnected work.

But first I need to test out its features. There's a long weekend coming up (two long weekends in a row this month), I'll play with git a bit then.

[Update]
Ok, The git workflow description at Calice points me at git reset. So

git-reset --hard HEAD

does what git commit+git revert does, but without the bogosity of actually having a commit message in the logs.

Now I'm trying to figure out how to get the list of files modified in a given commit (in svn, svn log -v).

Ah well, now it's just time read the git manual. I read the CVS manual and the SVN manual, I should be able to wrap my brain around git :-).

Friday, August 17, 2007

gmail smtp requires TLS

I use evolution at work (none of that Outlook creationism for me) and, on my laptop too. At work I was confused because I couldn't send email through smtp.gmail.com. I thought it was just work firewall rules. It wasn't though. Formerly, I could send from my *@gmail.com addresses using the company SMTP server. Then the SMTP server was reconfigured to be tighter and to require authentication. I couldn't send mail with a From: of bopolissimus@gmail.com anymore. I tried to set up SMTP+SSL to smtp.gmail.com. And then I wondered for a long time why that was failing.

Well, it's because I'm too lazy to read the damn manual.

It says so right on gmail (i.e., mail.google.com), SMTP requires TLS. It's POP3 that requires SSL. If I cared more about the asymmetry there I'd wonder why they aren't both TLS or SSL. But no, I'm too busy with other work to care about that just now :-). I'm just glad I can send mail out again without having to log into the web based gmail client. That's a great client (I was testing out mail.yahoo.com yesterday and that site is ridiculously slow on my ridiculously slow 800Mhz workstation :-), but I do prefer to have everything in one place, retreating to the web based client only in emergency (which is never, actually, since if I can't check my mail on my laptop or my work desktop, then I just won't check mail. I'm too paranoid to check my mail at internet cafes since they all run windows.

Wednesday, August 15, 2007

Windows is Free

Dave Gutteridge, on tlug.jp has a great article on how common windows piracy is and how that affects Linux uptake.

He says a lot of things I've always wanted to say but never had the time or patience to set down at such length.

Bravo.

Tuesday, August 14, 2007

HP sales versus newbie

A very good friend of mine went to buy a computer. I couldn't go with her, and she's comfortable enough financially that she doesn't need to find the cheapest computer, so she went to an HP reseller.

I prefer for her (and other newbies) who can afford it to buy branded hardware anyway (although I wouldn't necessarily go with HP, I'd go with something a bit cheaper, say Lenovo, or Acer). The presumption being that the hardware quality will be a bit better than that of pure clones and while it's possible to build superior boxes out of clone parts (with careful study of all the parts/options), I didn't have the time to help her with that, and she didn't have the knowledge (frankly, neither do I, anymore) to do that.

Well, the HP reseller sold her on the "fastest computer available", it came with Vista Home Basic and with evaluation versions of Home/Student MS Office 2007.

Gripe #1: the computer came with 512MB of memory. For a $1000 computer, there should be
1-2GB of memory in there.

Gripe #2: the CPU is 1.6Ghz. That's not a speedster by any standard. My laptop is faster
than that.

Gripe #3: Vista Home Basic is ridiculously slow. A lot of the user interface has changed
so it's difficult to find things.

Gripe #4: MS Office 2007 has completely discombobulated the user interface. I couldn't find
anything until, after some random clicking, we clicked on the icon at the top right
of the window (sort of like the [Start] button, except Vista doesn't have a start
button anymore, it's just an icon, in Office, it's a something button that brings
down a vertical menu because the former horizontal menu isn't there anymore).

Even the random clicking didn't help much at first since the computer is so slow
that clicking on that icon didn't do anything (or it caused some flicker as the
menu popped down and then went away instantly due to clicks elsewhere).

Boy, I'd forgotten how dumb windows makes me feel. And the fact that MS changes the user interface gratuitiously and so radically makes me wonder about its future. I'm not going to have any fun helping my friend with her computer. If I had the time I'd save her a bunch of money and get some other brand from any store other than the one she bought from, and definitely not HP either. Unfortunately, she's going to upgrade her computer to a better CPU and I'll go back there to help her set things up on it. The only fun I'll be having is when I surreptitiously repartition the drive and put Linux on there, and when I claim my unlimited beers. The beers will deaden the pain of working with Vista (yech) and Office (yech, yech, gaaak), and HP (gaak).

Thursday, August 09, 2007

10 things your IT guy wants you to know

Good article on 10 Things your IT guy wants you to know.

I like it because it's solution oriented and very mature. the very opposite of the BOFH

Saturday, July 28, 2007

no git-svn yet

I was going to test out git-svn, but I couldn't make heads or tails of it. So I'm working with svnmerge and I like it very much. It looks like git would be very nice to work with, but since I can't understand it for now, I'm going to watch linus' youtube presentation on git.

Linus is pretty irritating in the presentation, and vlc won't fast forward over the flv file I've got, so I can't skip the pointless part. I'm just going to have to sit through the whole thing I guess. Maybe mostly listen to it and only look at it when he discusses something that looks like the slide is important.

Thursday, July 26, 2007

backup and restore

I'm backing up my laptop's /home filesystem to my USB harddrive because I think it's time to change filesystems. /home is xfs. A few weeks ago though I found what seems to be a bad sector on that partition (an ISO image on /home had sections that were unreadable, although the same CD that the ISO was built from was perfect). Unfortunately, neither XFS nor JFS has the capacity to accept badblocks output so that the blocks found bad can be marked unusable (decreasing usable disk space a bit, but keeping data safe).

So I'm backing up my data (damn it's taking a long time to backup 37GB over a USB cable) so I can reformat /home as reiserfs (likely) or ext3 (less likely). And then it'll be another night of running badblocks so I can feed that to the new filesystem.

This isn't a big deal. I'm reading widely and playing chess against crafty (and losing every game). So it's not time lost. I'll go to bed soon and hope (but unconsciously) that the backup will be done by tomorrow morning, so I can format, badblocks, and slowly copy the data back.

This laptop doesn't have any S.M.A.R.T. options in the BIOS, so I can't take advantage of those options (apparently JFS and XFS rely on S.M.A.R.T. to handle bad blocks for them). Heck, since Ubuntu makes the IDE drive look like a SCSI drive, I can't even hdparm -d1 /dev/sda. I get:


/dev/sda:
setting using_dma to 1 (on)
HDIO_SET_DMA failed: Inappropriate ioctl for device


Yech. There's probably a way to force Ubuntu to treat the drive as an IDE drive instead of emulating SCSI for it. I haven't gotten around to surfing for that solution though. It's not important enough just yet.

The next morning: Wow, badblocks has gone through just a fourth of the disk and the badblocks file is already 135MB. I think I'll have to go with ext3 instead of reiserfs so that I can take advantage of the -c parameter to both mkfs.ext3 and fsck.ext3. Yech, I've always had more problems with ext2/ext3 than with reiserfs/xfs with corruption after powerloss. But I'm going to have to bite the bullet here. And anyway, it's a laptop. The only time the OS wouldn't be shut down correctly would be if there were some sort of kernel panic (haven't got those in a long time, since I stopped compiling and using win4lin kernels) or if I were to turn the laptop off. The battery works as a UPS, so I won't get instant off when the wall power goes out.

I should really buy a new harddrive, of course. I'm not able to just yet though, so I'll limp along with this one and make weekly rdiff-backups to the USB drive, and another rdiff-backup everytime I transfer pictures and videos of Timmy from the digital camera. :-)

Thinice

I thought I'd look for an Ubuntu (gnome) desktop theme I liked. So I looked around and tested the themes in System | Preferences | Theme. I didn't much like what I saw, but then I clicked on "Customize" and, testing the different themes there, found that I liked the *darkness* of the Thinice theme.

I tend to lower the brightness of the screen on any computer I use. Even on a laptop LCD, I prefer for the screen to be less bright. That isn't consistent with the dark text on light background of my terminal windows, but there it is, Very well then, ... I contain multitudes.

In any case, I liked thinice and I'm going to move all my computers (work and home) to that theme :-). The scrollbar sliders are cool too.

Monday, July 23, 2007

DRY

So this code I'm working through (it was supposed to be a trivial exercise in fixing brace style) has turned into a nightmare. I can understand when people copy and paste some code. Maybe copying and pasting the same code twice or three times is OK, although three times is stretching it. BUT GODDAMN IT, MUST THE SAME DAMN CODE BE COPIED 23 TIMES????

And it's not just one function it's more like 8 functions copied and slightly modified (or not modified) all over the place. If this had to be done at the beginning because there was no time to refactor, __NOW__ is the time to refactor because any bugs that come up (will need to be fixed 23 times. And I guarantee that at least of those bugs will be missed.

Parameterize, abstract, and remove redundancy. Dammit.

Oh yeah, that's Don't Repeat Yourself.

the root of all evil

Alright, it's not all that evil, but I'm looking at this PHP code:


$message = 'Hi, ' . "\r\n";
$message .= "\r\n";
$message .= 'Your account at ' . $this->domain . ' is awaiting activation.' . "\r\n";
$message .= "\r\n";
$message .= 'To activate your account, please visit ' . $this->domain . '/members/activate/' . $activation_key . "\r\n";
$message .= "\r\n";
mail($to, $subject, $message, $headers);


And I'm thinking,

  • mixing single quoted strings and double quoted strings.
  • mixing single quoted strings, double quoted strings, and concatenating variables instead of putting them inline


I don't care too much about the strings being hardcoded, the app doesn't need to be multilingual, yet. But I'm struck by the fact that in the attempt to optimize (in PHP, single quoted strings are faster than double quoted strings since the runtime doesn't need to try to do string interpolation (parse the string to find variables, and replace the variables with their values).

On the other hand, this code is going to send mail. This is a classic too early optimization. The network will be the bottleneck, or writing the file will be the bottleneck (if we write the emails into a file first for batch sending later [which isn't relevant for the concrete case, the email is sent immediately, see the mailto(...) function call]). And it's harder to read (mixing two kinds of strings always is, and in fact the code is mixing three kinds of strings, the third being variables. Code for maintainability first, code for performance only after profiling and finding the hotspots in the code.

Sunday, July 22, 2007

ionice!!!

Hot damn! ionice is incredible.

I was going to say "nice", but that would have been obvious and shallow.

I know, that's a link to a short tutorial on how to use ionice, I like short tutorial links though, so I can test something out quickly.

I'm installing something very IO heavy in vmware. This is on a single-core 1.5Ghz, 1.25GB Ram laptop (slow IDE hard drive). Before ionice, the browser and sometimes all of X would stall on me for some seconds (30-40) before getting more responsive. I don't mind if the vmware process takes a long time to run. If it finishes tomorrow, well, I'll just sleep through it. So it's very nice to be able to lower its IO priority so that it doesn't make the laptop completely unusable when it's shoveling gigabytes around on the disk.

Highly recommended. Requires at least kernel 2.6.13 though. I've already asked the system administrators at work for one of the debian servers at work to be upgraded to 2.6.13 or higher. That box runs a very long running doxygen process that makes everything else crawl for a while. It'll be great to get some of that performance back :-).

Saturday, July 21, 2007

trying out git-svn

I've got a pretty good solution to the merging problem in svn. I've also previously used svk for disconnected work. I couldn't stand the ugly commit messages svk created though. I'm now testing out git-svn. If the commit messages from git-svn are reasonable, and there are no problems with branches and merges and commits to svn, and it runs very fast, then I may personally switch to it.

If git-svn works out as well as promised then I'll switch to using it and the others on my team can decide whether they want to stick with pure svn or try out git-svn.

svnmerge heaven

There are three major problems with subversion.

  • It's slow
  • You have to be online to the repository to do many operations (not distributed)
  • Merging is hard

Git apparently solves all those problems. So says Linus on youtube.

I haven't used git and I'm not likely to at $DAYJOB. It took a long time to convince the developers and system administrators at $DAYJOB to actually use svn and I'm not done with the conversion yet, technical support isn't on the version control bandwagon yet. So there's just no way I'm going to spend another year or two convincing people to switch to git from subversion.

I don't worry too much about being online to do most operations. At the office I'm online to the svn server, and at home or anywhere else with an internet connection I can get through to the office on the VPN. If I'm not online, well, I just won't work. Or I'll work with svk if necessary.

The current full working copy (including branches) at work is pretty large, so an svn status on that *is* pretty slow. Even svn status on just the trunk is slow. But we work around that by avoiding working at the top of a branch unless it's really necessary. Working in individual subdirectories is much faster and the only time we ever need to work at the top of a branch is when we need to see what all the uncommitted changes have been to that branch, or when we need to do an svn log to see what all the committed changes have been to the branch.

For a long time though, I would make branched tags but would not actually do experimental or development branches because, while branching is easy, merging was painful. It could be done, but it was so inconvenient I never tried to do it.

Finally, svnmerge has landed. Svnmerge is a python program (on Ubuntu feisty, part of the subversion-tools package) that takes the tedium and complexity out of merging in svn. The link above has a good introduction to svnmerge. I learned the basics, though, from Ken Kinder's little howto for svnmerge.

I've tested it out once or twice with real branches at work, it works pretty well and hasn't failed me yet. I wouldn't be surprised if there were some weird or extreme corner cases where svnmerge could get confused and do the wrong thing, but I'll worry about that when I get there. I haven't seen any reports of that yet and I intend to stay away from the more complex features anyway unless I really need them (e.g., no bidirectional merge until at the end, when the experimental branch is stable and is ready to be fully merged back into the trunk). In any case, I expect that development on svnmerge will fix any such showstopper bugs before I ever see them since I intend to be as considerate and conservative as I can be when using svnmerge ;-).

I'm very happy that merging in svn is finally convenient. It's been a long time, I've done my share of hand-merging branches. I'm glad that tedium is going away.

Wednesday, July 18, 2007

firefox multi-tab home

Long ago I knew that firefox supported multiple-tabs for the "Home Page". And then I forgot.

Just the other day I rediscovered this. It's very convenient. My "Home Page(s)" button now opens


  • a cacti tab to monitor the database server, our internal time tracking web page,
  • a gmail tab,
  • a tab that opens our internal doxygen documentation and,
  • because I'm studying svnmerge, since I've been waiting for decent merge support in svn since early svn betas:
    Ken Kinder on "Subversion merge tracking with svnmerge"

Tuesday, July 17, 2007

SQL subtotals, grandtotals

I really should google more. I sat down and thought for several hours trying to find a way to get running totals out of an SQL query. I should really give up earlier so I could have googled and found:

SQL Server: Calculating Running Totals, Subtotals and Grand Total Without a Cursor


It's got some SQL-Server-isms in there but it's generic enough that I learned the basic technique pretty quickly and implemented it in postgresql. I got my query to use running totals, and used that as a springboard to getting running balance working. I haven't yet gotten around to getting subtotals and grandtotals working, but I'm sure I'll get around to that soon, SQL use where I work is getting more sophisticated. Years ago the code used monkey-see-monkey-do and mysql style treating the database as a dumb datastore. We're on the way to something between mysql style dumb queries and doing joins in php and oracle style "do everything in the database". I think both styles have their appropriate niches, but our systems are in neither of those niches, we need to be more moderate, using SQL where it's appropriate and business logic in applications where *that's* appropriate.

Monday, July 16, 2007

minimal centos vmware image

I had to build a minimal centos 4.4 vmware image recently. Two projects I'm working on use centos because our team systems administrator is an RHCE, so he uses a familiar distribution. I don't much care which distribution I use. CentOS is fine as long as I can get reasonably new versions of the software I require (php, postgresql).

In fact CentOS 4.4 isn't that distribution, with php stuck at somewhere around 4.3 and postgresql at 7.4. But it's certainly stable. And I can build any necessary software from source, so I don't feel any great need to upgrade to 5 (although we should probably have a plan for that upgrade path for sometime in the next 6 months).

For this distribution, I had to install Oracle 10g Express Edition (for learning Oracle, and for prototyping). That makes the installed VM bloat up by a lot. I went through the installed RPMs and removed everything I didn't think I'd need (and a few things that I found I needed later on). Later, I had to reinstall some development packages since I needed to build php from source (because I couldn't figure out how to get CentOS' built-in php to talk to oracle). I eventually wound up installing php 5.3.2 since I couldn't get php 4.3.9 to do what I wanted (connect to oracle). That's probably pilot error, but I don't mind the upgrade, and if there are incompatibilities with the installed php 4.3.9 on the deployed live servers, well, I'll ask the team sysad to deploy 5.3.2 there (after some paranoid testing on the vmware image).

After building php, I removed the development packages again :-). For when I need the list again:

gcc apr-devel gcc-c++ libtool bison flex make
autoconf automake cpp db4-devel apr-devel
glibc-devel glibc-headers apr-util-devel
httpd-devel libstdc++-devel openldap-devel
openssl-devel pcre-devel postgresql-devel
zlib-devel libpng-devel libxml2-devel

The vmware image we use doesn't have any X anything in there except what is needed for vmware-toolbox (useful for resizing). I thought that I absolutely needed to have X actually running in the VM. That may have been true with older versions of vmware, but with the free vmware-server, I can safely do X11 forwarding over ssh and do the vmware-toolbox resizing using the X on the host. No need to have gnome and all the rest of the packages it pulls in just for resizing the vmware virtual drives.

Tuesday, June 26, 2007

vmware networking - wireless bridge, nat problems

I was setting up a vmware image of Ubuntu Feisty the other night and I had a heck of a time with the networking. I went through and tried bridged, nat and host-only. I couldn't get bridged or nat to even talk to the host computer. host-only could talk to the host, I could even get it to NAT to the wifi-router, but I couldn't get it to go past that.

I wiped that image and redid the work and now I've got it working. The first basic problems was that I didn't look in dmesg. On ubuntu, it's necessary to use vmware-any-any to get vmware to work with the Ubuntu kernels (or something, in any case, something doesn't work, maybe compiler issues, and it's necessary to patch with vmware-any-any so that the vmware modules will compile).

After I finally looked in dmesg, there was a section that said that vmware bridge over a wifi device doesn't work with vmware-any-any. OK, next up was nat.

That didn't work either. It wasn't until I rebuilt the image (in fact, uninstalled and reinstalled free vmware-server) last night that I finally got nat working. Previously I had used vmware-config.pl to edit the networking settings (using the editor) and I had decided to always use vmnet0 for the bridge, and then later the nat, and later host-only and then, in the vmware client, chosen BRIDGE, NAT, HOST-ONLY as appropriate. That doesn't always work because apparently vmware has some sort of mapping for the vmnet numbers. Choosing NAT but having manually edited it at vmnet0 makes it not work because NAT starts at around vmnet8.

The trick, I found last night, was to select CUSTOM and then select the correct /dev/vmnet[0-9] entry. I've got networking working now (NAT though, since bridging on a wireless device still doesn't work) and have got the rest of the project done (install oracle 10g express edition with a small sample database, for use by my team in testing an oracle application we're developing for a large government owned corporation).

Oh yeah, and to solve it without a trick (i.e., canonically), just use the network connection wizard. It'll choose the correct number for the vmnet device type that you want to use. I like having things numbered sequentially though, which is why I got into trouble in the first place.

Sunday, June 24, 2007

Oracle bogosity - no boolean column type

Oracle has no boolean column type. That is, in a create table statement, you can't say:
MY_BOOLEAN_COLUMN boolean
I've seen some discussion of this and most of it boils down to what Tom Kyte says, that you don't need a boolean type since you can use an integer(1/0), a character(T/F,Y/N,even 1/0) or anything you like. I suppose you could use varchar(5) and use "true" and "false".

For a while I accepted this explanation, until I ran across an oracle database that had boolean types using all of these conventions (in different tables, although I did see T/F and Y/N for different columns in the same table!).

Of course it was implementer error that they didn't use check constraints on those pseudo-boolean fields. So in the integer field, it was possible to set the "boolean" to 314. and in the character fields, well, it was possible to have T/F/Y/N/1/0 all in the same column (fortunately, the character field was limited to one character, else I would have had even more fun with that stupidity).

I suppose Oracle is that way (bogus) because of legacy code, compatibility issues, and inertia. I can see internal discussions going sort of in the direction of creating a boolean type but stopping short of actually doing so because it just seems so hard, or no one wants to rock the boat and introduce potential compatibility issues (e.g., when oracle software uses boolean, and then won't work with oracle installations which didn't have the boolean type).

Another problem, of course, is that anyone confused enough to use all those different encodings for pseudo-booleans, and worse, IN THE SAME COLUMN with no check constraints, is going to continue being confused when the boolean type is introduced. They won't use the boolean type, they'll continue using their iodine-deficiency-generated solution. But just because idiots will continue in their idiocy is no reason to avoid doing the right thing. As it is, when a boolean field is concerned, there's going to be a discussion as to which convention to use and then there's going to be a random choice (unless the shop in question has advanced to the point of having a convention for boolean fields, in which case I say, bravo). If a true boolean column type were available, the canonical answer would be to use that. Iodine-deficient DBAs could still use their non-boolean hacks, but at least a canonically correct solution would exist, guiding iodine-sufficient (but trained by incompetent or iodine-deficient DBAs) in the right direction.

Friday, June 22, 2007

auto-convert images for blog

Sol and I take a lot of pictures. The camera automatically names them (with zero prefixed integer sequential filenames) but it's very easy for filenames to collide (two different days can have 000001.jpg files). I also take pictures at a rather high resolution. The resulting images take up a LOT of space.

I wrote a shell script that, with the help of GraphicsMagick (or ImageMagick) takes all those jpgs and creates two files, one a thumbnail (ending in -th.jpg) and one a large images (ending in -1024.jpg). The date of file transfer (from camera to laptop) is prepended to the image name so that filename collisions become impossible.
irec
I originally put the thumbnails and -1024 files in separate directories. Now I put them in the same directory so that the files are easy to upload to photobucket (they're in the same directory, so clicking on the Browse to select an image button brings me to the same directory. It's very easy this way to upload the thumbnail and the -1024 together).

I still keep the thumb directory around but I populate it with links from the "smaller" directory. Keeping thumb around doesn't really make sense anymore. It's not like I have programs or scripts that depend on existence or contents of that directory. Just laziness, I guess.

If the script were named "picstoblog" (see below) I would do something like the ff to process all the directories in my Pics directory.

for fn in *
do
if [ -d $fn ]
then
pushd .
cd $fn
picstoblog
popd
fi
done


----
picstoblog script below, some things could be improved (mainly be simplifying/eliding, e.g., thumb), but i don't care enough to actually do the fixes)
-----

#!/bin/bash

if [ ! -d thumb ]
then
mkdir thumb
else
rm -f thumb/*
fi

if [ ! -d smaller ]
then
mkdir smaller
fi

for fn in *.jpg
do
base=`basename $fn | cut -f 1 -d '.'`
d=`pwd | cut -f 1-3 -d "-" | sed "s/-//g"`
d=`echo $d | basename $d`

sm=$d-$base-1024.jpg
th=$d-$base-th.jpg

if [ ! -f smaller/$sm ]
then
gm convert -scale 1024x768 -quality "70%" $fn smaller/$sm
fi

if [ ! -f smaller/$th ]
then
gm convert -scale 200x150 -quality "50%" $fn smaller/$th
fi

# for older files, remove if already there so can link
rm -f thumb/$sm
ln -s smaller/$sm thumb/$sm
ln -s smaller/$th thumb/$th
done