void print_path_exists(yajl_gen json_gen, char *buffer, const char *title, const char *path, const char *format, const char *format_down) { const char *walk; char *outwalk = buffer; struct stat st; const bool exists = (stat(path, &st) == 0); if (exists || format_down == NULL) { walk = format; } else { walk = format_down; } INSTANCE(path); START_COLOR((exists ? "color_good" : "color_bad")); for (; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "title")) { outwalk += sprintf(outwalk, "%s", title); walk += strlen("title"); } else if (BEGINS_WITH(walk + 1, "status")) { outwalk += sprintf(outwalk, "%s", (exists ? "yes" : "no")); walk += strlen("status"); } } END_COLOR; OUTPUT_FULL_TEXT(buffer); }
void gtkwave_send_initchannel_commands (void) { enum GTKWaveViewType viewType = getGTKWaveViewType (); if (viewType == GTKWaveViewNone) return; char *hhhfilename = g_strdup_printf ("%s.hhh", projectName); FILE *f = fopen (hhhfilename, "r"); char buf[10000], *ptr; while (1) { ptr = fgets (buf, 10000, f); if (!ptr || feof (f)) break; if (BEGINS_WITH (buf, "init-channel ")) { int channum = atoi (buf + strlen ("init-channel ")); if (viewType != GTKWaveViewAllTracedChans) { ptr = strrchr (buf, ' '); if (!ptr || strcmp (ptr, " isPort\n") != 0) continue; if (viewType == GTKWaveViewNamedPortsOnly) { char *name = strchr (buf, '\"'); if (!name) continue; ptr = strchr (name + 1, '\"'); if (!ptr || *(ptr - 1) == '.') continue; } } char *command = g_strdup_printf ("add-trace-with-key %d\n", channum); gtkwave_send_command (command); g_free (command); } else if (BEGINS_WITH (buf, "time 0")) break; } gtkwave_send_command ("zoom fit\n"); gtkwave_send_command ("redraw\n"); }
void print_load(yajl_gen json_gen, char *buffer, const char *format, const int max_threshold) { char *outwalk = buffer; /* Get load */ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(sun) || defined(__DragonFly__) double loadavg[3]; const char *walk; bool colorful_output = false; if (getloadavg(loadavg, 3) == -1) goto error; for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (loadavg[0] >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } if (BEGINS_WITH(walk+1, "1min")) { outwalk += sprintf(outwalk, "%1.2f", loadavg[0]); walk += strlen("1min"); } if (BEGINS_WITH(walk+1, "5min")) { outwalk += sprintf(outwalk, "%1.2f", loadavg[1]); walk += strlen("5min"); } if (BEGINS_WITH(walk+1, "15min")) { outwalk += sprintf(outwalk, "%1.2f", loadavg[2]); walk += strlen("15min"); } if (colorful_output) END_COLOR; } *outwalk = '\0'; OUTPUT_FULL_TEXT(buffer); return; error: #endif OUTPUT_FULL_TEXT("cant read load"); (void)fputs("i3status: Cannot read system load using getloadavg()\n", stderr); }
/** * Computes the ratio of two numbers in files and displays them. * */ void print_ratio_watch(yajl_gen json_gen, char *buffer, const char *title, const char *format_down, const char *format_high, const char *format_low, const char *path_numerator, const char *path_denominator, const float low_threshold) { char *outwalk = buffer; float numerator = 0.0; float denominator = 0.0; if (!glob_read_number(path_numerator, &numerator) || !glob_read_number(path_denominator, &denominator)) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", format_down); END_COLOR; OUTPUT_FULL_TEXT(buffer); return; } float percentage = (numerator / denominator) * 100.0; const char *walk = percentage >= low_threshold ? format_high : format_low; for (; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "percentage")) { outwalk += sprintf(outwalk, "%.00f%s", percentage, pct_mark); walk += strlen("percentage"); } } END_COLOR; OUTPUT_FULL_TEXT(buffer); }
void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down) { const char *walk; char *addr_string = get_ipv6_addr(); char *outwalk = buffer; if (addr_string == NULL) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", format_down); END_COLOR; OUTPUT_FULL_TEXT(buffer); return; } START_COLOR("color_good"); for (walk = format_up; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; } else if (BEGINS_WITH(walk + 1, "ip")) { outwalk += sprintf(outwalk, "%s", addr_string); walk += strlen("ip"); } else { *(outwalk++) = '%'; } } END_COLOR; OUTPUT_FULL_TEXT(buffer); }
int parse_output( const char * const output, int * const temp ) { fprintf(stderr, "%s\n", output); char temp_str[16]; char *j = temp_str; bool good_line = false; for (const char *i = output; *i != 0; i++) { if (BEGINS_WITH(i, "GPU Current Temp")) { good_line = true; j = temp_str; } if (*i == '\r' || *i == '\n') { good_line = false; } if (good_line && *i >= '0' && *i <= '9') { *(j++) = *i; } } *j = 0; return sscanf(temp_str, "%d", temp); }
void ProcessSignal (char *str) { char *ptr = strchr (str, ' ') + 1; int num = atoi (ptr); ptr = strchr (ptr, ' ') + 1; struct Edge *edge = g_ptr_array_index (edges, num - 1); int signum = 0; if (BEGINS_WITH (ptr, "requp")) signum = 1; else if (BEGINS_WITH (ptr, "ackup")) signum = 2; else if (BEGINS_WITH (ptr, "reqdown")) signum = 3; else if (BEGINS_WITH (ptr, "ackdown")) signum = 0; // ptr = strchr (ptr, ' ') + 1; int threadNum = 0; //atoi (ptr); ChanTraceItem *traceItem = g_new0 (ChanTraceItem, 1); traceItem->time = last_processed_time; traceItem->signum = signum; traceItem->edge = edge; /* Add to Edge */ PtrEdgeInfo edgeInfo = (PtrEdgeInfo) edge->data; GPtrArray *trace = edgeInfo->trace; g_ptr_array_add (trace, traceItem); /* Add to Thread */ if (threadNum) { struct ControlThread *thread = &controlThreads[threadNum]; g_ptr_array_add (thread->trace, traceItem); } /* Add to Positions */ if (!positions[last_processed_time].trace) positions[last_processed_time].trace = g_ptr_array_new (); g_ptr_array_add (positions[last_processed_time].trace, traceItem); }
/* * Does a statvfs and prints either free, used or total amounts of bytes in a * human readable manner. * */ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type) { const char *walk; char *outwalk = buffer; INSTANCE(path); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) struct statfs buf; if (statfs(path, &buf) == -1) return; #else struct statvfs buf; if (statvfs(path, &buf) == -1) return; #endif for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk+1, "free")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, prefix_type); walk += strlen("free"); } if (BEGINS_WITH(walk+1, "used")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), prefix_type); walk += strlen("used"); } if (BEGINS_WITH(walk+1, "total")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, prefix_type); walk += strlen("total"); } if (BEGINS_WITH(walk+1, "avail")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, prefix_type); walk += strlen("avail"); } if (BEGINS_WITH(walk+1, "percentage_free")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks); walk += strlen("percentage_free"); } if (BEGINS_WITH(walk+1, "percentage_used_of_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks); walk += strlen("percentage_used_of_avail"); } if (BEGINS_WITH(walk+1, "percentage_used")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks); walk += strlen("percentage_used"); } if (BEGINS_WITH(walk+1, "percentage_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks); walk += strlen("percentage_avail"); } } *outwalk = '\0'; OUTPUT_FULL_TEXT(buffer); }
/* * Reads the CPU utilization from /proc/stat and returns the usage as a * percentage. * */ void print_cpu_usage(yajl_gen json_gen, char *buffer, const char *format) { const char *walk; char *outwalk = buffer; int curr_user = 0, curr_nice = 0, curr_system = 0, curr_idle = 0, curr_total; int diff_idle, diff_total, diff_usage; #if defined(LINUX) static char statpath[512]; char buf[1024]; strcpy(statpath, "/proc/stat"); if (!slurp(statpath, buf, sizeof(buf)) || sscanf(buf, "cpu %d %d %d %d", &curr_user, &curr_nice, &curr_system, &curr_idle) != 4) goto error; curr_total = curr_user + curr_nice + curr_system + curr_idle; diff_idle = curr_idle - prev_idle; diff_total = curr_total - prev_total; diff_usage = (diff_total ? (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 : 0); prev_total = curr_total; prev_idle = curr_idle; #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) size_t size; long cp_time[CPUSTATES]; size = sizeof cp_time; if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) < 0) goto error; #else /* This information is taken from the boot cpu, any other cpus are currently ignored. */ long cp_time[CPUSTATES]; int mib[2]; size_t size = sizeof(cp_time); mib[0] = CTL_KERN; mib[1] = KERN_CPTIME; if (sysctl(mib, 2, cp_time, &size, NULL, 0)) goto error; #endif curr_user = cp_time[CP_USER]; curr_nice = cp_time[CP_NICE]; curr_system = cp_time[CP_SYS]; curr_idle = cp_time[CP_IDLE]; curr_total = curr_user + curr_nice + curr_system + curr_idle; diff_idle = curr_idle - prev_idle; diff_total = curr_total - prev_total; diff_usage = (diff_total ? (1000 * (diff_total - diff_idle) / diff_total + 5) / 10 : 0); prev_total = curr_total; prev_idle = curr_idle; #else goto error; #endif for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "usage")) { outwalk += sprintf(outwalk, "%02d%%", diff_usage); walk += strlen("usage"); } } OUTPUT_FULL_TEXT(buffer); return; error: OUTPUT_FULL_TEXT("cant read cpu usage"); (void)fputs("i3status: Cannot read CPU usage\n", stderr); }
void print_wireless_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down) { const char *walk; char *outwalk = buffer; wireless_info_t info; INSTANCE(interface); const char *ip_address = get_ip_addr(interface); if (ip_address == NULL) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", format_down); goto out; } if (get_wireless_info(interface, &info)) { walk = format_up; if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY) START_COLOR((info.quality < info.quality_average ? "color_degraded" : "color_good")); else START_COLOR("color_good"); } else { walk = format_down; START_COLOR("color_bad"); } for (; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk+1, "quality")) { if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY) { if (info.quality_max) outwalk += sprintf(outwalk, "%03d%%", PERCENT_VALUE(info.quality, info.quality_max)); else outwalk += sprintf(outwalk, "%d", info.quality); } else { *(outwalk++) = '?'; } walk += strlen("quality"); } if (BEGINS_WITH(walk+1, "signal")) { if (info.flags & WIRELESS_INFO_FLAG_HAS_SIGNAL) { if (info.signal_level_max) outwalk += sprintf(outwalk, "%03d%%", PERCENT_VALUE(info.signal_level, info.signal_level_max)); else outwalk += sprintf(outwalk, "%d dBm", info.signal_level); } else { *(outwalk++) = '?'; } walk += strlen("signal"); } if (BEGINS_WITH(walk+1, "noise")) { if (info.flags & WIRELESS_INFO_FLAG_HAS_NOISE) { if (info.noise_level_max) outwalk += sprintf(outwalk, "%03d%%", PERCENT_VALUE(info.noise_level, info.noise_level_max)); else outwalk += sprintf(outwalk, "%d dBm", info.noise_level); } else { *(outwalk++) = '?'; } walk += strlen("noise"); } if (BEGINS_WITH(walk+1, "essid")) { if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID) outwalk += sprintf(outwalk, "%s", info.essid); else *(outwalk++) = '?'; walk += strlen("essid"); } if (BEGINS_WITH(walk+1, "ip")) { outwalk += sprintf(outwalk, "%s", ip_address); walk += strlen("ip"); } #ifdef LINUX if (BEGINS_WITH(walk+1, "bitrate")) { char br_buffer[128]; iw_print_bitrate(br_buffer, sizeof(br_buffer), info.bitrate); outwalk += sprintf(outwalk, "%s", br_buffer); walk += strlen("bitrate"); } #endif } out: END_COLOR; OUTPUT_FULL_TEXT(buffer); }
gint read_trace_timer_callback (gpointer data) { // fprintf (stderr,"read_trace_timer_callback\n"); int last_drawable_time_ref = last_drawable_time; // if (read_trace_timer1_enabled || 1) { char buf[10000]; int ret1; char *ret2; if (!hhh_filename) hhh_filename = g_strdup_printf ("%s.hhh", projectName); if (!hhh_file) hhh_file = fopen (hhh_filename, "r"); if (hhh_file) { clearerr (hhh_file); ret1 = fseek (hhh_file, last_nonCRed_position, SEEK_SET); again: ret2 = fgets (buf, 10000, hhh_file); if (ret1 != -1 && ret2 != NULL) { int size = strlen (buf); if (size && buf[size - 1] == '\n') { // printf("process %s\n", buf); if (BEGINS_WITH (buf, "time ")) { last_drawable_time = last_read_time; last_read_time = atoi (buf + 5); ASSERT (last_drawable_time < last_read_time); if (last_read_time == 0) { GtkWidget *warningButton = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (MainWindow2), "WarningButton")); if (!GTK_WIDGET_VISIBLE (warningButton)) { if (access ("nogtkwave", R_OK)) Launch_GTKWave (0); } } last_nonCRed_position = ftell (hhh_file); ASSERT (last_nonCRed_position != -1); while (last_read_time >= nb_positions) { positions = g_renew (struct HHHTimeUnitInfo, positions, 2 * nb_positions); memset (&positions[nb_positions], 0, nb_positions * sizeof (struct HHHTimeUnitInfo)); nb_positions *= 2; } positions[last_read_time].position = last_nonCRed_position; } else if (BEGINS_WITH (buf, "signal")) { // if (read_trace_timer1_enabled) // ProcessSignal (buf); } else if (BEGINS_WITH (buf, "data")) { // if (read_trace_timer1_enabled) // ProcessData (buf); } else if (BEGINS_WITH (buf, "new-thread")) { // if (read_trace_timer1_enabled) // ProcessNewThread (buf); } else if (BEGINS_WITH (buf, "end")) { last_drawable_time = last_read_time; StopReadTraceTimer (); } last_nonCRed_position = ftell (hhh_file); ASSERT (last_nonCRed_position != -1); goto again; } }
/* * Does a statvfs and prints either free, used or total amounts of bytes in a * human readable manner. * */ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const int half_threshold, const int full_threshold) { const char *walk; char *outwalk = buffer; double usage=0; bool colorful_output = half_threshold>0 || full_threshold>0; INSTANCE(path); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) struct statfs buf; if (statfs(path, &buf) == -1) return; #else struct statvfs buf; if (statvfs(path, &buf) == -1) return; #endif if (colorful_output) { usage=100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks; if(usage>full_threshold) { START_COLOR("color_bad"); } else if(usage > half_threshold) { START_COLOR("color_degraded"); } } for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk+1, "free")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree); walk += strlen("free"); } if (BEGINS_WITH(walk+1, "used")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree)); walk += strlen("used"); } if (BEGINS_WITH(walk+1, "total")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks); walk += strlen("total"); } if (BEGINS_WITH(walk+1, "avail")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail); walk += strlen("avail"); } if (BEGINS_WITH(walk+1, "percentage_free")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks); walk += strlen("percentage_free"); } if (BEGINS_WITH(walk+1, "percentage_used_of_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks); walk += strlen("percentage_used_of_avail"); } if (BEGINS_WITH(walk+1, "percentage_used")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks); walk += strlen("percentage_used"); } if (BEGINS_WITH(walk+1, "percentage_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks); walk += strlen("percentage_avail"); } } if(colorful_output) { END_COLOR; } *outwalk = '\0'; OUTPUT_FULL_TEXT(buffer); }
/* * Get battery information from /sys. Note that it uses the design capacity to * calculate the percentage, not the last full capacity, so you can see how * worn off your battery is. * */ void print_battery_info(int number, const char *format, bool last_full_capacity) { time_t empty_time; struct tm *empty_tm; char buf[1024]; char statusbuf[16]; char percentagebuf[16]; char remainingbuf[256]; char emptytimebuf[256]; const char *walk, *last; int full_design = -1, remaining = -1, present_rate = -1; charging_status_t status = CS_DISCHARGING; memset(statusbuf, '\0', sizeof(statusbuf)); memset(percentagebuf, '\0', sizeof(percentagebuf)); memset(remainingbuf, '\0', sizeof(remainingbuf)); memset(emptytimebuf, '\0', sizeof(emptytimebuf)); #if defined(LINUX) static char batpath[512]; sprintf(batpath, "/sys/class/power_supply/BAT%d/uevent", number); if (!slurp(batpath, buf, sizeof(buf))) { printf("No battery"); return; } for (walk = buf, last = buf; (walk-buf) < 1024; walk++) { if (*walk == '\n') { last = walk+1; continue; } if (*walk != '=') continue; if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW") || BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW")) remaining = atoi(walk+1); else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW")) present_rate = atoi(walk+1); else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging")) status = CS_CHARGING; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full")) status = CS_FULL; else { /* The only thing left is the full capacity */ if (last_full_capacity) { if (!BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL") && !BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL")) continue; } else { if (!BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN") && !BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN")) continue; } full_design = atoi(walk+1); } } if ((full_design == 1) || (remaining == -1)) return; (void)snprintf(statusbuf, sizeof(statusbuf), "%s", (status == CS_CHARGING ? "CHR" : (status == CS_DISCHARGING ? "BAT" : "FULL"))); (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.02f%%", (((float)remaining / (float)full_design) * 100)); if (present_rate > 0) { float remaining_time; int seconds, hours, minutes, seconds_remaining; if (status == CS_CHARGING) remaining_time = ((float)full_design - (float)remaining) / (float)present_rate; else if (status == CS_DISCHARGING) remaining_time = ((float)remaining / (float)present_rate); else remaining_time = 0; seconds_remaining = (int)(remaining_time * 3600.0); hours = seconds_remaining / 3600; seconds = seconds_remaining - (hours * 3600); minutes = seconds / 60; seconds -= (minutes * 60); (void)snprintf(remainingbuf, sizeof(remainingbuf), "%02d:%02d:%02d", max(hours, 0), max(minutes, 0), max(seconds, 0)); empty_time = time(NULL); empty_time += seconds_remaining; empty_tm = localtime(&empty_time); (void)snprintf(emptytimebuf, sizeof(emptytimebuf), "%02d:%02d:%02d", max(empty_tm->tm_hour, 0), max(empty_tm->tm_min, 0), max(empty_tm->tm_sec, 0)); } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) int state; int sysctl_rslt; size_t sysctl_size = sizeof(sysctl_rslt); if (sysctlbyname(BATT_LIFE, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { printf("No battery"); return; } present_rate = sysctl_rslt; if (sysctlbyname(BATT_TIME, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { printf("No battery"); return; } remaining = sysctl_rslt; if (sysctlbyname(BATT_STATE, &sysctl_rslt, &sysctl_size, NULL,0) != 0) { printf("No battery"); return; } state = sysctl_rslt; if (state == 0 && present_rate == 100) status = CS_FULL; else if (state == 0 && present_rate < 100) status = CS_CHARGING; else status = CS_DISCHARGING; full_design = sysctl_rslt; (void)snprintf(statusbuf, sizeof(statusbuf), "%s", (status == CS_CHARGING ? "CHR" : (status == CS_DISCHARGING ? "BAT" : "FULL"))); (void)snprintf(percentagebuf, sizeof(percentagebuf), "%02d%%", present_rate); if (state == 1) { int hours, minutes; minutes = remaining; hours = minutes / 60; minutes -= (hours * 60); (void)snprintf(remainingbuf, sizeof(remainingbuf), "%02dh%02d", max(hours, 0), max(minutes, 0)); } #endif for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { putchar(*walk); continue; } if (strncmp(walk+1, "status", strlen("status")) == 0) { printf("%s", statusbuf); walk += strlen("status"); } else if (strncmp(walk+1, "percentage", strlen("percentage")) == 0) { printf("%s", percentagebuf); walk += strlen("percentage"); } else if (strncmp(walk+1, "remaining", strlen("remaining")) == 0) { printf("%s", remainingbuf); walk += strlen("remaining"); } else if (strncmp(walk+1, "emptytime", strlen("emptytime")) == 0) { printf("%s", emptytimebuf); walk += strlen("emptytime"); } } }
static bool slurp_battery_info(struct battery_info *batt_info, yajl_gen json_gen, char *buffer, int number, const char *path, const char *format_down) { char *outwalk = buffer; #if defined(LINUX) char buf[1024]; memset(buf, 0, 1024); const char *walk, *last; bool watt_as_unit = false; int voltage = -1; char batpath[512]; sprintf(batpath, path, number); INSTANCE(batpath); if (!slurp(batpath, buf, sizeof(buf))) { OUTPUT_FULL_TEXT(format_down); return false; } for (walk = buf, last = buf; (walk - buf) < 1024; walk++) { if (*walk == '\n') { last = walk + 1; continue; } if (*walk != '=') continue; if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW=")) { watt_as_unit = true; batt_info->remaining = atoi(walk + 1); batt_info->percentage_remaining = -1; } else if (BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW=")) { watt_as_unit = false; batt_info->remaining = atoi(walk + 1); batt_info->percentage_remaining = -1; } else if (BEGINS_WITH(last, "POWER_SUPPLY_CAPACITY=") && batt_info->remaining == -1) { batt_info->percentage_remaining = atoi(walk + 1); } else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW=")) batt_info->present_rate = abs(atoi(walk + 1)); else if (BEGINS_WITH(last, "POWER_SUPPLY_VOLTAGE_NOW=")) voltage = abs(atoi(walk + 1)); /* on some systems POWER_SUPPLY_POWER_NOW does not exist, but actually * it is the same as POWER_SUPPLY_CURRENT_NOW but with μWh as * unit instead of μAh. We will calculate it as we need it * later. */ else if (BEGINS_WITH(last, "POWER_SUPPLY_POWER_NOW=")) batt_info->present_rate = abs(atoi(walk + 1)); else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging")) batt_info->status = CS_CHARGING; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full")) batt_info->status = CS_FULL; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Discharging")) batt_info->status = CS_DISCHARGING; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=")) batt_info->status = CS_UNKNOWN; else if (BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN=") || BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN=")) batt_info->full_design = atoi(walk + 1); else if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL=") || BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL=")) batt_info->full_last = atoi(walk + 1); } /* the difference between POWER_SUPPLY_ENERGY_NOW and * POWER_SUPPLY_CHARGE_NOW is the unit of measurement. The energy is * given in mWh, the charge in mAh. So calculate every value given in * ampere to watt */ if (!watt_as_unit && voltage >= 0) { if (batt_info->present_rate > 0) { batt_info->present_rate = (((float)voltage / 1000.0) * ((float)batt_info->present_rate / 1000.0)); } if (batt_info->remaining > 0) { batt_info->remaining = (((float)voltage / 1000.0) * ((float)batt_info->remaining / 1000.0)); } if (batt_info->full_design > 0) { batt_info->full_design = (((float)voltage / 1000.0) * ((float)batt_info->full_design / 1000.0)); } if (batt_info->full_last > 0) { batt_info->full_last = (((float)voltage / 1000.0) * ((float)batt_info->full_last / 1000.0)); } } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) int state; int sysctl_rslt; size_t sysctl_size = sizeof(sysctl_rslt); if (sysctlbyname(BATT_LIFE, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return false; } batt_info->percentage_remaining = sysctl_rslt; if (sysctlbyname(BATT_TIME, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return false; } batt_info->seconds_remaining = sysctl_rslt * 60; if (sysctlbyname(BATT_STATE, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return false; } state = sysctl_rslt; if (state == 0 && batt_info->percentage_remaining == 100) batt_info->status = CS_FULL; else if ((state & ACPI_BATT_STAT_CHARGING) && batt_info->percentage_remaining < 100) batt_info->status = CS_CHARGING; else batt_info->status = CS_DISCHARGING; #elif defined(__OpenBSD__) /* * We're using apm(4) here, which is the interface to acpi(4) on amd64/i386 and * the generic interface on macppc/sparc64/zaurus, instead of using sysctl(3) and * probing acpi(4) devices. */ struct apm_power_info apm_info; int apm_fd; apm_fd = open("/dev/apm", O_RDONLY); if (apm_fd < 0) { OUTPUT_FULL_TEXT("can't open /dev/apm"); return false; } if (ioctl(apm_fd, APM_IOC_GETPOWER, &apm_info) < 0) OUTPUT_FULL_TEXT("can't read power info"); close(apm_fd); /* Don't bother to go further if there's no battery present. */ if ((apm_info.battery_state == APM_BATTERY_ABSENT) || (apm_info.battery_state == APM_BATT_UNKNOWN)) { OUTPUT_FULL_TEXT(format_down); return false; } switch (apm_info.ac_state) { case APM_AC_OFF: batt_info->status = CS_DISCHARGING; break; case APM_AC_ON: batt_info->status = CS_CHARGING; break; default: /* If we don't know what's going on, just assume we're discharging. */ batt_info->status = CS_DISCHARGING; break; } batt_info->percentage_remaining = apm_info.battery_life; /* Can't give a meaningful value for remaining minutes if we're charging. */ if (batt_info->status != CS_CHARGING) { batt_info->seconds_remaining = apm_info.minutes_left * 60; } #elif defined(__NetBSD__) /* * Using envsys(4) via sysmon(4). */ int fd, rval; bool is_found = false; char sensor_desc[16]; prop_dictionary_t dict; prop_array_t array; prop_object_iterator_t iter; prop_object_iterator_t iter2; prop_object_t obj, obj2, obj3, obj4, obj5; if (number >= 0) (void)snprintf(sensor_desc, sizeof(sensor_desc), "acpibat%d", number); fd = open("/dev/sysmon", O_RDONLY); if (fd < 0) { OUTPUT_FULL_TEXT("can't open /dev/sysmon"); return false; } rval = prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict); if (rval == -1) { close(fd); return false; } if (prop_dictionary_count(dict) == 0) { prop_object_release(dict); close(fd); return false; } iter = prop_dictionary_iterator(dict); if (iter == NULL) { prop_object_release(dict); close(fd); } /* iterate over the dictionary returned by the kernel */ while ((obj = prop_object_iterator_next(iter)) != NULL) { /* skip this dict if it's not what we're looking for */ if (number < 0) { /* we want all batteries */ if (!BEGINS_WITH(prop_dictionary_keysym_cstring_nocopy(obj), "acpibat")) continue; } else { /* we want a specific battery */ if (strcmp(sensor_desc, prop_dictionary_keysym_cstring_nocopy(obj)) != 0) continue; } is_found = true; array = prop_dictionary_get_keysym(dict, obj); if (prop_object_type(array) != PROP_TYPE_ARRAY) { prop_object_iterator_release(iter); prop_object_release(dict); close(fd); return false; } iter2 = prop_array_iterator(array); if (!iter2) { prop_object_iterator_release(iter); prop_object_release(dict); close(fd); return false; } struct battery_info batt_buf = { .full_design = 0, .full_last = 0, .remaining = 0, .present_rate = 0, .status = CS_UNKNOWN, }; int voltage = -1; bool watt_as_unit = false; /* iterate over array of dicts specific to target battery */ while ((obj2 = prop_object_iterator_next(iter2)) != NULL) { obj3 = prop_dictionary_get(obj2, "description"); if (obj3 == NULL) continue; if (strcmp("charging", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); if (prop_number_integer_value(obj3)) batt_buf.status = CS_CHARGING; else batt_buf.status = CS_DISCHARGING; } else if (strcmp("charge", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); obj4 = prop_dictionary_get(obj2, "max-value"); obj5 = prop_dictionary_get(obj2, "type"); batt_buf.remaining = prop_number_integer_value(obj3); batt_buf.full_design = prop_number_integer_value(obj4); if (strcmp("Ampere hour", prop_string_cstring_nocopy(obj5)) == 0) watt_as_unit = false; else watt_as_unit = true; } else if (strcmp("discharge rate", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); batt_buf.present_rate = prop_number_integer_value(obj3); } else if (strcmp("charge rate", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); batt_info->present_rate = prop_number_integer_value(obj3); } else if (strcmp("last full cap", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); batt_buf.full_last = prop_number_integer_value(obj3); } else if (strcmp("voltage", prop_string_cstring_nocopy(obj3)) == 0) { obj3 = prop_dictionary_get(obj2, "cur-value"); voltage = prop_number_integer_value(obj3); } } prop_object_iterator_release(iter2); if (!watt_as_unit && voltage != -1) { batt_buf.present_rate = (((float)voltage / 1000.0) * ((float)batt_buf.present_rate / 1000.0)); batt_buf.remaining = (((float)voltage / 1000.0) * ((float)batt_buf.remaining / 1000.0)); batt_buf.full_design = (((float)voltage / 1000.0) * ((float)batt_buf.full_design / 1000.0)); batt_buf.full_last = (((float)voltage / 1000.0) * ((float)batt_buf.full_last / 1000.0)); } if (batt_buf.remaining == batt_buf.full_design) batt_buf.status = CS_FULL; add_battery_info(batt_info, &batt_buf); } prop_object_iterator_release(iter); prop_object_release(dict); close(fd); if (!is_found) { OUTPUT_FULL_TEXT(format_down); return false; } batt_info->present_rate = abs(batt_info->present_rate); #endif return true; } /* * Populate batt_info with aggregate information about all batteries. * Returns false on error, and an error message will have been written. */ static bool slurp_all_batteries(struct battery_info *batt_info, yajl_gen json_gen, char *buffer, const char *path, const char *format_down) { #if defined(LINUX) char *outwalk = buffer; bool is_found = false; char *placeholder; char *globpath = sstrdup(path); if ((placeholder = strstr(path, "%d")) != NULL) { char *globplaceholder = globpath + (placeholder - path); *globplaceholder = '*'; strcpy(globplaceholder + 1, placeholder + 2); } if (!strcmp(globpath, path)) { OUTPUT_FULL_TEXT("no '%d' in battery path"); return false; } glob_t globbuf; if (glob(globpath, 0, NULL, &globbuf) == 0) { for (size_t i = 0; i < globbuf.gl_pathc; i++) { /* Probe to see if there is such a battery. */ struct battery_info batt_buf = { .full_design = 0, .full_last = 0, .remaining = 0, .present_rate = 0, .status = CS_UNKNOWN, }; if (!slurp_battery_info(&batt_buf, json_gen, buffer, i, globbuf.gl_pathv[i], format_down)) return false; is_found = true; add_battery_info(batt_info, &batt_buf); } } globfree(&globbuf); free(globpath); if (!is_found) { OUTPUT_FULL_TEXT(format_down); return false; } batt_info->present_rate = abs(batt_info->present_rate); #else /* FreeBSD and OpenBSD only report aggregates. NetBSD always * iterates through all batteries, so it's more efficient to * aggregate in slurp_battery_info. */ return slurp_battery_info(batt_info, json_gen, buffer, -1, path, format_down); #endif return true; } void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_unk, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds) { const char *walk; char *outwalk = buffer; struct battery_info batt_info = { .full_design = -1, .full_last = -1, .remaining = -1, .present_rate = -1, .seconds_remaining = -1, .percentage_remaining = -1, .status = CS_UNKNOWN, }; bool colorful_output = false; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__OpenBSD__) /* These OSes report battery stats in whole percent. */ integer_battery_capacity = true; #endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__OpenBSD__) /* These OSes report battery time in minutes. */ hide_seconds = true; #endif if (number < 0) { if (!slurp_all_batteries(&batt_info, json_gen, buffer, path, format_down)) return; } else { if (!slurp_battery_info(&batt_info, json_gen, buffer, number, path, format_down)) return; } // *Choose* a measure of the 'full' battery. It is whichever is better of // the battery's (hardware-given) design capacity (batt_info.full_design) // and the battery's last known good charge (batt_info.full_last). // We prefer the design capacity, but use the last capacity if we don't have it, // or if we are asked to (last_full_capacity == true); but similarly we use // the design capacity if we don't have the last capacity. // If we don't have either then both full_design and full_last <= 0, // which implies full <= 0, which bails out on the following line. int full = batt_info.full_design; if (full <= 0 || (last_full_capacity && batt_info.full_last > 0)) { full = batt_info.full_last; } if (full <= 0 && batt_info.remaining < 0 && batt_info.percentage_remaining < 0) { /* We have no physical measurements and no estimates. Nothing * much we can report, then. */ OUTPUT_FULL_TEXT(format_down); return; } if (batt_info.percentage_remaining < 0) { batt_info.percentage_remaining = (((float)batt_info.remaining / (float)full) * 100); /* Some batteries report POWER_SUPPLY_CHARGE_NOW=<full_design> when fully * charged, even though that’s plainly wrong. For people who chose to see * the percentage calculated based on the last full capacity, we clamp the * value to 100%, as that makes more sense. * See http://bugs.debian.org/785398 */ if (last_full_capacity && batt_info.percentage_remaining > 100) { batt_info.percentage_remaining = 100; } } if (batt_info.seconds_remaining < 0 && batt_info.present_rate > 0 && batt_info.status != CS_FULL) { if (batt_info.status == CS_CHARGING) batt_info.seconds_remaining = 3600.0 * (full - batt_info.remaining) / batt_info.present_rate; else if (batt_info.status == CS_DISCHARGING) batt_info.seconds_remaining = 3600.0 * batt_info.remaining / batt_info.present_rate; else batt_info.seconds_remaining = 0; } if (batt_info.status == CS_DISCHARGING && low_threshold > 0) { if (batt_info.percentage_remaining >= 0 && strcasecmp(threshold_type, "percentage") == 0 && batt_info.percentage_remaining < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else if (batt_info.seconds_remaining >= 0 && strcasecmp(threshold_type, "time") == 0 && batt_info.seconds_remaining < 60 * low_threshold) { START_COLOR("color_bad"); colorful_output = true; } } #define EAT_SPACE_FROM_OUTPUT_IF_NO_OUTPUT() \ do { \ if (outwalk == prevoutwalk) { \ if (outwalk > buffer && isspace((int)outwalk[-1])) \ outwalk--; \ else if (isspace((int)*(walk + 1))) \ walk++; \ } \ } while (0) for (walk = format; *walk != '\0'; walk++) { char *prevoutwalk = outwalk; if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "status")) { const char *statusstr; switch (batt_info.status) { case CS_CHARGING: statusstr = status_chr; break; case CS_DISCHARGING: statusstr = status_bat; break; case CS_FULL: statusstr = status_full; break; default: statusstr = status_unk; } outwalk += sprintf(outwalk, "%s", statusstr); walk += strlen("status"); } else if (BEGINS_WITH(walk + 1, "percentage")) { if (integer_battery_capacity) { outwalk += sprintf(outwalk, "%.00f%s", batt_info.percentage_remaining, pct_mark); } else { outwalk += sprintf(outwalk, "%.02f%s", batt_info.percentage_remaining, pct_mark); } walk += strlen("percentage"); } else if (BEGINS_WITH(walk + 1, "remaining")) { if (batt_info.seconds_remaining >= 0) { int seconds, hours, minutes; hours = batt_info.seconds_remaining / 3600; seconds = batt_info.seconds_remaining - (hours * 3600); minutes = seconds / 60; seconds -= (minutes * 60); if (hide_seconds) outwalk += sprintf(outwalk, "%02d:%02d", max(hours, 0), max(minutes, 0)); else outwalk += sprintf(outwalk, "%02d:%02d:%02d", max(hours, 0), max(minutes, 0), max(seconds, 0)); } walk += strlen("remaining"); EAT_SPACE_FROM_OUTPUT_IF_NO_OUTPUT(); } else if (BEGINS_WITH(walk + 1, "emptytime")) { if (batt_info.seconds_remaining >= 0) { time_t empty_time = time(NULL) + batt_info.seconds_remaining; set_timezone(NULL); /* Use local time. */ struct tm *empty_tm = localtime(&empty_time); if (hide_seconds) outwalk += sprintf(outwalk, "%02d:%02d", max(empty_tm->tm_hour, 0), max(empty_tm->tm_min, 0)); else outwalk += sprintf(outwalk, "%02d:%02d:%02d", max(empty_tm->tm_hour, 0), max(empty_tm->tm_min, 0), max(empty_tm->tm_sec, 0)); } walk += strlen("emptytime"); EAT_SPACE_FROM_OUTPUT_IF_NO_OUTPUT(); } else if (BEGINS_WITH(walk + 1, "consumption")) { if (batt_info.present_rate >= 0) outwalk += sprintf(outwalk, "%1.2fW", batt_info.present_rate / 1e6); walk += strlen("consumption"); EAT_SPACE_FROM_OUTPUT_IF_NO_OUTPUT(); } } if (colorful_output) END_COLOR; OUTPUT_FULL_TEXT(buffer); }
void print_mpd(yajl_gen json_gen, char *buffer, const char *host, int port, const char *password, const char *format) { const char *walk; char *outwalk = buffer; static char titlebuf[40]; static char artistbuf[40]; static char albumbuf[40]; static char trackbuf[10]; static char datebuf[10]; static struct mpd_connection *conn; struct mpd_status *status = NULL; enum mpd_state state; struct mpd_song *song; /* First run */ if (conn == NULL) { conn = mpd_connection_new(host, port, 1500); if (conn == NULL) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", "ERROR"); goto print_end; } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", "CONNECT ERROR"); mpd_connection_free(conn); conn = NULL; goto print_end; } if (password != NULL && strcmp(password, "") != 0 && !mpd_run_password(conn, password)) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", "PASS ERROR"); mpd_connection_free(conn); conn = NULL; goto print_end; } } if ((status = mpd_run_status(conn))) { state = mpd_status_get_state(status); } if (!status || (state != MPD_STATE_PLAY && state != MPD_STATE_PAUSE)) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", "Stopped"); mpd_connection_free(conn); conn = NULL; goto print_end; } mpd_status_free(status); if (state == MPD_STATE_PLAY) START_COLOR("color_good"); else if (state == MPD_STATE_PAUSE) START_COLOR("color_degraded"); song = mpd_run_current_song(conn); COPY_CROP(titlebuf, mpd_song_get_tag(song, MPD_TAG_TITLE, 0)); COPY_CROP(artistbuf, mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)); COPY_CROP(albumbuf, mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)); COPY_CROP(trackbuf, mpd_song_get_tag(song, MPD_TAG_TRACK, 0)); COPY_CROP(datebuf, mpd_song_get_tag(song, MPD_TAG_DATE, 0)); mpd_song_free(song); for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk+1, "title")) { if (*titlebuf) outwalk += sprintf(outwalk, "%s", titlebuf); walk += strlen("title"); } else if (BEGINS_WITH(walk+1, "artist")) { if (*artistbuf) outwalk += sprintf(outwalk, "%s", artistbuf); walk += strlen("artist"); } else if (BEGINS_WITH(walk+1, "album")) { if (*albumbuf) outwalk += sprintf(outwalk, "%s", albumbuf); walk += strlen("album"); } else if (BEGINS_WITH(walk+1, "track")) { if (*trackbuf) outwalk += sprintf(outwalk, "%s", trackbuf); walk += strlen("track"); } else if (BEGINS_WITH(walk+1, "date")) { if (*datebuf) outwalk += sprintf(outwalk, "%s", datebuf); walk += strlen("date"); } } print_end: END_COLOR; OUTPUT_FULL_TEXT(buffer); return; }
void TryParsingScript (char *filename, int pass) { FILE *f = fopen (filename, "r"); if (!f) return; char buf[100]; if (fgets (buf, 100, f) == NULL) { perror("fgets"); exit(1); } if (BEGINS_WITH (buf, "-- breeze-sim-ctrl script")) { if (pass == 1) scriptFilename = filename; while (!feof (f) && fgets (buf, 100, f)) { char *ptr = strchr (buf, '\n'); if (ptr) *ptr = 0; char *arg2 = strchr (buf, ' ') + 1; if (BEGINS_WITH (buf, "use-breeze-file ")) { if (pass == 1) projectName = g_strdup (arg2); } else if (BEGINS_WITH (buf, "use-layout-file ")) { if (pass == 1) layoutFilename = g_strdup (arg2); } else if (BEGINS_WITH (buf, "resize-window ")) { if (pass == 2) { int width, height; width = atoi (arg2); arg2 = strchr (arg2, ' ') + 1; height = atoi (arg2); gtk_window_set_default_size (GTK_WINDOW (MainWindow2), width, height); } } else if (BEGINS_WITH (buf, "open-graph-view")) { if (pass == 2) { GtkToggleButton *graphToggleButton = GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (MainWindow2), "GraphToggleButton")); gtk_toggle_button_set_active (graphToggleButton, TRUE); } } else { if (pass == 1) fprintf (stderr, "Undefined command in breeze-sim-ctrl script: %s\n", buf); } } } fclose (f); }
int main (int argc, char *argv[]) { // gtk_set_locale (); gtk_init (&argc, &argv); { /* Add the Balsa installation dir (or BALSAHOME/share) as the first path element */ char *balsaHome = getenv ("BALSAHOME"); char *shareDir; if (!balsaHome) balsaHome = BALSAHOME; shareDir = g_strconcat (balsaHome, "/share", NULL); LibBreeze_AddIncludePath (shareDir); g_free (shareDir); } /* Add the current directory as the secondpath element */ char *currentDir = g_get_current_dir (); LibBreeze_AddIncludePath (currentDir); setvbuf (stdout, NULL, _IOLBF, 0); if (argc < 2) { printf ("Usage: %s [<options>] file\n" " All options are parsed, used if recognised, and passed to breeze-sim.\n" " Recognised options:\n" " -I (--include) <dir>\n" " -k (--keep-channel-numbers)\n" " -l (--layout) <filename>\n" " -p (--part) <part name>\n", *argv); exit (EXIT_FAILURE); } int i; for (i = 1; i < argc - 1; i++) { if (BEGINS_WITH (argv[i], "-I") || BEGINS_WITH (argv[i], "--include")) { if (!argv[i + 1]) { fprintf (stderr, "Usage: -I <dir>\n"); exit (EXIT_FAILURE); } LibBreeze_AddIncludePath (argv[i + 1]); i++; } else if (BEGINS_WITH (argv[i], "-k") || BEGINS_WITH (argv[i], "--keep-channel-numbers")) { save_channel_numbers = TRUE; } else if (BEGINS_WITH (argv[i], "-l") || BEGINS_WITH (argv[i], "--layout")) { if (!argv[i + 1]) { fprintf (stderr, "Usage: -l (--layout) <filename>\n"); exit (EXIT_FAILURE); } layoutFilename = g_strdup (argv[i + 1]); i++; } else if (BEGINS_WITH (argv[i], "-p") || BEGINS_WITH (argv[i], "--part")) { if (!argv[i + 1]) { fprintf (stderr, "Usage: -p (--part) <part name>\n"); exit (EXIT_FAILURE); } partName = g_strdup (argv[i + 1]); i++; } } projectName = g_strdup (argv[argc - 1]); TryParsingScript (projectName, 1); if (ENDS_WITH (projectName, ".breeze")) projectName[strlen (projectName) - strlen (".breeze")] = 0; projectNameWithPath = g_strdup_printf ("%s/%s", currentDir, projectName); g_free (currentDir); breezesim_passedArgs = g_new0 (char *, argc - 2); memcpy (breezesim_passedArgs, argv + 1, (argc - 2) * sizeof (char *)); breezesim_passedArgCount = argc - 2; if (CheckForSameSimulationRunning ()) { GtkWidget *msg = create_BreezeSimCtrlAlreadyRunning (); gtk_widget_show (msg); pidFilename = 0; } else main_finish_initialisation (); gtk_main (); if (pidFilename) remove (pidFilename); return 0; }
void print_nvidia_temperature_info( yajl_gen json_gen, char *buffer, int interval, const char *format, int max_threshold ) { char *outwalk = buffer; static int pipefd[2]; static int forked = false; pid_t cpid = 1; char temp_buff[4096]; // if the nvidia-smi process hasn't been spawned if (!forked) { if (pipe(pipefd) == -1) { perror("pipe"); return; } cpid = fork(); forked = true; } switch (cpid) { case -1: perror("fork"); return; case 0: close(pipefd[0]); dup2(pipefd[1], 1); char buff[16]; sprintf(buff, "%d", interval); default_command[2] = buff; execve(*default_command, default_command, default_command + 6); perror("execve"); exit(0); } struct pollfd poll_fd = { pipefd[0], POLLIN }; int poll_st = poll(&poll_fd, 1, 0); if (poll_st < 0) { perror("poll"); return; } if (poll_st == 0) { return; } for (const char * walk = format; *walk != 0; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "degrees")) { bool colorful_output = false; int read_st = read(pipefd[0], temp_buff, sizeof(temp_buff)); if (read_st < 0) { perror("read"); return; } // TODO: check if failed int temp; parse_output(temp_buff, &temp); if (temp >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%d", temp); if (colorful_output) { END_COLOR; } walk += strlen("degrees"); } } OUTPUT_FULL_TEXT(buffer); }
void ProcessUntilTime (int untilTime) { DEBUG_printf ("ProcessUntilTime %d\n", untilTime); ASSERT (untilTime <= last_drawable_time); if (untilTime <= last_processed_time) return; char buf[10000]; int ret1; char *ret2; FILE *hhh_file2 = fopen (hhh_filename, "r"); last_processed_time++; do { long pos = positions[last_processed_time].position; if (pos) { ret1 = fseek (hhh_file2, pos, SEEK_SET); break; } last_processed_time++; } while (last_processed_time <= untilTime); if (last_processed_time > untilTime) { last_processed_time = untilTime; goto end; } if (ret1 == -1) { fprintf (stderr, "Strange error in ProcessUntilTime: ret1==-1\n"); exit (-1); } while (1) { ret2 = fgets (buf, 10000, hhh_file2); if (ret2 == NULL) { fprintf (stderr, "Strange error in ProcessUntilTime: ret2==NULL\n"); exit (-1); } int size = strlen (buf); if (!size || buf[size - 1] != '\n') break; // printf("process %s\n", buf); if (BEGINS_WITH (buf, "time ")) { int time = atoi (buf + 5); if (time > untilTime) goto end; last_processed_time = time; } else if (BEGINS_WITH (buf, "signal")) { ProcessSignal (buf); } else if (BEGINS_WITH (buf, "dataon ")) { ProcessDataOn (buf); } else if (BEGINS_WITH (buf, "dataoff ")) { ProcessDataOff (buf); } else if (BEGINS_WITH (buf, "new-thread")) { ProcessNewThread (buf); } else if (BEGINS_WITH (buf, "end-thread")) { ProcessEndThread (buf); } else if (BEGINS_WITH (buf, "end")) { last_processed_time = last_read_time; goto end; } } end: fclose (hhh_file2); }
static bool below_threshold(struct statfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) { #else static bool below_threshold(struct statvfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) { #endif if (strcasecmp(threshold_type, "percentage_free") == 0) { return 100.0 * (double)buf.f_bfree / (double)buf.f_blocks < low_threshold; } else if (strcasecmp(threshold_type, "percentage_avail") == 0) { return 100.0 * (double)buf.f_bavail / (double)buf.f_blocks < low_threshold; } else if (strcasecmp(threshold_type, "bytes_free") == 0) { return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold; } else if (strcasecmp(threshold_type, "bytes_avail") == 0) { return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold; } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) { uint64_t base = strcasecmp(prefix_type, "decimal") == 0 ? DECIMAL_BASE : BINARY_BASE; double factor = 1; switch (threshold_type[0]) { case 'T': case 't': factor *= base; case 'G': case 'g': factor *= base; case 'M': case 'm': factor *= base; case 'K': case 'k': factor *= base; break; default: return false; } if (strcasecmp(threshold_type + 1, "bytes_free") == 0) { return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold * factor; } else if (strcasecmp(threshold_type + 1, "bytes_avail") == 0) { return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold * factor; } } return false; } /* * Does a statvfs and prints either free, used or total amounts of bytes in a * human readable manner. * */ void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold) { const char *walk; char *outwalk = buffer; bool colorful_output = false; INSTANCE(path); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) struct statfs buf; if (statfs(path, &buf) == -1) return; #else struct statvfs buf; if (statvfs(path, &buf) == -1) { /* If statvfs errors, e.g., due to the path not existing, * we use the format for a not mounted device. */ format = format_not_mounted; } else if (format_not_mounted != NULL) { FILE *mntentfile = setmntent("/etc/mtab", "r"); struct mntent *m; bool found = false; while ((m = getmntent(mntentfile)) != NULL) { if (strcmp(m->mnt_dir, path) == 0) { found = true; break; } } endmntent(mntentfile); if (!found) { format = format_not_mounted; } } #endif if (low_threshold > 0 && below_threshold(buf, prefix_type, threshold_type, low_threshold)) { START_COLOR("color_bad"); colorful_output = true; } for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "free")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, prefix_type); walk += strlen("free"); } if (BEGINS_WITH(walk + 1, "used")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), prefix_type); walk += strlen("used"); } if (BEGINS_WITH(walk + 1, "total")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, prefix_type); walk += strlen("total"); } if (BEGINS_WITH(walk + 1, "avail")) { outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, prefix_type); walk += strlen("avail"); } if (BEGINS_WITH(walk + 1, "percentage_free")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks); walk += strlen("percentage_free"); } if (BEGINS_WITH(walk + 1, "percentage_used_of_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks); walk += strlen("percentage_used_of_avail"); } if (BEGINS_WITH(walk + 1, "percentage_used")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks); walk += strlen("percentage_used"); } if (BEGINS_WITH(walk + 1, "percentage_avail")) { outwalk += sprintf(outwalk, "%.01f%%", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks); walk += strlen("percentage_avail"); } } if (colorful_output) END_COLOR; *outwalk = '\0'; OUTPUT_FULL_TEXT(buffer); }
/* * Reads the CPU temperature from /sys/class/thermal/thermal_zone%d/temp (or * the user provided path) and returns the temperature in degree celcius. * */ void print_cpu_temperature_info(yajl_gen json_gen, char *buffer, int zone, const char *path, const char *format, int max_threshold) { char *outwalk = buffer; #ifdef THERMAL_ZONE const char *walk; bool colorful_output = false; char *thermal_zone; if (path == NULL) asprintf(&thermal_zone, THERMAL_ZONE, zone); else { static glob_t globbuf; if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) die("glob() failed\n"); if (globbuf.gl_pathc == 0) { /* No glob matches, the specified path does not contain a wildcard. */ asprintf(&thermal_zone, path, zone); } else { /* glob matched, we take the first match and ignore the others */ asprintf(&thermal_zone, "%s", globbuf.gl_pathv[0]); } globfree(&globbuf); } INSTANCE(thermal_zone); for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (BEGINS_WITH(walk + 1, "degrees")) { #if defined(LINUX) static char buf[16]; long int temp; if (!slurp(thermal_zone, buf, sizeof(buf))) goto error; temp = strtol(buf, NULL, 10); if (temp == LONG_MIN || temp == LONG_MAX || temp <= 0) *(outwalk++) = '?'; else { if ((temp / 1000) >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%ld", (temp / 1000)); if (colorful_output) { END_COLOR; colorful_output = false; } } #elif defined(__DragonFly__) struct sensor th_sensor; size_t th_sensorlen; th_sensorlen = sizeof(th_sensor); if (sysctlbyname(thermal_zone, &th_sensor, &th_sensorlen, NULL, 0) == -1) { perror("sysctlbyname"); goto error; } if (MUKTOC(th_sensor.value) >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%.2f", MUKTOC(th_sensor.value)); if (colorful_output) { END_COLOR; colorful_output = false; } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) int sysctl_rslt; size_t sysctl_size = sizeof(sysctl_rslt); if (sysctlbyname(thermal_zone, &sysctl_rslt, &sysctl_size, NULL, 0)) goto error; if (TZ_AVG(sysctl_rslt) >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%d.%d", TZ_KELVTOC(sysctl_rslt)); if (colorful_output) { END_COLOR; colorful_output = false; } #elif defined(__OpenBSD__) struct sensordev sensordev; struct sensor sensor; size_t sdlen, slen; int dev, numt, mib[5] = {CTL_HW, HW_SENSORS, 0, 0, 0}; sdlen = sizeof(sensordev); slen = sizeof(sensor); for (dev = 0;; dev++) { mib[2] = dev; if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) { if (errno == ENXIO) continue; if (errno == ENOENT) break; goto error; } /* 'path' is the node within the full path (defaults to acpitz0). */ if (BEGINS_WITH(sensordev.xname, thermal_zone)) { mib[3] = SENSOR_TEMP; /* Limit to temo0, but should retrieve from a full path... */ for (numt = 0; numt < 1 /*sensordev.maxnumt[SENSOR_TEMP]*/; numt++) { mib[4] = numt; if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1) { if (errno != ENOENT) { warn("sysctl"); continue; } } if ((int)MUKTOC(sensor.value) >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%.2f", MUKTOC(sensor.value)); if (colorful_output) { END_COLOR; colorful_output = false; } } } } #elif defined(__NetBSD__) int fd, rval; bool err = false; prop_dictionary_t dict; prop_array_t array; prop_object_iterator_t iter; prop_object_iterator_t iter2; prop_object_t obj, obj2, obj3; fd = open("/dev/sysmon", O_RDONLY); if (fd == -1) goto error; rval = prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &dict); if (rval == -1) { err = true; goto error_netbsd1; } /* No drivers registered? */ if (prop_dictionary_count(dict) == 0) { err = true; goto error_netbsd2; } iter = prop_dictionary_iterator(dict); if (iter == NULL) { err = true; goto error_netbsd2; } /* iterate over the dictionary returned by the kernel */ while ((obj = prop_object_iterator_next(iter)) != NULL) { /* skip this dict if it's not what we're looking for */ if ((strlen(prop_dictionary_keysym_cstring_nocopy(obj)) != strlen(thermal_zone)) || (strncmp(thermal_zone, prop_dictionary_keysym_cstring_nocopy(obj), strlen(thermal_zone)) != 0)) continue; array = prop_dictionary_get_keysym(dict, obj); if (prop_object_type(array) != PROP_TYPE_ARRAY) { err = true; goto error_netbsd3; } iter2 = prop_array_iterator(array); if (!iter2) { err = true; goto error_netbsd3; } /* iterate over array of dicts specific to target sensor */ while ((obj2 = prop_object_iterator_next(iter2)) != NULL) { obj3 = prop_dictionary_get(obj2, "cur-value"); float temp = MUKTOC(prop_number_integer_value(obj3)); if ((int)temp >= max_threshold) { START_COLOR("color_bad"); colorful_output = true; } outwalk += sprintf(outwalk, "%.2f", temp); if (colorful_output) { END_COLOR; colorful_output = false; } break; } prop_object_iterator_release(iter2); } error_netbsd3: prop_object_iterator_release(iter); error_netbsd2: prop_object_release(dict); error_netbsd1: close(fd); if (err) goto error; #endif walk += strlen("degrees"); } } free(thermal_zone); OUTPUT_FULL_TEXT(buffer); return; error: free(thermal_zone); #endif OUTPUT_FULL_TEXT("can't read temp"); (void)fputs("i3status: Cannot read temperature. Verify that you have a thermal zone in /sys/class/thermal or disable the cpu_temperature module in your i3status config.\n", stderr); }
/* * Get battery information from /sys. Note that it uses the design capacity to * calculate the percentage, not the last full capacity, so you can see how * worn off your battery is. * */ void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity) { time_t empty_time; struct tm *empty_tm; char buf[1024]; char statusbuf[16]; char percentagebuf[16]; char remainingbuf[256]; char emptytimebuf[256]; char consumptionbuf[256]; const char *walk, *last; char *outwalk = buffer; bool watt_as_unit; bool colorful_output = false; int full_design = -1, remaining = -1, present_rate = -1, voltage = -1; charging_status_t status = CS_DISCHARGING; memset(statusbuf, '\0', sizeof(statusbuf)); memset(percentagebuf, '\0', sizeof(percentagebuf)); memset(remainingbuf, '\0', sizeof(remainingbuf)); memset(emptytimebuf, '\0', sizeof(emptytimebuf)); memset(consumptionbuf, '\0', sizeof(consumptionbuf)); static char batpath[512]; sprintf(batpath, path, number); INSTANCE(batpath); #if defined(LINUX) if (!slurp(batpath, buf, sizeof(buf))) { OUTPUT_FULL_TEXT(format_down); return; } for (walk = buf, last = buf; (walk-buf) < 1024; walk++) { if (*walk == '\n') { last = walk+1; continue; } if (*walk != '=') continue; if (BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_NOW")) { watt_as_unit = true; remaining = atoi(walk+1); } else if (BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_NOW")) { watt_as_unit = false; remaining = atoi(walk+1); } else if (BEGINS_WITH(last, "POWER_SUPPLY_CURRENT_NOW")) present_rate = atoi(walk+1); else if (BEGINS_WITH(last, "POWER_SUPPLY_VOLTAGE_NOW")) voltage = atoi(walk+1); /* on some systems POWER_SUPPLY_POWER_NOW does not exist, but actually * it is the same as POWER_SUPPLY_CURRENT_NOW but with μWh as * unit instead of μAh. We will calculate it as we need it * later. */ else if (BEGINS_WITH(last, "POWER_SUPPLY_POWER_NOW")) present_rate = atoi(walk+1); else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Charging")) status = CS_CHARGING; else if (BEGINS_WITH(last, "POWER_SUPPLY_STATUS=Full")) status = CS_FULL; else { /* The only thing left is the full capacity */ if (last_full_capacity) { if (!BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL") && !BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL")) continue; } else { if (!BEGINS_WITH(last, "POWER_SUPPLY_CHARGE_FULL_DESIGN") && !BEGINS_WITH(last, "POWER_SUPPLY_ENERGY_FULL_DESIGN")) continue; } full_design = atoi(walk+1); } } /* the difference between POWER_SUPPLY_ENERGY_NOW and * POWER_SUPPLY_CHARGE_NOW is the unit of measurement. The energy is * given in mWh, the charge in mAh. So calculate every value given in * ampere to watt */ if (!watt_as_unit) { present_rate = (((float)voltage / 1000.0) * ((float)present_rate / 1000.0)); remaining = (((float)voltage / 1000.0) * ((float)remaining / 1000.0)); full_design = (((float)voltage / 1000.0) * ((float)full_design / 1000.0)); } if ((full_design == -1) || (remaining == -1)) { OUTPUT_FULL_TEXT(format_down); return; } (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); float percentage_remaining = (((float)remaining / (float)full_design) * 100); if (integer_battery_capacity) { (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.00f%%", percentage_remaining); } else { (void)snprintf(percentagebuf, sizeof(percentagebuf), "%.02f%%", percentage_remaining); } if (present_rate > 0) { float remaining_time; int seconds, hours, minutes, seconds_remaining; if (status == CS_CHARGING) remaining_time = ((float)full_design - (float)remaining) / (float)present_rate; else if (status == CS_DISCHARGING) remaining_time = ((float)remaining / (float)present_rate); else remaining_time = 0; seconds_remaining = (int)(remaining_time * 3600.0); hours = seconds_remaining / 3600; seconds = seconds_remaining - (hours * 3600); minutes = seconds / 60; seconds -= (minutes * 60); if (status == CS_DISCHARGING && low_threshold > 0) { if (strncmp(threshold_type, "percentage", strlen(threshold_type)) == 0 && percentage_remaining < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else if (strncmp(threshold_type, "time", strlen(threshold_type)) == 0 && seconds_remaining < 60 * low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else { colorful_output = false; } } (void)snprintf(remainingbuf, sizeof(remainingbuf), "%02d:%02d:%02d", max(hours, 0), max(minutes, 0), max(seconds, 0)); empty_time = time(NULL); empty_time += seconds_remaining; empty_tm = localtime(&empty_time); (void)snprintf(emptytimebuf, sizeof(emptytimebuf), "%02d:%02d:%02d", max(empty_tm->tm_hour, 0), max(empty_tm->tm_min, 0), max(empty_tm->tm_sec, 0)); (void)snprintf(consumptionbuf, sizeof(consumptionbuf), "%1.2fW", ((float)present_rate / 1000.0 / 1000.0)); } else { /* On some systems, present_rate may not exist. Still, make sure * we colorize the output if threshold_type is set to percentage * (since we don't have any information on remaining time). */ if (status == CS_DISCHARGING && low_threshold > 0) { if (strncmp(threshold_type, "percentage", strlen(threshold_type)) == 0 && percentage_remaining < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } } } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) int state; int sysctl_rslt; size_t sysctl_size = sizeof(sysctl_rslt); if (sysctlbyname(BATT_LIFE, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return; } present_rate = sysctl_rslt; if (sysctlbyname(BATT_TIME, &sysctl_rslt, &sysctl_size, NULL, 0) != 0) { OUTPUT_FULL_TEXT(format_down); return; } remaining = sysctl_rslt; if (sysctlbyname(BATT_STATE, &sysctl_rslt, &sysctl_size, NULL,0) != 0) { OUTPUT_FULL_TEXT(format_down); return; } state = sysctl_rslt; if (state == 0 && present_rate == 100) status = CS_FULL; else if (state == 0 && present_rate < 100) status = CS_CHARGING; else status = CS_DISCHARGING; full_design = sysctl_rslt; (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); (void)snprintf(percentagebuf, sizeof(percentagebuf), "%02d%%", present_rate); if (state == 1) { int hours, minutes; minutes = remaining; hours = minutes / 60; minutes -= (hours * 60); (void)snprintf(remainingbuf, sizeof(remainingbuf), "%02dh%02d", max(hours, 0), max(minutes, 0)); if (strncmp(threshold_type, "percentage", strlen(threshold_type)) == 0 && present_rate < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else if (strncmp(threshold_type, "time", strlen(threshold_type)) == 0 && remaining < (u_int) low_threshold) { START_COLOR("color_bad"); colorful_output = true; } } #elif defined(__OpenBSD__) /* * We're using apm(4) here, which is the interface to acpi(4) on amd64/i386 and * the generic interface on macppc/sparc64/zaurus, instead of using sysctl(3) and * probing acpi(4) devices. */ struct apm_power_info apm_info; int apm_fd; apm_fd = open("/dev/apm", O_RDONLY); if (apm_fd < 0) { OUTPUT_FULL_TEXT("can't open /dev/apm"); return; } if (ioctl(apm_fd, APM_IOC_GETPOWER, &apm_info) < 0) OUTPUT_FULL_TEXT("can't read power info"); close(apm_fd); /* Don't bother to go further if there's no battery present. */ if ((apm_info.battery_state == APM_BATTERY_ABSENT) || (apm_info.battery_state == APM_BATT_UNKNOWN)) { OUTPUT_FULL_TEXT(format_down); return; } switch(apm_info.ac_state) { case APM_AC_OFF: status = CS_DISCHARGING; break; case APM_AC_ON: status = CS_CHARGING; break; default: /* If we don't know what's going on, just assume we're discharging. */ status = CS_DISCHARGING; break; } (void)snprintf(statusbuf, sizeof(statusbuf), "%s", BATT_STATUS_NAME(status)); (void)snprintf(percentagebuf, sizeof(percentagebuf), "%02d%%", apm_info.battery_life); if (status == CS_DISCHARGING && low_threshold > 0) { if (strncmp(threshold_type, "percentage", strlen(threshold_type)) == 0 && apm_info.battery_life < low_threshold) { START_COLOR("color_bad"); colorful_output = true; } else if (strncmp(threshold_type, "time", strlen(threshold_type)) == 0 && apm_info.minutes_left < (u_int) low_threshold) { START_COLOR("color_bad"); colorful_output = true; } } /* Can't give a meaningful value for remaining minutes if we're charging. */ if (status != CS_CHARGING) { (void)snprintf(remainingbuf, sizeof(remainingbuf), "%d", apm_info.minutes_left); } else { (void)snprintf(remainingbuf, sizeof(remainingbuf), "%s", "(CHR)"); } if (colorful_output) END_COLOR; #endif #define EAT_SPACE_FROM_OUTPUT_IF_EMPTY(_buf) \ do { \ if (strlen(_buf) == 0) { \ if (outwalk > buffer && isspace(outwalk[-1])) \ outwalk--; \ else if (isspace(*(walk+1))) \ walk++; \ } \ } while (0) for (walk = format; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (strncmp(walk+1, "status", strlen("status")) == 0) { outwalk += sprintf(outwalk, "%s", statusbuf); walk += strlen("status"); } else if (strncmp(walk+1, "percentage", strlen("percentage")) == 0) { outwalk += sprintf(outwalk, "%s", percentagebuf); walk += strlen("percentage"); } else if (strncmp(walk+1, "remaining", strlen("remaining")) == 0) { outwalk += sprintf(outwalk, "%s", remainingbuf); walk += strlen("remaining"); EAT_SPACE_FROM_OUTPUT_IF_EMPTY(remainingbuf); } else if (strncmp(walk+1, "emptytime", strlen("emptytime")) == 0) { outwalk += sprintf(outwalk, "%s", emptytimebuf); walk += strlen("emptytime"); EAT_SPACE_FROM_OUTPUT_IF_EMPTY(emptytimebuf); } else if (strncmp(walk+1, "consumption", strlen("consumption")) == 0) { outwalk += sprintf(outwalk, "%s", consumptionbuf); walk += strlen("consumption"); EAT_SPACE_FROM_OUTPUT_IF_EMPTY(consumptionbuf); } } if (colorful_output) END_COLOR; OUTPUT_FULL_TEXT(buffer); }