summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@iohq.net>2015-06-27 00:29:14 -0600
committerAaron Ball <nullspoon@iohq.net>2015-06-27 00:29:14 -0600
commit82e4ad2efd34cffaed26e620fcde2ca6090a648a (patch)
treea35d83a86c3beacbc974524637e8a628b74f1b94
downloadterminus-82e4ad2efd34cffaed26e620fcde2ca6090a648a.tar.gz
terminus-82e4ad2efd34cffaed26e620fcde2ca6090a648a.tar.xz
Initial commit of terminus source code
This version is fully working, though it is still lacking in some functionality.
-rw-r--r--Makefile7
-rw-r--r--src/main.c200
2 files changed, 207 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..cdae433
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+out = terminus
+
+all:
+ cc src/main.c -lm -o $(out)
+
+debug:
+ make all dbg="-g"
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..c36ac6e
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,200 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+
+//
+// Converts the given day count to seconds (multiplies by the number of seconds
+// in a day, 86400).
+//
+// @param days Day count to convert to seconds
+//
+// @return long Number of total seconds in the given day duration
+//
+long days_to_seconds(int days) {
+ return days * 86400;
+}
+
+
+//
+// Converts the given "string integer" to a long datatype. This is useful for
+// programs that take command line arguments from the user and they need to
+// treats those arguments like actual numbers.
+//
+// @param intstr Integer string
+//
+// @return long The integer represented by the given string
+//
+long ctoi(char* intstr) {
+ // TODO: This doesn't work yet
+ int i = 0;
+ long out = 0;
+
+ while(intstr[i] != '\0') {
+ //printf("%d\n", intstr[i] - 48);
+ if(intstr[i] == '0') {
+ out += pow(10,i);
+ } else {
+ out += (intstr[i] - 48) + pow(10,i);
+ }
+ i++;
+ }
+ return out;
+}
+
+
+//
+//
+//
+int get_user_home(char* out) {
+ if(getenv("HOME") != NULL) {
+ strcpy(out, getenv("HOME"));
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+
+//
+// Writes the current timestamp to the specified lastlogin file
+//
+// @param path Path to the lastlogin file
+//
+// @return int Status of the write operation
+//
+int write_lastlogin(char* path) {
+ FILE* f = fopen(path, "w+");
+
+ // Exit if file cannot be opened for writing
+ if(f == NULL) { return 1; }
+
+ // Write the current time
+ fprintf(f, "%d", time(NULL));
+
+ fclose(f);
+ return 0;
+}
+
+
+//
+// Gets the time_t value contained in the specified lastlogin file.
+//
+// @param lastlogin_path Path to the lastlogin file to be read
+// @param lastlogin Output time_t variable
+//
+// @return int Status of reading the lastlogin file
+//
+int get_lastlogin(char* lastlogin_path, time_t* lastlogin) {
+ // File pointer to lastlogin file (used for reading and writing)
+ FILE* lastlogin_file;
+ // String contents of the lastlogin file
+ char lastlogin_str[32];
+
+ // Attempt read lastlogin file contents
+ lastlogin_file = fopen(lastlogin_path, "r");
+
+ if(lastlogin_file == NULL) {
+ return 1;
+ } else {
+ // Read the lastlogin file and set its value to lastlogin
+ fgets(lastlogin_str, 32, lastlogin_file);
+ *lastlogin = atoi(lastlogin_str);
+ fclose(lastlogin_file);
+ }
+ return 0;
+}
+
+
+//
+// Executes the specified command, printing the output.
+// Note that this does read the calling shell's environmental variables, and so
+// absolute paths are not necessary if the command targets an executable in
+// PATH.
+//
+// @param cmd Command to be executed and output to be printed
+//
+// @return int Execution status of the command
+// Note that if the command fails execution at start, -1 is
+// returned.
+//
+int exec_cmd(char* cmd) {
+ FILE* p = popen(cmd, "r");
+ if(p == NULL) { return -1; }
+
+ // Buffer for each line
+ char line[256];
+ // For each line, print the output
+ while (fgets(line, sizeof(line)-1, p) != NULL) {
+ printf("%s", line);
+ }
+
+ return pclose(p);
+}
+
+
+//
+// Ye olde main function
+//
+int main(int argc, char* argv[]) {
+ char home[128];
+ int days;
+ char* cmd;
+ // Expected path to lastlogin file
+ char lastlogin_path[256];
+ // Time-related variables
+ time_t now;
+ time_t threshold;
+ time_t lastlogin;
+
+ if(argc < 3) {
+ printf(
+ "Please specify a timeout threshold (in days) as well as a command\n"
+ "or commands to be run if the threshold is exceeded.\n\n"
+ "Example:\n"
+ " terminus 5 '<command to execute>'\n\n"
+ "This example will execute the given command if the user has not\n"
+ "logged in in the last 5 days.\n\n"
+ );
+ return 1;
+ }
+
+ // Get program arguments
+ days = atoi(argv[1]);
+ cmd = argv[2];
+
+ // Compose path to lastlogin file
+ get_user_home(home);
+ strcpy(lastlogin_path, home);
+ strcat(lastlogin_path, "/.lastlogin");
+
+ // Set time-related values
+ now = time(NULL);
+ threshold = days_to_seconds(days);
+ if(get_lastlogin(lastlogin_path, &lastlogin) == 1) {
+ // Create lastlogin file since it doesn't exist
+ printf("Lastlogin file could not be read. Writing\n");
+ if(write_lastlogin(lastlogin_path) == 1) {
+ printf("Failure writing lastlogin\n");
+ return 1;
+ }
+ // Go ahead and set lastlogin time, since writing it means we're using
+ // "now".
+ lastlogin = time(NULL);
+ }
+
+ // Determine if I'm dead
+ if((now - lastlogin) > threshold) {
+ printf("You're dead!\n");
+ exec_cmd(cmd);
+ } else {
+ if(write_lastlogin(lastlogin_path) == 1) {
+ printf("Failure writing lastlogin\n");
+ return 1;
+ }
+ printf("You're not dead!\n");
+ }
+
+ return 0;
+}

Generated by cgit