Updated tomd and tomc to do solid communication over sockets.
[tlb/tomd.git] / src / common / guile_helpers.c
index 0984fdd..1cb6b2e 100644 (file)
 
 #include <libguile.h>
 #include <pwd.h>
+#include <fcntl.h>
+#include <string.h>
 
+#include "../../include/job.h"
 #include "../../include/macros.h"
+#include "../../include/scm_interface.h"
 
 #define MANIFEST_LOC "/.config/tomd/init/manifest.scm"
 
-static void load_job(void)
-{
+#define MAX_JOBS 10
+
+static struct job jobs[MAX_JOBS];
+
+static struct job load_job(SCM job_list, int index)
+{  
+  struct job ret = { NULL };
+  SCM scm_cur_job = SCM_ARR(job_list, index);
+
+  if(scm_is_false(job_predicate(scm_cur_job))){
+    tomd_p("job %d wasn't a real job type.", index);
+    return ret;
+  }
+
+  SCM scm_name = get_name(scm_cur_job);
+  SCM scm_cmd = get_cmd(scm_cur_job);
+  SCM scm_args = get_args(scm_cur_job);
+
+  /* TODO > Handle these. */
+  /* planned is to be able to run at different points, and at */
+  /* the request of a user. for testing we do things all at */
+  /* boot up. */
+  SCM scm_start_trigger = get_start_trigger(scm_cur_job);
+  SCM scm_end_trigger = get_end_trigger(scm_cur_job);
+
+  char *job_name = scm_to_locale_string(scm_name);
+  char *job_cmd = scm_to_locale_string(scm_cmd);
+  char *real_args[10];
+  int jlen = scm_to_int(scm_length(scm_args));
+  for(int j = 0;
+      j < jlen;
+      j++){
+    real_args[j] =
+      scm_to_locale_string(SCM_ARR(scm_args, j));
+  }
+
+  ret.name = job_name;
+  ret.cmd = job_cmd;
   
+  for(int j = 1;
+      j <= jlen;
+      j++){
+    ret.args[j] = real_args[j - 1];
+  }
+  ret.args[jlen + 1] = NULL;
+  ret.args[0] = ret.cmd;
+
+  return ret;
 }
 
 static void *load_manifest(void *args)
@@ -36,11 +85,8 @@ static void *load_manifest(void *args)
   }
   manifest_loc = (char *)args;
 
-  /* tomd_p("load_manifest called with arg '%s'", args); */
-
   scm_c_primitive_load(args);
 
-  /* now that we have the file in memory, lets grab the value of job-list */
   SCM scm_job_list =
     scm_c_public_ref("tomd manifest", "job-list");
 
@@ -54,77 +100,16 @@ static void *load_manifest(void *args)
     return NULL;
   }
 
-  SCM scm_job_predicate =
-    scm_c_public_ref("tomd job", "c-check-job");
-
-  SCM scm_job_cmd =
-    scm_c_public_ref("tomd job", "c-job-cmd");
-
-  SCM scm_job_args =
-    scm_c_public_ref("tomd job", "c-job-args");
-
-  SCM scm_job_start_trigger =
-    scm_c_public_ref("tomd job", "c-job-start-trigger");
-
-  SCM scm_job_end_trigger =
-    scm_c_public_ref("tomd job", "c-job-end-trigger");
-
-  
-  SCM scm_len = scm_length(scm_job_list);
-  int len = scm_to_int(scm_len);
   int i;
+  int len = SCM_LIST_LEN(scm_job_list);
+  tomd_p("len=%d, max=%d", len, MAX_JOBS);
   for(i = 0;
-      i < len;
+      i < len && i < MAX_JOBS;
       i++){
-    SCM scm_i =
-      scm_from_signed_integer(i);
-    SCM scm_cur_job =
-      scm_list_ref(scm_job_list, scm_i);
-
-    /* scm_cur_job should be a job */    
-    if(scm_is_false(scm_call(scm_job_predicate, scm_cur_job, SCM_UNDEFINED))){
-      tomd_p("job %d wasn't a real job type.", i);
-      continue;
-    }
-
-    SCM scm_cmd =
-      scm_call(scm_job_cmd,
-               scm_cur_job,
-               SCM_UNDEFINED);
-    SCM scm_args =
-      scm_call(scm_job_args,
-               scm_cur_job,
-               SCM_UNDEFINED);
-    SCM scm_start_trigger =
-      scm_call(scm_job_start_trigger,
-               scm_cur_job,
-               SCM_UNDEFINED);
-    SCM scm_end_trigger =
-      scm_call(scm_job_end_trigger,
-               scm_cur_job,
-               SCM_UNDEFINED);
-
-    char *job_cmd =
-      scm_to_locale_string(scm_cmd);
-
-    char *real_args[10];
-    int jlen = scm_to_int(scm_length(scm_args));
-    for(int j = 0;
-        j < jlen;
-        j++){
-      real_args[j] =
-        scm_to_locale_string(scm_list_ref(scm_args, scm_from_int(j)));
-    }
-
-    tomd_p("JOB <%d>:", i);
-    tomd_p("     cmd:'%s'", job_cmd);
-    for(int j = 0;
-        j < jlen;
-        j++){
-      tomd_p(" arg [%d]:'%s'", j, real_args[j]);
-    }
+    jobs[i] = load_job(scm_job_list, i);
   }
   tomd_p("looked at %d jobs.", i);
