-rw-r--r-- | core/opiealarm/opiealarm.c | 36 | ||||
-rwxr-xr-x | root/etc/resume-scripts/R46opiealarm | 2 |
2 files changed, 25 insertions, 13 deletions
diff --git a/core/opiealarm/opiealarm.c b/core/opiealarm/opiealarm.c index 3a06236..ac98832 100644 --- a/core/opiealarm/opiealarm.c +++ b/core/opiealarm/opiealarm.c | |||
@@ -1,309 +1,321 @@ | |||
1 | /* opiealarm.c | 1 | /* opiealarm.c |
2 | * This program is for extracting the event time/date out | 2 | * This program is for extracting the event time/date out |
3 | * of /etc/resumeat and setting the RTC alarm to that time/date. | 3 | * of /etc/resumeat and setting the RTC alarm to that time/date. |
4 | * It is designed to run via a script just before the iPaq | 4 | * It is designed to run via a script just before the iPaq |
5 | * is suspended. | 5 | * is suspended. |
6 | * | 6 | * |
7 | * Roughly based on ipaqalarm from Benjamin Long | 7 | * Roughly based on ipaqalarm from Benjamin Long |
8 | * | 8 | * |
9 | * written by Robert Griebl <sandman@handhelds.org> | 9 | * written by Robert Griebl <sandman@handhelds.org> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <stdio.h> | 12 | #include <stdio.h> |
13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
14 | #include <sys/ioctl.h> | 14 | #include <sys/ioctl.h> |
15 | #include <sys/time.h> | 15 | #include <sys/time.h> |
16 | #include <sys/types.h> | 16 | #include <sys/types.h> |
17 | #include <fcntl.h> | 17 | #include <fcntl.h> |
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | #include <errno.h> | 19 | #include <errno.h> |
20 | #include <time.h> | 20 | #include <time.h> |
21 | #include <stdlib.h> | 21 | #include <stdlib.h> |
22 | #include <syslog.h> | 22 | #include <syslog.h> |
23 | #include <signal.h> | 23 | #include <signal.h> |
24 | #include <errno.h> | 24 | #include <errno.h> |
25 | #include <string.h> | 25 | #include <string.h> |
26 | 26 | ||
27 | 27 | ||
28 | #define PIDFILE "/var/run/opiealarm.pid" | 28 | #define PIDFILE "/var/run/opiealarm.pid" |
29 | #define APMFILE "/proc/apm" | 29 | #define APMFILE "/proc/apm" |
30 | 30 | ||
31 | FILE *log; // debug only | 31 | FILE *log; // debug only |
32 | 32 | ||
33 | int resume ( void ); | 33 | int resume ( int resuspend ); |
34 | int suspend ( void ); | 34 | int suspend ( void ); |
35 | int main ( int argc, char **argv ); | 35 | int main ( int argc, char **argv ); |
36 | int fork_with_pidfile ( void ); | 36 | int fork_with_pidfile ( void ); |
37 | int kill_with_pidfile ( void ); | 37 | int kill_with_pidfile ( void ); |
38 | void remove_pidfile ( void ); | 38 | void remove_pidfile ( void ); |
39 | void usage ( void ); | 39 | void usage ( void ); |
40 | void sig_handler ( int sig ); | 40 | void sig_handler ( int sig ); |
41 | void error_msg_and_die ( int perr, const char *msg ); | 41 | void error_msg_and_die ( int perr, const char *msg ); |
42 | int onac ( void ); | 42 | int onac ( void ); |
43 | 43 | ||
44 | static int opiealarm_was_running; | 44 | static int opiealarm_was_running; |
45 | 45 | ||
46 | 46 | ||
47 | void log_msg ( const char *msg ) | 47 | void log_msg ( const char *msg ) |
48 | { | 48 | { |
49 | if ( log ) { | 49 | if ( log ) { |
50 | fprintf ( log, msg ); | 50 | fprintf ( log, msg ); |
51 | fflush ( log ); | 51 | fflush ( log ); |
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | void error_msg_and_die ( int perr, const char *msg ) | 55 | void error_msg_and_die ( int perr, const char *msg ) |
56 | { | 56 | { |
57 | if ( perr ) | 57 | if ( perr ) |
58 | log_msg ( strerror ( errno )); | 58 | log_msg ( strerror ( errno )); |
59 | log_msg ( msg ); | 59 | log_msg ( msg ); |
60 | 60 | ||
61 | while ( 1 ) // pretend we are waiting on RTC, so opiealarm -r can kill us | 61 | while ( 1 ) // pretend we are waiting on RTC, so opiealarm -r can kill us |
62 | sleep ( 1 ); | 62 | sleep ( 1 ); |
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
66 | void sig_handler ( int sig ) | 66 | void sig_handler ( int sig ) |
67 | { | 67 | { |
68 | log_msg ( "GOT SIGNAL -> EXITING\n" ); | 68 | log_msg ( "GOT SIGNAL -> EXITING\n" ); |
69 | fclose ( log ); | 69 | fclose ( log ); |
70 | remove_pidfile ( ); | 70 | remove_pidfile ( ); |
71 | exit ( 0 ); | 71 | exit ( 0 ); |
72 | } | 72 | } |
73 | 73 | ||
74 | void usage ( void ) | 74 | void usage ( void ) |
75 | { | 75 | { |
76 | fprintf ( stderr, "Usage: opiealarm -r|-s\n" ); | 76 | fprintf ( stderr, "Usage: opiealarm -r|-s [-a]\n\n" ); |
77 | fprintf ( stderr, "\t-s\tSuspend mode: set RTC alarm\n" ); | ||
78 | fprintf ( stderr, "\t-r\tResume mode: kill running opiealarm\n" ); | ||
79 | fprintf ( stderr, "\t-a <x>\tResuspend in <x> seconds (resume mode)\n\n" ); | ||
77 | exit ( 1 ); | 80 | exit ( 1 ); |
78 | } | 81 | } |
79 | 82 | ||
80 | int fork_with_pidfile ( void ) | 83 | int fork_with_pidfile ( void ) |
81 | { | 84 | { |
82 | FILE *fp; | 85 | FILE *fp; |
83 | pid_t pid; | 86 | pid_t pid; |
84 | 87 | ||
85 | pid = fork ( ); | 88 | pid = fork ( ); |
86 | 89 | ||
87 | if ( pid > 0 ) | 90 | if ( pid > 0 ) |
88 | exit ( 0 ); | 91 | exit ( 0 ); |
89 | else if ( pid < 0 ) { | 92 | else if ( pid < 0 ) { |
90 | perror ( "forking failed" ); | 93 | perror ( "forking failed" ); |
91 | return 0; | 94 | return 0; |
92 | } | 95 | } |
93 | 96 | ||
94 | signal ( SIGTERM, sig_handler ); | 97 | signal ( SIGTERM, sig_handler ); |
95 | signal ( SIGINT, sig_handler ); | 98 | signal ( SIGINT, sig_handler ); |
96 | 99 | ||
97 | // save pid | 100 | // save pid |
98 | if (( fp = fopen ( PIDFILE, "w" ))) { | 101 | if (( fp = fopen ( PIDFILE, "w" ))) { |
99 | fprintf ( fp, "%d", getpid ( )); | 102 | fprintf ( fp, "%d", getpid ( )); |
100 | fclose ( fp ); | 103 | fclose ( fp ); |
101 | 104 | ||
102 | // detach | 105 | // detach |
103 | close ( 0 ); | 106 | close ( 0 ); |
104 | close ( 1 ); | 107 | close ( 1 ); |
105 | close ( 2 ); | 108 | close ( 2 ); |
106 | 109 | ||
107 | setpgid ( 0, 0 ); | 110 | setpgid ( 0, 0 ); |
108 | 111 | ||
109 | return 1; | 112 | return 1; |
110 | } | 113 | } |
111 | else { | 114 | else { |
112 | perror ( PIDFILE ); | 115 | perror ( PIDFILE ); |
113 | return 0; | 116 | return 0; |
114 | } | 117 | } |
115 | } | 118 | } |
116 | 119 | ||
117 | int kill_with_pidfile ( void ) | 120 | int kill_with_pidfile ( void ) |
118 | { | 121 | { |
119 | FILE *fp; | 122 | FILE *fp; |
120 | pid_t pid; | 123 | pid_t pid; |
121 | 124 | ||
122 | if (( fp = fopen ( PIDFILE, "r" ))) { | 125 | if (( fp = fopen ( PIDFILE, "r" ))) { |
123 | if ( fscanf ( fp, "%d", &pid ) == 1 ) | 126 | if ( fscanf ( fp, "%d", &pid ) == 1 ) |
124 | return ( kill ( pid, SIGTERM ) == 0 ) ? 1 : 0; | 127 | return ( kill ( pid, SIGTERM ) == 0 ) ? 1 : 0; |
125 | fclose ( fp ); | 128 | fclose ( fp ); |
126 | } | 129 | } |
127 | return 0; | 130 | return 0; |
128 | } | 131 | } |
129 | 132 | ||
130 | void remove_pidfile ( void ) | 133 | void remove_pidfile ( void ) |
131 | { | 134 | { |
132 | unlink ( PIDFILE ); | 135 | unlink ( PIDFILE ); |
133 | 136 | ||
134 | signal ( SIGTERM, SIG_DFL ); | 137 | signal ( SIGTERM, SIG_DFL ); |
135 | signal ( SIGINT, SIG_DFL ); | 138 | signal ( SIGINT, SIG_DFL ); |
136 | } | 139 | } |
137 | 140 | ||
138 | 141 | ||
139 | int main ( int argc, char **argv ) | 142 | int main ( int argc, char **argv ) |
140 | { | 143 | { |
141 | int mode = 0; | 144 | int mode = 0; |
145 | int ac_resusp = 0; | ||
142 | int opt; | 146 | int opt; |
143 | 147 | ||
144 | while (( opt = getopt ( argc, argv, "rs" )) != EOF ) { | 148 | while (( opt = getopt ( argc, argv, "a:rs" )) != EOF ) { |
145 | switch ( opt ) { | 149 | switch ( opt ) { |
146 | case 's': | 150 | case 's': |
147 | mode = 's'; | 151 | mode = 's'; |
148 | break; | 152 | break; |
149 | case 'r': | 153 | case 'r': |
150 | mode = 'r'; | 154 | mode = 'r'; |
151 | break; | 155 | break; |
156 | case 'a': | ||
157 | ac_resusp = atoi ( optarg ); | ||
158 | if ( ac_resusp < 30 ) { | ||
159 | ac_resusp = 120; | ||
160 | |||
161 | fprintf ( stderr, "Warning: resuspend timeout must be >= 30 sec. -- now set to 120 sec\n" ); | ||
162 | } | ||
163 | break; | ||
152 | default: | 164 | default: |
153 | usage ( ); | 165 | usage ( ); |
154 | } | 166 | } |
155 | } | 167 | } |
156 | 168 | ||
157 | if ( geteuid ( ) != 0 ) { | 169 | if ( geteuid ( ) != 0 ) { |
158 | fprintf ( stderr, "You need root priviledges to run opiealarm." ); | 170 | fprintf ( stderr, "You need root priviledges to run opiealarm." ); |
159 | return 2; | 171 | return 2; |
160 | } | 172 | } |
161 | 173 | ||
162 | if ( !mode ) | 174 | if ( !mode ) |
163 | usage ( ); | 175 | usage ( ); |
164 | 176 | ||
165 | // kill running opiealarm | 177 | // kill running opiealarm |
166 | opiealarm_was_running = kill_with_pidfile ( ); | 178 | opiealarm_was_running = kill_with_pidfile ( ); |
167 | remove_pidfile ( ); | 179 | remove_pidfile ( ); |
168 | 180 | ||
169 | if ( mode == 'r' ) | 181 | switch ( mode ) { |
170 | return resume ( ); | 182 | case 'r': return resume ( ac_resusp ); |
171 | else | 183 | case 's': |
172 | return suspend ( ); | 184 | default : return suspend ( ); |
173 | 185 | } | |
174 | return 0; | 186 | return 0; |
175 | } | 187 | } |
176 | 188 | ||
177 | 189 | ||
178 | int suspend ( void ) | 190 | int suspend ( void ) |
179 | { | 191 | { |
180 | FILE *fp; | 192 | FILE *fp; |
181 | char buf [64]; | 193 | char buf [64]; |
182 | time_t t; | 194 | time_t t; |
183 | struct tm *tm; | 195 | struct tm *tm; |
184 | int fd; | 196 | int fd; |
185 | 197 | ||
186 | 198 | ||
187 | if ( !fork_with_pidfile ( )) | 199 | if ( !fork_with_pidfile ( )) |
188 | return 3; | 200 | return 3; |
189 | 201 | ||
190 | log = fopen ( "/tmp/opiealarm.log", "w" ); | 202 | log = fopen ( "/tmp/opiealarm.log", "w" ); |
191 | log_msg ( "STARTING\n" ); | 203 | log_msg ( "STARTING\n" ); |
192 | 204 | ||
193 | 205 | ||
194 | 206 | ||
195 | if (!( fp = fopen ( "/etc/resumeat", "r" ))) | 207 | if (!( fp = fopen ( "/etc/resumeat", "r" ))) |
196 | error_msg_and_die ( 1, "/etc/resumeat" ); | 208 | error_msg_and_die ( 1, "/etc/resumeat" ); |
197 | 209 | ||
198 | if ( !fgets ( buf, sizeof( buf ) - 1, fp )) | 210 | if ( !fgets ( buf, sizeof( buf ) - 1, fp )) |
199 | error_msg_and_die ( 1, "/etc/resumeat" ); | 211 | error_msg_and_die ( 1, "/etc/resumeat" ); |
200 | 212 | ||
201 | fclose ( fp ); | 213 | fclose ( fp ); |
202 | 214 | ||
203 | t = atoi ( buf ); | 215 | t = atoi ( buf ); |
204 | 216 | ||
205 | if ( t == 0 ) | 217 | if ( t == 0 ) |
206 | error_msg_and_die ( 0, "/etc/resumeat contains an invalid time description" ); | 218 | error_msg_and_die ( 0, "/etc/resumeat contains an invalid time description" ); |
207 | 219 | ||
208 | /* subtract 5 sec from event time... */ | 220 | /* subtract 5 sec from event time... */ |
209 | t -= 5; | 221 | t -= 5; |
210 | 222 | ||
211 | if ( log ) | 223 | if ( log ) |
212 | fprintf ( log, "Setting RTC alarm to %d\n", t ); | 224 | fprintf ( log, "Setting RTC alarm to %d\n", t ); |
213 | 225 | ||
214 | tm = gmtime ( &t ); | 226 | tm = gmtime ( &t ); |
215 | 227 | ||
216 | // Write alarm time to RTC | 228 | // Write alarm time to RTC |
217 | if (( fd = open ( "/dev/misc/rtc", O_RDWR )) < 0 ) | 229 | if (( fd = open ( "/dev/misc/rtc", O_RDWR )) < 0 ) |
218 | error_msg_and_die ( 1, "/dev/misc/rtc" ); | 230 | error_msg_and_die ( 1, "/dev/misc/rtc" ); |
219 | // set alarm time | 231 | // set alarm time |
220 | if ( ioctl ( fd, RTC_ALM_SET, tm ) < 0 ) | 232 | if ( ioctl ( fd, RTC_ALM_SET, tm ) < 0 ) |
221 | error_msg_and_die ( 1, "ioctl RTC_ALM_SET" ); | 233 | error_msg_and_die ( 1, "ioctl RTC_ALM_SET" ); |
222 | // enable alarm irq | 234 | // enable alarm irq |
223 | if ( ioctl ( fd, RTC_AIE_ON, 0 ) < 0 ) | 235 | if ( ioctl ( fd, RTC_AIE_ON, 0 ) < 0 ) |
224 | error_msg_and_die ( 1, "ioctl RTC_AIE_ON" ); | 236 | error_msg_and_die ( 1, "ioctl RTC_AIE_ON" ); |
225 | 237 | ||
226 | log_msg ( "SLEEPING\n" ); | 238 | log_msg ( "SLEEPING\n" ); |
227 | 239 | ||
228 | // wait for alarm irq | 240 | // wait for alarm irq |
229 | if ( read ( fd, buf, sizeof( unsigned long )) < 0 ) | 241 | if ( read ( fd, buf, sizeof( unsigned long )) < 0 ) |
230 | error_msg_and_die ( 1, "read rtc alarm" ); | 242 | error_msg_and_die ( 1, "read rtc alarm" ); |
231 | 243 | ||
232 | log_msg ( "WAKEUP\n" ); | 244 | log_msg ( "WAKEUP\n" ); |
233 | 245 | ||
234 | // disable alarm irq | 246 | // disable alarm irq |
235 | if ( ioctl ( fd, RTC_AIE_OFF, 0 ) < 0 ) | 247 | if ( ioctl ( fd, RTC_AIE_OFF, 0 ) < 0 ) |
236 | error_msg_and_die ( 1, "ioctl RTC_AIE_OFF" ); | 248 | error_msg_and_die ( 1, "ioctl RTC_AIE_OFF" ); |
237 | 249 | ||
238 | close ( fd ); | 250 | close ( fd ); |
239 | 251 | ||
240 | log_msg ( "EXITING\n" ); | 252 | log_msg ( "EXITING\n" ); |
241 | 253 | ||
242 | fclose ( log ); | 254 | fclose ( log ); |
243 | remove_pidfile ( ); | 255 | remove_pidfile ( ); |
244 | 256 | ||
245 | return 0; | 257 | return 0; |
246 | } | 258 | } |
247 | 259 | ||
248 | 260 | ||
249 | static int onac ( void ) | 261 | static int onac ( void ) |
250 | { | 262 | { |
251 | FILE *fp; | 263 | FILE *fp; |
252 | int on = 0; | 264 | int on = 0; |
253 | 265 | ||
254 | if (( fp = fopen ( APMFILE, "r" ))) { | 266 | if (( fp = fopen ( APMFILE, "r" ))) { |
255 | int ac = 0; | 267 | int ac = 0; |
256 | 268 | ||
257 | if ( fscanf ( fp, "%*[^ ] %*d.%*d 0x%*x 0x%x 0x%*x 0x%*x %*d%% %*i %*c", &ac ) == 1 ) | 269 | if ( fscanf ( fp, "%*[^ ] %*d.%*d 0x%*x 0x%x 0x%*x 0x%*x %*d%% %*i %*c", &ac ) == 1 ) |
258 | on = ( ac == 0x01 ) ? 1 : 0; | 270 | on = ( ac == 0x01 ) ? 1 : 0; |
259 | 271 | ||
260 | fclose ( fp ); | 272 | fclose ( fp ); |
261 | } | 273 | } |
262 | return on; | 274 | return on; |
263 | } | 275 | } |
264 | 276 | ||
265 | int resume ( void ) | 277 | int resume ( int resuspend ) |
266 | { | 278 | { |
267 | FILE *fp; | 279 | FILE *fp; |
268 | 280 | ||
269 | // re-suspend when on AC (optional) when woken up via RTC | 281 | // re-suspend when on AC (optional) when woken up via RTC |
270 | 282 | ||
271 | if ( !opiealarm_was_running ) { // opiealarm -s got it's RTC signal -> wake up by RTC | 283 | if ( !opiealarm_was_running ) { // opiealarm -s got it's RTC signal -> wake up by RTC |
272 | if ( onac ( )) { | 284 | if ( resuspend && onac ( )) { |
273 | time_t start, now; | 285 | time_t start, now; |
274 | char *argv [4]; | 286 | char *argv [4]; |
275 | 287 | ||
276 | if ( !fork_with_pidfile ( )) | 288 | if ( !fork_with_pidfile ( )) |
277 | return 4; | 289 | return 4; |
278 | 290 | ||
279 | // sleep 120sec (not less!) | 291 | // sleep <resuspend> sec (not less!) |
280 | time ( &start ); | 292 | time ( &start ); |
281 | do { | 293 | do { |
282 | sleep ( 1 ); | 294 | sleep ( 1 ); |
283 | time ( &now ); | 295 | time ( &now ); |
284 | } while (( now - start ) < 120 ); | 296 | } while (( now - start ) < resuspend ); |
285 | 297 | ||
286 | if ( onac ( )) { // still on ac | 298 | if ( onac ( )) { // still on ac |
287 | // system() without fork | 299 | // system() without fork |
288 | argv[0] = "qcop"; | 300 | argv[0] = "qcop"; |
289 | argv[1] = "QPE/Desktop"; | 301 | argv[1] = "QPE/Desktop"; |
290 | argv[2] = "suspend()"; | 302 | argv[2] = "suspend()"; |
291 | argv[3] = 0; | 303 | argv[3] = 0; |
292 | 304 | ||
293 | // hard coded for now ...but needed | 305 | // hard coded for now ...but needed |
294 | setenv ( "LOGNAME", "root", 1 ); | 306 | setenv ( "LOGNAME", "root", 1 ); |
295 | setenv ( "HOME", "/root", 1 ); | 307 | setenv ( "HOME", "/root", 1 ); |
296 | setenv ( "LD_LIBRARY_PATH", "/opt/QtPalmtop/lib", 1 ); | 308 | setenv ( "LD_LIBRARY_PATH", "/opt/QtPalmtop/lib", 1 ); |
297 | setenv ( "QTDIR", "/opt/QtPalmtop", 1 ); | 309 | setenv ( "QTDIR", "/opt/QtPalmtop", 1 ); |
298 | 310 | ||
299 | remove_pidfile ( ); | 311 | remove_pidfile ( ); |
300 | 312 | ||
301 | execv ( "/opt/QtPalmtop/bin/qcop", argv ); | 313 | execv ( "/opt/QtPalmtop/bin/qcop", argv ); |
302 | 314 | ||
303 | perror ( "exec for qcop failed" ); | 315 | perror ( "exec for qcop failed" ); |
304 | return 5; | 316 | return 5; |
305 | } | 317 | } |
306 | } | 318 | } |
307 | } | 319 | } |
308 | return 0; | 320 | return 0; |
309 | } | 321 | } |
diff --git a/root/etc/resume-scripts/R46opiealarm b/root/etc/resume-scripts/R46opiealarm index c258047..169dc30 100755 --- a/root/etc/resume-scripts/R46opiealarm +++ b/root/etc/resume-scripts/R46opiealarm | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # Starts opiealarm, which only runs while the iPaq sleeps | 2 | # Starts opiealarm, which only runs while the iPaq sleeps |
3 | # and wakes it up when the RTC alarm goes off. | 3 | # and wakes it up when the RTC alarm goes off. |
4 | 4 | ||
5 | /opt/QtPalmtop/bin/opiealarm -r | 5 | /opt/QtPalmtop/bin/opiealarm -r -a 120 |