Days progress

Null (0)
Eines (1)
Zwei (2)
Drei (3)
Vier (4) – tis one hard to remember lol
Fuenf (5) – properly fünf
Sechs (6)
Sieben (7)
Acht (8)
Neun (9)
Zehn (10)
Elf (11)
Zwoelf (12) – properly zwölf
Dreizehn (13)
Vierzehn (14)
Fuenfzehn (15) – properly fünfzehn
Sechszehn (16)
Siebzehn (17)
Achtzehn (18)
Neunzehn (19)
Zwozig (20) – I wonder if Zweizig would be interrupted as 20. Seems that ‘zwo’ seems to be used in place of Zwei at times to avoid confusing people.. Probably foreigners lol.
einetausend (1000)

For the most part German numbers seem pretty logical and seem to follow the same convention style as English numbers. I.e. 15 in English is Fift-Teen, rymes with 5th (fifth, Viertel) a fraction and teen being a fairly standard suffix for any thing between ( > 10 && < 20 ). So Siebzehn makes sense for Seventeen. Its more or less 'Seven Ten' which is basically what a 17 is. Or maybe it could just be my backwards mind that finds this all so logical ! hehe I dunno. Larger numbers seen to follow a similar style but with a und (and) in the middle and changing suffixes as you got, teens, twenties, thirties and so on. But each comparable German suffix seems to end in ‘zig’ except for Dreissig (dreißig, thirty). Much like how in English many of then have a ‘ty’ suffix often preceded by an r or ir. Fourty “four’ity” (Vierundvierzig), Seventy (Siebundsiebzig), or Fifty (Fuenfundfuenfzig). Quiet logical imho. Sechhundertzweiundzwanzig (626) looks about right to me aside from being a mouth full but who says I know any thing. Six hundred Two and Twenty – logical. It seems while we use a decimal point . In German a comma , seems to be used and pronouced. I wonder how 600,400.01 would be spoken if 3.04 would be like ‘Drei Komma null vier’. I think thats some what grammatically correct. ‘Komma’ always seems to be capitalized, the first word being capitalized the way I wrote it is probably an English’ism. I’ve yet to learn much for German grammar and punctuation. Instead concentrating on basic spoken communication and reading. I’ll worry more about it when I have a rough understanding of how words work out, then I’ll worry more about sentences and phases. So far though the only languages I know my way around well is C and English +S lol sorry to say but I think its in that order :-P

read file

This is a little thing I’ve been working on this month. Its made to simulate the behavior of ‘cat file’ and ‘head -n’ / ‘tail -n’ more or less scratch a little itch. It works very simple as its supposed to be simple. It parses arguments taking a count to its -t and -b switches. It looks through argv till it finds a file to open. It’ll read the entire file out, if it’s given the -t switch it will read out up to the count its given. If its given the -b switch, it will read the entire file. Store the location of every newline in a linked-list. Then rewind the list, seek to the specified location (plus padding) and print out the end of the remainder of the file.

Heres a straight copy & paste of it. Portability wise it assumes that the file is in the correct format and requires a number of functions that first appeared in BSD 4.x, namely getopts, fgetln, and err/errx. It also presumes that their should be enough room to store the location of every newline in the file within memory. So if one only has 64K of RAM, it might be a problem to read a few files xD.

I can’t say if its well written or not… I don’t know of any program with my system that does exactly this other then what this simulates. Rather then wrap around cat/head/tail using system() or including the sources I worked through this as a learning experience. Its more or less written in the style I prefer, the type on a line of its own bit in function declarations is the only ‘real’ part of it stemming from my occasional reads of stuff in /usr/src alone.

/*
* rf read file to standard out
*/

// vim: set noexpandtab ts=8 sw=4 ai :
// vi: set ai nu ts=8 sw=4 :

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>


static void readall( FILE *, int );
static void readtop( FILE *, int );
static int readbottom( FILE *, int );
static void usage( void );

struct lnpos {
long nl;
struct lnpos *next;
};

