This program reads a command (or any character sequence) from stdin and
takes the path to the history file as an argument. The history file should
be empty or contain a list of commands each of which should be followed
by a tab character and a usage count. An example for a line in such a
history file is the following.

st      234

updhist reads a command from stdin, increases its count in the history
file, writes the file out again (overwriting the old one) and then writes
the command to stdout before exiting.
---
 updhist.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 updhist.c

diff --git a/updhist.c b/updhist.c
new file mode 100644
index 0000000..8078b3e
--- /dev/null
+++ b/updhist.c
@@ -0,0 +1,84 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+static void
+usage(void)
+{
+       printf("usage: updhist historyfile\n");
+       exit(0);
+}
+
+static void
+update_hist_file(char* p, char* cmdname, size_t len)
+{
+       FILE *hist = NULL, *nhist = NULL;
+       char *tmpname;
+       char buf[BUFSIZ];
+       int ret, searching = 1;
+       long int count;
+       size_t fnlen;
+
+       if (!(hist = fopen(p, "r")))
+               die("Could not open history file: %s\n", p);
+
+       fnlen = strlen(p);
+       tmpname = malloc(fnlen+5);
+       strcpy(tmpname, p);
+       strcat(tmpname, ".tmp");
+       if (!(nhist = fopen(tmpname, "w")))
+               die("Could not open the history file to write: %s\n", p);
+
+       while (fscanf(hist, "%200s\t%ld", buf, &count) == 2) {
+               if (searching) {
+                       searching = strcmp(buf, cmdname);
+                       if (searching==0)
+                               count++;
+               }
+
+               fprintf(nhist, "%s\t%lu\n", buf, count);
+       }
+       if (searching)
+               fprintf(nhist, "%s\t%d\n", cmdname, 1);
+
+       ret = feof(hist);
+       if (!ret)
+               die("Could not parse history file completely. Exiting.\n");
+
+       fclose(hist);
+       fclose(nhist);
+
+       ret = rename(tmpname, p);
+       if (ret)
+               die("Could not overwrite old history file with the new one. 
Exiting.\n");
+       free(tmpname);
+}
+
+int
+main(int argc, char *argv[])
+{
+       size_t n, len;
+       char stdinbuf[BUFSIZ];
+
+       if (argc < 2)
+               usage();
+
+       while ((n = fread(stdinbuf, 1, sizeof(stdinbuf), stdin))) {
+               if (fwrite(stdinbuf, 1, n, stdout) == n)
+                       continue;
+               fprintf(stderr, "fwrite to stdout did not write all data. Wrote 
only %lu bytes.\n", n);
+       }
+       fclose(stdout);
+
+       len = strlen(stdinbuf);
+       if (len == 0)
+               return 1;
+
+       stdinbuf[--len] = '\0';
+       update_hist_file(argv[1], stdinbuf, len);
+
+       return 0;
+}
-- 
2.6.2


Reply via email to