Octo Performance Engineering

Sunday, November 04, 2007

Using Cron and SCP for Backups and Such

From: www.spaceprogram.com/knowledge/cron_scp.html

Using Cron and SCP for Backups and Such
Introduction

This document will explain the steps required to use scp in cron. This is generally useful to do automated backups on Linux and other nix variations.
Instructions

These instructions will walk you through what it takes.

1. Generate a private/public key pair

Simple command to do this:
ssh-keygen -t rsa

Leave the passphrase empty so that cron can use it passwordless. Just be sure nobody gets your private key.

2. Copy the public key to the remote server
scp ~/.ssh/id_rsa.pub remote_host:

3. Add local key to remote servers trusted key

Log on to the remote server and if there has never been a key created for this user on the remote machine, run the ssh-keygen -t rsa just to get the key directory and stuff set up.

Then concatenate the new key to your authorized_keys file:

cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

Now for some reason, you may have to do this to the keys file:

chmod 644 ~/.ssh/authorized_keys

4. Now try logging into the remote machine again from local

ssh REMOTE_USERNAME@remote_host

This should log you in without asking for a password. If it doesn't, then something must be wrong at this point and you should go through the steps above again.

This should also mean that scp will work the same way and you might want to test that scp works by copying a file from local to remote using scp. If no password, then we're all good.

5. Now lets test out cron script

My cron script for this example is simply going to copy a directory of files using scp to the remote server.

scp -r /PATH_TO_FILES/ REMOTE_USER@remote_host:BACKUPS/

And that's about all she wrote. Save that in a file called backup.sh (or whatever you want to call it), chmod 755 i it and then try running it. ./backup.sh to run it. If it works, then next stop is to cron it.

6. Add script to cron jobs

Easiest way is to simply copy the backup.sh file into /etc/cron.daily/ . This will make it run every day. Choose another cron.SOMETIME to make it run more or less often. If you want more control on when it's run, read up on adding it to the crontab.

Tuesday, May 01, 2007

"Hello, World" in SDL/OpenGL

Here's a small "hello, world" demo program written in C++ using SDL and OpenGL. It was successfully compiled with Visual Studio 8 along with SDL and SDL_ttf libraries. You can get SDL and SDL_ttf from sourceforge.net.

The program is based on the code provided by Ernest Pazera, the author of "Focus on SDL", the Premier Press Game Development Series.

Since I don't like to use VS IDE, I opted to use nmake instead. It makes programming much easier for me.

=====================================================================================
// ===========================================================================
// HelloWorld.h
//
// CJKim, Octo Simple LLC, 01-May-07
//

// include SDL stuff
#include "SDL.h"
#include "SDL_ttf.h"

class CHelloWorld
{
private:
SDL_Surface* m_pDisplaySurface;
SDL_Surface* m_pTextSurf0;
SDL_Surface* m_pTextSurf1;
SDL_Surface* m_pTextSurf2;
SDL_Surface* m_pTextSurf3;
TTF_Font* m_pLargeFont;
TTF_Font* m_pSmallFont;
int m_skipLarge;
int m_skipSmall;
static int m_ScreenWidth;
static int m_ScreenHeight;
void CalcLoc(SDL_Surface* sfc, SDL_Rect& src, SDL_Rect& dst);

public:
CHelloWorld(char *fontName);
virtual ~CHelloWorld();
void Render();
void Italicize();
};

// -- end of HelloWorld.h --


// ===========================================================================
// HelloWorld.cpp -- "Hello, World" in SDL
//
// CJKim, Octo Simple LLC, 01-May-07
// based on ernest pazera's work 10JUN2002
//

// requires static linkage to:
// SDL.lib, SDLmain.lib, SDL_ttf.lib

// for Windows, requires dynamic linkage to:
// sdl.dll, sdl_ttf.dll

#include <iostream>
#include <stdlib.h>
#include "HelloWorld.h"

// screen dimensions
int CHelloWorld::m_ScreenWidth = 640;
int CHelloWorld::m_ScreenHeight = 480;

#undef main

void CHelloWorld::CalcLoc(SDL_Surface *s, SDL_Rect &src, SDL_Rect &dst)
{
// source rectangle
src.x = src.y = 0;
src.w = s->w;
src.h = s->h;

// destination rectangle
dst = src;
dst.x = (m_ScreenWidth - dst.w) / 2;
dst.y = (m_ScreenHeight - dst.h) / 2;
}

