Deleted done items
[gregoa/zavai.git] / src / at.vala
1 /*
2  * at - at interface
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 using GLib;
22
23 namespace at {
24
25 public struct Event
26 {
27         int id;
28         time_t deadline;
29 }
30
31 // Return the earliest ID in the queue, or -1 if none are found
32 // Queue is null for all queues, otherwise a queue name
33 public static Event earliestID(string? queue = null)
34 {
35         Event res = { -1, 0 };
36
37         string argv[4];
38         argv[0] = "/usr/bin/atq";
39         if (queue == null)
40                 argv[1] = null;
41         else
42         {
43                 argv[1] = "-q";
44                 argv[2] = queue;
45                 argv[3] = null;
46         }
47
48         Pid pid;
49         int stdout;
50
51         try
52         {
53                 if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdout, null))
54                         return res;
55         } catch (SpawnError e) {
56                 stderr.printf("Cannot run 'at -q': %s\n", e.message);
57                 return res;
58         }
59
60         FileStream fs = FileStream.fdopen(stdout, "r");
61         if (fs == null)
62                 return res;
63
64         char buf[200];
65         string? line;
66         while ((line = fs.gets(buf)) != null)
67         {
68                 if (!line[0].isdigit()) continue;
69                 weak string rest;
70                 ulong id = line.to_ulong(out rest, 10);
71                 Time t = Time();
72                 rest = t.strptime(rest.offset(1), "%a %b %d %H:%M:%S %Y");
73                 if (rest == null) continue;
74                 if (rest.size() < 2) continue;
75                 //stderr.printf("PARSE QUEUE rest %s\n", rest);
76                 // Skip the queue of tasks currently being executed
77                 //if (rest[1] == '=') continue;
78                 // Skip entries not in the wanted queue
79                 if (queue != null && rest[1] != queue[0]) continue;
80                 time_t tt = t.mktime();
81                 if (res.deadline == 0 || tt < res.deadline) {
82                         res.id = (int)id;
83                         res.deadline = tt;
84                 }
85         }
86         Process.close_pid(pid);
87         return res;
88 }
89
90 public delegate bool jobParser(int fd);
91
92 // Get the contents of a job given its id
93 public static bool jobContents(int id, jobParser parser)
94 {
95         string argv[4];
96         argv[0] = "/usr/bin/at";
97         argv[1] = "-c";
98         argv[2] = id.to_string();
99         argv[3] = null;
100
101         Pid pid;
102         int stdoutfd;
103
104         try
105         {
106                 if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdoutfd, null))
107                         return false;
108         } catch (SpawnError e) {
109                 stderr.printf("Cannot run 'at -c': %s\n", e.message);
110                 return false;
111         }
112
113         bool res = parser(stdoutfd);
114
115         Process.close_pid(pid);
116
117         return res;
118 }
119
120 /*
121 TODO: schedule alarms via at
122
123 Uses the 'z' queue.
124
125 atq -q z  can be used to list the jobs (for example, at startup, or after a job has run)
126 at -c id  can be used to query a job, parsing its contents (which can have
127           comments or variables being set)
128 zavai --notify ...  can be used to notify the job (and start zavai if it's not running)
129
130 Alarm needs to be able to serialize itself to an at invocation and to
131 deserialize itself from the output of at -c
132
133 Alarm needs to deserialize also a job with no special markers whatsoever: a
134 generic at job.
135 */
136
137
138 /*
139 public class Alarm : Object
140 {
141         // TODO: make a factory method to construct from an "at -c" output
142
143         // TODO: make a method that provides an at invocation
144
145         public signal void trigger(Alarm a);
146
147         public time_t deadline;
148         public string label;
149
150         public Alarm(time_t deadline, string label)
151         {
152                 this.deadline = deadline;
153                 this.label = label;
154         }
155 }
156 */
157
158         // Schedule a task that notifies a string
159         // TODO public void schedule_label(const Alarm a);
160
161         // Return the next item in the queue due to be run
162         // TODO public Alarm? next_scheduled();
163
164 }