Monday, February 11, 2019

New Favorite Trackball - Elecom M-XT3UR


Years ago, I was dealing with carpal tunnel syndrome pain, pain that would keep me awake at night. I built my own braces, built a sling where I could sleep with my hands elevated at night. I was trying a bunch of things and wanted to avoid surgery. Some of my friends had benefited from surgery, some had not. I stumbled onto split keyboards and trackballs. With split keyboards and trackballs, I found the pain diminishing, to the point today where I rarely think about pain. For me, split keyboards and trackballs let me type all day.

For keyboards, my favorite is the Microsoft Wired Natural Ergonomic Keyboard 4000.

For trackballs, my favorite has been the Wired Logitech Trackman Wheel, T-BB18. These have been out of production for years, and I have been replacing them with the Wireless Logitech Trackman Wheel, M370. The M370 is pretty good, except for the batteries. The batteries last a long time, but when they start going low, double clicking, dragging, and other operations get a bit flakey. This drives me nuts when I am trying to get something important done and I can't get double clicks to work cleanly. I really want a wired trackball. I don't want to worry about batteries.

Many recommended the Wired Elecom M-XT3UR as a replacement, and I can support that recommendation. Its a bit smaller than the M370 and I think I would like a trackball that is larger than the M370, but after a weekend I feel at home and find myself wanting a spare to take into work. I want to replace my M370s with the Elecom trackballs.

Thumbs up to the Elecom M-XT3UR.

Monday, September 17, 2018

LetsEncrypt


This weekend, I decided to try the EFF’s LetsEncrypt certificates. It was easy for Apache, not as well worked out for Postfix/Dovecot.

My self signed certificates on a couple of my Linux boxes have been torturing me when using Apple Mail. Apple is doing the right thing trying to warn you about self signed certificates.

I tried to go straight to the EFF email solution STARTTLS. After fumbling around with that for many hours, I decided I would get Apache working and then tackle Postfix/Dovecot. I don’t really want Apache on these boxes nor do I want them exposed directly to the internet, but it seemed like a good way to start understanding LetsEncrypt.

I cleared out all the Apache stuff that I had played with previously on a Debian system, reinstalled Apache2, and used these instructions to get the LetsEncrypt certificate installed:

https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04

I looked at a number of different pages about LetsEncrypt and this set of instructions seemed straight forward.

I poked a hole in my firewall for apache, which was necessary for LetsEncrypt and setup a public DNS entry for that Debian box.

The Apache certificates installed painlessly.

Next I tackled the Postfix/Dovecot certificates. I ended up using this set of instructions:

https://www.upcloud.com/support/secure-postfix-using-lets-encrypt/

This took more fumbling around but it works and now my Apple mail is happy with reading mail from my main Debian box.

I decided to leave the Debian box with the default web page up overnight in case I discovered something that would require re-doing the certificates.  Oh wow! The internet is a dangerous place. I thought nobody would notice my Debian box. The logs this morning were just full of random IP addresses trying all sorts of non-existant URLs, most ending in “.php”. I was glad I had cleared out all my old experiments and reinstalled Apache. I had what I wanted, so I turned off all external access again.

For Apache, LetsEncrypt is easy. I’m am going to play more with STARTTLS and see if I can find a way to make easy to do. Maybe I’m just misunderstanding something.

Monday, June 18, 2018

Plug for SportsTalkDM.com

This is a shameless plug for my cousin’s boy Daniel.

Daniel has been quoting sports scores to me since he was 6 or 7 years old. I think he got his iPod when he was about 8 and he would sit in his room with his little miniature NFL helmets in front of him and make videos of himself commenting on upcoming football matches. A few weeks back, the now 14 year old Daniel asked me, what I would use to make a website.  Since then he has created a website, SportsTalkDM.com, Sports Talk with Daniel, and a Patreon page, Patreon.com/sportstalkdm and posted a bunch of content. I think his NFL article is pretty good for a 14 year old. Like most first time web authors, he is watching for every page view. I haven’t helped him to this point, but I probably will this weekend, since adding the Javascript for Google AdSense has got him stumped. I would appreciate if anyone could click on his page. He doesn’t have feedback or anyway to comment on his main site, but you can comment and like on his Patreon page. I think this is pretty good and I want to try to encourage him.

