initial commit
This commit is contained in:
		
							parent
							
								
									47a0e8dec3
								
							
						
					
					
						commit
						94ea78f0fe
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| slstatus | ||||
| slstatus.o | ||||
							
								
								
									
										49
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| # See LICENSE file for copyright and license details.
 | ||||
| 
 | ||||
| include config.mk | ||||
| 
 | ||||
| SRC = ${NAME}.c | ||||
| OBJ = ${SRC:.c=.o} | ||||
| 
 | ||||
| all: options ${NAME} | ||||
| 
 | ||||
| options: | ||||
| 	@echo ${NAME} build options: | ||||
| 	@echo "CFLAGS   = ${CFLAGS}" | ||||
| 	@echo "LDFLAGS  = ${LDFLAGS}" | ||||
| 	@echo "CC       = ${CC}" | ||||
| 
 | ||||
| .c.o: | ||||
| 	@echo CC $< | ||||
| 	@${CC} -c ${CFLAGS} $< | ||||
| 
 | ||||
| ${OBJ}: config.mk | ||||
| 
 | ||||
| ${NAME}: ${OBJ} | ||||
| 	@echo CC -o $@ | ||||
| 	@${CC} -o $@ ${OBJ} ${LDFLAGS} | ||||
| 
 | ||||
| clean: | ||||
| 	@echo cleaning | ||||
| 	@rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz | ||||
| 
 | ||||
| dist: clean | ||||
| 	@echo creating dist tarball | ||||
| 	@mkdir -p ${NAME}-${VERSION} | ||||
| 	@cp -R Makefile config.mk LICENSE \
 | ||||
| 		${SRC} ${NAME}-${VERSION} | ||||
| 	@tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION} | ||||
| 	@gzip ${NAME}-${VERSION}.tar | ||||
| 	@rm -rf ${NAME}-${VERSION} | ||||
| 
 | ||||
| install: all | ||||
| 	@echo installing executable file to ${DESTDIR}${PREFIX}/bin | ||||
| 	@mkdir -p ${DESTDIR}${PREFIX}/bin | ||||
| 	@cp -f ${NAME} ${DESTDIR}${PREFIX}/bin | ||||
| 	@chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME} | ||||
| 
 | ||||
| uninstall: | ||||
| 	@echo removing executable file from ${DESTDIR}${PREFIX}/bin | ||||
| 	@rm -f ${DESTDIR}${PREFIX}/bin/${NAME} | ||||
| 
 | ||||
| .PHONY: all options clean dist install uninstall | ||||
							
								
								
									
										22
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								config.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| /* See LICENSE file for copyright and license details. */ | ||||
| 
 | ||||
| /* alsa sound */ | ||||
| static const char soundcard[] = "default"; | ||||
| static const char channel[]   = "Master"; | ||||
| 
 | ||||
| /* cpu temperature */ | ||||
| static const char tempfile[] = "/sys/devices/platform/coretemp.0/hwmon/hwmon2/temp1_input"; | ||||
| 
 | ||||
| /* wifi */ | ||||
| static const char wificard[] = "wlp3s0"; | ||||
| 
 | ||||
| /* battery */ | ||||
| static const char batterynowfile[]  = "/sys/class/power_supply/BAT0/energy_now"; | ||||
| static const char batteryfullfile[] = "/sys/class/power_supply/BAT0/energy_full_design"; | ||||
| 
 | ||||
| /* time */ | ||||
| static const char timeformat[] = "%y-%m-%d %H:%M:%S"; | ||||
| 
 | ||||
| /* statusbar */ | ||||
| #define FORMATSTRING "wifi %4s | bat %4s | cpu %4s %3s | ram %3s | vol %4s | %3s" | ||||
| #define ARGUMENTS wifi_signal(), battery(), cpu_usage(), cpu_temperature(), ram_usage(), volume(), datetime() | ||||
							
								
								
									
										30
									
								
								config.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								config.mk
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| NAME = slstatus | ||||
| VERSION = 1.0 | ||||
| 
 | ||||
