Skip to content
API Documentation
BastionGuard™
CronTab.vala
Go to the documentation of this file.
1/*
2 * CronTab.vala
3 *
4 * Copyright 2012-2018 Tony George <teejeetech@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 *
22 */
23
24using TeeJee.Logging;
27using TeeJee.Misc;
28
29public class CronTab : GLib.Object {
30
31 public static string crontab_text = null;
32
33 public static void clear_cached_text(){
34 crontab_text = null;
35 }
36
37 public static string crontab_read_all(string user_name = ""){
38 string std_out, std_err;
39
40 var cmd = "crontab -l";
41 if (user_name.length > 0){
42 cmd += " -u %s".printf(user_name);
43 }
44
45 log_debug(cmd);
46
47 int ret_val = exec_sync(cmd, out std_out, out std_err);
48
49 if (ret_val != 0){
50 log_debug(_("Failed to read cron tab"));
51 return "";
52 }
53 else{
54 return std_out;
55 }
56 }
57
58 public static bool has_job(string entry, bool partial_match, bool use_cached_text){
59
60 // read crontab file
61 string tab = "";
62 if (use_cached_text && (crontab_text != null)){
63 tab = crontab_text;
64 }
65 else{
67 tab = crontab_text;
68 }
69
70 var lines = new Gee.ArrayList<string>();
71 foreach(string line in tab.split("\n")){
72 lines.add(line);
73 }
74
75 // check if entry exists
76 foreach(string line in lines){
77 if (line == entry){
78 return true; // return
79 }
80 else if (partial_match && line.contains(entry)){
81 return true; // return
82 }
83 }
84
85 return false;
86 }
87
88 public static bool add_job(string entry, bool use_cached_text){
89
90 // read crontab file
91 string tab = "";
92 if (use_cached_text && (crontab_text != null)){
93 tab = crontab_text;
94 }
95 else{
97 tab = crontab_text;
98 }
99
100 var lines = new Gee.ArrayList<string>();
101 foreach(string line in tab.split("\n")){
102 lines.add(line);
103 }
104
105 // check if entry exists
106 foreach(string line in lines){
107 if (line == entry){
108 return true; // return
109 }
110 }
111
112 // append entry
113 lines.add(entry);
114
115 // create new tab
116 string tab_new = "";
117 foreach(string line in lines){
118 if (line.length > 0){
119 tab_new += "%s\n".printf(line);
120 }
121 }
122
123 // write temp crontab file
124 string temp_file = get_temp_file_path();
125 file_write(temp_file, tab_new);
126
127 // install crontab file
128 var cmd = "crontab \"%s\"".printf(temp_file);
129 int status = exec_sync(cmd);
130
131 if (status != 0){
132 log_error(_("Failed to add cron job") + ": %s".printf(entry));
133 return false;
134 }
135 else{
136 log_msg(_("Cron job added") + ": %s".printf(entry));
137 return true;
138 }
139 }
140
141 public static bool remove_job(string entry, bool use_regex, bool use_cached_text){
142
143 // read crontab file
144 string tab = "";
145 if (use_cached_text && (crontab_text != null)){
146 tab = crontab_text;
147 }
148 else{
150 tab = crontab_text;
151 }
152
153 var lines = new Gee.ArrayList<string>();
154 foreach(string line in tab.split("\n")){
155 lines.add(line);
156 }
157
158 Regex regex = null;
159
160 if (use_regex){
161 try {
162 regex = new Regex(entry);
163 }
164 catch (Error e) {
165 log_error (e.message);
166 }
167 }
168
169 // check if entry exists
170 bool found = false;
171 for(int i=0; i < lines.size; i++){
172 string line = lines[i];
173 if (line != null){
174 line = line.strip();
175 }
176
177 if (use_regex && (regex != null)){
178
179 MatchInfo match;
180 if (regex.match(line, 0, out match)) {
181 lines.remove(line);
182 found = true;
183 }
184 }
185 else{
186 if (line == entry){
187 lines.remove(line);
188 found = true;
189 }
190 }
191 }
192 if (!found){
193 return true;
194 }
195
196 // create new tab
197 string tab_new = "";
198 foreach(string line in lines){
199 if (line.length > 0){
200 tab_new += "%s\n".printf(line);
201 }
202 }
203
204 // write temp crontab file
205 string temp_file = get_temp_file_path();
206 file_write(temp_file, tab_new);
207
208 // install crontab file
209 var cmd = "crontab \"%s\"".printf(temp_file);
210 int status = exec_sync(cmd);
211
212 if (status != 0){
213 log_error(_("Failed to remove cron job") + ": %s".printf(entry));
214 return false;
215 }
216 else{
217 log_msg(_("Cron job removed") + ": %s".printf(entry));
218 return true;
219 }
220 }
221
222 public static bool install(string file_path, string user_name = ""){
223
224 if (!file_exists(file_path)){
225 log_error(_("File not found") + ": %s".printf(file_path));
226 return false;
227 }
228
229 var cmd = "crontab";
230 if (user_name.length > 0){
231 cmd += " -u %s".printf(user_name);
232 }
233 cmd += " \"%s\"".printf(file_path);
234
235 log_debug(cmd);
236
237 int status = exec_sync(cmd);
238
239 if (status != 0){
240 log_error(_("Failed to install crontab file") + ": %s".printf(file_path));
241 return false;
242 }
243 else{
244 log_msg(_("crontab file installed") + ": %s".printf(file_path));
245 return true;
246 }
247 }
248
249 public static bool export(string file_path, string user_name = ""){
250 if (file_exists(file_path)){
251 file_delete(file_path);
252 }
253
254 bool ok = file_write(file_path, crontab_read_all(user_name));
255
256 if (!ok){
257 log_error(_("Failed to export crontab file") + ": %s".printf(file_path));
258 return false;
259 }
260 else{
261 log_msg(_("crontab file exported") + ": %s".printf(file_path));
262 return true;
263 }
264 }
265
266 public static bool import(string file_path, string user_name = ""){
267 return install(file_path, user_name);
268 }
269
270 public static bool add_script_file(string file_name, string cron_dir_type, string text, bool stop_cron_emails){
271
272 /* Note:
273 * cron.d and cron.hourly are managed by cron so it expects entries in crontab format
274 * minute hour day_of_month month day_of_week user command
275 *
276 * cron.{daily|weekly|monthly} are read by anacron. scripts placed here should have commands only.
277 * */
278
279 switch (cron_dir_type){
280 case "d":
281 case "hourly":
282 case "daily":
283 case "weekly":
284 case "monthly":
285 break;
286 default:
287 log_error("Cron directory type parameter not valid" + ": %s".printf(cron_dir_type));
288 log_error("Expected values: d, hourly, daily, weekly, monthly");
289 return false;
290 }
291
292 string file_path = "/etc/cron.%s/%s".printf(cron_dir_type, file_name.replace(".","-")); // dot is not allowed in file name
293
294 string sh = "";
295 sh += "SHELL=/bin/bash" + "\n";
296 sh += "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" + "\n";
297 if (stop_cron_emails){
298 sh += "MAILTO=\"\"" + "\n";
299 }
300 sh += "\n";
301 sh += text + "\n";
302
303 if (file_exists(file_path) && (file_read(file_path) == sh)){
304 log_debug(_("Cron task exists") + ": %s".printf(file_path));
305 return true;
306 }
307
308 file_write(file_path, sh);
309 Posix.chown(file_path, 0, 0); // chown to root:root
310 Posix.chmod(file_path, 0644);
311
312 log_msg(_("Added cron task") + ": %s".printf(file_path));
313
314 return true;
315 }
316
317 public static bool remove_script_file(string file_name, string cron_dir_type){
318
319 switch (cron_dir_type){
320 case "d":
321 case "hourly":
322 case "daily":
323 case "weekly":
324 case "monthly":
325 break;
326 default:
327 log_error("Cron directory type parameter not valid" + ": %s".printf(cron_dir_type));
328 log_error("Expected values: d, hourly, daily, weekly, monthly");
329 return false;
330 }
331
332 string file_path = "/etc/cron.%s/%s".printf(cron_dir_type, file_name.replace(".","-")); // dot is not allowed in file name
333
334 if (!file_exists(file_path)){
335 return true;
336 }
337
338 file_delete(file_path);
339
340 log_msg(_("Removed cron task") + ": %s".printf(file_path));
341
342 return true;
343 }
344}
#define _(s)
static bool add_job(string entry, bool use_cached_text)
Definition CronTab.vala:88
static void clear_cached_text()
Definition CronTab.vala:33
static bool install(string file_path, string user_name="")
Definition CronTab.vala:222
static string crontab_read_all(string user_name="")
Definition CronTab.vala:37
static string crontab_text
Definition CronTab.vala:31
static bool export(string file_path, string user_name="")
Definition CronTab.vala:249
static bool has_job(string entry, bool partial_match, bool use_cached_text)
Definition CronTab.vala:58
static bool remove_job(string entry, bool use_regex, bool use_cached_text)
Definition CronTab.vala:141
static bool add_script_file(string file_name, string cron_dir_type, string text, bool stop_cron_emails)
Definition CronTab.vala:270
static bool remove_script_file(string file_name, string cron_dir_type)
Definition CronTab.vala:317
bool file_exists(string file_path)
string? file_read(string file_path)
bool file_write(string file_path, string contents)
bool file_delete(string file_path)
void log_debug(string message)
void log_error(string message, bool highlight=false, bool is_warning=false)
void log_msg(string message, bool highlight=false)
int exec_sync(string cmd, out string? std_out=null, out string? std_err=null)