Initial commit

This commit is contained in:
Fierelier 2023-09-27 23:02:54 +02:00
commit ae5d09fbf9
7 changed files with 122 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/pm-tui

9
README.txt Normal file
View File

@ -0,0 +1,9 @@
pm-tui is a TUI (Terminal User Interface) for pm-utils. It allows non-privileged users to sleep, hibernate, reboot and shut down.
Installation:
./build
sudo ./install
It uses full paths to the executables. To change them, create/edit a file in src/platform. To change which platform to use, edit env.
env also contains some other settings related to compilation and installation.

5
compile Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(dirname "$(realpath -s "$BASH_SOURCE")")"
source "$SCRIPT_DIR/env"
"$CC" -std=gnu89 -Werror -Wall -Os -include "src/platform/$PLATFORM.h" "src/main.c" -o "$SCRIPT_DIR/$DISTRO" $CFLAGS

4
env Normal file
View File

@ -0,0 +1,4 @@
PLATFORM="${PLATFORM:=linux}"
DISTRO="${DISTRO:=pm-tui}"
CC="${CC:=gcc}"
INSTALL_DIR="${INSTALL_DIR:=/usr/local/bin}"

9
install Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(dirname "$(realpath -s "$BASH_SOURCE")")"
source "$SCRIPT_DIR/env"
mkdir -p "$INSTALL_DIR"
cp "$SCRIPT_DIR/$DISTRO" "$INSTALL_DIR"
chown root "$INSTALL_DIR/$DISTRO"
chmod 755 "$INSTALL_DIR/$DISTRO"
chmod u+s "$INSTALL_DIR/$DISTRO"

89
src/main.c Normal file
View File

@ -0,0 +1,89 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
void *emalloc(void *ptr, size_t size) {
void *m = realloc(ptr,size);
if (m == NULL) {
fprintf(stderr,"error 255: malloc failed\n");
exit(255);
}
return m;
}
char readline(char * buffer,int maxsize) {
int index = 0;
maxsize -= 1;
while (index < maxsize) {
read(STDIN_FILENO,&buffer[index],sizeof(char));
if (buffer[index] == '\n') {
buffer[index] = 0;
return 1;
}
index += 1;
}
read(STDIN_FILENO,&buffer[maxsize],sizeof(char));
if (buffer[maxsize] == '\n') {
buffer[maxsize] = 0;
return 1;
}
char endbuffer;
read(STDIN_FILENO,&endbuffer,sizeof(char));
if (endbuffer == '\n') { return 1; }
while (1) {
read(STDIN_FILENO,&endbuffer,sizeof(char));
if (endbuffer == '\n') { return 0; }
}
}
int main(int argc, char **argv) {
extern char **environ;
environ = NULL; // Clear environment to boost security
// Menu
char choice;
char valid;
while (1) {
printf("1) Suspend Hybrid\n");
printf("2) Suspend\n");
printf("3) Hibernate\n");
printf("4) Reboot\n");
printf("5) Shutdown\n");
printf("Choice: ");
fflush(stdout);
valid = readline(&choice,1);
if (valid == 0) { goto loop; }
choice -= 48; // ASCII to integer
if ((choice > 0) && (choice < 6)) {
break;
}
loop:
printf("\n");
}
char **cmd;
cmd = emalloc(NULL,1 * sizeof(char*)); // As of now, all cmds are just 1 char* long, but there might be more required somewhen.
if (choice == 1) { cmd[0] = CMD_HYBRID; }
if (choice == 2) { cmd[0] = CMD_SUSPEND; }
if (choice == 3) { cmd[0] = CMD_HIBERNATE; }
if (choice == 4) { cmd[0] = CMD_REBOOT; }
if (choice == 5) { cmd[0] = CMD_POWEROFF; }
int uid = getuid(); // User who's calling the program
int euid = geteuid(); // User who owns the program
// Run program
setuid(euid); // root
int rtn = execv(cmd[0],cmd);
setuid(uid); // unroot
if (rtn == -1) {
return 254 - errno;
}
return 0;
}

5
src/platform/linux.h Normal file
View File

@ -0,0 +1,5 @@
#define CMD_HYBRID "/usr/sbin/pm-suspend-hybrid"
#define CMD_SUSPEND "/usr/sbin/pm-suspend"
#define CMD_HIBERNATE "/usr/sbin/pm-hibernate"
#define CMD_REBOOT "/sbin/reboot"
#define CMD_POWEROFF "/sbin/poweroff"