| # Customize below to fit your system
 | ||||
| 
 | ||||
| # paths
 | ||||
| PREFIX = /usr/local | ||||
| MANPREFIX = ${PREFIX}/share/man | ||||
| 
 | ||||
| X11INC = /usr/X11R6/include | ||||
| X11LIB = /usr/X11R6/lib | ||||
| 
 | ||||
| # includes and libs
 | ||||
| INCS = -I. -I/usr/include -I${X11INC} | ||||
| LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lasound | ||||
| 
 | ||||
| # flags
 | ||||
| CPPFLAGS = -DVERSION=\"${VERSION}\" | ||||
| CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} | ||||
| #CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
 | ||||
| LDFLAGS = -g ${LIBS} | ||||
| #LDFLAGS = -s ${LIBS}
 | ||||
| 
 | ||||
| # Solaris
 | ||||
| #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
 | ||||
| #LDFLAGS = ${LIBS}
 | ||||
| 
 | ||||
| # compiler and linker
 | ||||
| CC = cc | ||||
| 
 | ||||
							
								
								
									
										302
									
								
								slstatus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										302
									
								
								slstatus.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,302 @@ | ||||
| /* See LICENSE file for copyright and license details. */ | ||||
| 
 | ||||
| #include <alsa/asoundlib.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| #include <X11/Xlib.h> | ||||
| 
 | ||||
| #include "config.h" | ||||
| 
 | ||||
| char *smprintf(char *fmt, ...); | ||||
| 
 | ||||
| void *setstatus(char *str); | ||||
| 
 | ||||
| char *wifi_signal(); | ||||
| char *battery(); | ||||
| char *cpu_usage(); | ||||
| char *cpu_temperature(); | ||||
| char *ram_usage(); | ||||
| char *volume(); | ||||
| char *datetime(); | ||||
| 
 | ||||
| static Display *dpy; | ||||
| 
 | ||||
| /* smprintf function */ | ||||
| char * | ||||
| smprintf(char *fmt, ...) | ||||
| { | ||||
| 	va_list fmtargs; | ||||
| 	char *ret; | ||||
| 	int len; | ||||
| 
 | ||||
| 	va_start(fmtargs, fmt); | ||||
| 	len = vsnprintf(NULL, 0, fmt, fmtargs); | ||||
| 	va_end(fmtargs); | ||||
| 
 | ||||
| 	ret = malloc(++len); | ||||
| 	if (ret == NULL) { | ||||
| 		fprintf(stderr, "Malloc error."); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 
 | ||||
| 	va_start(fmtargs, fmt); | ||||
| 	vsnprintf(ret, len, fmt, fmtargs); | ||||
| 	va_end(fmtargs); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /* set statusbar (WM_NAME) */ | ||||
| void | ||||
| setstatus(char *str) | ||||
| { | ||||
| 	XStoreName(dpy, DefaultRootWindow(dpy), str); | ||||
| 	XSync(dpy, False); | ||||
| } | ||||
| 
 | ||||
| /* alsa volume percentage */ | ||||
| char * | ||||
| volume() | ||||
| { | ||||
|         int mute = 0; | ||||
|         long vol = 0, max = 0, min = 0; | ||||
|          | ||||
|         snd_mixer_t *handle; | ||||
|         snd_mixer_elem_t *pcm_mixer, *mas_mixer; | ||||
|         snd_mixer_selem_id_t *vol_info, *mute_info; | ||||
|         snd_mixer_open(&handle, 0); | ||||
|         snd_mixer_attach(handle, soundcard); | ||||
|         snd_mixer_selem_register(handle, NULL, NULL); | ||||
|         snd_mixer_load(handle); | ||||
|         snd_mixer_selem_id_malloc(&vol_info); | ||||
|         snd_mixer_selem_id_malloc(&mute_info); | ||||
|         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); | ||||
|         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) | ||||
|                 snd_mixer_selem_id_free(vol_info); | ||||
|         if (mute_info) | ||||
|                 snd_mixer_selem_id_free(mute_info); | ||||
|         if (handle) | ||||
|                 snd_mixer_close(handle); | ||||
|          | ||||
|         if (!mute) | ||||
|             return "mute"; | ||||
|         else | ||||
|             return smprintf("%d%%", (vol * 100) / max); | ||||
| } | ||||
| 
 | ||||
