-rw-r--r-- | core/opiealarm/opiealarm.c | 230 |
1 files changed, 186 insertions, 44 deletions
diff --git a/core/opiealarm/opiealarm.c b/core/opiealarm/opiealarm.c index 33d631d..3a06236 100644 --- a/core/opiealarm/opiealarm.c +++ b/core/opiealarm/opiealarm.c | |||
@@ -22,9 +22,25 @@ | |||
22 | #include <syslog.h> | 22 | #include <syslog.h> |
23 | #include <signal.h> | 23 | #include <signal.h> |
24 | #include <errno.h> | ||
25 | #include <string.h> | ||
24 | 26 | ||
25 | 27 | ||
26 | #define PIDFILE "/var/run/opiealarm.pid" | 28 | #define PIDFILE "/var/run/opiealarm.pid" |
29 | #define APMFILE "/proc/apm" | ||
30 | |||
31 | FILE *log; // debug only | ||
32 | |||
33 | int resume ( void ); | ||
34 | int suspend ( void ); | ||
35 | int main ( int argc, char **argv ); | ||
36 | int fork_with_pidfile ( void ); | ||
37 | int kill_with_pidfile ( void ); | ||
38 | void remove_pidfile ( void ); | ||
39 | void usage ( void ); | ||
40 | void sig_handler ( int sig ); | ||
41 | void error_msg_and_die ( int perr, const char *msg ); | ||
42 | int onac ( void ); | ||
27 | 43 | ||
28 | FILE *log; | 44 | static int opiealarm_was_running; |
29 | 45 | ||
30 | 46 | ||
@@ -43,11 +59,122 @@ void error_msg_and_die ( int perr, const char *msg ) | |||
43 | log_msg ( msg ); | 59 | log_msg ( msg ); |
44 | 60 | ||
45 | unlink ( PIDFILE ); | 61 | while ( 1 ) // pretend we are waiting on RTC, so opiealarm -r can kill us |
62 | sleep ( 1 ); | ||
63 | } | ||
64 | |||
65 | |||
66 | void sig_handler ( int sig ) | ||
67 | { | ||
68 | log_msg ( "GOT SIGNAL -> EXITING\n" ); | ||
69 | fclose ( log ); | ||
70 | remove_pidfile ( ); | ||
71 | exit ( 0 ); | ||
72 | } | ||
73 | |||
74 | void usage ( void ) | ||
75 | { | ||
76 | fprintf ( stderr, "Usage: opiealarm -r|-s\n" ); | ||
46 | exit ( 1 ); | 77 | exit ( 1 ); |
47 | } | 78 | } |
48 | 79 | ||
80 | int fork_with_pidfile ( void ) | ||
81 | { | ||
82 | FILE *fp; | ||
83 | pid_t pid; | ||
84 | |||
85 | pid = fork ( ); | ||
86 | |||
87 | if ( pid > 0 ) | ||
88 | exit ( 0 ); | ||
89 | else if ( pid < 0 ) { | ||
90 | perror ( "forking failed" ); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | signal ( SIGTERM, sig_handler ); | ||
95 | signal ( SIGINT, sig_handler ); | ||
96 | |||
97 | // save pid | ||
98 | if (( fp = fopen ( PIDFILE, "w" ))) { | ||
99 | fprintf ( fp, "%d", getpid ( )); | ||
100 | fclose ( fp ); | ||
101 | |||
102 | // detach | ||
103 | close ( 0 ); | ||
104 | close ( 1 ); | ||
105 | close ( 2 ); | ||
106 | |||
107 | setpgid ( 0, 0 ); | ||
108 | |||
109 | return 1; | ||
110 | } | ||
111 | else { | ||
112 | perror ( PIDFILE ); | ||
113 | return 0; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | int kill_with_pidfile ( void ) | ||
118 | { | ||
119 | FILE *fp; | ||
120 | pid_t pid; | ||
121 | |||
122 | if (( fp = fopen ( PIDFILE, "r" ))) { | ||
123 | if ( fscanf ( fp, "%d", &pid ) == 1 ) | ||
124 | return ( kill ( pid, SIGTERM ) == 0 ) ? 1 : 0; | ||
125 | fclose ( fp ); | ||
126 | } | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | void remove_pidfile ( void ) | ||
131 | { | ||
132 | unlink ( PIDFILE ); | ||
133 | |||
134 | signal ( SIGTERM, SIG_DFL ); | ||
135 | signal ( SIGINT, SIG_DFL ); | ||
136 | } | ||
137 | |||
138 | |||
139 | int main ( int argc, char **argv ) | ||
140 | { | ||
141 | int mode = 0; | ||
142 | int opt; | ||
143 | |||
144 | while (( opt = getopt ( argc, argv, "rs" )) != EOF ) { | ||
145 | switch ( opt ) { | ||
146 | case 's': | ||
147 | mode = 's'; | ||
148 | break; | ||
149 | case 'r': | ||
150 | mode = 'r'; | ||
151 | break; | ||
152 | default: | ||
153 | usage ( ); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | if ( geteuid ( ) != 0 ) { | ||
158 | fprintf ( stderr, "You need root priviledges to run opiealarm." ); | ||
159 | return 2; | ||
160 | } | ||
161 | |||
162 | if ( !mode ) | ||
163 | usage ( ); | ||
164 | |||
165 | // kill running opiealarm | ||
166 | opiealarm_was_running = kill_with_pidfile ( ); | ||
167 | remove_pidfile ( ); | ||
49 | 168 | ||
169 | if ( mode == 'r' ) | ||
170 | return resume ( ); | ||
171 | else | ||
172 | return suspend ( ); | ||
50 | 173 | ||
51 | void suspend_on_rtc ( ) | 174 | return 0; |
175 | } | ||
176 | |||
177 | |||
178 | int suspend ( void ) | ||
52 | { | 179 | { |
53 | FILE *fp; | 180 | FILE *fp; |
@@ -58,4 +185,12 @@ void suspend_on_rtc ( ) | |||
58 | 185 | ||
59 | 186 | ||
187 | if ( !fork_with_pidfile ( )) | ||
188 | return 3; | ||
189 | |||
190 | log = fopen ( "/tmp/opiealarm.log", "w" ); | ||
191 | log_msg ( "STARTING\n" ); | ||
192 | |||
193 | |||
194 | |||
60 | if (!( fp = fopen ( "/etc/resumeat", "r" ))) | 195 | if (!( fp = fopen ( "/etc/resumeat", "r" ))) |
61 | error_msg_and_die ( 1, "/etc/resumeat" ); | 196 | error_msg_and_die ( 1, "/etc/resumeat" ); |
@@ -80,5 +215,5 @@ void suspend_on_rtc ( ) | |||
80 | 215 | ||
81 | // Write alarm time to RTC | 216 | // Write alarm time to RTC |
82 | if (( fd = open ( "/dev/misc/rtc", O_RDWR ) < 0 ); | 217 | if (( fd = open ( "/dev/misc/rtc", O_RDWR )) < 0 ) |
83 | error_msg_and_die ( 1, "/dev/misc/rtc" ); | 218 | error_msg_and_die ( 1, "/dev/misc/rtc" ); |
84 | // set alarm time | 219 | // set alarm time |
@@ -102,66 +237,73 @@ void suspend_on_rtc ( ) | |||
102 | 237 | ||
103 | close ( fd ); | 238 | close ( fd ); |
104 | } | ||
105 | 239 | ||
240 | log_msg ( "EXITING\n" ); | ||
106 | 241 | ||
107 | void sig_handler ( int sig ) | ||
108 | { | ||
109 | log_msg ( "GOT SIGNAL -> EXITING\n" ); | ||
110 | fclose ( log ); | 242 | fclose ( log ); |
111 | unlink ( PIDFILE ); | 243 | remove_pidfile ( ); |
112 | exit ( 0 ); | 244 | |
245 | return 0; | ||
113 | } | 246 | } |
114 | 247 | ||
115 | 248 | ||
116 | int main ( ) | 249 | static int onac ( void ) |
117 | { | 250 | { |
118 | FILE *fp; | 251 | FILE *fp; |
119 | pid_t pid; | 252 | int on = 0; |
120 | 253 | ||
121 | if ( geteuid ( ) != 0 ) { | 254 | if (( fp = fopen ( APMFILE, "r" ))) { |
122 | fprintf ( stderr, "You need root priviledges to run opiealarm." ); | 255 | int ac = 0; |
123 | return 1; | ||
124 | } | ||
125 | 256 | ||
126 | pid = fork ( ); | 257 | if ( fscanf ( fp, "%*[^ ] %*d.%*d 0x%*x 0x%x 0x%*x 0x%*x %*d%% %*i %*c", &ac ) == 1 ) |
258 | on = ( ac == 0x01 ) ? 1 : 0; | ||
127 | 259 | ||
128 | if ( pid > 0 ) | 260 | fclose ( fp ); |
129 | return 0; | ||
130 | else if ( pid < 0 ) { | ||
131 | perror ( "Could not fork." ); | ||
132 | return 2; | ||
133 | } | 261 | } |
134 | 262 | return on; | |
135 | // save pid | ||
136 | if (!( fp = fopen ( PIDFILE, "w" ))) { | ||
137 | perror ( PIDFILE ); | ||
138 | return 3; | ||
139 | } | 263 | } |
140 | 264 | ||
141 | fprintf ( fp, "%d", getpid ( )); | 265 | int resume ( void ) |
142 | fclose ( fp ); | 266 | { |
267 | FILE *fp; | ||
143 | 268 | ||
144 | // detach | 269 | // re-suspend when on AC (optional) when woken up via RTC |
145 | close ( 0 ); | ||
146 | close ( 1 ); | ||
147 | close ( 2 ); | ||
148 | 270 | ||
149 | setpgid ( 0, 0 ); | 271 | if ( !opiealarm_was_running ) { // opiealarm -s got it's RTC signal -> wake up by RTC |
272 | if ( onac ( )) { | ||
273 | time_t start, now; | ||
274 | char *argv [4]; | ||
150 | 275 | ||
151 | log = fopen ( "/tmp/opiealarm.log", "w" ); | 276 | if ( !fork_with_pidfile ( )) |
152 | log_msg ( "STARTING\n" ); | 277 | return 4; |
153 | 278 | ||
154 | signal ( SIGTERM, sig_handler ); | 279 | // sleep 120sec (not less!) |
155 | signal ( SIGINT, sig_handler ); | 280 | time ( &start ); |
281 | do { | ||
282 | sleep ( 1 ); | ||
283 | time ( &now ); | ||
284 | } while (( now - start ) < 120 ); | ||
156 | 285 | ||
157 | extractevent ( ); | 286 | if ( onac ( )) { // still on ac |
287 | // system() without fork | ||
288 | argv[0] = "qcop"; | ||
289 | argv[1] = "QPE/Desktop"; | ||
290 | argv[2] = "suspend()"; | ||
291 | argv[3] = 0; | ||
158 | 292 | ||
159 | signal ( SIGTERM, SIG_DFL ); | 293 | // hard coded for now ...but needed |
160 | signal ( SIGINT, SIG_DFL ); | 294 | setenv ( "LOGNAME", "root", 1 ); |
295 | setenv ( "HOME", "/root", 1 ); | ||
296 | setenv ( "LD_LIBRARY_PATH", "/opt/QtPalmtop/lib", 1 ); | ||
297 | setenv ( "QTDIR", "/opt/QtPalmtop", 1 ); | ||
161 | 298 | ||
162 | log_msg ( "EXITING\n" ); | 299 | remove_pidfile ( ); |
163 | 300 | ||
164 | fclose ( log ); | 301 | execv ( "/opt/QtPalmtop/bin/qcop", argv ); |
165 | unlink ( PIDFILE ); | 302 | |
303 | perror ( "exec for qcop failed" ); | ||
304 | return 5; | ||
305 | } | ||
306 | } | ||
307 | } | ||
166 | return 0; | 308 | return 0; |
167 | } | 309 | } |