Friday, December 29, 2017

DO-178B/C Friendly Debugging Macros


Sorting through some PDFs and a PDF I had saved if from a friend, Mike Potts, mjp66@sbcglobal.net, that is worth talking about.

In DO178B/C code, you want each line of code covered by a requirement or requirements, and ideally nothing else. The requirements say what you are going to do and only what you are going to do. Every DO178 project I have been in has had to deal with dead or deactivated code. There are many cases where you would like to keep some debugging code in there that you could re-activate when things go wrong to see information. Mike has a set of C macros that leave no code behind when compiled for production. Not even stray semi-colons.

I have used this philosophy many times over the years and keep a set of notes he gave me long ago about how to use this:


Hello, 

Ed asked about debug printf.

Here is how it works, you enable Serial-Input-Output (SERIO) Debugging Prints with #define SERIO_DEBUG.

To issue a debugged printf, you call it with two parentheses and NO semicolon.

Yes it looks weird, and takes some getting use to, but watch.

SERIO_DEBUG_MSG(("NMEA Semap, BUSY %11d\n", hi_pri_clock_read()/TICKS_PER_MS_HIGH))

A bunch of these macros are stored in the debugging module's header file:

#if (defined(SERIO_DEBUG))
#define SERIO_DEBUG_MSG(macro_string) printf macro_string;
#else
#define SERIO_DEBUG_MSG(macro_string)
#endif

If SERIO_DEBUG is defined, then the SERIO_DEBUG_MSG and the first set of parentheses turn into a printf and a semicolon.

If SERIO_DEBUG is not defined, the while macro disappears (and does not even leave a semicolon behind).

This is kinda nice, not even a semicolon left behind to disturb certification. I like pre-processor tricks.
If you want to carry this idea forward, you can use something similar to:

#ifdef LINK_ERROR #include <debug.h>
#define GPS_ERROR_MSG(macro_string) {debug_msg macro_string; debugbreak();}
#else
#define GPS_ERROR_MSG(macro_string) debug_msg macro_string;
#endif

This error printf happens to be writen as non-maskable, but can optionally issue a debugger break statement that is provided by a specific tool set.

We were consistent with this naming convention.