CHelloWorld::CHelloWorld(char *fontName = "arial.ttf") :
m_pDisplaySurface(NULL),
m_pLargeFont(NULL),
m_pSmallFont(NULL),
m_skipLarge(58),
m_skipSmall(14)
{
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO)==-1) {
std::cerr << "Could not initialize SDL!" << std::endl;
exit(1);
}

std::cerr << "SDL Initialization Completed." << std::endl;

// set up to uninitialize SDL at exit
atexit(SDL_Quit);

SDL_WM_SetCaption("Hello, world!", "Hello, world!");

// create windowed environment
m_pDisplaySurface = SDL_SetVideoMode(m_ScreenWidth, m_ScreenHeight, 0, SDL_ANYFORMAT);
if (m_pDisplaySurface == NULL) {
std::cerr << "Could not set up display surface!" << std::endl;
exit(1);
}

//initialize SDL_ttf
if (TTF_Init() < 0) {
std::cerr << "Unable to initialize TTF: " << TTF_GetError() << std::endl;
exit(1);
}

// open fonts
m_pLargeFont = TTF_OpenFont(fontName, 50);
m_pSmallFont = TTF_OpenFont(fontName, 12);
if (NULL == m_pLargeFont || NULL == m_pSmallFont) {
std::cerr << "Cannot load " << fontName << ": " << TTF_GetError() << std::endl;
exit(1);
}
std::cout << "Using " << fontName << ", Size 50 and 12" << std::endl;

// see how many pixels need to be skipped to print the next line
m_skipLarge = TTF_FontLineSkip(m_pLargeFont);
m_skipSmall = TTF_FontLineSkip(m_pSmallFont);
std::cout << "Large Font Skip = " << int(m_skipLarge) << " Pixels" << std::endl;
std::cout << "Small Font Skip = " << int(m_skipSmall) << " Pixels" << std::endl;
}

CHelloWorld::~CHelloWorld()
{
// destroy text surface
SDL_FreeSurface(m_pTextSurf0);
SDL_FreeSurface(m_pTextSurf3);
SDL_FreeSurface(m_pTextSurf2);
SDL_FreeSurface(m_pTextSurf1);

// close the font
TTF_CloseFont(m_pSmallFont);
TTF_CloseFont(m_pLargeFont);

// quit SDL_ttf
TTF_Quit();
}

void CHelloWorld::Render()
{
// set up colors
SDL_Color fgcolor, bgcolor, instcolor;

fgcolor.r = 255; // black
fgcolor.g = 255;
fgcolor.b = 255;

bgcolor.r = 128; // gray
bgcolor.g = 128;
bgcolor.b = 128;

instcolor.r = 0;
instcolor.g = 128;
instcolor.b = 128;

// render text
m_pTextSurf1 = TTF_RenderText_Solid( m_pLargeFont, "Solid: Hello, world!", fgcolor);
m_pTextSurf2 = TTF_RenderText_Shaded( m_pLargeFont, "Shaded: Hello, world!", fgcolor, bgcolor);
m_pTextSurf3 = TTF_RenderText_Blended(m_pLargeFont, "Blended: Hello, world!", fgcolor);
m_pTextSurf0 = TTF_RenderText_Solid( m_pSmallFont, "Hit Escape to Quit", instcolor);

//rectangles
SDL_Rect rcSrc;
SDL_Rect rcDst;

// blit the surface
CalcLoc(m_pTextSurf1, rcSrc, rcDst); rcDst.y -= m_skipLarge * 1;
SDL_BlitSurface(m_pTextSurf1, &rcSrc, m_pDisplaySurface, &rcDst);
CalcLoc(m_pTextSurf2, rcSrc, rcDst); rcDst.y += m_skipLarge * 0 + (-3 + rand() % 6);
SDL_BlitSurface(m_pTextSurf2, &rcSrc, m_pDisplaySurface, &rcDst);
CalcLoc(m_pTextSurf3, rcSrc, rcDst); rcDst.y += m_skipLarge * 1;
SDL_BlitSurface(m_pTextSurf3, &rcSrc, m_pDisplaySurface, &rcDst);

// instruction text at the bottom of the screen
rcSrc.x = rcSrc.y = 0;
rcSrc.w = m_pTextSurf0->w; rcSrc.h = m_pTextSurf0->h;
rcDst = rcSrc;
rcDst.x = (m_ScreenWidth - rcDst.w) / 2;
rcDst.y = (m_ScreenHeight - m_skipSmall - 5);
SDL_BlitSurface(m_pTextSurf0, &rcSrc, m_pDisplaySurface, &rcDst);
SDL_UpdateRect(m_pDisplaySurface, 0, 0, 0, 0);
}