int
main( int argc, char *argv[] ) {

char *erptr;
int t_flag = 0, b_flag = 0;
int ch, lncnt;
FILE *fp;

extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;

while ( (ch = getopt(argc, argv, "b:t:")) != -1 ) {
switch (ch) {
case 'b':
b_flag++;
lncnt = strtol(optarg, &erptr, 10);
if ( *erptr || lncnt <= 0 )
errx( 1, "Improper line count -- %s", optarg );
break;
case 't':
t_flag++;
lncnt = strtol(optarg, &erptr, 10);
if ( *erptr || lncnt <= 0 )
errx( 1, "Improper line count -- %s", optarg );
break;
case '?':
default:
usage();
return 1;
}
argc -= optind;
argv += optind;
}


/* loop through cli args and find a file to open */
for ( int i = 0; i <= argc; i++ ) {
fp = fopen( argv[i], "r" );
if ( fp == NULL )
err( 1, "File does not exist or could not be opened "
"for reading -- %s", optarg );
}

if ( (t_flag < 1) && (b_flag < 1) ) {
readall( fp, lncnt );
} else if ( t_flag > 0 ) {
readtop( fp, lncnt );
} else if ( b_flag > 0 ) {
readbottom( fp, lncnt );
} else {
errx( 1, "flag processing failed" );
}

fclose( fp );
return 0;
}

/*
* print out an open file to standard output
*/

static void
readall( FILE *fp, int lncnt ) {

while ( (lncnt = fgetc( fp )) != EOF ) {
printf( "%c", lncnt );
}
}

/* Read n lines from the top of the file.
* note that it was very inspired by the head(1) implementation of BSD
*/
static void
readtop( FILE *fp, int lncnt ) {

char *cp;
size_t error, rlen;
while ( lncnt && (cp = fgetln( fp, &rlen )) != NULL ) {
error = fwrite( cp, sizeof(char), rlen, stdout );
if ( error != rlen )
err( 1, "stdout" );
lncnt--;
}
}


/* Read n lines from the bottom of the file
* This function really should be broken up - but I have not learned how yet.
*/
static int
readbottom( FILE *fp, int lncnt ) {

char *cp;
int hmany = lncnt;
long nlnum = 0;
long where;
size_t error, rlen;

struct lnpos *root;
struct lnpos *cur;

root = malloc( sizeof(struct lnpos) );
if ( root == NULL )
err( 1, "can't init the list" );
root->next = 0;
cur = root;

cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't add nodes" );
cur = cur->next;

/* read the file, count every 'n' and store them in a new member of
* our linked list.
*/
while ( (lncnt = fgetc( fp )) != EOF ) {
if ( lncnt == 'n' ) {
nlnum++;
cur->nl = ftell( fp );
if ( cur->next != NULL )
cur = cur->next;
cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't add nodes" );
cur = cur->next;
}
}

/* rewind our linked-list and seek b_flag + 1 segments short of the
* end of the list.
*/
cur = root->next;
hmany++;
while ( hmany < nlnum ) {
cur = cur->next;
nlnum--;

}

where = fseek( fp, cur->nl, SEEK_SET );
if ( where != 0 )
err( 1, "could not seek through the filen" );

while ( lncnt && (cp = fgetln( fp, &rlen )) != NULL ) {
error = fwrite( cp, sizeof(char), rlen, stdout );
if ( error != rlen )
err( 1, "stdout" );
lncnt--;
cur = cur->next;
if ( cur->next == 0 )
return 0;
}
return 0;
}


static void
usage( void ) {
fprintf( stderr, "usage:n rf filen "
"rf [-t number lines from the top] filen "
"rf [ -b number of lines from the bottom ] [ file ]n" );
}


Any comments about the file it self or its design is much welcome by this moron who tries to teach him self.

Nice pair

Pioneer HDJ-1000 headphones /w ear-cup http://www.amazon.com/Pioneer-HDJ-1000-Headphones-ear-cup/dp/B0002DV7Z2

Temptational joke