Enables were always *_DEBUG, and the associated debugging prints were always *_DEBUG_MSG.
This allowed us the option of sprinkling some extra computation code (within #ifdef *_DEBUG) near the printfs and still 'clearly' be debugging code.

These was also a master debug_on macro to globally enable the whole group.

-Mike

Mike is a really sharp guy and always goes that the extra distance to make things right. One of his recent project's was to put together a really excellent setup guide for the Ubiquity EdgeRouter X, a fantastic little router. His setup guide was mentioned on Security Now, Episode 641, before Christmas and can be found at https://github.com/mjp66/Ubiquiti


Friday, September 09, 2016

PowerPC Ubuntu Installation on PowerPC Mac Mini

Just my quick notes:

PowerPC Linux on Mac Mini, 7447a, September 9, 2016

  • I haven’t had success with high resolution monitors, I had to use a 1024x768 monitor and the 1280x1024 monitor from work also functioned correctly
  • ISO Image for Ubuntu Power 14.05 from Ubuntu
  • live radeon.agpmode=-1
  • You need the radeon.agpmode=-1 to keep the graphics from locking up.
  • Double click the install icon on the desktop
  • Don’t add extra options like download the packages while installing.
  • You may have to manually erase all partitions, if it’s getting hung up go into the advanced (manual) partition setup, erase all the partitions and start the installation from scratch.
  • Create the encrypted disk, default partitions
  • Encrypt home directories
  • Boot the installation with “Linux radeon.agpmode=-1 video=radeonfb:1024x768”
  • Edit /etc/yaboot.cnf, find the “append=“ and add “radeon.agpmode=-1 video=radeonfb:1024x768”
  • /bin/ybin -v to update the kernel




Sunday, May 08, 2016

Find where a routine is defined in shared libraries.


I can't find a reasonable Linux command that will let me search all the shared libraries defined by the ld.conf configuration and LD_LIBRARY_PATH. I keep ending up grep'ing through all the directories. So here is a short script on github:

https://gist.github.com/edt11x/13212082576ca7ceba227422e621c8d8

Friday, April 08, 2016

Apple Pencil Case

First attempt at a Apple Pencil case. My thought was that copper would look nice.








I am going to try Plumbers Caulk for a soft closed end.


Let that dry standing up.


Quick wood interference fit cap to start with.











Friday, December 18, 2015

Google Fi Charging Stand


Some notes about the Google Fi Charging Stand:





*  2 - 8x8 green base plates
* 13 - 4x1 green bricks
*  5 - 6x1 green bricks
*  2 - 2x1 green bricks
*  5 - 6x1 light blue bricks
* 10 - 4x1 light blue bricks
*  5 - 2x1 light blue bricks
*  2 - 2x1 yellow angled bricks
*  2 - 2x1 yellow bricks
*  5 - 4x1 yellow bricks
*  1 - 6x1 yellow brick
*  1 - 2x1 white brick
*  2 - 6x1 white bricks
*  2 - 4x1 white bricks
*  2 - 3x1 angled white bricks
*  1 - 4x1 light green brick
*  2 - 3x1 angled light green bricks



Saturday, May 12, 2012

Installing Apple Packages Remotely

I have a Mac that I maintain remotely and I have been using the command line software update to install the standard Mac updates.

# softwareupdate --list

# softwareupdate --install --all

I didn't know I could do the same thing for packages until this morning when the 10.7.4 update broke one of my macs in a weird way. I could do many things as long I didn't touch the menu bar or some dialog boxes. If I did, the program seemed to hang in using the shader compiler to send stuff to the ATI chip.

I downloaded the 10.7.4 Combo Update from Apple, but I could not launch the Installer.

This article gave me the info I needed. 

http://hints.macworld.com/article.php?story=20030614230204397

I found out I can run package updates from the command line.

sudo installer -pkg MacOSXUpdCombo10.7.4.pkg

 

Sunday, February 26, 2012

Get a List of Installed Packages in Debian

Note to self:

To save:
$ dpkg --get-selections > installedPackagesDate.txt

To recover:
# dpkg --set-selections < installedPackagesDate.txt && apt-get dselect-upgrade

Sunday, February 19, 2012

Know Your Mac

Here's a list of known process names for Mac applications that I think is formatted in a helpful way:

http://triviaware.com/macprocess/all

 

Sunday, January 22, 2012

StreamFree.TV

A site that ranks some of the Roku channels and channels that are not in the Channel Store:

http://streamfree.tv/

Between the Roku, iTunes and Podcasts, I am overloaded on things I really want to watch, but don't have time.

Saturday, January 21, 2012

MarsEdit - New Favorite Blog Tool

 

MarsEdit works well for what I want to do with it.

http://www.red-sweater.com/marsedit/

My old favorite Blogo, appears to now be a dead product. It doesn't work with Mac OS X Lion, and there doesn't seem to be any activity to fix it.

I also give MarsEdit extra points for being available in the Mac App store.

 

Manually Deleting Mac Applications

 

My quick list of things to look for when deleting Mac applications manually. Most mac applications seem well behaved and only populate things in /Applications and maybe a couple things in ~/Library. Other applications seems to try to put things in all sort of directories and even their own uninstaller doesn't clean up after them. Today's problem child is Mark/Space's Missing Sync. I ran the uninstaller, but it left behind a lot of stuff. So this is just my list of places to go look to uninstall the remaining pieces of applications.

  • First look to see if they have an uninstaller in /Applications
  • Re-download the package and see if the package comes with an uninstaller.
  • Applications, look for Applications and Folders named for what you want to uninstall.
  • Run AppZapper if there is no uninstaller
  • /Library/Application Support
  • /Library/Frameworks
  • /Library/Preferences
  • /Library/LaunchAgents
  • /Library/LaunchDaemons
  • /System/Library/Extensions
  • ~/Library/Application Support
  • ~/Library/Preferences

 

 

Monday, December 20, 2010

Manually Connecting to an SSL IMAP Server

A good quick article on how to manually log into an IMAP Server using SSL is at:

http://www.jaharmi.com/2007/09/26/using_openssl_securely_connect_your_imap_account

The important part is:

As an example, here’s how you could log into an Exchange account, select the “Inbox” folder, and log out:

$ openssl s_client -connect server:port -crlf
? LOGIN username password
? SELECT Inbox
? LOGOUT


Thursday, October 28, 2010

Wednesday, May 12, 2010

Minimal OpenGL Program on RedHat EL 4.0

Here is a minimal OpenGL program on RedHat EL 4.0. The Makefile:



all:
gcc -L/usr/X11R6/lib -L/usr/X11R6/lib/modules/extensions exampleGlx.c -o dssglx -lX11 -lglx -lGL

And the program:



#include <GL/glx.h>
#include <GL/gl.h>
#include <X11/Xdmcp.h>
#include <unistd.h>

static int attributeListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };
static int attributeListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };

static Bool WaitForNotify(Display *d, XEvent *e, char *arg)
{
return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
}

int main(int argc, char **argv)
{
Display *dpy;
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
Window win;
GLXContext cx;
XEvent event;
int swap_flag = FALSE;

dpy = XOpenDisplay(0);

vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeListSgl);
if (vi == NULL)
{
vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributeListDbl);
swap_flag = TRUE;
}
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);

cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
swa.colormap = cmap;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 100, 100,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
XMapWindow(dpy, win);
XIfEvent(dpy, &event, WaitForNotify, (char*)win);

glXMakeCurrent(dpy, win, cx);
glClearColor(1,1,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
if (swap_flag) glXSwapBuffers(dpy,win);
sleep(10);
}
</unistd.h>


Sunday, November 08, 2009

A simple description of how to use Autotools


From

http://smalltalk.gnu.org/blog/bonzinip/all-you-should-really-know-about-autoconf-and-automake

A very good description of a simple use of autoconf and automake:

The problem with autotools is that it is used for complicated things, and people cut-and-paste complicated things even when they ought to be simple. 99% of people just need a way to access .pc files and generate juicy Makefiles, the portability part is taken care by glib, sdl and so on.

The most basic autotools setup is 9 lines.

configure.ac:

AC_INIT([package], [version])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_HEADERS([config.h]) # not really needed
AC_PROG_CC # or AC_PROG_CXX
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefile.am:

bin_PROGRAMS = hello
hello_SOURCES = hello.c

And you're ready for:

$ autoreconf -fvi
$ ./configure
$ make

On top of this, for each package you need, you add:

PKG_CHECK_MODULES([cairo], [cairo])
PKG_CHECK_MODULES([fontconfig], [fontconfig])

AM_CFLAGS = $(cairo_CFLAGS) $(fontconfig_CFLAGS)
LIBS += $(cairo_LIBS) $(fontconfig_LIBS)

respectively in configure.ac (after AC_PROG_CC) and Makefile.am. Is that complicated?


Saturday, September 19, 2009

Time Machine Restore - A Pleasant Experience


I recently had a disk go bad in my iMac. The disk would often boot if the computer was cold but then would start having errors as it warmed up and ... corrupting files.

