a bunch of stuff, i don't know
[puffcrash.git] / puffcrash.c
index 3419f8ab98151f099f7706f13597a6ddff242e90..b043db7fd7887d0ce3cbc43908f95beebc34028c 100644 (file)
  */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <signal.h>
+
+#define LINE_SIZE 4096
+
+struct config {
+       char *obj_path;
+       char *tool_path;
+       char *src_path;
+       FILE *conf;
+       FILE *term;
+} *gcfg;
+
+struct sigaction sigact;
+static void sigh(int);
+static void sigc(void);
+
+static void __dead
+usage(void)
+{
+       fprintf(stderr, "usage: puffcrash [-c config] [serial console log]\n");
+       exit(1);
+}
+
+void
+sigh(int sig)
+{
+       if (sig == SIGINT) sigc();
+}
+
+void
+sigc(void)
+{
+       if (gcfg->obj_path) free(gcfg->obj_path);
+       if (gcfg->tool_path) free(gcfg->tool_path);
+       if (gcfg->src_path) free(gcfg->src_path);
+
+       if (gcfg->conf) fclose(gcfg->conf);
+       if (gcfg->term && gcfg->term != stdin) fclose(gcfg->term);
+
+       exit(1);
+}
+
+int
+parse_config(char *config_path, struct config *cfg)
+{
+       char *line, *i;
+       int check = 0;
+
+       cfg->conf = fopen(config_path, "r");
+
+       if(!(line = calloc(1, 256)) || !cfg->conf)
+           return 1;
+
+       while ((fgets(line, 256, cfg->conf))) {
+           if (strstr(line, "obj_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->obj_path, i, PATH_MAX);
+               check |= (1 << 0);
+           } else if (strstr(line, "tool_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->tool_path, i, PATH_MAX);
+               check |= (1 << 1);
+           } else if (strstr(line, "src_path")) {
+               i = strstr(line, "=") + 2;
+               strlcpy(cfg->src_path, i, PATH_MAX);
+               check |= (1 << 2);
+           }
+       }
+
+       free(line);
+
+       if (check == 0x7)
+           return 0;
+       else
+           return 1;
+}
+
+void
+watch_serial(void)
+{
+       char *line;
+
+       if (!(line = calloc(1, LINE_SIZE))) {
+           printf("could not allocate memory\n");
+           sigc();
+       }
+
+       while ((fgets(line, LINE_SIZE, gcfg->term))) {
+           printf("%s", line);
+       }
+}
 
 int
 main(int argc, char *argv[])
 {
+       struct config cfg;
+       int ch;
+       char term_path[PATH_MAX], config_path[PATH_MAX];
+
+       bzero(&cfg, sizeof(struct config));
+       strlcpy(config_path, "/etc/puffcrash.conf", PATH_MAX);
+
+       atexit(sigc);
+       sigact.sa_handler = sigh;
+       sigemptyset(&sigact.sa_mask);
+       sigact.sa_flags = 0;
+       sigaction(SIGINT, &sigact, (struct sigaction *) NULL);
+
+       while ((ch = getopt(argc, argv, "c:")) != -1) {
+           switch (ch) {
+           case 'c':
+               strlcpy(config_path, optarg, PATH_MAX);
+               break;
+           default:
+               usage();
+               break;
+           }
+       }
+
+       argv += optind;
+       argc -= optind;
+
+       cfg.obj_path  = calloc(1, PATH_MAX);
+       cfg.tool_path = calloc(1, PATH_MAX);
+       cfg.src_path  = calloc(1, PATH_MAX);
+
+       gcfg = &cfg;
+
+       if (parse_config(config_path, &cfg)) {
+           printf("failed to parse config file %s.\n", config_path);
+           sigc();
+       }
+
+       if (argc) {
+           strlcpy(term_path, argv[0], PATH_MAX);
+           cfg.term = fopen(term_path, "r");
+       } else
+           cfg.term = stdin;
+
+       if (!cfg.term) {
+           printf("failed to open serial console output logfile \"%s\"\n", argv[0]);
+           sigc();
+       }
+
+       watch_serial();
+
        return 0;
 }