+  jobs[i].cmd = NULL;
 }
 
 static char *lookup_user_folder(void)
@@ -132,20 +117,12 @@ static char *lookup_user_folder(void)
   uid_t user = getuid();
   struct passwd *userpasswd =
     getpwuid(user);
-  /* tomd_p("pw_name='%s'", userpasswd->pw_name); */
-  /* tomd_p("pw_passwd='%s'", userpasswd->pw_passwd); */
-  /* tomd_p("pw_uid='%d'", userpasswd->pw_uid); */
-  /* tomd_p("pw_gid='%d'", userpasswd->pw_gid); */
-  /* tomd_p("pw_gecos='%s'", userpasswd->pw_gecos); */
-  /* tomd_p("pw_dir='%s'", userpasswd->pw_dir); */
-  /* tomd_p("pw_shell='%s'", userpasswd->pw_shell); */
 
   /* take the manifest location and sub ~ for pw_dir */
   char *buffer = (char *)malloc(sizeof(char) * 300);
   strcpy(buffer, userpasswd->pw_dir);
   int len = strlen(userpasswd->pw_dir);
   strcpy(buffer + len, MANIFEST_LOC);
-  /* tomd_p("full config path:'%s'", buffer); */
   return buffer;
 }
 
@@ -154,11 +131,86 @@ void load_jobs(void)
   char *manifest = lookup_user_folder();
   tomd_p("Loading jobs from '%s'", manifest);
   
-  /* get into the manifest.scm file */
   void *res =
     scm_with_guile(load_manifest,
                    (void *) manifest);
-  /* check if the variable 'job-list' is defined */
 
   tomd_p("Finished loading.");
+
+  int i = 0;
+  while(1){
+    if(i >= MAX_JOBS ||
+       jobs[i].cmd == NULL) {
+      break;
+    }
+    tomd_p("JOB <%d>:", i);
+    tomd_p("     cmd:'%s'", jobs[i].cmd);
+    int j = 1;
+    while(1){
+      if(i >= 10 ||
+         jobs[i].args[j] == NULL){
+        break;
+      }
+      tomd_p(" arg [%d]:'%s'", j, jobs[i].args[j]);
+      j++;
+    }
+    i++;
+  }
+}
+
+#define LOG_DIR "/var/log/tomd/"
+
+void run_job(int index)
+{
+  struct job *job = &jobs[index];
+
+  pid_t pid = fork();
+  if(pid == 0){                 /* child */
+    /* redirect to a file */
+    char buf[100];
+    strcpy(buf, LOG_DIR);
+    strcpy(buf + strlen(LOG_DIR), job->name);
+    tomd_p("redirecting stdout to %s.", buf);
+    if(unlink(buf) != 0){
+      perror("file couldn't be removed.");
+    }
+
+    int fd = open(buf, O_WRONLY | O_CREAT, 0644);
+    if(fd < 0){
+      perror("[tomd] couldn't open file.");
+      return;
+    }
+
+    dup2(fd, STDOUT_FILENO);
+    dup2(fd, STDERR_FILENO);
+    close(fd);
+    execvp(job->cmd, job->args);
+    tomd_p("execvp for '%s' failed", job->cmd);
+    perror("");
+    exit(EXIT_FAILURE);
+  }else{                        /* parent */
+    tomd_p("forked [%d] to run '%s'", pid, job->cmd);
+    job->pid = pid;
+  }
+}
+
+void lookup_job(char *my_job_name)
+{
+  
+}
+
+void run_jobs(void)
+{
+  int i;
+  for(i = 0;
+      i < MAX_JOBS;
+      i++){
+    if(jobs[i].cmd == NULL){
+      tomd_p("out of jobs");
+      return;
+    }else{
+      tomd_p("running job [%d] '%s'", i, jobs[i].cmd);
+      run_job(i);
+    }
+  }        
 }