Domácí úkol č.2

Makefile
CC = gcc
CFLAGS = -std=c99 -pedantic -Wall -O3
PROGS = tail
LOGIN = xkalab00
ARCHIVER = zip
 
all: $(PROGS)
 
tail: tail.c
 
clean:
	-rm -f $(PROGS)
 
pack:
	-$(ARCHIVER) $(LOGIN).zip *.c Makefile
tail.c
// tail.c
// Řešení IJC-DU2, příklad 1a)
// Autor: Jan Kaláb, FIT
// Přeloženo gcc 4.1.1 || 4.1.2
 
#include <stdio.h>
#include <stdlib.h>
 
FILE *otevri(char *soubor) {
	//printf("Oteviram %s...\n", soubor);
	FILE *fp = fopen(soubor, "r");
	return fp;
}
 
int seekprint(char *pozadovany_soubor, unsigned int pozadovanych_radku, unsigned short int odzacatku) {
	FILE *soubor = otevri(pozadovany_soubor); //otevrem soubor
	if (soubor == NULL) { //kdyz se to nepovedlo
		fprintf(stderr, "Nepodarilo se otevrit soubor %s\n", pozadovany_soubor);
		return EXIT_FAILURE;
	}
 
	//Jdem hledat poslednich n radku
	fseek(soubor, 0, SEEK_END);
	long delka = ftell(soubor);
	fseek(soubor, 0, SEEK_SET);
	//printf("Soubor ma %ld znaku\n", delka);
	long offset = 0;
	unsigned int prectenych_radku = 0;
	if (odzacatku != 0) prectenych_radku = 2; //todle moc nevim proc zrovna 2
	int znak;
	while (prectenych_radku <= pozadovanych_radku) {
		if (odzacatku != 0) fseek(soubor, offset, SEEK_SET); else fseek(soubor, offset, SEEK_END);
		if (abs(offset) > delka) { //kdyz uz jsme moc daleko
			//fprintf(stderr, "Jsme mimo soubor!\n");
			if (odzacatku != 0) fseek(soubor, 0, SEEK_END); else fseek(soubor, 0, SEEK_SET);
			break;
		}
		znak = getc(soubor);
		if (znak == '\n') prectenych_radku++;
		if (odzacatku != 0) offset++; else offset--;
	}
	//printf("offset = %ld\n", offset);
	//printf("pozice = %ld\n", ftell(soubor));
 
	//Vyblejem to
	while ((znak = getc(soubor)) != EOF) putchar(znak);
 
	//Skoncime
	fclose(soubor);
	return EXIT_SUCCESS;
}
 
int main(int argc, char *argv[]) {
	if (argc == 1) { //stdin
		//malloc
		unsigned int alok = 1;
		int *text = malloc(alok * sizeof(int));
		if (text == NULL) {
			fprintf(stderr, "Nedokazu alokovat pamet\n");
			return EXIT_FAILURE;
		}
 
		//cteni
		int znak = getchar();
		unsigned int precteno=1;
 
		while (znak != EOF) {
			//putchar(znak);
			if (precteno >= alok) {//realloc
				alok*=2;
				if ((text = realloc(text, alok * sizeof(int))) == NULL) {
					fprintf(stderr, "Nedokazu realokovat pamet\n");
					free(text);
					return EXIT_FAILURE;
				}
			}
			text[precteno-1] = znak;
			znak = getchar();
			precteno++;
		}
 
		//najdem poslednich 10 radku
		unsigned int vypis=precteno;
		unsigned int radku=0;
		while (radku <= 10 && vypis > 0) {
			vypis--;
			if (text[vypis-1] == '\n') radku++;
		}
 
		//Vyblejem to
		while (vypis < precteno) {
			putchar(text[vypis]);
			vypis++;
		}
		//printf("Alokovano: %d\n", alok);
 
		//Skoncime
		free(text);
		return EXIT_SUCCESS;
	}
	if (argc == 2) { //10 radku
		if (seekprint(argv[1], 10, 0) == EXIT_FAILURE) return EXIT_FAILURE;
		return EXIT_SUCCESS;
	}
	if (argc == 3) { //spesl
		unsigned int pozadovanych_radku = atoi(argv[1]+1);
		//printf("Chces otevrit soubor %s s parametrem %s\n", argv[2], argv[1]);
		if (argv[1][0] != '-' && argv[1][0] != '+') { //blbost
			fprintf(stderr, "Nevim co po me chces!\n");
			return EXIT_FAILURE;
		}
		if (argv[1][0] == '-') { //poslednich n radku
			if (seekprint(argv[2], pozadovanych_radku, 0) == EXIT_FAILURE) return EXIT_FAILURE;
			return EXIT_SUCCESS;
		}
		if (argv[1][0] == '+') { //od radku n
			if (seekprint(argv[2], pozadovanych_radku, 1) == EXIT_FAILURE) return EXIT_FAILURE;
			return EXIT_SUCCESS;
		}
	}
	fprintf(stderr, "Chces toho po me moc!\n");
	return EXIT_FAILURE;
}