1 Thing I’d love to see. Is a simple yet powerful language like Perl/Python/Ruby thats got a C/C++ style compiler like GCC. Like being able to run the C pre-processor on the files before compilation and being able to link the object files together into an executable.

But also, a simple interpreter that implements the standard library and can run single file ‘scripts’ like a Bourne Shell. Yet with the options of being able to ‘link’ to pre-compiled libraries of code to extend itself in order to run the script. That way, people could use the interpreter for use interactive (like irb / python) yet run scripts and not have to have a development environment (compiler and friends) and any precompiled libraries could be distributed with the script.

Like

import math_module
import sockets_module

Compile the app and link it to a math and socket library. Or i f we’re using the interpreter.

foo -l lib1, lib2

or even in the script

#!/usr/bin/foo -L /usr/lib/foo/

Would be kinda cool.

The power, flexibility, and speed of a compiler yet the simplicity of an interpretor. But with keeping the ability to also use various libraries of code with the scripts. One could probably do some preprocessor work to include the library code in the script before using it too and save disk space.

Wouldn’t it be awesome if one could work on a Project in Python instead of C++ and keep a compiled executable. Yet when ya need a little script for some ‘loose ends’ to just go ahead and write a script to do it in the same language as the project ? Hehehehe.

I think D has the ability of doing a script, like #!/path/compiler -run at the top of the file. No clue if its a dual-purpose compiler/interpretor or if it just compiles an executable in temp space and runs it or what.

rf.c semi-final

Well to make a long story short. I found out that calling setlocale() made my program (rf) crash when ever I used to -b switch. But strangely on OpenBSD it ran perfectly fine.

Sure enough after 2 days of tracking I found a few bugs and the little blighter I’ve just squashed was just the one I expected to find. It was just a matter of how. Just a bad pointer, my guess is after the setlocale() call. It was pointing some where FreeBSD didn’t like and without the call it wasn’t enough to get ballocked at. Who cares how thats possible… as long as its fixed hehe. Well as best as _I_ can tell any way.

The projects grown and I’ve learned quite since the start. Both about working in C, using Makefiles, dealing with GCC, GDB in more depth, and groff e.t.c. For sear size we are at:

#wc [ lines | words | bytes | filename ] 
16 121 778 COPYING
25 68 735 Makefile.optimize
255 1023 6517 rf.c
11 114 3636 rf.o
87 333 1819 rf.1
9 68 404 tags
403 1727 13889 total

I have 3 Makefiles, a generic makefile for building the application on i686. Makefile.debug that does likewise but includes debugging symbols. And Makefile.optimize that has a few extra flags with mostly optimization options in it (hence the name). Each also can do a ‘make install’ for me. All in all gcc gets called from Makefile.optimize with:

-Wall -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Winline -Wnested-externs -std=c99 -march=i686 -fforce-mem -fforce-addr -finline-functions -fstrength-reduce -floop-optimize

I made some other changes too. I rewrote parts of main, its still not pretty but a wrapper on fopen() I think makes it easier to dick with. I finally added a -v option to see the file name. I was trying to figure out how to make a variadic macro and stumbled onto the __FILE__ and __LINE__ additions to C hehehe. I also decided to have it clean up after its malloc’ing. AFAIK a programs memory is free()’d after it exits so I didn’t bother. Now I did for completeness sake. clean_up() is called after handling the output done in read_bottom (which actually uses read_all() to printout the file). So that if for some odd reason theres really low memory or some thing and it takes *awhile* to handle malloc’ing and seeking semi-end-to-end through a linked-list. I figured it’d be a good ‘just in case’ even if its not likely.

I really would like to rewrite read_top() b/c I don’t know of any comparable function to fgetln() on windows and a Macro that inlines a rough equivalent to my beloved err() function too. Which likewise is available from the BSD and GNU C Libraries and both are marked as ‘first appeared in 4.4BSD’ in the man pages. And AFAICT not available from Microsofts implementation.

One thing I need to do is learn more about groff and the man page macros and stuff. So far its mostly been a matter of reading my systems man pages and trial/error to get a fairly decent manpage.

I try to keep things small, my displays usually 80×25 or 80×35 if I’m working on Windows (GVIM) and 1 thing I really hate. Is a huge function thats so freaking big, you don’t even remember the NAME of it by the time you hit the closing bra}e. So lol, I do my best not to write functions that long. At 60 some lines with comments I think read_bottom should be broken up into 2 smaller functions, the extra function call is negiable overhead I’m sure. I just think it would take longer to read. Really if you snip off the variable declarations and list startup (which could be function’ized) it almost fits on 1 screen. be_verbose man as well be a macro or inline function too. Although a compiler could take care of that choice it self I’m sure.

To be honest, I just like functions that are small, do whats asked, and avoid being swiss-army knifes.

/*-
* Copyright (C) 2007
* Terry M. P*****. All rights reserved.
*
* permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


// 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 <locale.h>
#include <unistd.h>

struct lnpos {
long nl;
struct lnpos *next;
} lnpos = { .next = 0, .nl = 0 };

static FILE *open_file( char * );
static void read_all( FILE *, int );
static void read_top( FILE *, int );
static void read_bottom( FILE *, int );
static void clean_up( struct lnpos *);
static void be_verbose( void );
static void usage( void );


static const char *this_progname;

/*
* rf - read file to standard out v1.27
*/

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

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

