/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "components.h"
#include "config.h"
int
run(const char *program)
{
pid_t pid = fork();
if (pid == 0)
{
// child process, we don't want to ignore signals
signal(SIGCHLD, SIG_DFL);
/*
* we don't want std{out,err} to be associated with the terminal,
* but we also don't want to close it to avoid the file descriptors
* being re-used potentially leading to problems, so reopen them to /dev/null
*/
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
char *args[ARG_LIMIT];
char *buff = malloc(BUFF_SIZE);
if (buff == NULL)
{
perror("malloc");
return -1;
}
/*
* the program we're calling might have arguments,
* so we tokenise the string and add each part to an array
* that we will use in execvp
*/
strncpy(buff, program, BUFF_SIZE-1);
char *t = strtok(buff, " ");
int z = 0;
while (t != NULL && z < ARG_LIMIT-1) // save a position for NULL
{
args[z] = t;
t = strtok(NULL, " ");
z++;
}
args[z] = (char *)0;
execvp(args[0], args);
_exit(1);
}
else if (pid == -1)
{
perror("fork");
return -1;
}
return 1;
}
int
dectobin(int dec)
{
if (dec == 0) return 0;
if (dec == 1) return 1;
return (dec % 2) + 10 * dectobin(dec / 2);
}
char *eatnonascii(char *food, size_t len)
{
if (len <= 0) return food;
while (food[len-1] < 32 || food[len-1] > 126)
{
food[--len] = '\0';
}
return food;
}
void
gettime(int *store)
{
time_t t = time(NULL);
struct tm *tm = localtime(&t);
store[0] = tm->tm_hour;
store[1] = tm->tm_min;
}
int
converthour(int hour)
{
return (hour - 12 < 0) ? 0 : hour - 12;
}
char *currenttime(char *store, size_t size, int flag)
{
int time[2];
char meridiem[3];
gettime(time);
if (flag & SHOWMERIDIEM)
{
meridiem[1] = 'M';
meridiem[2] = '\0';
if (time[0] < 12)
meridiem[0] = 'A';
else
meridiem[0] = 'P';
}
if (flag & NORMALTIME)
{
if (time[0] == 0)
time[0] = 12;
else if (time[0] > 12)
time[0] = converthour(time[0]);
}
if (flag & BINARYTIME)
{
snprintf(store, size, "%05d:%05d%s ", dectobin(time[0]),
dectobin(time[1]),
meridiem);
}
/* military time is the default, so we need not do anything */
else
{
snprintf(store, size, "%02d:%02d%s ", time[0], time[1],
meridiem);
}
return store;
}
int has_low_batt = 0;
char *battery(char *store, size_t size, int flag)
{
FILE *capacity;
char cap[4];
capacity = fopen("/sys/class/power_supply/BAT0/capacity", "r");
if (!capacity)
{
fprintf(stderr, "cannot read battery percent\n");
return "error ";
}
fread(cap, 1, 4, capacity);
fclose(capacity);
int percent = atoi(cap);
if (percent != 100)
percent++;
if ( !has_low_batt && percent < LOWBATT)
{
run(LOWBATTERY);
has_low_batt = 1;
}
else if (has_low_batt && percent > LOWBATT)
{
has_low_batt = 0;
}
snprintf(store, size, "%d%% ", percent);
return store;
}
char *charging(char *store, size_t size, int flag)
{
FILE *state;
char cap[15];
state = fopen("/sys/class/power_supply/BAT0/status", "r");
if (!state)
{
fprintf(stderr, "cannot read battery state\n");
return "error ";
}
fgets(cap, 15, state);
eatnonascii(cap, strlen(cap));
/* my thinkpad says "Unknown" when charged ... */
if (strcmp(cap, "Unknown") == 0) strcpy(cap, "F");
if (strcmp(cap, "Charged") == 0) strcpy(cap, "F");
if (strcmp(cap, "Charging") == 0) strcpy(cap, "C");
if (strcmp(cap, "Discharging") == 0) strcpy(cap, "D");
fclose(state);
snprintf(store, size, "%s ", cap);
return store;
}
char *volume(char *store, size_t size, int flag)
{
// TODO
return store;
}
char *cputemp(char *store, size_t size, int flag)
{
FILE *cpufile;
char temp[15];
int t;
cpufile = fopen(TEMPFILE, "r");
if (!cpufile)
{
fprintf(stderr, "cannot read CPU temp\n");
return "error ";
}
fgets(temp, 4, cpufile);
eatnonascii(temp, strlen(temp));
if (temp[2] == '0')
temp[2] = '\0';
fclose(cpufile);
t = atoi(temp);
if (flag & FARENHEIT)
{
t = (t*9)/5+32;
snprintf(store, size, "%d°F ", t);
}
else
snprintf(store, size, "%d°C ", t);
return store;
}