void record_clear(record_t *record) { record->enabled = false; strlist_clear(&record->prog_line); strlist_clear(&record->lib_line); record->filename[0] = '\0'; record->fd = NULL; record->raw_fd = NULL; }
strlist char2strlist(char *buf) { char *data = NULL; char *curr = buf; char *next = NULL; strlist result = STRLIST_INITIALIZER; while (curr && *curr) { while (isspace(*curr)) ++curr; data = decodeStr(curr, &next); if (!strlist_push_back(&result, data)) { strlist_clear(&result); break; } curr = next; } return result; }
void _cwt_textblk_clear(CwtTextBlkPtr tb) { JQ_ASSERT(tb); strlist_clear(tb->lines); tb->top_line = tb->lines->strings.first; }
void record_update(record_t *newRecord) { FILE *index_fd; FILE *new_fd; char index_filename[PATH_MAX]; char new_index_filename[PATH_MAX]; strncpy(index_filename, config.record_dir, sizeof(index_filename)); strncat(index_filename, "/", sizeof(index_filename) - strlen(index_filename)); strncat(index_filename, HISTORY_RECORD_INDEX_FILE, sizeof(index_filename) - strlen(index_filename)); errno = 0; index_fd = fopen(index_filename, "r"); if (!index_fd) { fprintf(stderr, "Could not open %s\n", index_filename); return; } strncpy(new_index_filename, index_filename, sizeof(new_index_filename)); strncat(new_index_filename, ".update", sizeof(new_index_filename) - strlen(new_index_filename)); new_fd = fopen(new_index_filename, "w"); if (!new_fd) { fprintf(stderr, "Could not open %s\n", new_index_filename); return; } char *buf = NULL; bool found = false; strlist prog_line = STRLIST_INITIALIZER; while ( (buf = fgets_static(index_fd))) { chomp(buf); if (buf[0] == '\t' || buf[0] == '\0') { fprintf(new_fd, "%s\n", buf); buf[0] = '\0'; continue; } prog_line = char2strlist(buf); if (strlist_cmp(&prog_line, &newRecord->prog_line)) { fprintf(new_fd, "%s\n", buf); strlist_push_front(&newRecord->lib_line, newRecord->filename); buf = strlist2char(&newRecord->lib_line); fprintf(new_fd, "\t%s\n", buf); strlist_pop_front(&newRecord->lib_line); while ( (buf = fgets_static(index_fd)) && buf[0] == '\t') { chomp(buf); strlist lib_line = char2strlist(buf); strlist_pop_front(&lib_line); if (!strlist_cmp(&lib_line, &newRecord->lib_line)) fprintf(new_fd, "%s\n", buf); strlist_clear(&lib_line); } fprintf(new_fd, "%s", buf); // NOTE: Do not print "%s\n" here. found = true; break; } if (strcmp(strlist_get(&newRecord->prog_line, 0), strlist_get(&prog_line, 0)) < 0) break; strlist_clear(&prog_line); fprintf(new_fd, "%s\n", buf); buf[0] = '\0'; } // New binary signature entry. if (!found) { char *buf2; buf2 = strlist2char(&newRecord->prog_line); fprintf(new_fd, "%s\n", buf2); strlist_push_front(&newRecord->lib_line, newRecord->filename); buf2 = strlist2char(&newRecord->lib_line); fprintf(new_fd, "\t%s\n\n", buf2); strlist_pop_front(&newRecord->lib_line); if (buf && buf[0] != '\0') fprintf(new_fd, "%s\n", buf); } while ( (buf = fgets_static(index_fd))) fprintf(new_fd, "%s", buf); // NOTE: Do not print "%s\n" here. fclose(index_fd); fclose(new_fd); unlink(index_filename); rename(new_index_filename, index_filename); }
bool record_search(record_t *newRecord) { FILE *index_fd; char *index_filename; bool found = false, latest = true; index_filename = sprintf_static("%s/%s", config.record_dir, HISTORY_RECORD_INDEX_FILE); errno = 0; index_fd = fopen(index_filename, "r"); if (errno && errno == ENOENT) { index_fd = fopen(index_filename, "w"); if (!index_fd) { fprintf(config.outfd, "*\n* Error opening history record index %s. Disabling history record.\n*\n", index_filename); newRecord->enabled = false; return false; } fclose(index_fd); } else if (!index_fd) { fprintf(config.outfd, "*\n* Error opening history record index %s. Disabling history record.\n*\n", index_filename); newRecord->enabled = false; return false; } else { // We should use C++ string instead to avoid buffer overflows. char *buf; while ( (buf = fgets_static(index_fd))) { if (buf[0] == '\t' || buf[0] == '\n') continue; chomp(buf); strlist prog_line = char2strlist(buf); if (strlist_cmp(&prog_line, &newRecord->prog_line)) { strlist diff_list = STRLIST_INITIALIZER; while (!found && (buf = fgets_static(index_fd)) && buf[0] == '\t') { chomp(buf); strlist lib_line = char2strlist(buf + 1); strncpy(newRecord->filename, strlist_get(&lib_line, 0), sizeof(newRecord->filename)); strlist_pop_front(&lib_line); if (strlist_cmp(&lib_line, &newRecord->lib_line)) { found = true; } else { if (latest) diff_list = libs_diff(&lib_line, &newRecord->lib_line); latest = false; } strlist_clear(&lib_line); } if (!found) { fprintf(config.outfd, "* Warning: Current library set unknown. Differences from latest run include:\n"); fprintf(config.outfd, "*\n"); for (unsigned i = 0; i < diff_list.count; ++i) fprintf(config.outfd, "%s\n", strlist_get(&diff_list, i)); } else if (!latest) fprintf(config.outfd, "* Warning: Current library signature does not match latest run.\n"); strlist_clear(&diff_list); } strlist_clear(&prog_line); } fclose(index_fd); } if (!found) { // Fill storage file information const char *prog_file = strlist_get(&newRecord->prog_line, 0); if (strrchr(prog_file, '/')) prog_file = strrchr(prog_file, '/') + 1; snprintf(newRecord->filename, sizeof(newRecord->filename), "%s/%s-XXXXXX", config.record_dir, prog_file); int file_desc = mkstemp(newRecord->filename); newRecord->fd = fdopen(file_desc, "a"); } else { newRecord->fd = fopen(newRecord->filename, "a"); } char timestr[STRING_MAX]; time_t timestamp = time(NULL); strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %Z", localtime(×tamp)); fprintf(newRecord->fd, "Log start: %s\n", timestr); fprintf(newRecord->fd, "--------------------------------------------------------------------------------\n"); char raw_filename[ PATH_MAX ]; strncpy(raw_filename, newRecord->filename, sizeof(raw_filename)); strncat(raw_filename, ".raw", sizeof(raw_filename) - strlen(raw_filename)); newRecord->raw_fd = fopen(raw_filename, "a"); fprintf(newRecord->raw_fd, "Raw transcript log start: %s\n", timestr); fprintf(newRecord->raw_fd, "--------------------------------------------------------------------------------\n"); return (found && latest); }