#include #include #include #include #include void showtodo(void); void addtodo(void); void deltodo(int); int mygetline(char[], int, FILE*); static char *todofile = "/home/mujo/.todo"; /* read a line into s, return line length */ /* not using getline(3) for learning purposes */ int mygetline(char s[], int lim, FILE *file) { int c, i; for (i = 0; i < lim - 1 && (c = getc(file)) != EOF \ && c != '\n'; ++i) { s[i] = c; } if (c == '\n') { s[i] = '\n'; ++i; } s[i] = '\0'; return i; } /* read from todo file and write to stdout */ void showtodo() { FILE *file; int len, i; char line[BUFSIZ]; if ((file = fopen(todofile, "r")) == NULL) err(1, "fopen"); for (i = 1; (len = mygetline(line, BUFSIZ, file)) > 0; ++i) printf("%d: %s", i, line); fclose(file); } /* read from stdin and write to todo file */ void addtodo() { FILE *file; int c; if ((file = fopen(todofile, "a")) == NULL) err(1, "fopen"); while ((c = getc(stdin)) != '\n') putc(c, file); putc('\n', file); fclose(file); } /* remove line, numbered ln, from todo file */ void deltodo(int lnum) { FILE *file, *tmp; int c, lcur; lcur = 1; if ((file = fopen(todofile, "r")) == NULL) err(1, "fopen"); if ((tmp = tmpfile()) == NULL) err(1, "tmpfile"); while ((c = getc(file)) != EOF) { if (lcur != lnum) putc(c, tmp); if (c == '\n') ++lcur; } rewind(tmp); fclose(file); /* reopen todo file for writing to truncate */ if ((file = fopen(todofile, "w")) == NULL) err(1, "fopen"); while ((c = getc(tmp)) != EOF) putc(c, file); fclose(file); fclose(tmp); } int main(int argc, char *argv[]) { int ch; int ln; const char *errstr; if (argc == 1) showtodo(); while ((ch = getopt(argc, argv, "sad:")) != -1) { switch(ch) { case 's': showtodo(); break; case 'a': addtodo(); break; case 'd': ln = strtonum(optarg, 1, INT_MAX, &errstr); if (errstr != NULL) err(1, "line num is %s: %s", errstr, optarg); deltodo(ln); break; default: errx(1, "- show|add|del"); } } return 0; }