X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/b176d0a2d0e3048f22b35083ea7d6571aaa69260..093f39df23da146cc88e9987469081e5b3016cfe:/slstatus.c diff --git a/slstatus.c b/slstatus.c index d6f5e2d..505f25d 100644 --- a/slstatus.c +++ b/slstatus.c @@ -2,43 +2,29 @@ /* global libraries */ #include +#include #include +#include +#include +#include #include +#include +#include #include #include #include #include -#include +#include #include #include +#include +#include #include #include #include -/* global variables */ -static Display *dpy; - -/* statusbar configuration type and struct */ -typedef char *(*op_fun) (const char *); -struct arg { - op_fun func; - const char *format; - const char *args; -}; - -/* functions */ -void setstatus(const char *); -char *smprintf(const char *, ...); -char *get_battery(const char *); -char *get_cpu_temperature(const char *); -char *get_cpu_usage(const char *); -char *get_datetime(const char *); -char *get_diskusage(const char *); -char *get_ram_usage(const char *); -char *get_volume(const char *); -char *get_wifi_signal(const char *); - -/* include config header */ +/* local headers */ +#include "slstatus.h" #include "config.h" /* set statusbar */ @@ -67,7 +53,7 @@ smprintf(const char *fmt, ...) /* battery percentage */ char * -get_battery(const char *battery) +battery_perc(const char *battery) { int now, full, perc; char batterynowfile[64] = ""; @@ -117,32 +103,9 @@ get_battery(const char *battery) return smprintf("%d%%", perc); } -/* cpu temperature */ -char * -get_cpu_temperature(const char *file) -{ - int temperature; - FILE *fp; - - /* open temperature file */ - if (!(fp = fopen(file, "r"))) { - fprintf(stderr, "Could not open temperature file.\n"); - return smprintf("n/a"); - } - - /* extract temperature */ - fscanf(fp, "%d", &temperature); - - /* close temperature file */ - fclose(fp); - - /* return temperature in degrees */ - return smprintf("%d°C", temperature / 1000); -} - /* cpu percentage */ char * -get_cpu_usage(const char *null) +cpu_perc(const char *null) { int perc; long double a[4], b[4]; @@ -184,29 +147,52 @@ get_cpu_usage(const char *null) /* date and time */ char * -get_datetime(const char *timeformat) +datetime(const char *timeformat) { time_t tm; size_t bufsize = 64; char *buf = malloc(bufsize); + if (buf == NULL) { + fprintf(stderr, "Failed to get date/time"); + return smprintf("n/a"); + } /* get time in format */ time(&tm); setlocale(LC_TIME, ""); if(!strftime(buf, bufsize, timeformat, localtime(&tm))) { setlocale(LC_TIME, "C"); + free(buf); fprintf(stderr, "Strftime failed.\n"); return smprintf("n/a"); } setlocale(LC_TIME, "C"); /* return time */ - return smprintf("%s", buf); + char *ret = smprintf("%s", buf); + free(buf); + return ret; +} + +/* disk free */ +char * +disk_free(const char *mountpoint) +{ + struct statvfs fs; + + /* try to open mountpoint */ + if (statvfs(mountpoint, &fs) < 0) { + fprintf(stderr, "Could not get filesystem info.\n"); + return smprintf("n/a"); + } + + /* return free */ + return smprintf("%f", (float)fs.f_bsize * (float)fs.f_bfree / 1024 / 1024 / 1024); } /* disk usage percentage */ char * -get_diskusage(const char *mountpoint) +disk_perc(const char *mountpoint) { int perc = 0; struct statvfs fs; @@ -218,15 +204,174 @@ get_diskusage(const char *mountpoint) } /* calculate percent */ - perc = 100 * (1.0f - ((float)fs.f_bavail / (float)fs.f_blocks)); + perc = 100 * (1.0f - ((float)fs.f_bfree / (float)fs.f_blocks)); /* return perc */ return smprintf("%d%%", perc); } +/* disk total */ +char * +disk_total(const char *mountpoint) +{ + struct statvfs fs; + + /* try to open mountpoint */ + if (statvfs(mountpoint, &fs) < 0) { + fprintf(stderr, "Could not get filesystem info.\n"); + return smprintf("n/a"); + } + + /* return total */ + return smprintf("%f", (float)fs.f_bsize * (float)fs.f_blocks / 1024 / 1024 / 1024); +} + +/* disk used */ +char * +disk_used(const char *mountpoint) +{ + struct statvfs fs; + + /* try to open mountpoint */ + if (statvfs(mountpoint, &fs) < 0) { + fprintf(stderr, "Could not get filesystem info.\n"); + return smprintf("n/a"); + } + + /* return used */ + return smprintf("%f", (float)fs.f_bsize * ((float)fs.f_blocks - (float)fs.f_bfree) / 1024 / 1024 / 1024); +} + +/* entropy available */ +char * +entropy(const char *null) +{ + int entropy = 0; + FILE *fp; + + /* open entropy file */ + if (!(fp = fopen("/proc/sys/kernel/random/entropy_avail", "r"))) { + fprintf(stderr, "Could not open entropy file.\n"); + return smprintf("n/a"); + } + + /* extract entropy */ + fscanf(fp, "%d", &entropy); + + /* close entropy file */ + fclose(fp); + + /* return entropy */ + return smprintf("%d", entropy); +} + +/* gid */ +char * +gid(const char *null) +{ + gid_t gid; + + if ((gid = getgid()) < 0) { + fprintf(stderr, "Could no get gid."); + return smprintf("n/a"); + } else { + return smprintf("%d", gid); + } + + return smprintf("n/a"); +} + +/* hostname */ +char * +hostname(const char *null) +{ + char hostname[HOST_NAME_MAX]; + FILE *fp; + + /* open hostname file */ + if (!(fp = fopen("/proc/sys/kernel/hostname", "r"))) { + fprintf(stderr, "Could not open hostname file.\n"); + return smprintf("n/a"); + } + + /* extract hostname */ + fscanf(fp, "%s\n", hostname); + + /* close hostname file */ + fclose(fp); + + /* return entropy */ + return smprintf("%s", hostname); +} + +/* ip address */ +char * +ip(const char *interface) +{ + struct ifaddrs *ifaddr, *ifa; + int s; + char host[NI_MAXHOST]; + + /* check if getting ip address works */ + if (getifaddrs(&ifaddr) == -1) + { + fprintf(stderr, "Error getting IP address."); + return smprintf("n/a"); + } + + /* get the ip address */ + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) + continue; + + s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + + if ((strcmp(ifa->ifa_name, interface) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) + { + if (s != 0) + { + fprintf(stderr, "Error getting IP address."); + return smprintf("n/a"); + } + return smprintf("%s", host); + } + } + + /* free the address */ + freeifaddrs(ifaddr); + + /* return n/a if nothing works */ + return smprintf("n/a"); +} + +/* ram free */ +char * +ram_free(const char *null) +{ + long free; + FILE *fp; + + /* open meminfo file */ + if (!(fp = fopen("/proc/meminfo", "r"))) { + fprintf(stderr, "Error opening meminfo file."); + return smprintf("n/a"); + } + + /* read the values */ + fscanf(fp, "MemTotal: %*d kB\n"); + fscanf(fp, "MemFree: %ld kB\n", &free); + + /* close meminfo file */ + fclose(fp); + + /* return free ram as string */ + return smprintf("%f", (float)free / 1024 / 1024); +} + /* ram percentage */ char * -get_ram_usage(const char *null) +ram_perc(const char *null) { int perc; long total, free, buffers, cached; @@ -254,47 +399,218 @@ get_ram_usage(const char *null) return smprintf("%d%%", perc); } +/* ram total */ +char * +ram_total(const char *null) +{ + long total; + FILE *fp; + + /* open meminfo file */ + if (!(fp = fopen("/proc/meminfo", "r"))) { + fprintf(stderr, "Error opening meminfo file."); + return smprintf("n/a"); + } + + /* read the values */ + fscanf(fp, "MemTotal: %ld kB\n", &total); + + /* close meminfo file */ + fclose(fp); + + /* return total ram as string */ + return smprintf("%f", (float)total / 1024 / 1024); +} + +/* ram used */ +char * +ram_used(const char *null) +{ + long free, total, buffers, cached, used; + FILE *fp; + + /* open meminfo file */ + if (!(fp = fopen("/proc/meminfo", "r"))) { + fprintf(stderr, "Error opening meminfo file."); + return smprintf("n/a"); + } + + /* read the values */ + fscanf(fp, "MemTotal: %ld kB\n", &total); + fscanf(fp, "MemFree: %ld kB\n", &free); + fscanf(fp, "MemAvailable: %ld kB\nBuffers: %ld kB\n", &buffers, &buffers); + fscanf(fp, "Cached: %ld kB\n", &cached); + + /* close meminfo file */ + fclose(fp); + + /* calculate used */ + used = total - free - buffers - cached; + + /* return used ram as string */ + return smprintf("%f", (float)used / 1024 / 1024); +} + +/* custom shell command */ +char * +run_command(const char* command) +{ + int good; + FILE *fp; + char buffer[64]; + + /* try to open the command output */ + if (!(fp = popen(command, "r"))) { + fprintf(stderr, "Could not get command output for: %s.\n", command); + return smprintf("n/a"); + } + + /* get command output text, save it to buffer */ + fgets(buffer, sizeof(buffer)-1, fp); + + /* close it again */ + pclose(fp); + + /* add nullchar at the end */ + for (int i = 0 ; i != sizeof(buffer) ; i++) { + if (buffer[i] == '\0') { + good = 1; + break; + } + } + if (good) { + buffer[strlen(buffer) - 1] = '\0'; + } + + /* return the output */ + return smprintf("%s", buffer); +} + +/* temperature */ +char * +temp(const char *file) +{ + int temperature; + FILE *fp; + + /* open temperature file */ + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "Could not open temperature file.\n"); + return smprintf("n/a"); + } + + /* extract temperature */ + fscanf(fp, "%d", &temperature); + + /* close temperature file */ + fclose(fp); + + /* return temperature in degrees */ + return smprintf("%d°C", temperature / 1000); +} + +/* username */ +char * +username(const char *null) +{ + register struct passwd *pw; + register uid_t uid; + + /* get the values */ + uid = geteuid (); + pw = getpwuid (uid); + + /* if it worked, return */ + if (pw) { + return smprintf("%s", pw->pw_name); + } + else { + fprintf(stderr, "Could not get username.\n"); + return smprintf("n/a"); + } + + return smprintf("n/a"); +} + +/* uid */ +char * +uid(const char *null) +{ + register uid_t uid; + + /* get the values */ + uid = geteuid (); + + /* if it worked, return */ + if (uid) { + return smprintf("%d", uid); + } + else { + fprintf(stderr, "Could not get uid.\n"); + return smprintf("n/a"); + } + + return smprintf("n/a"); +} + + /* alsa volume percentage */ char * -get_volume(const char *soundcard) +vol_perc(const char *soundcard) { int mute = 0; long vol = 0, max = 0, min = 0; - - /* get volume from alsa */ snd_mixer_t *handle; snd_mixer_elem_t *pcm_mixer, *mas_mixer; snd_mixer_selem_id_t *vol_info, *mute_info; + + /* open everything */ snd_mixer_open(&handle, 0); snd_mixer_attach(handle, soundcard); snd_mixer_selem_register(handle, NULL, NULL); snd_mixer_load(handle); + + /* prepare everything */ snd_mixer_selem_id_malloc(&vol_info); snd_mixer_selem_id_malloc(&mute_info); + /* check */ + if (vol_info == NULL || mute_info == NULL) { + fprintf(stderr, "Could not get alsa volume"); + return smprintf("n/a"); + } snd_mixer_selem_id_set_name(vol_info, channel); snd_mixer_selem_id_set_name(mute_info, channel); pcm_mixer = snd_mixer_find_selem(handle, vol_info); mas_mixer = snd_mixer_find_selem(handle, mute_info); + + /* get the info */ snd_mixer_selem_get_playback_volume_range((snd_mixer_elem_t *)pcm_mixer, &min, &max); snd_mixer_selem_get_playback_volume((snd_mixer_elem_t *)pcm_mixer, SND_MIXER_SCHN_MONO, &vol); snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute); - if (vol_info) + + /* clean up */ + if (vol_info) { snd_mixer_selem_id_free(vol_info); - if (mute_info) + } + if (mute_info) { snd_mixer_selem_id_free(mute_info); - if (handle) + } + if (handle) { snd_mixer_close(handle); + } /* return the string (mute) */ - if (!mute) + if (!mute) { return smprintf("mute"); - else + } + else { return smprintf("%d%%", (vol * 100) / max); + } } /* wifi percentage */ char * -get_wifi_signal(const char *wificard) +wifi_perc(const char *wificard) { int bufsize = 255; int strength; @@ -352,9 +668,48 @@ get_wifi_signal(const char *wificard) return smprintf("%d%%", strength); } +/* wifi essid */ +char * +wifi_essid(const char *wificard) +{ + char *id = malloc(IW_ESSID_MAX_SIZE+1); + if (id == NULL) { + fprintf(stderr, "Cannot get ESSID."); + return smprintf("n/a"); + } + int sockfd; + struct iwreq wreq; + + /* prepare */ + memset(&wreq, 0, sizeof(struct iwreq)); + wreq.u.essid.length = IW_ESSID_MAX_SIZE+1; + + /* set the interface */ + sprintf(wreq.ifr_name, wificard); + + /* check */ + if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + fprintf(stderr, "Cannot open socket for interface: %s\n", wificard); + return smprintf("n/a"); + } + wreq.u.essid.pointer = id; + if (ioctl(sockfd,SIOCGIWESSID, &wreq) == -1) { + fprintf(stderr, "Get ESSID ioctl failed for interface %s\n", wificard); + return smprintf("n/a"); + } + + /* return the essid */ + if (strcmp((char *)wreq.u.essid.pointer, "") == 0) { + return smprintf("n/a"); + } + else { + return smprintf("%s", (char *)wreq.u.essid.pointer); + } +} + /* main function */ int -main() +main(void) { char status_string[1024]; struct arg argument; @@ -368,14 +723,20 @@ main() /* return status every interval */ for (;;) { /* clear the string */ - strcpy(status_string, ""); + memset(status_string, 0, sizeof(status_string)); /* generate status_string */ for (size_t i = 0; i < sizeof(args) / sizeof(args[0]); ++i) { argument = args[i]; char *res = argument.func(argument.args); char *element = smprintf(argument.format, res); + if (element == NULL) { + element = smprintf("n/a"); + fprintf(stderr, "Failed to format output."); + } strcat(status_string, element); + free(res); + free(element); } /* return the statusbar */