bool record_create(record_t *record, const char *prog, int argc, char **argv) { char hash_buf[SHA1_STRING_LEN]; const char *prog_bin = prog; unsigned i; record_clear(record); if (strrchr(prog, '/')) prog_bin = strrchr(prog, '/') + 1; if (!sha1_file(prog, hash_buf)) return false; strlist_push_back(&record->prog_line, prog_bin); strlist_push_back(&record->prog_line, sha1_file(prog, hash_buf)); for (i = 0; i < (unsigned)argc; ++i) strlist_push_back(&record->prog_line, argv[i]); strlist lib_list = STRLIST_INITIALIZER; get_libs(&lib_list, prog); for (i = 0; i < lib_list.count; ++i) { const char *lib_path = strlist_get(&lib_list, i); if (!sha1_file(lib_path, hash_buf)) continue; strlist_push_back(&record->lib_line, lib_path); strlist_push_back(&record->lib_line, sha1_file(lib_path, hash_buf)); } record->enabled = true; return true; }
strlist libs_diff(strlist *prev_run, strlist *curr_run) { strlist result = STRLIST_INITIALIZER; char buf[STRING_MAX]; unsigned prev_cnt = 0, curr_cnt = 0; char *prev_ptr = strlist_get(prev_run, prev_cnt); char *curr_ptr = strlist_get(curr_run, curr_cnt); int retval = 0; while (prev_ptr || curr_ptr) { if (prev_ptr && curr_ptr) { retval = strcmp(prev_ptr, curr_ptr); if (retval == 0) { // Libraries match. Compare file contents. char *prev_hash = strlist_get(prev_run, ++prev_cnt); char *curr_hash = strlist_get(curr_run, ++curr_cnt); if (strcmp(prev_hash, curr_hash) != 0) { snprintf(buf, sizeof(buf), "* %s has changed since last run.", prev_ptr); strlist_push_back(&result, buf); } prev_ptr = strlist_get(prev_run, ++prev_cnt); curr_ptr = strlist_get(curr_run, ++curr_cnt); continue; } } if (!curr_ptr || retval < 0) { // If (there are no more libraries from `ldd`) OR // (library from history record not found in `ldd` list) snprintf(buf, sizeof(buf), "* Mutatee is no longer dependent on %s.", prev_ptr); strlist_push_back(&result, buf); ++prev_cnt; // Skip digest string. prev_ptr = strlist_get(prev_run, ++prev_cnt); } else if (!prev_ptr || retval > 0) { // If (there are no more libraries from the history record) OR // (library from `ldd` not found in history record list) snprintf(buf, sizeof(buf), "* Mutatee is now dependent on %s.", curr_ptr); strlist_push_back(&result, buf); ++curr_cnt; // Skip digest string. curr_ptr = strlist_get(curr_run, ++curr_cnt); } } return result; }
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; }