(void)setlocale( LC_ALL, "" );

this_progname = argv[0];

while ( (ch = getopt(argc, argv, "b:t:v")) != -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 'v':
v_flag++;
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}

/* This is ugly but cleaner then w/o open_file(). */
if ( argv[1] == NULL ) {
usage();
} else if ( (t_flag < 1) && (b_flag < 1) && (v_flag < 1) ) {
fp = open_file( argv[1] );
read_all( fp, lncnt );
} else if ( (v_flag != 0) && (t_flag < 1) && (b_flag < 1) ) {
fp = open_file( argv[2] );
read_all( fp, lncnt );
} else if ( t_flag > 0 ) {
fp = open_file( argv[3] );
read_top( fp, lncnt );
} else if ( b_flag > 0 ) {
fp = open_file( argv[3] );
read_bottom( fp, lncnt );
} else {
usage();
/* NOTREACHED */
}

if ( v_flag != 0 )
be_verbose();

fclose( fp );
return 0;

}


/* Simple fopen wrapper to keep the if...else if...else blockage from
* getting even uglier. Since doing other wise would defeat the purpose of it.
* open_file() halts the program if fopen failed.
*/
static FILE
*open_file( char *arg ) {

FILE *fto;

fto = fopen( arg, "r" );
if ( fto == NULL )
errx( 1, "File can not be opened or"
" does not exist -- %sn", arg );
return fto;
}


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

static void
read_all( 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
read_top( 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
*/
static void
read_bottom( FILE *fp, int lncnt ) {

int hmany = lncnt;
long nlnum = 0;
long where;

struct lnpos *root = 0;
struct lnpos *cur = 0;

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 first node" );
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 );
cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't store line feeds" );
cur = cur->next;

}
}

/* Let's mark the end of the list and move to it */
cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't terminate the list" );
cur = cur->next;
cur->next = NULL;

/* rewind our linked-list and seek to b_flag segments. So readall() starts from
* the correct fseek offset to print till EOF. - This keeps down on
* unnecessary code here !
*/
cur = root;
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" );

read_all( fp, lncnt );
clean_up( root );
}

/* Simple destructor - walk the list and free() the memory before the
* program exits.
*/
static void
clean_up( struct lnpos *rp ) {

struct lnpos *t = rp;
struct lnpos *atpos = rp;

while ( atpos != NULL ) {
free( t );
atpos = atpos->next;
t = atpos;
}
}

static void
be_verbose( void ) {

printf("==> %s <==n", __FILE__);
}

static void
usage( void ) {

(void)fprintf( stderr, "usage: %s [-t count | -b count] "
"[-v] [file ...]n",
this_progname );

exit( EXIT_FAILURE );
}

I’ve learned so much in the past 2 months, its awesome. Really this is the largest project I’ve ever worked on in my ~/Programming directory. 255 Lines isn’t much but when your a bumbling baboon trying to learn in the wilderness. It kinda helps to learn by reading and writing code I guess.

I also want to start assembling a little personal library of functions and macros that I can draw on to do odds and ends without rewriting them. After all with my little ‘toys’ I might have use of other stuff from time to time hehe.

Time for BEEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Caesar

Ok so I’m a crazy stooge !

I spent the night trying to evade my allergies by implementing a simple rot13 program based on some super-short implemnetations of the algorithm from USENET.

Shes got interactive and file based rot13, a -r option set up to use a different rotation then 13… but I havn’t implemented those yet hehehe.

Had a lot of fun working on it and learned a few things while working on the manual page that even let me clean up rf.1 !

Diff and Patch

Tests have shown, that using diff to create a patch file and using the patch file to patch the origenal. Have been largly successful so long as the origenal has not been edited since the diff was made.

rf.c

Well I’ve done some correcting to my little back scratcher, including two bug fixes and changes to the man page.

/*-
* Copyright (C) 2007
* Terry *. P*****. All rights reserved.
*
* permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


// 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>

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

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

/*
* rf - read file to standard out v1.1
*/

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;
}
}

if ( (t_flag < 1) && (b_flag < 1) ) {
fp = fopen( argv[1], "r" );
if ( fp == NULL )
errx( 1, "File can not be opened or"
" does not exist -- %sn", argv[1] );
readall( fp, lncnt );
} else if ( t_flag > 0 ) {
fp = fopen( argv[3], "r" );
if ( fp == NULL )
errx( 1, "File can not be opened or"
" does not exist -- %sn", argv[3] );
readtop( fp, lncnt );
} else if ( b_flag > 0 ) {
fp = fopen( argv[3], "r" );
if ( fp == NULL )
errx( 1, "File can not be opened or"
" does not exist -- %sn", argv[3] );
readbottom( fp, lncnt );
} else {
usage();
/* NOTREACHED */
}

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
*/
static void
readbottom( FILE *fp, int lncnt ) {

int hmany = lncnt;
long nlnum = 0;
long where;

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 to b_flag + 1 segments short of the
* end of the list _before_ calling readall. So readall _starts_ from
* the correct fseek offset to print till EOF.
*/
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" );

readall( fp, lncnt );
}

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" );
}

