Talkd and Debian Lenny 5.0.4
June 24th, 2010
When working with other developers, I like to chat on the server itself using talkd. Talkd is the server that notifies a user that someone else wants to initiate a conversation. It acts a repository of invitations, responding to requests by clients wishing to rendezvous to hold a conversation
apt-get install inetutils-inetd apt-get install talk apt-get install talkd
vi /etc/inetd.conf
Make sure you have in the /etc/inetd.conf the following:
talk dgram udp4 wait root /usr/sbin/in.talkd in.talkd ntalk dgram udp4 wait root /usr/sbin/in.ntalkd in.ntalkd
/etc/init.d/inetutils-inetd restart
How to fix the Gulf Oil Spill
June 9th, 2010
Three steps
1) The US government authorizes the release of gold from Fort Knox, via National Security or Executive Order
2) Chop it up into fine powder and mix the powdered gold with biodegradable material, so that it floats and will stick to the oil.
3) Seed the oil slicks with about 1 ounce per cubic foot of oil, on average.
RESULT: You’ll have lots of companies out there sucking the oil up, getting the gold and reselling the oil. you’ll have a gold rush on the beaches. You’ll have people out there getting the oil off the beach (to get the gold).
You’ll generate a short term micro-economy in the Gulf area, as support services are needed to support the gold rushers (hotels, restaurants, food, and equipment!).
Why not? The gold in Fort Knox does nothing, as is. It just sits there. About 4600 tons of gold is available. http://en.wikipedia.org/wiki/United_States_Bullion_Depository
Courier IMAP on Debian Lenny with Apple mail.app
February 18th, 2010
If you maintain various virtual domains on a Debian Lenny box you can use Apple’s mail.app to access each virtual domain so you can send/receive e-mail as different users on those virtual domains. I use mail.app to access many virtual domains, on a daily basis and it works pretty well. This short article, describes how to set up the server correctly.
Install Courier with IMAP and IMAP SSL. If you want to be somewhat secure, only install the courier-imap-ssl. When you are prompted if you want to set up the web configuration directories, select NO.
apt-get install courier-imap courier-imap-ssl
If you are running mailx, you’ll need to install the mailbox conversion program
apt-get install mb2md
Create the Courier mail directory, using maildirmake
su - myuser cd /home/myuser maildirmake Maildir
Convert the contents of the current mbox to the Maildir
su - myuser mb2md -s /home/myuser/mbox -d /home/myuser/Maildir
For future incoming e-mail, let the email go into mbox, but put a copy into Maildir, create a .procmailrc with the following:
MAILDIR=$HOME/Maildir :0c $MAILDIR/
A little bit of this and that
November 30th, 2009
Back in 2002, I started writing C++ with a unique style of combining Modern C++ Design and Domain Driven Design. My endeavor was to write a 3D game engine. It was a fun exercise.
First, define the Math Trait. We will use the Real Number System
template <typename T>
struct RealNumberSystem
{
//3 tuple Reals
static int const N=3;
typedef T Radian;
typedef T Theta;
typedef T Rho;
typedef T Radius;
typedef T Scalar;
};
Next, define the Geometry Trait. We will use Standard Euclidean. The Tuple4 typedef is interesting.
struct StandardEuclidean
{
static int const RightHanded=1;
static int const LeftHanded=0;
typedef Vector1x3<float> RowVector;
typedef Vector3x1<float> ColumnVector;
typedef Matrix3x3<float> Matrix3;
typedef ColumnVector Origin;
typedef ColumnVector Axis;
typedef ColumnVector AnyVector;
typedef ColumnVector ComponentVector;
typedef Matrix3 Basis;
typedef ColumnVector Point;
typedef ColumnVector Normal;
typedef ColumnVector Direction;
//Four dimensions
typedef Vector<float,4,1,Storage2Dim> Tuple4;
};
The following is the most critical class, which I think is the linch-pin that holds the math and the geometry together. Without this class, there is NO mathematical representation of a geometrical point, therefore the domain semantics within the code would eventually break down. I think this is the most conceptually beautiful code I have ever written:
//Mathematical representation of Geometrical Point
#include "Vector.h"
template <typename T>
class Cartesian : public Vector3x1<T>
{
public:
Cartesian(T x, T y, T z) : Vector3x1<T>(x,y,z)
{
}
};
Finally, define the Coordinate Systems and transformations between the systems
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//CoordinateSystem Template Class Declaration
template <typename T,
template <typename T1> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class Cartesian3DCoordinateSystem
{
public:
//Direct Access
typename GeometryTrait::Axis m_U[MathTrait<T>::N];
typename GeometryTrait::Origin m_P;
Cartesian3DCoordinateSystem()
{
if(GeometryTrait::RightHanded)
{
m_P.Set(0,0,0);
m_U[0].Set(1,0,0);
m_U[1].Set(0,1,0);
m_U[2].Set(0,0,1);
}
else
{
m_P.Set(0,0,0);
m_U[0].Set(0,0,1);
m_U[1].Set(0,1,0);
m_U[2].Set(1,0,0);
}
}
//Create this Coordinate System's Basis to match X
Cartesian3DCoordinateSystem(const typename GeometryTrait::AnyVector& X)
{
if(GeometryTrait::RightHanded)
{
m_P.Set(0,0,0);
m_U[0].Set(1,0,0);
m_U[1].Set(0,1,0);
m_U[2].Set(0,0,1);
}
else
{
m_P.Set(0,0,0);
m_U[0].Set(0,0,1);
m_U[1].Set(0,1,0);
m_U[2].Set(1,0,0);
}
typename MathTrait<T>::Scalar Y[MathTrait::N]={0};
for (int i=0; i<MathTrait<T>::N; ++i);
{
Y[i]=VectorColumn3::Dot(m_U[i],(X-m_P));
m_U[i]*=Y[i];
}
}
typename GeometryTrait::Basis GetBasis()
{
typename GeometryTrait::Basis R(m_U[0],m_U[1],m_U[2]);
return R;
}
};
template <typename T,
template <typename> class MathTrait,
typename GeometryTrait>
Vector3x1<T> Cylindrical2Cartesian(const CylindricalCoordinateSystem<T,MathTrait,GeometryTrait>& c)
{
//m_Angle must be in Radians
return (Vector3x1<float>((c.m_R*sin(c.m_Angle)),(c.m_R*cos(c.m_Angle)),0));
}
template <typename T,
template <typename T> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class CylindricalCoordinateSystem
{
public:
//Direct Access
typename GeometryTrait::Origin m_Z;
typename MathTrait<T>::Theta m_Angle;
typename MathTrait<T>::Radius m_R; //Radians
CylindricalCoordinateSystem()
{
m_Angle=T();
m_R=T();
}
void SetAngleDegrees(T angle)
{
const float pi=3.141592653f;
const float radconv=pi/180;
m_Angle=angle*radconv;
}
//The axis parameters are perpendicular
CylindricalCoordinateSystem(T x, T y, typename GeometryTrait::Origin Z)
{
//x and y are relative to Z
x=Z.x-x;
y=Z.y=y;
m_R=sqrt((pow(x,2)+pow(y,2)));
m_Angle=(acos(x/m_R));
if(y<=0) m_Angle=-m_Angle;
}
};
template <typename T,
template <typename T> class MathTrait,
typename GeometryTrait>
Vector3x1<T> Spherical2Cartesian(const SphericalCoordinateSystem<T,MathTrait,GeometryTrait>& c)
{
return (Vector3x1<float>((c.m_R*sin(c.m_PolarAngle)*cos(c.m_Azimuth)),(c.m_R*sin(c.m_PolarAngle)*cos(c.m_Azimuth)),(c.m_R*cos(c.m_PolarAngle))));
}
template <typename T,
template <typename T1> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class SphericalCoordinateSystem
{
public:
//Direct Access
typename MathTrait<T>::Radius m_R;
typename MathTrait<T>::Theta m_Azimuth;
typename MathTrait<T>::Rho m_PolarAngle;
SphericalCoordinateSystem(typename GeometryTrait::Point P)
{
m_R=sqrt((pow(P.x,2)+pow(P.y,2)+pow(P.z,2)));
m_PolarAngle=acos(P.z/m_R);
m_Azimuth=acos(x/(sqrt(pow(P.x,2)+pow(P.y,2))));
}
};
Define a linear component and a plane. I often wonder how things would be different, if we used: typename GeometryTrait = NonEuclidean
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//LinearComponent Template Class Definition
template <typename T,
typename GeometryTrait=StandardEuclidean>
class LinearComponent
{
public:
//Direct access
typename GeometryTrait::Point m_B;
typename GeometryTrait::ColumnVector m_M;
LinearComponent(typename const GeometryTrait::Point& B, typename const GeometryTrait::ColumnVector& M) :
m_B(B), m_M(M)
{
m_M.Normalize();
}
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//Plane Template Class Definition
template <typename T,
typename GeometryTrait=StandardEuclidean>
class Plane
{
public:
//Three dimensional representation
typename GeometryTrait::Point m_P;
typename GeometryTrait::Normal m_N;
//Four dimensional representation
typename GeometryTrait::Tuple4 m_ND; // <N,D>
Plane() : m_P(),m_N()
{
}
Plane(const T& px, const T& py, const T& pz,
const T& nx, const T& ny, const T& nz, const T& d) : m_P(px,py,pz),m_N(nx,ny,nz),m_ND(nx,ny,nz,d)
{
m_N.Normalize();
assert( (Vector<float,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0])==0));
}
Plane(const T& A, const T& B, const T& C, const T& D) : m_N(A,B,C), m_P(), m_ND(A,B,C,D)
{
assert(m_N.Magnitude()>0);
(m_ND.m_Storage.M[3][0])/=m_N.Magnitude();
m_N.Normalize();
//Create a dummy Point
m_P=m_N * -m_ND.m_Storage.M[3][0];
//D==-(N dot P)
T ndotp=(Vector<T,3,1>::Dot(m_N,m_P));
T d=m_ND.m_Storage.M[3][0];
assert(fabs(d + ndotp) < 0.001f);
// N dot P + D == 0
T dd=(Vector<T,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0]));
assert(fabs(dd) < 0.001f); //dd==zero
}
void SetNormal(const T& x, const T& y, const T& z)
{
m_N.Set(x,y,z);
m_N.Normalize();
m_ND.Set(m_N.x,m_N.y,m_N.z,0); //Direction
}
void SetPoint(const T& x, const T& y, const T& z)
{
m_P.Set(x,y,z);
}
void SetD(const T& d)
{
m_ND.m_Storage.M[3][0]=d;
}
T GetD() const
{
return m_ND.m_Storage.M[3][0];
}
Plane(typename const GeometryTrait::Point& P, typename const GeometryTrait::Normal& N) : m_P(P), m_N(N)
{
//Make calculations easier by normalizing
m_N.Normalize();
m_ND.Set(N.x,N.y,N.z,-(Vector<float,3,1>::Dot(m_N,P)));
assert( (Vector<float,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0])==0));
}
};
I’ve left out the Matrix template and Vector template code, since it’s pretty boring.
Hyper-Meta-Protocol
November 18th, 2009
Twitter is an informal protocol for transferring ideas and opinions in extremely compact form. Interestingly, Humans have adapted to the protocol, instead of the protocol adapting to Humans. These User-created protocols ride on top of of Twitter and are adopted by other Twitter users, if found useful.
Meta Protocol?
If we consider this informal protocol for a moment, we start to realize the protocols can be considered a Hyper-Meta-Protocol (HMP) or a protocol that is extensible but can also define itself.Mechanization
So let’s try to mechanize the adoption of meta-protocols that ride on top of a particular protocol:1) A protocol is essentially the process of synchronizing two or more state machines and optionally, transferring information between two or more two state machines.
2) Given the definition of protocol, we can constrain state machine changes such that those changes can be synchronized between the two or more separate state machines and therefore create different state-machines pairs, maintaining different meta-protocol sessions.
3) We reconcile differences or contradictions between different Users of the protocol, by performing squelching of non-popular meta-protocol sessions at the server level..
Some properties
- Stateful
HMPs are stateful, in that an HMP is implemented by a State Machine
- In-Band
HMPs are recursively in-band capable. That is to say, an HMP may contain another in-band HMP.
- In-Band Modification
In-band HMP/State-Machine may inspect/modify the containing HMP, but only if the containing HMP/State-Machine allows.
The Tragedy of Anti-Virus Software
April 2nd, 2009
We believe that our computer anti-virus software will protect our computer and our data. Is that belief justified? Let’s take an informal look:
First some definitions
Let’s define the term “unknown virus/worm” as a virus that is “in the wild” and the anti-virus companies do not know about it because the behavior of the virus/worm is so stealthy (or so targeted, or just new) that it does not call attention to itself.
Let’s define the term “known virus/worm” as a virus that has a virus signature and can be scanned and found.
Now some numbers:
Symantec reported in 2007 that a little more than 700,000 computer viruses were identified. Let’s say that the 700,000 viruses represent 99.99% of all virus/worm (known and unknown), leaving at least .01% unknown . The number of unknown virus/worm would then be about 70.
Let’s divide that 70 by 12 months, that comes out to 6 unknown virus/worm per month or about 0.2 viruses a day. To make this simpler, let’s say on average there is 1 unknown virus/worm that is produced each 5 days.
Let’s say that of each unknown virus, it takes about an average of 72 hours for it to become detected and a virus signature created.
Now for the kicker:
Such an unknown virus/worm would have an infection rate of 100% during those 72 hours. This suggests that the larger the computer network, the higher the probability of infection.
The true horror:
Since the infection rate, of that virus/worm is 100%, during those 72 hours, this means you’ve most likely been infected but you just don’t know it (yet), and your anti-virus software is running perfectly. This means for at least 72 hours, your computer is under the control of the virus/worm writer.
Are we doomed?
The majority of experts believe that the vast majority of virus/worm writers are not state sponsored, which means state resources (human, equipment, material) are not being actively used to create viruses/worms for the purposes of world computer domination of the average person. That is not to say, such resources are not being actively used to target specific computers in particular governments.
If you are considered an average target, then you are at risk. An average target consists of computer users that run active-content from the Internet, either by receiving non text-e-mail, downloading and installing questionable free tools and utilities, or running non text-based browsers that run active-content either through client-side or plugin technologies.
What if you are directly targeted?
Sucks to be you. If you think you are actually targeted (if your paranoia is really justified), the only hope is to go totally offline. Otherwise the following may help:
- Don’t be an average target
- Maintain multiple backups of your data
- Maintain archives of your data
- Subdividing your network results in a reduction of risk, on average; a network consisting of one computer is the safest (but still not 100% safe).