X-Git-Url: https://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=puffcrash.git;a=blobdiff_plain;f=puffcrash.c;h=b043db7fd7887d0ce3cbc43908f95beebc34028c;hp=3419f8ab98151f099f7706f13597a6ddff242e90;hb=HEAD;hpb=46f0819c5086050816c326aa3d5c97a31ad02344 diff --git a/puffcrash.c b/puffcrash.c index 3419f8a..b043db7 100644 --- a/puffcrash.c +++ b/puffcrash.c @@ -15,9 +15,155 @@ */ #include +#include +#include +#include +#include +#include + +#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; }