And the manual which writing got me interested in roff, I’ll post when I have time to learn more about it. Basically the problem I had was caused by working on it. Originally under the conditions when 2 + 2 = 5 which is not good, because 2 + 2 is really == 4 !!!! I should never do stuff when I’m like that, but if I don’t try nothing gets done.

Go, what?

Well, to day I was working on some file. And for the first time I asked my self if I should use a ‘Goto’. The goto statement is probably one of the most controversial things I’ve ever read of in computing history.

The problem was, I had the option of repeating several lines of code at several conditionals in a if-elif-else construct. I thought about using a goto to walkk on over to that. So as to only right it once. When I asked my self, Do I even remember the syntax for a Goto ! LMAO !!! I can’t even ever remember using a Go to in any language. The only time I recall learning about using was breifly in an historical C tutorial by by Brian W. Kernighan. Then I thought, since I didn’t want to clutter things by getting repetitive – Why not get off my lazy arse and wrap it in a function?

Really the only purpose of using goto often I could see would be to avoid using functions at all. The best usage of it I can see, which could still be wrapped in a function if wanted. Although I’m sure thats not always best. I don’t see any thing wrong with goto, but I don’t see it as an excuse not to use functions, if-elif-else, switch/case, for/while/do-while e.t.c. what ever constructs the language provides.

I think, in my opinion this would be a good clause to use the ‘infernal goto’

for condintion
do
code
if true
goto handle
else
skip
A number of things like this and eventually

handle:
code to handle false
done

As a method of keeping some exception handling at the end of a loop rather then packing it some where with a nice interface or some thing. I dunno, personally I like doing things in a manor that I know is crystal clear.

For example, column stacking on a door for a bang & clear. It should be clear as can be who is banging, who is openning, and which one enters first, e.t.c.

Post it for the future.

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Some times I dislike being the only one in this burg I know. With a passion for computers and coding in my age group…

Sheesh man, I was in diapers with a Tandy 1000 and TRS-80 Colour Computer for toys. WebTV introduced me to the World Wide Web. A Computer donated from our Church showed me Windows 98 and got me doing like 8+ hour a day learning stuff via Earthlink Dialup.

Look at me now? I’ll be 19 this June. 3 Computers, desktop, desktop turned server, and laptop. Plus Ma’s desktop. Stuck living with Windows often. Yet I breath naturally on my FreeBSD / PC-BSD systems. Feels good to long into FreeBSD even if its through PuTTY at times.

No clue wtfrig I started learning programming, I don’t even care much for C++ in retrospect. Yet I love C !!! GO figure. When I get to a working vacation in July. I plan on boning up on Pythons standard library. I’m only very familer at that level with C and some of the BSD / POSIX extensions on my system. Most of which, I rather like…

Learning to do stuff at CLI levels, learning, understanding, and mastering complexity == heaven. Flib it, man I don’t even _use_ an _IDE_ as most call it. I started with Dev-C++ now? My little bag of tricks. Vi, Vim, Ex, I can use Emacsen but prefer Visen ;-). GCC, the only compiler I’ve ever used but I like it so far. Although I wish it’d be better at reminding me that I transposed a , /or . although thats a font and many lines later issue. I’ve found using GCC from the command line much more flexible. GDB for debugging, skip the GUI ! Lint for simplistic code checking, ctags for larger stuff. A bloody fine manual for system calls, the standard library, and ncurses. A very good Bourne Shell implementation for scripting and many choices. BSD & GNU make, and a number of other things I’ve yet to learn like groff and automake.

Most people my age? Ask’em what C Programming is and they’d probably say forging report cards ! Most probably wouldn’t even know what the HTML in index.html stands for.. A lot of my friends are not even the most computer literate.

I’ve been told in my youth that my mind was like some one older then my years… But I’ve always valued my uniqueness. How many lusers do you know. Who’d manufacture their own fscking mother board & write device drivers as necessary for if they only knew how !!!!!!!!!!!!! Ok , so I’m a crazy lune… can’t help that. But, GOD, I Love to learn about stuff that gets my interest. He’s blessed me so much with being able to learn as much as I have. Odds are, if it wasn’t for that one computer Robert gave me. When he heard ma wouldn’t let me repartion & dual boot ma’s computer. I probably never would have gotten into *nix systems as much as I have. If my sister didn’t get me my laptop. I’d probably never been able to learn this much for programming. Its been a great blessing, one that I’m very thankful for. To me, its a joy to learn some thing new and interesting every day. I’d be happy some day, to know as much about computers as Mel Kaye did lol.

Yet still… who do I have to share this passion with? Mm, no one…….

Thats what pains me lately.

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.

Well I found the anwser to my problem by kicking around rather then kicking my self.

(t_flag < 1) && (b_flag < 1) *not* ((t_flag) && (b_flag) < 1) *smacks self* sleepy idiot !