| /* cpu temperature */ | ||||
| char * | ||||
| cpu_temperature() | ||||
| { | ||||
|     int temperature; | ||||
|     FILE *fp; | ||||
| 
 | ||||
|     /* open temperature file */ | ||||
|     if (!(fp = fopen(tempfile, "r"))) { | ||||
|         fprintf(stderr, "Could not open temperature file.\n"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     /* extract temperature, close file */ | ||||
|     fscanf(fp, "%d", &temperature); | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     /* return temperature in degrees */ | ||||
|     return smprintf("%d°C", temperature / 1000); | ||||
| } | ||||
| 
 | ||||
| /* wifi percentage */ | ||||
| char * | ||||
| wifi_signal() | ||||
| { | ||||
|     int bufsize = 255; | ||||
| 	int strength; | ||||
| 	char buf[bufsize]; | ||||
| 	char *datastart; | ||||
|     char path_start[16] = "/sys/class/net/"; | ||||
|     char path_end[11] = "/operstate"; | ||||
|     char path[32]; | ||||
| 	FILE *fp; | ||||
| 
 | ||||
|     /* generate the path name */ | ||||
|     strcat(path, path_start); | ||||
|     strcat(path, wificard); | ||||
|     strcat(path, path_end); | ||||
| 
 | ||||
|     /* open wifi file, extract status, close file */ | ||||
|     if(!(fp = fopen(path, "r"))) { | ||||
|         fprintf(stderr, "Error opening wifi operstate file."); | ||||
|         exit(1); | ||||
|     } | ||||
|     char status[5]; | ||||
|     fgets(status, 5, fp); | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     /* check if interface down */ | ||||
|     if(strcmp(status, "up\n") != 0){ | ||||
|         return "n/a"; | ||||
|     } | ||||
| 
 | ||||
|     /* open wifi file */ | ||||
|     if (!(fp = fopen("/proc/net/wireless", "r"))) { | ||||
|         fprintf(stderr, "Error opening wireless file."); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     /* extract the signal strength and close the file */ | ||||
| 	fgets(buf, bufsize, fp); | ||||
| 	fgets(buf, bufsize, fp); | ||||
| 	fgets(buf, bufsize, fp); | ||||
| 	if ((datastart = strstr(buf, "wlp3s0:")) != NULL) { | ||||
| 		datastart = strstr(buf, ":"); | ||||
| 		sscanf(datastart + 1, " %*d   %d  %*d  %*d        %*d      %*d      %*d      %*d      %*d        %*d", | ||||
| 	           &strength); | ||||
| 	} | ||||
| 	fclose(fp); | ||||
| 
 | ||||
|     /* return strength in percent */ | ||||
|     return smprintf("%d%%", strength); | ||||
| } | ||||
| 
 | ||||
| /* battery percentage */ | ||||
| char * | ||||
| battery() | ||||
| { | ||||
| 	int batt_now; | ||||
|     int batt_full; | ||||
|     int batt_perc; | ||||
| 	FILE *fp; | ||||
| 
 | ||||
|     /* open battery now file, extract and close */ | ||||
| 	if (!(fp = fopen(batterynowfile, "r"))) { | ||||
|         fprintf(stderr, "Error opening battery file."); | ||||
|         exit(1); | ||||
|     } | ||||
| 	fscanf(fp, "%i", &batt_now); | ||||
| 	fclose(fp); | ||||
| 	 | ||||
|     /* extract battery full file, extract and close */ | ||||
| 	if (!(fp = fopen(batteryfullfile, "r"))) { | ||||
|         fprintf(stderr, "Error opening battery file."); | ||||
|         exit(1); | ||||
|     } | ||||
| 	fscanf(fp, "%i", &batt_full); | ||||
| 	fclose(fp); | ||||
| 
 | ||||
|     /* calculate percent */ | ||||
| 	batt_perc = batt_now / (batt_full / 100); | ||||
| 
 | ||||
|     /* return percent */ | ||||
| 	return smprintf("%d%%", batt_perc); | ||||
| } | ||||
| 
 | ||||
| /* date and time */ | ||||
| char * | ||||
| datetime() | ||||
| { | ||||
| 	time_t tm; | ||||
| 	size_t bufsize = 19; | ||||
| 	char *buf = malloc(bufsize); | ||||
| 
 | ||||
|     /* get time in format */ | ||||
| 	time(&tm); | ||||
| 	if(!strftime(buf, bufsize, timeformat, localtime(&tm))) { | ||||
| 		fprintf(stderr, "Strftime failed.\n"); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 
 | ||||
|     /* return time */ | ||||
| 	return buf; | ||||
| } | ||||
| 
 | ||||
| /* cpu percentage */ | ||||
| char * | ||||
| cpu_usage() | ||||
| { | ||||
|     FILE *fp; | ||||
|     long double a[4], b[4], cpu_perc; | ||||
| 
 | ||||
|     /* open stat file, read and close, do same after 1 second */ | ||||
| 	if (!(fp = fopen("/proc/stat","r"))) { | ||||
|         fprintf(stderr, "Error opening stat file."); | ||||
|         exit(1); | ||||
|     } | ||||
|     fscanf(fp,"%*s %Lf %Lf %Lf %Lf",&a[0],&a[1],&a[2],&a[3]); | ||||
|     fclose(fp); | ||||
|     sleep(1); | ||||
| 	if (!(fp = fopen("/proc/stat","r"))) { | ||||
|         fprintf(stderr, "Error opening stat file."); | ||||
|         exit(1); | ||||
|     } | ||||
|     fscanf(fp,"%*s %Lf %Lf %Lf %Lf",&b[0],&b[1],&b[2],&b[3]); | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     /* calculate average in 1 second */ | ||||
|     cpu_perc = 100 * ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3])); | ||||
| 
 | ||||
|     /* return avg cpu percentage */ | ||||
|     return smprintf("%d%%", (int)cpu_perc); | ||||
| } | ||||
| 
 | ||||
| /* ram percentage */ | ||||
| char * | ||||
| ram_usage() | ||||
| { | ||||
|     FILE *fp; | ||||
|     long total, free, available; | ||||
|     int ram_perc; | ||||
| 
 | ||||
|     /* read meminfo file, extract and close */ | ||||
| 	if (!(fp = fopen("/proc/meminfo", "r"))) { | ||||
|         fprintf(stderr, "Error opening meminfo file."); | ||||
|         exit(1); | ||||
|     } | ||||
|     fscanf(fp, "MemTotal: %ld kB\n", &total); | ||||
|     fscanf(fp, "MemFree: %ld kB\n", &free); | ||||
|     fscanf(fp, "MemAvailable: %ld kB\n", &available); | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     /* calculate percentage */ | ||||
|     ram_perc = 100 * (total - available) / total; | ||||
| 
 | ||||
|     /* return in percent */ | ||||
|     return smprintf("%d%%",ram_perc); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| main() | ||||
| { | ||||
|     char status[1024]; | ||||
| 
 | ||||
|     /* open display */ | ||||
|     if (( dpy = XOpenDisplay(0x0)) == NULL ) { | ||||
|         fprintf(stderr, "Cannot open display!\n"); | ||||
|         exit(1); | ||||
|     } | ||||
| 
 | ||||
|     /* return status every second */	 | ||||
| 	for (;;) { | ||||
| 		sprintf(status, FORMATSTRING, ARGUMENTS); | ||||
| 		setstatus(status); | ||||
| 	} | ||||
| 
 | ||||
|     /* close display */ | ||||
|     XCloseDisplay(dpy); | ||||
| 
 | ||||
|     /* exit successfully */ | ||||
| 	return 0; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user