Update to redirect logs to a file in /var/log/tomd
[tlb/tomd.git] / src / common / guile_helpers.c
CommitLineData
4f839c09
TB
1/* Copyright (C) 2018 Thomas Balzer */
2
3/* This file is part of tomd. */
4
5/* tomd is free software: you can redistribute it and/or modify */
6/* it under the terms of the GNU General Public License as published by */
7/* the Free Software Foundation, either version 3 of the License, or */
8/* (at your option) any later version. */
9
10/* tomd is distributed in the hope that it will be useful, */
11/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13/* GNU General Public License for more details. */
14
15/* You should have received a copy of the GNU General Public License */
16/* along with tomd. If not, see <http://www.gnu.org/licenses/>. */
17
82ff7d81
TB
18#include <libguile.h>
19#include <pwd.h>
06570394
TB
20#include <fcntl.h>
21#include <string.h>
82ff7d81 22
2599cbf7 23#include "../../include/job.h"
82ff7d81 24#include "../../include/macros.h"
3024ed65 25#include "../../include/scm_interface.h"
81643445 26
82ff7d81
TB
27#define MANIFEST_LOC "/.config/tomd/init/manifest.scm"
28
2599cbf7
TB
29#define MAX_JOBS 10
30
31static struct job jobs[MAX_JOBS];
32
33static struct job load_job(SCM job_list, int index)
34{
35 struct job ret = { NULL };
64694f43 36 SCM scm_cur_job = SCM_ARR(job_list, index);
3024ed65 37
3024ed65
TB
38 if(scm_is_false(job_predicate(scm_cur_job))){
39 tomd_p("job %d wasn't a real job type.", index);
2599cbf7 40 return ret;
3024ed65
TB
41 }
42
06570394 43 SCM scm_name = get_name(scm_cur_job);
64694f43
TB
44 SCM scm_cmd = get_cmd(scm_cur_job);
45 SCM scm_args = get_args(scm_cur_job);
3024ed65 46
64694f43
TB
47 /* TODO > Handle these. */
48 /* planned is to be able to run at different points, and at */
49 /* the request of a user. for testing we do things all at */
50 /* boot up. */
51 SCM scm_start_trigger = get_start_trigger(scm_cur_job);
52 SCM scm_end_trigger = get_end_trigger(scm_cur_job);
53
06570394 54 char *job_name = scm_to_locale_string(scm_name);
64694f43 55 char *job_cmd = scm_to_locale_string(scm_cmd);
3024ed65
TB
56 char *real_args[10];
57 int jlen = scm_to_int(scm_length(scm_args));
58 for(int j = 0;
59 j < jlen;
60 j++){
61 real_args[j] =
62 scm_to_locale_string(SCM_ARR(scm_args, j));
63 }
64
06570394 65 ret.name = job_name;
2599cbf7
TB
66 ret.cmd = job_cmd;
67
7813ae49
TB
68 for(int j = 1;
69 j <= jlen;
3024ed65 70 j++){
7813ae49 71 ret.args[j] = real_args[j - 1];
3024ed65 72 }
7813ae49
TB
73 ret.args[jlen + 1] = NULL;
74 ret.args[0] = ret.cmd;
2599cbf7
TB
75
76 return ret;
81643445
TB
77}
78
82ff7d81 79static void *load_manifest(void *args)
81643445 80{
82ff7d81 81 char *manifest_loc;
81643445 82 if(!args){
82ff7d81
TB
83 tomd_p("arg to load_manifest is NULL");
84 exit(EXIT_FAILURE);
85 }
86 manifest_loc = (char *)args;
87
82ff7d81
TB
88 scm_c_primitive_load(args);
89
82ff7d81
TB
90 SCM scm_job_list =
91 scm_c_public_ref("tomd manifest", "job-list");
92
93 if(scm_is_false(scm_job_list)){
94 tomd_p("no job-list found in manifest.scm");
95 return NULL;
96 }
97
98 if(scm_is_false(scm_list_p(scm_job_list))){
99 tomd_p("job-list found, but isn't a list.");
100 return NULL;
101 }
102
82ff7d81 103 int i;
3024ed65 104 int len = SCM_LIST_LEN(scm_job_list);
2599cbf7 105 tomd_p("len=%d, max=%d", len, MAX_JOBS);
82ff7d81 106 for(i = 0;
2599cbf7 107 i < len && i < MAX_JOBS;
82ff7d81 108 i++){
2599cbf7 109 jobs[i] = load_job(scm_job_list, i);
82ff7d81
TB
110 }
111 tomd_p("looked at %d jobs.", i);
2599cbf7 112 jobs[i].cmd = NULL;
82ff7d81
TB
113}
114
115static char *lookup_user_folder(void)
116{
117 uid_t user = getuid();
118 struct passwd *userpasswd =
119 getpwuid(user);
82ff7d81
TB
120
121 /* take the manifest location and sub ~ for pw_dir */
122 char *buffer = (char *)malloc(sizeof(char) * 300);
123 strcpy(buffer, userpasswd->pw_dir);
124 int len = strlen(userpasswd->pw_dir);
125 strcpy(buffer + len, MANIFEST_LOC);
82ff7d81 126 return buffer;
81643445
TB
127}
128
129void load_jobs(void)
130{
82ff7d81
TB
131 char *manifest = lookup_user_folder();
132 tomd_p("Loading jobs from '%s'", manifest);
133
81643445
TB
134 void *res =
135 scm_with_guile(load_manifest,
82ff7d81 136 (void *) manifest);
82ff7d81
TB
137
138 tomd_p("Finished loading.");
2599cbf7
TB
139
140 int i = 0;
141 while(1){
142 if(i >= MAX_JOBS ||
143 jobs[i].cmd == NULL) {
144 break;
145 }
146 tomd_p("JOB <%d>:", i);
147 tomd_p(" cmd:'%s'", jobs[i].cmd);
7813ae49 148 int j = 1;
2599cbf7
TB
149 while(1){
150 if(i >= 10 ||
151 jobs[i].args[j] == NULL){
152 break;
153 }
154 tomd_p(" arg [%d]:'%s'", j, jobs[i].args[j]);
155 j++;
156 }
157 i++;
158 }
81643445 159}
7813ae49 160
06570394
TB
161#define LOG_DIR "/var/log/tomd/"
162
7813ae49
TB
163void run_job(int index)
164{
165 struct job *job = &jobs[index];
166
167 pid_t pid = fork();
168 if(pid == 0){ /* child */
06570394
TB
169 /* int i = 0; */
170 /* while(1){ */
171 /* tomd_p("hallo"); */
172 /* if(job->args[i] == NULL){ */
173 /* tomd_p("arg [%d] is NULL", i); */
174 /* break; */
175 /* }else{ */
176 /* tomd_p("arg [%d] is '%s'", i, job->args[i]); */
177 /* } */
178 /* i++; */
179 /* } */
180
181 /* redirect to a file */
182 char buf[100];
183 strcpy(buf, LOG_DIR);
184 strcpy(buf + strlen(LOG_DIR), job->name);
185 tomd_p("redirecting stdout to %s.", buf);
186 if(unlink(buf) != 0){
187 perror("file couldn't be removed.");
7813ae49 188 }
06570394
TB
189
190 int fd = open(buf, O_WRONLY | O_CREAT, 0644);
191 if(fd < 0){
192 perror("[tomd] couldn't open file.");
193 return;
194 }
195
196 dup2(fd, STDOUT_FILENO);
197 dup2(fd, STDERR_FILENO);
198 close(fd);
7813ae49
TB
199 execvp(job->cmd, job->args);
200 tomd_p("execvp for '%s' failed", job->cmd);
201 perror("");
202 exit(EXIT_FAILURE);
203 }else{ /* parent */
204 tomd_p("forked [%d] to run '%s'", pid, job->cmd);
205 }
206}
207
208void run_jobs(void)
209{
210 int i;
211 for(i = 0;
212 i < MAX_JOBS;
213 i++){
214 if(jobs[i].cmd == NULL){
215 tomd_p("out of jobs");
216 return;
217 }else{
218 tomd_p("running job [%d] '%s'", i, jobs[i].cmd);
219 run_job(i);
220 }
221 }
222}