I have never had to test any of my Time Machine backups for a real purpose. I was concerned that I would find that not all the files I needed would be restored or I would find I only really had partial backups. I have had many bad experiences over the years with untested backups, including backups done by sys admins. So I doubted that Apple's magic backup would be complete.

So I stuck a blank hard disk in the machine and booted the 10.5 install CD. At this point you have two options, install a fresh copy of Mac OS X and restore your files and settings, or just restore everything from Time Machine. I chose to restore everything from Time Machine, started it and went to bed.

I was pleasantly surprised to find a complete restore. I had to resync my dot mac data and a couple little things. The worst one was the ~/Library/Caches directory was not created with permissions for me to write to it. But overall, I was very happy.


Thursday, August 20, 2009

Simple OpenGL Texture Example

Here is a simple example of code to use an OpenGL Texture.





// Apple gcc program0.c -framework opengl -framework glut
// A simple OpenGL and glut program
#include <GLUT/glut.h> /* Header File For The GLut Library*/
#include <stdint.h>

//
// You need to generate the texture data that you are going to
// use. GIMP will convert a bitmap, jpg, etc. to a "C" structure
// that you can use almost directly.
//


// GIMP RGBA C-Source image dump (f35_schem_02_edit_4.c)

static const struct {
uint32_t width;
uint32_t height;
uint32_t bytes_per_pixel; /* 3:RGB, 4:RGBA */
uint8_t pixel_data[128 * 128 * 4 + 1];
} planform = {
128, 128, 4,
"\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
"\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0"
"\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
// ... much of the texture deleted
"\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0"
"\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377",
};


// The routine to draw the screen
void display() {
// A value to hold our texture handle
static uint32_t texture = 0;
static int32_t firstTimeDone = 0;

// Clear the display
glClear(GL_COLOR_BUFFER_BIT);
// Set the color to white
glColor3f(1.0, 1.0, 1.0);
// Setup the coordinates to what I am used to
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

// Get a texture number if we dont have one
if (!firstTimeDone)
{
// Get a texture number
glGenTextures(1, &texture);

// Tell OpenGL that we want to use that texture
glBindTexture(GL_TEXTURE_2D, texture);

// You have to tell OpenGL how to take the raw bitmap data
// in the structure above to put it into a texture. We
// do this with a glTexImage2D() call. We will describe the
// structure above and how we want it stored internally in
// OpenGl.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, planform.width, planform.height,
0, GL_RGBA, GL_UNSIGNED_BYTE, planform.pixel_data);

// OpenGl lets you describe how you want to scale the
// texture data when the destination is bigger or smaller
// than the original texture data. In this case, we want
// simple linear scaling.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// First Time is done
firstTimeDone = 1;
}
else
{
// Tell OpenGL that we want to use that texture
glBindTexture(GL_TEXTURE_2D, texture);
}

// We are going to put the texture on a 2D surface, much
// like we would apply a decal.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

// Normally you leave GL_TEXTURE_2D turned off unless
// you are applying a decal to a surface. Since we are
// doing that, we turn it on here.
glEnable(GL_TEXTURE_2D);

// Draw the square
glBegin(GL_POLYGON);

// Here we want to associate a point in the texture with the
// vertex we are drawing on the screen. So these are paired up.
glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5, -0.5);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5, 0.5);
glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5, 0.5);
glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5, -0.5);

// End of the list of verticies
glEnd();
// Turn texture drawing back off, normally we leave if off.
glDisable(GL_TEXTURE_2D);

// Flush the data. In many drivers, this causes the
// actual draw to the Frame Buffer.
glFlush();
}

int main(int argc, char **argv) {
// A minimal GLUT setup to get GLUT up and going.
// If you use EGL or some other windowing system
// other than GLUT, you need to replace this.
glutInit(&argc, argv);
glutInitWindowSize(512,512);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("The glut hello world program");
glutDisplayFunc(display);
glClearColor(0.0, 0.0, 0.0, 1.0);
glutMainLoop(); // Infinite event loop
return 0;
}

</stdint.h>