2022-04-18 09:27:05 -05:00
# define _POSIX_C_SOURCE 200809L
2019-03-24 16:31:05 -06:00
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>
2021-10-28 17:27:05 +02:00
# include <fcntl.h>
# include <errno.h>
2019-03-24 16:31:05 -06:00
# include <signal.h>
2020-08-12 10:24:42 -06:00
# ifdef __OpenBSD__
# define SIGPLUS SIGUSR1+1
# define SIGMINUS SIGUSR1-1
# else
# define SIGPLUS SIGRTMIN
# define SIGMINUS SIGRTMIN
# endif
2019-03-24 16:31:05 -06:00
# define LENGTH(X) (sizeof(X) / sizeof (X[0]))
2019-11-30 14:43:33 -07:00
# define CMDLENGTH 50
2020-08-14 12:36:38 -06:00
# define MIN( a, b ) ( ( a < b) ? a : b )
2020-05-28 10:39:07 +02:00
# define STATUSLENGTH (LENGTH(blocks) * CMDLENGTH + 1)
2019-03-24 21:51:40 -06:00
2019-03-24 16:31:05 -06:00
typedef struct {
2019-03-29 21:10:46 -06:00
char * icon ;
2019-03-24 16:31:05 -06:00
char * command ;
unsigned int interval ;
unsigned int signal ;
} Block ;
2020-08-12 10:24:42 -06:00
# ifndef __OpenBSD__
2020-04-01 11:45:00 -04:00
void dummysighandler ( int num ) ;
2020-08-12 10:24:42 -06:00
# endif
2019-03-24 16:31:05 -06:00
void sighandler ( int num ) ;
2019-03-24 21:51:40 -06:00
void getcmds ( int time ) ;
2020-08-14 12:36:38 -06:00
void getsigcmds ( unsigned int signal ) ;
2024-01-24 23:02:21 +01:00
void setupsignals ( void ) ;
2019-12-16 14:35:29 -07:00
void sighandler ( int signum ) ;
2019-11-13 13:58:20 -07:00
int getstatus ( char * str , char * last ) ;
2024-01-24 23:02:21 +01:00
void statusloop ( void ) ;
void termhandler ( int sig ) ;
void pstdout ( void ) ;
void psomebar ( void ) ;
static void ( * writestatus ) ( void ) = psomebar ;
2019-03-24 16:31:05 -06:00
# include "blocks.h"
2019-11-30 14:43:33 -07:00
static char statusbar [ LENGTH ( blocks ) ] [ CMDLENGTH ] = { 0 } ;
2020-05-28 10:39:07 +02:00
static char statusstr [ 2 ] [ STATUSLENGTH ] ;
2019-11-13 13:58:20 -07:00
static int statusContinue = 1 ;
2021-10-28 17:27:05 +02:00
static char somebarPath [ 128 ] ;
static int somebarFd = - 1 ;
2019-03-24 16:31:05 -06:00
2019-03-24 21:51:40 -06:00
//opens process *cmd and stores output in *output
2019-03-29 21:10:46 -06:00
void getcmd ( const Block * block , char * output )
2019-03-24 16:31:05 -06:00
{
2024-01-24 23:02:21 +01:00
FILE * cmdf ;
int i ;
2019-03-29 21:10:46 -06:00
strcpy ( output , block - > icon ) ;
2024-01-24 23:02:21 +01:00
cmdf = popen ( block - > command , " r " ) ;
2019-03-24 16:31:05 -06:00
if ( ! cmdf )
return ;
2024-01-24 23:02:21 +01:00
i = strlen ( block - > icon ) ;
if ( fgets ( output + i , CMDLENGTH - i - delimLen , cmdf ) ! = ( output + i ) ) {
exit ( 1 ) ;
}
2019-11-30 14:43:33 -07:00
i = strlen ( output ) ;
2020-11-18 12:09:15 +01:00
if ( i = = 0 ) {
//return if block and command output are both empty
pclose ( cmdf ) ;
2020-08-29 11:58:28 -06:00
return ;
2020-11-18 12:09:15 +01:00
}
2020-08-27 04:47:07 +00:00
if ( delim [ 0 ] ! = ' \0 ' ) {
//only chop off newline if one is present at the end
i = output [ i - 1 ] = = ' \n ' ? i - 1 : i ;
strncpy ( output + i , delim , delimLen ) ;
}
2020-08-14 12:36:38 -06:00
else
output [ i + + ] = ' \0 ' ;
2019-03-24 16:31:05 -06:00
pclose ( cmdf ) ;
}
void getcmds ( int time )
{
const Block * current ;
2020-09-09 13:10:49 -06:00
for ( unsigned int i = 0 ; i < LENGTH ( blocks ) ; i + + ) {
2019-03-24 16:31:05 -06:00
current = blocks + i ;
if ( ( current - > interval ! = 0 & & time % current - > interval = = 0 ) | | time = = - 1 )
2019-03-29 21:10:46 -06:00
getcmd ( current , statusbar [ i ] ) ;
2019-03-24 16:31:05 -06:00
}
}
2020-08-14 12:36:38 -06:00
void getsigcmds ( unsigned int signal )
2019-03-24 16:31:05 -06:00
{
const Block * current ;
2020-09-09 13:10:49 -06:00
for ( unsigned int i = 0 ; i < LENGTH ( blocks ) ; i + + ) {
2019-03-24 16:31:05 -06:00
current = blocks + i ;
if ( current - > signal = = signal )
2019-03-29 21:10:46 -06:00
getcmd ( current , statusbar [ i ] ) ;
2019-03-24 16:31:05 -06:00
}
}
void setupsignals ( )
{
2022-12-03 19:12:30 +01:00
struct sigaction sa = { 0 } ;
2020-08-12 10:24:42 -06:00
# ifndef __OpenBSD__
2022-12-03 19:12:30 +01:00
/* initialize all real time signals with dummy handler */
sa . sa_handler = dummysighandler ;
for ( int i = SIGRTMIN ; i < = SIGRTMAX ; i + + )
sigaction ( i , & sa , NULL ) ;
2020-08-12 10:24:42 -06:00
# endif
2020-04-01 11:45:00 -04:00
2022-12-03 19:12:30 +01:00
sa . sa_handler = sighandler ;
2020-09-09 13:10:49 -06:00
for ( unsigned int i = 0 ; i < LENGTH ( blocks ) ; i + + ) {
2019-03-24 16:31:05 -06:00
if ( blocks [ i ] . signal > 0 )
2022-12-03 19:12:30 +01:00
sigaction ( SIGMINUS + blocks [ i ] . signal , & sa , NULL ) ;
2019-03-24 16:31:05 -06:00
}
}
2019-11-13 13:58:20 -07:00
int getstatus ( char * str , char * last )
2019-03-24 16:31:05 -06:00
{
2019-11-13 13:58:20 -07:00
strcpy ( last , str ) ;
2019-11-26 22:43:16 -07:00
str [ 0 ] = ' \0 ' ;
2020-08-19 10:10:43 -06:00
for ( unsigned int i = 0 ; i < LENGTH ( blocks ) ; i + + )
2019-11-26 22:43:16 -07:00
strcat ( str , statusbar [ i ] ) ;
2020-08-14 12:36:38 -06:00
str [ strlen ( str ) - strlen ( delim ) ] = ' \0 ' ;
2019-11-13 13:58:20 -07:00
return strcmp ( str , last ) ; //0 if they are the same
2019-03-24 16:31:05 -06:00
}
2021-10-28 17:27:05 +02:00
void pstdout ( )
2019-03-24 16:31:05 -06:00
{
2021-10-28 17:27:05 +02:00
if ( ! getstatus ( statusstr [ 0 ] , statusstr [ 1 ] ) ) //Only write out if text has changed.
2019-11-13 13:58:20 -07:00
return ;
2021-10-28 17:27:05 +02:00
printf ( " %s \n " , statusstr [ 0 ] ) ;
fflush ( stdout ) ;
2020-09-09 13:10:49 -06:00
}
2019-03-24 16:31:05 -06:00
2021-10-28 17:27:05 +02:00
void psomebar ( )
2019-11-26 22:43:16 -07:00
{
if ( ! getstatus ( statusstr [ 0 ] , statusstr [ 1 ] ) ) //Only write out if text has changed.
return ;
2021-10-29 20:39:29 +02:00
if ( somebarFd < 0 ) {
somebarFd = open ( somebarPath , O_WRONLY | O_CLOEXEC ) ;
if ( somebarFd < 0 & & errno = = ENOENT ) {
// assume somebar is not ready yet
sleep ( 1 ) ;
somebarFd = open ( somebarPath , O_WRONLY | O_CLOEXEC ) ;
}
if ( somebarFd < 0 ) {
perror ( " open " ) ;
return ;
}
}
2022-04-18 09:27:05 -05:00
dprintf ( somebarFd , " status %s \n " , statusstr [ 0 ] ) ;
2019-11-26 22:43:16 -07:00
}
2019-03-24 16:31:05 -06:00
2019-03-24 21:51:40 -06:00
void statusloop ( )
2019-03-24 16:31:05 -06:00
{
2024-01-24 23:02:21 +01:00
int i ;
2019-03-24 16:31:05 -06:00
setupsignals ( ) ;
2024-01-24 23:02:21 +01:00
i = 0 ;
2019-03-24 16:31:05 -06:00
getcmds ( - 1 ) ;
2020-09-09 13:10:49 -06:00
while ( 1 ) {
2020-08-19 10:10:43 -06:00
getcmds ( i + + ) ;
2019-11-26 22:43:16 -07:00
writestatus ( ) ;
2020-09-05 15:48:54 -06:00
if ( ! statusContinue )
break ;
2024-01-24 23:02:21 +01:00
sleep ( 1 ) ;
2019-03-24 16:31:05 -06:00
}
}
2020-04-01 11:45:00 -04:00
# ifndef __OpenBSD__
/* this signal handler should do nothing */
void dummysighandler ( int signum )
{
return ;
}
# endif
2019-03-24 16:31:05 -06:00
void sighandler ( int signum )
{
2020-08-12 10:24:42 -06:00
getsigcmds ( signum - SIGPLUS ) ;
2019-11-26 22:43:16 -07:00
writestatus ( ) ;
2019-03-24 16:31:05 -06:00
}
2024-01-24 23:02:21 +01:00
void termhandler ( int sig )
2019-03-24 16:31:05 -06:00
{
statusContinue = 0 ;
}
2024-01-24 23:02:21 +01:00
void sigpipehandler ( int sig )
2021-10-28 17:27:05 +02:00
{
2021-10-29 20:39:29 +02:00
close ( somebarFd ) ;
somebarFd = - 1 ;
2021-10-28 17:27:05 +02:00
}
2019-03-29 21:10:46 -06:00
int main ( int argc , char * * argv )
2019-03-24 16:31:05 -06:00
{
2020-09-09 13:10:49 -06:00
for ( int i = 0 ; i < argc ; i + + ) { //Handle command line arguments
2019-03-29 21:10:46 -06:00
if ( ! strcmp ( " -d " , argv [ i ] ) )
2020-08-14 12:36:38 -06:00
strncpy ( delim , argv [ + + i ] , delimLen ) ;
2020-08-19 10:10:43 -06:00
else if ( ! strcmp ( " -p " , argv [ i ] ) )
2019-11-26 22:43:16 -07:00
writestatus = pstdout ;
2022-04-18 09:38:07 -05:00
else if ( ! strcmp ( " -s " , argv [ i ] ) )
strcpy ( somebarPath , argv [ + + i ] ) ;
2019-03-29 21:10:46 -06:00
}
2022-04-18 09:38:07 -05:00
if ( ! strlen ( somebarPath ) ) {
strcpy ( somebarPath , getenv ( " XDG_RUNTIME_DIR " ) ) ;
strcat ( somebarPath , " /somebar-0 " ) ;
}
2020-08-16 12:21:46 +03:00
delimLen = MIN ( delimLen , strlen ( delim ) ) ;
2020-08-16 12:20:15 +03:00
delim [ delimLen + + ] = ' \0 ' ;
2019-03-24 16:31:05 -06:00
signal ( SIGTERM , termhandler ) ;
signal ( SIGINT , termhandler ) ;
2021-10-28 17:27:05 +02:00
signal ( SIGPIPE , sigpipehandler ) ;
2019-11-30 14:43:33 -07:00
statusloop ( ) ;
2020-09-09 13:10:49 -06:00
return 0 ;
2019-03-24 16:31:05 -06:00
}