Three Distros for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Steve Ballmer on his dark throne
In the Land of Redmond where the $hadow$ lie.
One distro to rule them all, One Ring to find them,
One distro to bring them all and in the darkness bind them
In the Land of Redmond where the $hadow$ lie.

There can only be one distro and its MicrosoftSUSE !

Sorrry, I couldn’t resist doing that just for the laughs !!!

SSMTP/Getmail how-to part III

back to part II

The getmail documentation said that was the best way to automate it, and its bloody better then buling up getmail with ‘daemon mode’ code. But also like the documentation said if we want to ‘stop’ this daemon like mail checking we need a script for cron to run getmail through and program it to not run getmail if a file is pressent. Now we can do this many ways, heck we could set a enviroment variable if we want.

I’ve written a little script that can be run with a users cron jobs and skip over all mail or only the given account. You need one rcfile per account and you can tweak it to follow any conventions you want. My RCFiles follow the convention of getmailrc-shortaccountname, hence getmailrc-bell and getmailrc-sas for my bellsouth and sasclan accounts. This script should work on any system that has a bourneshell compatible /bin/sh. Just edit the shebang if you need to run it as another shell (such as /bin/ksh).

#!/bin/sh

# Use getmail to check my E-Mail account using the RC variable
# This script has the advantage that one can save it as another file, change
# one variable and set a cron job to check each account at different times (1
# cron job per script). Then not only use a file in their .getmail folder to
# stop all the scripts from running getmail or use a file to stop one script
# from checking its account. It also keeps a log which will be trimmed by
# another script

# Name of the getmailrc file to use
RC=getmailrc-sas

# log to a file when mail is checked
LOGFILE=${HOME}/.getmail/cronjobs.log

#
# If a nomail or nocheck file is found in ~/.getmail/ exit without checking
# else look for a no file. Where is equal to every thing that
# comes after the getmailrc- in $RC. If none of these files exsist check mail
# using the $RC file.
#
if [ -e ${HOME}/.getmail/nomail ]
then
LOG=$(echo "Skipping mail for $RC")
exit 1
elif [ -e ${HOME}/.getmail/nocheck ]
then
LOG=$(echo "Skipping mail for $RC")
exit 1
else
DIE=$(ls ${HOME}/.getmail| grep $RC | cut -d '-' -f 2)
if [ -e ${HOME}/.getmail/no${DIE} ]
then
LOG=$(echo "You have desided not to check this mailbox - $DIE")
else
LOG=$(echo `date` "checked mailbox with $RC")
getmail -r$RC
fi
fi

# Update log with the result
echo $LOG >> $LOGFILE 2> /dev/null

if you want to use the script copy and paste it into a text file and mark it executible. I saved them as ~/.getmail/check-.sh and chmod’d them 0700

Ok, let us make a cron job, because this is allready a big long post that took me forever to write with the way my house is. I’m not detailing cron(8) so please read the handbook or read the fine manual.

I created this crontab file to run my scripts to check my accounts every 5 and 4 hours respecfully and to ‘trim’ my log file every week.

# rstf's crontab
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
HOME=/usr/home/rstf/
MAILTO=""
#
#minute hour mday month wday who command
#
# check sas every 5hr
5 * * * * rstf ${HOME}/.getmail/check-sas.sh
#
# check bell every 4hr
4 * * * * rstf ${HOME}/.getmail/check-bell.sh
#
# trim log @weekly
0 0 * * 0 rstf ${HOME}/sh/trim-getmail-cronlog
#

The trim-getmail-cronlog script is thus

#!/bin/sh

# Rotate my logfile for running get mail via cron

LOGFILE=${HOME}/.getmail/cronjobs.log
TMPDIR=/tmp/

if [ -e $LOGFILE ]
then
tail $LOGFILE > $TMPDIR/gmlog.$$
rm $LOGFILE
mv $TMPDIR/gmlog.$$ $LOGFILE
else
exit 1
fi

To load my crontab file into crons system i.e. /var/run/tabs/${USER} all I have to do is run a simple command.

crontab ~/rstf-contrab