void CHelloWorld::Italicize()
{
TTF_SetFontStyle(m_pLargeFont, TTF_STYLE_ITALIC);
}

void mainloop(CHelloWorld* hw)
{
// repeat until quitting
for (bool done = false; !done; ) {
//event structure
SDL_Event event;

// wait for an event
if (SDL_PollEvent(&event) == 0) {
hw->Render(); // update the screen
SDL_Delay(100);
continue;
}
//event occurred, check for quit
if (event.type == SDL_QUIT) {
done = true;
break;
}
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
done = true;
break;
default:
break;
}
}
}
}

// main function
int main(int argc, char* argv[])
{
CHelloWorld* pHW = new CHelloWorld();

pHW->Italicize(); // show it in italic

pHW->Render(); // paint the canvas, van gogh

mainloop(pHW); // loop until the user quits

delete pHW; // get rid of it

std::cout << "SDL Demo Program Exits Normally." << std::endl;

return (0);
}

// -- end of ttf.cpp --


#==================================================================================
#
# nmake makefile for HelloWorld.cpp
#

CFLAGS= \
/I "\work\games\SDL-1.2.11-dev\include" \
/I "\work\games\SDL_ttf-2.0.8\include" \
/EHsc

LDFLAGS= \
/LIBPATH:"\work\games\SDL-1.2.11-dev\lib" \
/LIBPATH:"\work\games\SDL_ttf-2.0.8\lib" \
SDL_ttf.lib \
SDL.lib \
glu32.lib \
opengl32.lib \
kernel32.lib \
user32.lib \
gdi32.lib \
advapi32.lib \
shell32.lib

PROGRAMS=HelloWorld.exe

# image_viewer.exe: image_viewer.cpp
# cl image_viewer.cpp $(CFLAGS) /link $(LDFLAGS)

all: $(PROGRAMS)

HelloWorld.obj: HelloWorld.cpp
$(CC) /nologo /c $(CFLAGS) HelloWorld.cpp

HelloWorld.exe: HelloWorld.obj
link /NOLOGO /OUT:HelloWorld.exe $(LDFLAGS) HelloWorld.obj

clean:
del $(PROGRAMS) *.obj

new: clean all

Thursday, April 19, 2007

Gdk-ERROR **: BadMatch (invalid parameter attributes) Error

On Linux (Fedora and other variants), if you receive the following error while trying to run a graphics application, read on.
Gdk-ERROR **: BadMatch (invalid parameter attributes)

This is caused by GDK not being able to make up its mind whether it should run in 32-bit or 24-bit mode since the application and the graphics environment being inconsistent. The solution is simple. Set the environment variable XLIB_SKIP_ARGB_VISUALS to 1 and rerun the application, e.g.
$ export XLIB_SKIP_ARGB_VISUALS=1

Good luck!

Friday, November 24, 2006

Copying a Unix Directory Tree

If you wish to copy an entire directory tree to another location while retaining the file permissions and ownerships, run the commands:

$ cd source_dir
$ find . -depth -print | cpio -pdv dest_dir

Wow!

Tuesday, November 21, 2006

Extracting Files in an RPM File

Maybe I am missing something but I couldn't figure out how to extract files in RPM files with the rpm command. Use the handy-dandy rpm2cpio command. For example,

rpm2cpio rpmfile | cpio -iv

If you'd like to list the content of an RPM file, do the following:

rpm -qlp rpmfile

Thursday, November 09, 2006

Running coLinux on a dual-core system

When running coLinux on a dual-core system, it blue-screens with the DRIVER_IRQL_NOT_LESS_OR_EQUAL error. In order to get around the problem, boot.ini must be modified. Ordinarily, the noexecute option is set to "optin" to indicate that the no-execute protection (also known as Data Execution Protection - DEP) is enabled. While it is useful for preventing malicious code from exploiting buffer overflow bugs, DEP must be disabled to run coLinux on dual-core systems. To do so, select system on the control panel. Click on the Advanced tab. In the "Startup and Recovery" section, click on the "Settings" button. In the "System startup" section, click on the "Edit" button. A notepad with boot.ini will appear. Modify "/noexecute=optin" as "/noexecute=AlwaysOff". Save the change and reboot the system.

Wednesday, October 25, 2006

Free Virtual CD/DVD Mount on Windows XP

Here's an inexpensive (free!) way from Microsoft to mount an .iso image file without burning a CD or DVD. Simply download the program and execute. Select a directory where you wish to store the program when it tries to unzip the content. Following the instruction given in "readme.txt" for the detail.

Here's the download link: winxpvirtualcdcontrolpanel