summaryrefslogtreecommitdiff
path: root/src/main.c
blob: d3baeea23ad166e0a813dac33da671576e6fbd86 (plain)
    1 /**
    2  * Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
    3  *
    4  * Terminus is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * Terminus is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with terminus.  If not, see <http://www.gnu.org/licenses/>.
   16  */
   17 #include <stdio.h>
   18 #include <stdlib.h>
   19 #include <string.h>
   20 #include <time.h>
   21 
   22 
   23 /**
   24  * Converts the given day count to seconds (multiplies by the number of seconds
   25  * in a day, 86400).
   26  *
   27  * @param days Day count to convert to seconds
   28  *
   29  * @return long Number of total seconds in the given day duration
   30  */
   31 long days_to_seconds(int days) {
   32   return days * 86400;
   33 }
   34 
   35 
   36 /**
   37  * TODO
   38  */
   39 int get_user_home(char* out) {
   40   if(getenv("HOME") != NULL) {
   41     strcpy(out, getenv("HOME"));
   42     return 0;
   43   } else {
   44     return 1;
   45   }
   46 }
   47 
   48 
   49 /**
   50  * Writes the current timestamp to the specified lastlogin file
   51  * 
   52  * @param path Path to the lastlogin file
   53  * 
   54  * @return int Status of the write operation
   55  */
   56 int write_lastlogin(char* path) {
   57   FILE* f = fopen(path, "w+");
   58 
   59   // Exit if file cannot be opened for writing
   60   if(f == NULL) { return 1; }
   61 
   62   // Write the current time
   63   fprintf(f, "%d", time(NULL));
   64 
   65   fclose(f);
   66   return 0;
   67 }
   68 
   69 
   70 /**
   71  * Gets the time_t value contained in the specified lastlogin file.
   72  *
   73  * @param lastlogin_path Path to the lastlogin file to be read
   74  * @param lastlogin Output time_t variable
   75  *
   76  * @return int Status of reading the lastlogin file
   77  */
   78 int get_lastlogin(char* lastlogin_path, time_t* lastlogin) {
   79   // File pointer to lastlogin file (used for reading and writing)
   80   FILE* lastlogin_file;
   81   // String contents of the lastlogin file
   82   char lastlogin_str[32];
   83 
   84   // Attempt read lastlogin file contents
   85   lastlogin_file = fopen(lastlogin_path, "r");
   86   
   87   if(lastlogin_file == NULL) {
   88     return 1;
   89   } else {
   90     // Read the lastlogin file and set its value to lastlogin
   91     fgets(lastlogin_str, 32, lastlogin_file);
   92     *lastlogin = atoi(lastlogin_str);
   93     fclose(lastlogin_file);
   94   }
   95   return 0;
   96 }
   97 
   98 
   99 /**
  100  * Executes the specified command, printing the output.
  101  * Note that this does read the calling shell's environmental variables, and so
  102  * absolute paths are not necessary if the command targets an executable in
  103  * PATH.
  104  * 
  105  * @param cmd Command to be executed and output to be printed
  106  * 
  107  * @return int Execution status of the command
  108  *             Note that if the command fails execution at start, -1 is
  109  *             returned.
  110  */
  111 int exec_cmd(char* cmd) {
  112   FILE* p = popen(cmd, "r");
  113   if(p == NULL) { return -1; }
  114 
  115   // Buffer for each line
  116   char line[256];
  117   // For each line, print the output
  118   while (fgets(line, sizeof(line)-1, p) != NULL) {
  119     printf("%s", line);
  120   }
  121 
  122   return pclose(p);
  123 }
  124 
  125 
  126 /**
  127  * Ye olde main function
  128  */
  129 int main(int argc, char* argv[]) {
  130   char home[128];
  131   int days;
  132   char* cmd;
  133   // Expected path to lastlogin file
  134   char lastlogin_path[256];
  135   // Time-related variables
  136   time_t now;
  137   time_t threshold;
  138   time_t lastlogin;
  139 
  140   if(argc < 3) {
  141     printf(
  142       "Please specify a timeout threshold (in days) as well as a command\n"
  143       "or commands to be run if the threshold is exceeded.\n\n"
  144       "Example:\n"
  145       "  terminus 5 '<command to execute>'\n\n"
  146       "This example will execute the given command if the user has not\n"
  147       "logged in in the last 5 days.\n\n"
  148     );
  149     return 1;
  150   }
  151 
  152   // Get program arguments
  153   days = atoi(argv[1]);
  154   cmd = argv[2];
  155 
  156   // Compose path to lastlogin file
  157   get_user_home(home);
  158   strcpy(lastlogin_path, home);
  159   strcat(lastlogin_path, "/.lastlogin");
  160 
  161   // Set time-related values
  162   now = time(NULL);
  163   threshold = days_to_seconds(days);
  164   if(get_lastlogin(lastlogin_path, &lastlogin) == 1) {
  165     // Create lastlogin file since it doesn't exist
  166     printf("Lastlogin file could not be read. Writing\n");
  167     if(write_lastlogin(lastlogin_path) == 1) {
  168       printf("Failure writing lastlogin\n");
  169       return 1;
  170     }
  171     // Go ahead and set lastlogin time, since writing it means we're using
  172     // "now".
  173     lastlogin = time(NULL);
  174   }
  175 
  176   // Determine if I'm dead
  177   if((now - lastlogin) > threshold) {
  178     printf("You're dead!\n");
  179     exec_cmd(cmd);
  180   } else {
  181     if(write_lastlogin(lastlogin_path) == 1) {
  182       printf("Failure writing lastlogin\n");
  183       return 1;
  184     }
  185     printf("You're not dead!\n");
  186   }
  187   
  188   return 0;
  189 }

Generated by cgit