/* A primitive version of the unix 'tail' command. * If this is primitive, I'm retarded, cuz this took me * a few hours :\ Licensed under the GNU GPL, * ABSOLUTELY NO WARRANTY! */ #include #define MAXLINE 1000 /* malloc() will come in time... */ #define MAXBUF 100 /* maximum size of buffer, yes, i'll malloc it in time... */ #define ALLOC 10000 /* god give me my malloc()! */ #define DEFCOUNT 10 /* default number of lines to output */ int atoi(char *s) { int val = 0; char c; while ((c = *s++) != '\0') { if (isdigit(c)) val = val * 10 + c - '0'; else return -1; } return val; } void usage(void) { printf("Usage: tail [-n lines]\n"); } int getline(char s[], int len) { /* truncates if input it too big */ char c; int i = 0; while ((c = getchar()) != EOF && c != '\n' && i < len - 1) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } char *alloc(int len) { /* closest to good i could get */ static char allocbuf[ALLOC]; static int index = 0; if (index + len < ALLOC) { index += len; return &allocbuf[index - len]; } return NULL; } int tail(int count) { char *buffer[MAXBUF]; /* where we store the inputted lines */ char temp[MAXLINE]; /* temporary storage */ int len; /* length of retrieved line */ int index = 0; /* the next buffer element to write to */ int wrap = 0; /* whether we've wrapped around at all */ int i; /* think _real_ hard about it... */ for (i = 0; i < MAXBUF; i++) buffer[i] = NULL; while ((len = getline(temp, MAXLINE)) > 0) { buffer[index] = alloc(len+1); if (buffer[index] == NULL) { printf("File too big, it seems.\n"); return -1; } strcpy(buffer[index], temp); index++; index %= count; if (index == 0) wrap = 1; } if (!wrap) index = 0; for (i = 0; i < count && buffer[index] != NULL; i++) { printf("%s", buffer[index]); index++; index %= count; } } int main(int argc, char *argv[]) { /*argv stands for "argument vector", fyi*/ int count, action; char c; action = 0; count = DEFCOUNT; while (--argc && (*++argv)[0] == '-') { while (c = *++argv[0]) { switch (c) { case 'n': if (*++argv[0] != '\0') usage(); action = 1; argc--; count = atoi(*++argv); if (count < 0) { printf("Negative lines?\n"); printf("This just isn't going to work out: %d\n", count); return -1; } else if (count == 0) { printf("Why don't you try cat filename > /dev/null.\n"); printf("...jackass...\n"); return -1; } else if (count > MAXBUF) { printf("TOO BIG!\n"); return -1; } /* make sure that no further characters will be processed */ while(*(argv[0]+1) != '\0') ++argv[0]; break; case 'h': if (!action) usage(); return -1; break; default: printf("Awol flag: %c\n", c); return -1; break; } } } if (argc != 0) { /* no args required */ usage(); }else { if(tail(count) == -1) return -1; else return 0; } }