/* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of the nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #define MAX_LABEL_LENGTH 32 #define PARAM_SHORT_VIEW 1 #define PARAM_MAX_ONLY 1 << 2 typedef struct { float cpu; float cpu_cores[64]; float acpi_sensors[16]; unsigned int cpu_cores_count; unsigned int acpi_sensors_count; } thermal_sensors; static void show_help(void) { puts("parametry:"); puts(" -m zobrazi pouze maximalni hodnoty"); puts(" -s kratky vypis"); puts(" -l "); } static int load_sensors(thermal_sensors *sensors) { memset(sensors, 0, sizeof(thermal_sensors)); char buffer[1024]; FILE *p_file = popen("sensors", "r"); if (NULL == p_file) return errno; float dval; const unsigned int section_cpu = 1; const unsigned int section_acpitz = 0; unsigned int section = 0; size_t index_acpitz = 0; size_t index_cpu = 0; size_t max_cpu_count = sizeof(sensors->cpu_cores) / sizeof(float); size_t max_acpi_count = sizeof(sensors->acpi_sensors) / sizeof(float); char pattern[64]; while (!feof(p_file)) { if (index_acpitz >= max_acpi_count) break; if (index_cpu >= max_cpu_count) break; if (fgets(buffer, sizeof(buffer), p_file) != NULL) { if (*buffer == '\n') { section = 0; continue; } if (0 == strncasecmp(buffer, "coretemp", 8)) { section = section_cpu; continue; } if (0 == strncasecmp(buffer, "acpitz", 6)) { section = section_acpitz; continue; } if (section_cpu == section) { if (sscanf(buffer, "Package id 0: %f", &dval) == 1) { sensors->cpu = dval; continue; } (void)sprintf(pattern, "Core %d: ", (int)index_cpu); (void)strncat(pattern, "%f", sizeof(pattern) - strlen(pattern) - 1); if (sscanf(buffer, pattern, &dval) == 1) { sensors->cpu_cores[index_cpu] = dval; index_cpu++; continue; } } else if (section_acpitz == section) { (void)sprintf(pattern, "temp%d: ", (int)index_acpitz+1); (void)strncat(pattern, "%f", sizeof(pattern) - strlen(pattern) - 1); if (sscanf(buffer, pattern, &dval) == 1) { sensors->acpi_sensors[index_acpitz] = dval; ++index_acpitz; continue; } } } else break; } sensors->cpu_cores_count = index_cpu; sensors->acpi_sensors_count = index_acpitz; (void)pclose(p_file); return (index_cpu > 0 || index_acpitz > 0) ? 1 : -1; } static void print_sensors_info_line(thermal_sensors *sensors, const char *szlabel, uint_fast32_t params) { if (szlabel && (*szlabel != 0)) { printf(szlabel); printf(" "); } float max_core = 0; for (size_t i = 0; i < sensors->cpu_cores_count; ++i) { if (sensors->cpu_cores[i] > max_core) max_core = sensors->cpu_cores[i]; } if (params & PARAM_MAX_ONLY) { if (params & PARAM_SHORT_VIEW) (void)printf("%.0f°", sensors->cpu > max_core ? sensors->cpu : max_core); else (void)printf("cpu: %.0f°C acpi:", sensors->cpu > max_core ? sensors->cpu : max_core); float max_acpi = 0.0; for (size_t i = 0; i < sensors->acpi_sensors_count; ++i) { if (sensors->acpi_sensors[i] > max_acpi) max_acpi = sensors->acpi_sensors[i]; } if (params & PARAM_SHORT_VIEW) (void)printf(" %.0f°", max_acpi); else (void)printf(" %.0f°C", max_acpi); } else { if (params & PARAM_SHORT_VIEW) (void)printf("%.0f° %.0f°, ", sensors->cpu, max_core); else (void)printf("cpu: %.0f°C %.0f°C acpi:", sensors->cpu, max_core); for (size_t i = 0; i < sensors->acpi_sensors_count; ++i) { if (params & PARAM_SHORT_VIEW) (void)printf(" %.0f°", sensors->acpi_sensors[i]); else (void)printf(" %.0f°C", sensors->acpi_sensors[i]); } } (void)printf("\n"); } int main(int argc, char **argv) { int opt; uint_fast32_t params = 0; char szlabel[MAX_LABEL_LENGTH]; *szlabel = 0; if (argc > 1) { while ((opt = getopt(argc, argv, "mshl:")) != -1) { switch (opt) { case 'l': if (strlen(optarg) <= sizeof(szlabel) - 1) strcpy(szlabel, optarg); break; case 'm': params |= PARAM_MAX_ONLY; break; case 's': params |= PARAM_SHORT_VIEW; break; case 'h': show_help(); return EXIT_SUCCESS; break; } } } thermal_sensors sensors; int retval = load_sensors(&sensors); if (-1 == retval) return EXIT_FAILURE; print_sensors_info_line(&sensors, szlabel, params); return EXIT_SUCCESS; }