On Fri, Oct 10, 2014 at 11:24:15PM -0700, Isaac Dunham wrote:
> On several occasions I've wished for a tool that can show battery charge,
> whether the power supply is working, and similar things.
> Some time back I wrote the original version of this for toybox;
> I just ported it to BusyBox.
> 
> If anyone could review it, I'd appreciate that.
> 
> Thanks,
> Isaac Dunham

Any comments? (Denys?)
Is it within scope?
(I'd love to hear anything, even if it's "that belongs elsewhere". 
There's been a lot of silence...)

Thanks,
Isaac Dunham

> From 0c0fad3ae324aa2383a9367715d205e41269d0c0 Mon Sep 17 00:00:00 2001
> From: Isaac Dunham <ibid...@gmail.com>
> Date: Fri, 10 Oct 2014 22:53:36 -0700
> Subject: [PATCH] Add "acpi" applet.
> 
> A tool to monitor power, temperature, and similar things.
> Ported from toybox; subset clone of acpi-1.7.
> 
> function                                             old     new   delta
> acpi_main                                              -     919    +919
> .rodata                                           134270  134673    +403
> read_int_at                                            -     129    +129
> read_type_at                                           -     119    +119
> packed_usage                                       29647   29721     +74
> applet_names                                        2451    2456      +5
> applet_main                                         1428    1432      +4
> applet_nameofs                                       714     716      +2
> ------------------------------------------------------------------------------
> (add/remove: 4/0 grow/shrink: 5/0 up/down: 1655/0)           Total: 1655 bytes
>    text          data     bss     dec     hex filename
>  887409          7512    1644  896565   dae35 busybox_old
>  889140          7528    1644  898312   db508 busybox_unstripped
> ---
>  miscutils/acpi.c | 171 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 171 insertions(+)
>  create mode 100644 miscutils/acpi.c
> 
> diff --git a/miscutils/acpi.c b/miscutils/acpi.c
> new file mode 100644
> index 0000000..f2a5601
> --- /dev/null
> +++ b/miscutils/acpi.c
> @@ -0,0 +1,171 @@
> +/* acpi.c - show power state
> + *
> + * Copyright 2013-2014 A.D., Isaac Dunham
> + *
> + * Based on toybox 0.5.0+ acpi.
> + * 
> + * Permission to use, copy, modify, and/or distribute this software for any
> + * purpose with or without fee is hereby granted.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +//config:config ACPI
> +//config:    bool "acpi"
> +//config:    default y
> +//config:    select PLATFORM_LINUX
> +//config:    help
> +//config:      Show status of power sources and thermal devices.
> +
> +//applet:IF_ACPI(APPLET(acpi, BB_DIR_USR_BIN, BB_SUID_DROP))
> +//kbuild:lib-$(CONFIG_ACPI) += acpi.o
> +
> +//usage:#define acpi_trivial_usage
> +//usage:    "[-abctV]"
> +//usage:#define acpi_full_usage "\n\n"
> +//usage:    "Show status of power sources and thermal devices.\n"
> +//usage:    "-a      show power adapters\n"
> +//usage:    "-b      show batteries\n"
> +//usage:    "-c      show cooling device state\n"
> +//usage:    "-t      show temperatures\n"
> +//usage:    "-V      show everything"
> +
> +
> +#define FLAG_a       1
> +#define FLAG_b       2
> +#define FLAG_c       4
> +#define FLAG_t       8
> +#define FLAG_V       16
> +
> +#include "libbb.h"
> +#include <glob.h>
> +
> +#define G_BUFSIZ 64
> +struct globals {
> +    int ac;
> +    int bat;
> +    int therm;
> +    int cool;
> +    char buf[G_BUFSIZ];
> +} FIX_ALIASING;
> +#define G (*(struct globals*)&bb_common_bufsiz1)
> +
> +static int read_int_at(int dirfd, const char *name)
> +{
> +    int fd, ret = 0;
> +    FILE *fil;
> +
> +    if ((fd = openat(dirfd, name, O_RDONLY)) < 0)
> +     return -1;
> +    fscanf(fil = fdopen(fd, "r"), "%d", &ret);
> +    fclose(fil);
> +
> +    return ret;
> +}
> +
> +static char *read_type_at(int dirfd)
> +{
> +    int fd;
> +    if ((fd = openat(dirfd, "type", O_RDONLY)) < 0)
> +     return 0;
> +    read(fd, G.buf, G_BUFSIZ-1);
> +    close(fd);
> +    if errno
> +     return 0;
> +    return G.buf;
> +}
> +
> +int acpi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> +int acpi_main(int argc UNUSED_PARAM, char **argv)
> +{
> +    glob_t files;
> +    int dfd, on, cur, max, temp, i;
> +    unsigned opts = getopt32(argv, "abctV");
> +
> +    if (opts & FLAG_V)
> +     opts = FLAG_a | FLAG_b | FLAG_c | FLAG_t;
> +    if (!opts)
> +     opts = FLAG_b;
> +    if (opts & (FLAG_a | FLAG_b)) {
> +     glob("/sys/class/power_supply/*/", GLOB_NOSORT, NULL, &files);
> +     for (i = 0; i < files.gl_pathc; i++) {
> +         errno = 0;
> +         if (0 <= (dfd = open(files.gl_pathv[i], O_RDONLY))) {
> +             if (!read_type_at(dfd))
> +                 goto ab_done;
> +
> +             if ((!strncmp(G.buf, "Battery", 7)) && (opts & FLAG_b)) {
> +                 int cap = read_int_at(dfd, "capacity");
> +
> +                 if (cap < 0) {
> +                     if ((max = read_int_at(dfd, "charge_full")) > 0)
> +                         cur = read_int_at(dfd, "charge_now");
> +                     else if ((max =
> +                               read_int_at(dfd, "energy_full")) > 0)
> +                         cur = read_int_at(dfd, "energy_now");
> +                     if (max > 0)
> +                         cap = 100 * cur / max;
> +                 }
> +                 if (cap >= 0)
> +                     printf("Battery %d: %d%%\n", G.bat++, cap);
> +
> +             } else if ((opts & FLAG_a)
> +                        && ((on = read_int_at(dfd, "online")) >= 0)) {
> +                 printf("Adapter %d: %s-line\n", G.ac++,
> +                        (on ? "on" : "off"));
> +             }
> +           ab_done:
> +             close(dfd);
> +         }
> +     }
> +     globfree(&files);
> +    }
> +    if (opts & FLAG_t) {
> +     glob("/sys/class/*/*/temp", GLOB_NOSORT, NULL, &files);
> +     glob("/sys/class/*/*/temp*_input", GLOB_NOSORT | GLOB_APPEND, NULL,
> +          &files);
> +     for (i = 0; i < files.gl_pathc; i++) {
> +         errno = 0;
> +         if ((0 < (temp = read_int_at(AT_FDCWD, files.gl_pathv[i])))
> +             || !errno) {
> +             //some tempertures are in milli-C, some in deci-C
> +             //reputedly some are in deci-K, but I have not seen them
> +             if (((temp >= 1000) || (temp <= -1000))
> +                 && (temp % 100 == 0))
> +                 temp /= 100;
> +             printf("Thermal %d: %d.%d degrees C\n", G.therm++,
> +                    temp / 10, temp % 10);
> +         }
> +     }
> +     globfree(&files);
> +    }
> +    if (opts & FLAG_c) {
> +     glob("/sys/class/thermal/*/", GLOB_NOSORT, NULL, &files);
> +     for (i = 0; i < files.gl_pathc; i++) {
> +         errno = 0;
> +         memset(G.buf, 0, 64);
> +         if (0 <= (dfd = open(files.gl_pathv[i], O_RDONLY))) {
> +             if (read_type_at(dfd) && !errno) {
> +                 G.buf[strlen(G.buf) - 1] = 0;
> +                 cur = read_int_at(dfd, "cur_state");
> +                 max = read_int_at(dfd, "max_state");
> +                 if (errno)
> +                     printf("Cooling %d: %s no state information\n",
> +                            G.cool++, G.buf);
> +                 else
> +                     printf("Cooling %d: %s %d of %d\n", G.cool++, G.buf,
> +                            cur, max);
> +             }
> +             close(dfd);
> +         }
> +     }
> +     globfree(&files);
> +    }
> +    return 0;
> +}
> -- 
> 2.1.2
> 

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to