/* * fwts_log_underline_xml() * write an underline across log, using character ch as the underline */ static void fwts_log_underline_xml(fwts_log_file *log_file, const int ch) { FWTS_UNUSED(log_file); FWTS_UNUSED(ch); /* No-op for xml */ }
static void fwts_log_section_begin_json(fwts_log_file *log_file, const char *name) { json_object *json_obj; json_object *json_log; FWTS_UNUSED(log_file); if ((json_obj = json_object_new_object()) == NULL) fwts_log_out_of_memory_json(); if ((json_log = json_object_new_array()) == NULL) fwts_log_out_of_memory_json(); /* * unfortunately json_object_object_add can fail on * a strdup, but it doesn't check this and doesn't * tell us about this either. Bit lame really. */ json_object_object_add(json_obj, name, json_log); if (json_stack_index > 0) if (json_object_array_add(json_stack[json_stack_index-1].log, json_obj) != 0) fwts_log_out_of_memory_json(); if (json_stack_index < MAX_JSON_STACK) { json_stack[json_stack_index].obj = json_obj; json_stack[json_stack_index].log = json_log; json_stack_index++; } else { fprintf(stderr, "json log stack overflow pushing section %s.\n", name); exit(EXIT_FAILURE); } }
static int s4_options_check(fwts_framework *fw) { FWTS_UNUSED(fw); if ((s4_multiple < 0) || (s4_multiple > 100000)) { fprintf(stderr, "--s4-multiple is %d, it should be 1..100000\n", s4_multiple); return FWTS_ERROR; } if ((s4_min_delay < 0) || (s4_min_delay > 3600)) { fprintf(stderr, "--s4-min-delay is %d, it cannot be less than zero or more than 1 hour!\n", s4_min_delay); return FWTS_ERROR; } if (s4_max_delay < s4_min_delay || s4_max_delay > 3600) { fprintf(stderr, "--s4-max-delay is %d, it cannot be less than --s4-min-delay or more than 1 hour!\n", s4_max_delay); return FWTS_ERROR; } if (s4_delay_delta <= 0.001) { fprintf(stderr, "--s4-delay-delta is %f, it cannot be less than 0.001\n", s4_delay_delta); return FWTS_ERROR; } if ((s4_sleep_delay < 10) || (s4_sleep_delay > 3600)) { fprintf(stderr, "--s4-sleep-delay is %d, it cannot be less than 10 seconds or more than 1 hour!\n", s4_sleep_delay); return FWTS_ERROR; } if ((s4_device_check_delay < 1) || (s4_device_check_delay > 3600)) { fprintf(stderr, "--s4-device-check-delay is %d, it cannot be less than 1 second or more than 1 hour!\n", s4_device_check_delay); return FWTS_ERROR; } if (s4_min_max_delay & s4_device_check) { fprintf(stderr, "Cannot use --s4-min-delay, --s4-max-delay, --s4-delay-delta as well as --s4-device-check, --s4-device-check-delay.\n"); return FWTS_ERROR; } return FWTS_OK; }
static int microcode_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); fwts_klog_free(klog); return FWTS_OK; }
static int clog_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); fwts_clog_free(clog_list); return FWTS_OK; }
int fwts_cmos_read(const uint8_t offset, uint8_t *value) { FWTS_UNUSED(offset); *value = ~0; /* Fake a failed read */ return FWTS_ERROR; }
static int ebda_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); fwts_klog_free(memory_map); return FWTS_OK; }
static int hpet_check_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); if (klog) fwts_text_list_free(klog); return FWTS_OK; }
static int uefirttime_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); fwts_lib_efi_runtime_close(fd); fwts_lib_efi_runtime_unload_module(fw); return FWTS_OK; }
static int syntaxcheck_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); fwts_iasl_deinit(); syntaxcheck_free_advice(); return FWTS_OK; }
static int mcfg_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); if (memory_map_list) fwts_memory_map_table_free(memory_map_list); return FWTS_OK; }
static void fwts_log_section_end_json(fwts_log_file *log_file) { FWTS_UNUSED(log_file); if (json_stack_index > 0) json_stack_index--; else { fprintf(stderr, "json log stack underflow.\n"); exit(EXIT_FAILURE); } }
/* * brightness_deinit() */ int brightness_deinit(fwts_framework *fw) { FWTS_UNUSED(fw); if (brightness_dir) (void)closedir(brightness_dir); brightness_path = NULL; brightness_dir = NULL; return FWTS_OK; }
static int s4_options_handler(fwts_framework *fw, int argc, char * const argv[], int option_char, int long_index) { FWTS_UNUSED(fw); FWTS_UNUSED(argc); FWTS_UNUSED(argv); switch (option_char) { case 0: switch (long_index) { case 0: s4_multiple = atoi(optarg); break; case 1: s4_min_delay = atoi(optarg); s4_min_max_delay = true; break; case 2: s4_max_delay = atoi(optarg); s4_min_max_delay = true; break; case 3: s4_delay_delta = atof(optarg); s4_min_max_delay = true; break; case 4: s4_sleep_delay = atoi(optarg); break; case 5: s4_device_check = true; break; case 6: s4_quirks = optarg; break; case 7: s4_device_check_delay = atoi(optarg); s4_device_check = true; } } return FWTS_OK; }
/* Callback function used when searching for processor devices in namespace. */ static ACPI_STATUS processor_handler(ACPI_HANDLE ObjHandle, uint32_t level, void *context, void **returnvalue) { ACPI_NAMESPACE_NODE *node = (ACPI_NAMESPACE_NODE *)ObjHandle; ACPI_NAMESPACE_NODE *parent = node->Parent; /* Unused parameters trigger errors. */ FWTS_UNUSED(level); FWTS_UNUSED(context); /* If the processor device is not located under _SB_, increment the error_count. */ if (strncmp(parent->Name.Ascii, "_SB_", sizeof(int32_t)) != 0) { int error_count; error_count = *((int *)returnvalue); error_count++; *((int *)returnvalue) = error_count; } /* Return 0 so namespace search continues. */ return 0; }
/* * fwts_printf() * plain old printf() wrapped for fwts */ int fwts_printf(fwts_framework *fw, const char *fmt, ...) { int len; va_list ap; FWTS_UNUSED(fw); va_start(ap, fmt); len = vfprintf(stdout, fmt, ap); fflush(stdout); va_end(ap); return len; }
/* * fwts_button_match_state() * find matching button state and keep count of matching * any non-matching states found * * The button state can be: * FWTS_BUTTON_LID_ANY - match any LID button state * FWTS_BUTTON_LID_OPENED - match any LID buttons that are open * FWTS_BUTTON_LID_CLOSED - match any LID buttons that are closed * FWTS_BUTTON_POWER_EXISTS - match any power putton states * * matched is a count of any button states that match, and not_matched * is a count of any button states that don't match. */ int fwts_button_match_state( fwts_framework *fw, const int button, int *matched, int *not_matched) { *matched = 0; *not_matched = 0; FWTS_UNUSED(fw); if (access(FWTS_PROC_ACPI_BUTTON, R_OK) == 0) return fwts_button_match_state_proc(button, matched, not_matched); return FWTS_ERROR; }
static int wrap_logind_do_s4(fwts_pm_method_vars *fwts_settings, const int percent, int *duration, const char *str) { FWTS_UNUSED(str); char *action = PM_HIBERNATE_LOGIND; fwts_progress_message(fwts_settings->fw, percent, "(Hibernating)"); /* This blocks by entering a glib mainloop */ *duration = fwts_logind_wait_for_resume_from_action(fwts_settings, action, s4_min_delay); fwts_log_info(fwts_settings->fw, "S4 duration = %d.", *duration); fwts_progress_message(fwts_settings->fw, percent, "(Resumed)"); return *duration > 0 ? 0 : 1; }
/* * fwts_acpi_deinit() * Close ACPIA engine and free method namespace */ int fwts_acpi_deinit(fwts_framework *fw) { int ret = FWTS_ERROR; FWTS_UNUSED(fw); if (fwts_acpi_initialized) { fwts_list_free(fwts_object_names, free); fwts_object_names = NULL; ret = fwts_acpica_deinit(); fwts_acpi_initialized = false; } return ret; }
static int wrap_sysfs_do_s4(fwts_pm_method_vars *fwts_settings, const int percent, int *duration, const char *str) { int status; FWTS_UNUSED(str); fwts_progress_message(fwts_settings->fw, percent, "(Hibernating)"); time(&(fwts_settings->t_start)); (void)fwts_klog_write(fwts_settings->fw, "Starting fwts hibernate\n"); (void)fwts_klog_write(fwts_settings->fw, FWTS_HIBERNATE "\n"); status = fwts_sysfs_do_hibernate(fwts_settings); (void)fwts_klog_write(fwts_settings->fw, FWTS_RESUME "\n"); (void)fwts_klog_write(fwts_settings->fw, "Finished fwts resume\n"); time(&(fwts_settings->t_end)); fwts_progress_message(fwts_settings->fw, percent, "(Resumed)"); *duration = (int)(fwts_settings->t_end - fwts_settings->t_start); return status; }
/* * fwts_log_printf_json() * print to a log */ static int fwts_log_print_json( fwts_log_file *log_file, const fwts_log_field field, const fwts_log_level level, const char *status, const char *label, const char *prefix, const char *buffer) { char tmpbuf[4096]; struct tm tm; time_t now; json_object *header; json_object *json_log = (json_object*)json_stack[json_stack_index-1].log; json_object *obj; char *str; FWTS_UNUSED(prefix); if (!((field & LOG_FIELD_MASK) & fwts_log_filter)) return 0; if (field & (LOG_NEWLINE | LOG_SEPARATOR | LOG_DEBUG)) return 0; time(&now); localtime_r(&now, &tm); if ((header = json_object_new_object()) == NULL) fwts_log_out_of_memory_json(); if ((obj = json_object_new_int(log_file->line_number)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "line_num", obj); snprintf(tmpbuf, sizeof(tmpbuf), "%2.2d/%2.2d/%-2.2d", tm.tm_mday, tm.tm_mon + 1, (tm.tm_year+1900) % 100); if ((obj = json_object_new_string(tmpbuf)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "date", obj); snprintf(tmpbuf, sizeof(tmpbuf), "%2.2d:%2.2d:%2.2d", tm.tm_hour, tm.tm_min, tm.tm_sec); if ((obj = json_object_new_string(tmpbuf)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "time", obj); if ((obj = json_object_new_string(fwts_log_field_to_str_full(field))) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "field_type", obj); str = fwts_log_level_to_str(level); if (!strcmp(str, " ")) str = "None"; if ((obj = json_object_new_string(str)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "level", obj); if ((obj = json_object_new_string(*status ? status : "None")) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "status", obj); if ((obj = json_object_new_string(label && *label ? label : "None")) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "failure_label", obj); /* Redundant really if ((obj = json_object_new_string(log->owner)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "owner", obj); */ if ((obj = json_object_new_string(buffer)) == NULL) fwts_log_out_of_memory_json(); json_object_object_add(header, "log_text", obj); json_object_array_add(json_log, header); log_file->line_number++; /* This is academic really */ return 0; }
/* * fwts_log_print_html() * print to a log */ static int fwts_log_print_html( fwts_log_file *log_file, const fwts_log_field field, const fwts_log_level level, const char *status, const char *label, const char *prefix, const char *buffer) { char *str; char *style; char *code_start; char *code_end; char *html_converted; FWTS_UNUSED(label); FWTS_UNUSED(prefix); if (!((field & LOG_FIELD_MASK) & fwts_log_filter)) return 0; if (field & (LOG_NEWLINE | LOG_SEPARATOR | LOG_DEBUG)) return 0; if ((html_converted = fwts_log_html_convert_ascii_str(buffer)) == NULL) { /* We can't report an error via the logging mechanism in case we loop */ fprintf(stderr, "Out of memory converting html.\n"); exit(EXIT_FAILURE); } fwts_log_html(log_file, "<TR>\n"); if (field & LOG_VERBATUM) { code_start = "<PRE class=style_code>"; code_end = "</PRE>"; } else { code_start = ""; code_end = ""; } switch (field & LOG_FIELD_MASK) { case LOG_ERROR: fwts_log_html(log_file, " <TD class=style_error>Error</TD>" "<TD COLSPAN=2>%s</TD>\n", html_converted); break; case LOG_WARNING: fwts_log_html(log_file, " <TD class=style_error>Warning</TD>" "<TD COLSPAN=2 class=style_advice_info>%s%s%s</TD>\n", code_start, html_converted, code_end); break; case LOG_HEADING: fwts_log_html(log_file, "<TD COLSPAN=2 class=style_heading>%s%s%s</TD>\n", code_start, html_converted, code_end); break; case LOG_INFO: fwts_log_html(log_file, " <TD></TD><TD COLSPAN=2 class=style_infos>%s%s%s</TD>\n", code_start, html_converted, code_end); break; case LOG_PASSED: fwts_log_html(log_file, "<TD class=style_passed>PASSED</TD><TD>%s</TD>\n", html_converted); break; case LOG_FAILED: switch (level) { case LOG_LEVEL_CRITICAL: style = " class=style_critical"; break; case LOG_LEVEL_HIGH: style = " class=style_high"; break; case LOG_LEVEL_MEDIUM: style = " class=style_medium"; break; case LOG_LEVEL_LOW: style = " class=style_low"; break; case LOG_LEVEL_INFO: case LOG_LEVEL_NONE: default: style = ""; break; } str = fwts_log_level_to_str(level); fwts_log_html(log_file, " <TD%s>%s [%s]</TD>\n", style, *status ? status : "", str); fwts_log_html(log_file, " <TD>%s</TD>\n", html_converted); break; case LOG_SKIPPED: fwts_log_html(log_file, "<TD class=style_skipped>Skipped</TD>" "<TD>%s%s%s</TD>\n", code_start, html_converted, code_end); break; case LOG_SUMMARY: fwts_log_html(log_file, " <TD></TD>" "<TD COLSPAN=2 class=style_summary>%s%s%s</TD>\n", code_start, html_converted, code_end); break; case LOG_ADVICE: fwts_log_html(log_file, " <TD class=style_advice>Advice</TD>" "<TD COLSPAN=2 class=style_advice_info>%s%s%s</TD>\n", code_start, html_converted, code_end); break; default: break; } free(html_converted); fwts_log_html(log_file, "</TR>\n"); fflush(log_file->fp); log_file->line_number++; /* not used, but bump it anyway */ return 0; }
/* * fwts_log_newline() * write newline to log */ static void fwts_log_newline_xml(fwts_log_file *log_file) { FWTS_UNUSED(log_file); /* No-op for xml */ }
/* * fwts_log_print_xml() * print to a log */ static int fwts_log_print_xml( fwts_log_file *log_file, const fwts_log_field field, const fwts_log_level level, const char *status, const char *label, const char *prefix, const char *buffer) { struct tm tm; time_t now; char *str; FWTS_UNUSED(prefix); if (!((field & LOG_FIELD_MASK) & fwts_log_filter)) return 0; if (field & (LOG_NEWLINE | LOG_SEPARATOR | LOG_DEBUG)) return 0; time(&now); localtime_r(&now, &tm); fprintf(log_file->fp, "%*s<logentry>\n", xml_stack_index * XML_INDENT, ""); fprintf(log_file->fp, "%*s<line_num>%" PRIu32 "</line_num>\n", (xml_stack_index + 1) * XML_INDENT, "", log_file->line_number); fprintf(log_file->fp, "%*s<date>%2.2d/%2.2d/%-2.2d</date>\n", (xml_stack_index + 1) * XML_INDENT, "", tm.tm_mday, tm.tm_mon + 1, (tm.tm_year+1900) % 100); fprintf(log_file->fp, "%*s<time>%2.2d:%2.2d:%2.2d</time>\n", (xml_stack_index + 1) * XML_INDENT, "", tm.tm_hour, tm.tm_min, tm.tm_sec); fprintf(log_file->fp, "%*s<field_type>%s</field_type>\n", (xml_stack_index + 1) * XML_INDENT, "", fwts_log_field_to_str_full(field)); str = fwts_log_level_to_str(level); if (!strcmp(str, " ")) str = "None"; fprintf(log_file->fp, "%*s<level>%s</level>\n", (xml_stack_index + 1) * XML_INDENT, "", str); fprintf(log_file->fp, "%*s<status>%s</status>\n", (xml_stack_index + 1) * XML_INDENT, "", *status ? status : "None"); fprintf(log_file->fp, "%*s<failure_label>%s</failure_label>\n", (xml_stack_index + 1) * XML_INDENT, "", label && *label ? label : "None"); fprintf(log_file->fp, "%*s<log_text>%s</log_text>\n", (xml_stack_index + 1) * XML_INDENT, "", buffer); fprintf(log_file->fp, "%*s</logentry>\n", xml_stack_index * XML_INDENT, ""); fflush(log_file->fp); log_file->line_number++; return 0; }
/* * fwts_log_newline() * write newline to log */ static void fwts_log_newline_json(fwts_log_file *log_file) { FWTS_UNUSED(log_file); /* No-op for json */ }