#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

struct item {
	char *string;
	int line;

	struct item *next;
};

int main(int argc, char **argv) 
{
	FILE *ff;		// The input file
	char line[1024];	// The input line
	struct item *head=NULL;	// The top of the linked list
	struct item *ptr;	// A temp pointer for wizzing down lists
	int lineno=0;		// which line number

	/* there is always 1 argc, the program name argv[0] */
	if (argc<2) {
		/* Moan if we don't get given a file name */
		fprintf(stderr, "Hey, gimme a file name!\n");
		exit(1);
	}

	if ((ff=fopen(argv[1], "r"))==NULL) {
		/* moan about it, but include the real Error message */
		fprintf(stderr, "Whoops, file '%s' said %s\n",
				argv[1], strerror(errno));
		exit(1);
	}

	while (!feof(ff) && fgets(line, 1024, ff)!=NULL) {
		struct item *new;
		char *c;

		/* chop the end off the line */
		if ((c=strchr(line, '\n'))!=NULL) *c=0;
		if ((c=strchr(line, '\r'))!=NULL) *c=0;

		/* make a new structure */
		new = malloc( sizeof(struct item) );

		/* fill it in */
		new->string = strdup( line );
		new->line=lineno;

		/* stick it at the top of the list */
		new->next=head;
		head=new;
		lineno++;
	}
	fclose(ff);

	/* now print it all out.
	   It's in reverse order, because we inserted at the
	   top of the list, like a stack */

	/* because head was NULL to begin with, and we copied that
	   to the next pointer each time, we know when we end up with
	   a NULL again, so we're done, without needing to know how long the
	   list was. This is also safe on empty lists */

	ptr=head;
	while ( ptr!=NULL ) {
		printf ("%d: %s\n", ptr->line, ptr->string);
		ptr=ptr->next;
	}
	exit (0);
}	


