summaryrefslogtreecommitdiff
path: root/library/alarmserver.cpp
Unidiff
Diffstat (limited to 'library/alarmserver.cpp') (more/less context) (show whitespace changes)
-rw-r--r--library/alarmserver.cpp91
1 files changed, 74 insertions, 17 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp
index 5e4dd18..2ea4025 100644
--- a/library/alarmserver.cpp
+++ b/library/alarmserver.cpp
@@ -35,13 +35,18 @@
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/stat.h> 36#include <sys/stat.h>
37 37
38#include <stdlib.h> 38#include <stdlib.h>
39#include <unistd.h> 39#include <unistd.h>
40 40
41struct timerEventItem { 41
42#undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume
43
44
45struct timerEventItem
46{
42 time_t UTCtime; 47 time_t UTCtime;
43 QCString channel, message; 48 QCString channel, message;
44 int data; 49 int data;
45 bool operator==( const timerEventItem &right ) const 50 bool operator==( const timerEventItem &right ) const
46 { 51 {
47 return ( UTCtime == right.UTCtime 52 return ( UTCtime == right.UTCtime
@@ -51,21 +56,26 @@ struct timerEventItem {
51 } 56 }
52}; 57};
53 58
54class TimerReceiverObject : public QObject 59class TimerReceiverObject : public QObject
55{ 60{
56public: 61public:
57 TimerReceiverObject() { } 62 TimerReceiverObject()
58 ~TimerReceiverObject() { } 63 { }
64 ~TimerReceiverObject()
65 { }
59 void resetTimer(); 66 void resetTimer();
60 void setTimerEventItem(); 67 void setTimerEventItem();
61 void deleteTimer(); 68 void deleteTimer();
62protected: 69protected:
63 void timerEvent( QTimerEvent *te ); 70 void timerEvent( QTimerEvent *te );
71
72#ifdef USE_ATD
64private: 73private:
65 QString atfilename; 74 QString atfilename;
75#endif
66}; 76};
67 77
68TimerReceiverObject *timerEventReceiver = NULL; 78TimerReceiverObject *timerEventReceiver = NULL;
69QList<timerEventItem> timerEventList; 79QList<timerEventItem> timerEventList;
70timerEventItem *nearestTimerEvent = NULL; 80timerEventItem *nearestTimerEvent = NULL;
71 81
@@ -112,13 +122,14 @@ static void saveState()
112 ds << it.current()->data; 122 ds << it.current()->data;
113 } 123 }
114 124
115 125
116 savefile.close(); 126 savefile.close();
117 unlink( savefilename ); 127 unlink( savefilename );
118 QDir d; d.rename(savefilename+".new",savefilename); 128 QDir d;
129 d.rename(savefilename + ".new", savefilename);
119 130
120 } 131 }
121} 132}
122 133
123/*! 134/*!
124 Sets up the alarm server. Restoring to previous state (session management). 135 Sets up the alarm server. Restoring to previous state (session management).
@@ -145,45 +156,67 @@ void AlarmServer::initialize()
145 timerEventReceiver = new TimerReceiverObject; 156 timerEventReceiver = new TimerReceiverObject;
146 setNearestTimerEvent(); 157 setNearestTimerEvent();
147 } 158 }
148} 159}
149 160
150 161
151 162#ifdef USE_ATD
152 163
153static const char* atdir = "/var/spool/at/"; 164static const char* atdir = "/var/spool/at/";
154 165
155static bool triggerAtd( bool writeHWClock = FALSE ) 166static bool triggerAtd( bool writeHWClock = FALSE )
156{ 167{
157 QFile trigger(QString(atdir) + "trigger"); 168 QFile trigger(QString(atdir) + "trigger");
158 if ( trigger.open(IO_WriteOnly|IO_Raw) ) { 169 if ( trigger.open(IO_WriteOnly|IO_Raw) ) {
159 if ( trigger.writeBlock("\n",2) != 2 ) { 170 if ( trigger.writeBlock("\n",2) != 2 ) {
160 QMessageBox::critical( 0, QObject::tr( "Out of Space" ), 171 QMessageBox::critical( 0, QObject::tr( "Out of Space" ),
161 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); 172 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) );
162 trigger.close(); 173 trigger.close();
163 QFile::remove( trigger.name() ); 174 QFile::remove
175 ( trigger.name() );
164 return FALSE; 176 return FALSE;
165 } 177 }
166 return TRUE; 178 return TRUE;
167 } 179 }
168 return FALSE; 180 return FALSE;
169} 181}
170 182
183#else
184
185static bool writeResumeAt ( time_t wakeup )
186{
187 FILE *fp = ::fopen ( "/var/run/resumeat", "w" );
188
189 if ( fp ) {
190 ::fprintf ( fp, "%d\n", (int) wakeup );
191 ::fclose ( fp );
192 }
193 else
194 qWarning ( "Failed to write wakeup time to /var/run/resumeat" );
195
196 return ( fp );
197}
198
199#endif
200
171void TimerReceiverObject::deleteTimer() 201void TimerReceiverObject::deleteTimer()
172{ 202{
203#ifdef USE_ATD
173 if ( !atfilename.isEmpty() ) { 204 if ( !atfilename.isEmpty() ) {
174 unlink( atfilename ); 205 unlink( atfilename );
175 atfilename = QString::null; 206 atfilename = QString::null;
176 triggerAtd( FALSE ); 207 triggerAtd( FALSE );
177 } 208 }
209#else
210 writeResumeAt ( 0 );
211#endif
178} 212}
179 213
180void TimerReceiverObject::resetTimer() 214void TimerReceiverObject::resetTimer()
181{ 215{
182 const int maxsecs = 2147000; 216 const int maxsecs = 2147000;
183 int total_written;
184 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); 217 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime);
185 QDateTime now = QDateTime::currentDateTime(); 218 QDateTime now = QDateTime::currentDateTime();
186 if ( nearest < now ) 219 if ( nearest < now )
187 nearest = now; 220 nearest = now;
188 int secs = TimeConversion::secsTo( now, nearest ); 221 int secs = TimeConversion::secsTo( now, nearest );
189 if ( secs > maxsecs ) { 222 if ( secs > maxsecs ) {
@@ -193,38 +226,51 @@ void TimerReceiverObject::resetTimer()
193 226
194 // System timer (needed so that we wake from deep sleep), 227 // System timer (needed so that we wake from deep sleep),
195 // from the Epoch in seconds. 228 // from the Epoch in seconds.
196 // 229 //
197 int at_secs = TimeConversion::toUTC(nearest); 230 int at_secs = TimeConversion::toUTC(nearest);
198 // qDebug("reset timer to %d seconds from Epoch",at_secs); 231 // qDebug("reset timer to %d seconds from Epoch",at_secs);
232
233#ifdef USE_ATD
234
199 QString fn = atdir + QString::number(at_secs) + "." 235 QString fn = atdir + QString::number(at_secs) + "."
200 + QString::number(getpid()); 236 + QString::number(getpid());
201 if ( fn != atfilename ) { 237 if ( fn != atfilename ) {
202 QFile atfile(fn+".new"); 238 QFile atfile(fn+".new");
203 if ( atfile.open(IO_WriteOnly|IO_Raw) ) { 239 if ( atfile.open(IO_WriteOnly|IO_Raw) ) {
240 int total_written;
241
204 // just wake up and delete the at file 242 // just wake up and delete the at file
205 QString cmd = "#!/bin/sh\nrm " + fn; 243 QString cmd = "#!/bin/sh\nrm " + fn;
206 total_written = atfile.writeBlock(cmd.latin1(),cmd.length()); 244 total_written = atfile.writeBlock(cmd.latin1(),cmd.length());
207 if ( total_written != int(cmd.length()) ) { 245 if ( total_written != int(cmd.length()) ) {
208 QMessageBox::critical( 0, tr("Out of Space"), 246 QMessageBox::critical( 0, tr("Out of Space"),
209 tr("Unable to schedule alarm.\n" 247 tr("Unable to schedule alarm.\n"
210 "Please free up space and try again") ); 248 "Please free up space and try again") );
211 atfile.close(); 249 atfile.close();
212 QFile::remove( atfile.name() ); 250 QFile::remove
251 ( atfile.name() );
213 return; 252 return;
214 } 253 }
215 atfile.close(); 254 atfile.close();
216 unlink( atfilename ); 255 unlink( atfilename );
217 QDir d; d.rename(fn+".new",fn); 256 QDir d;
257 d.rename(fn + ".new", fn);
218 chmod(fn.latin1(),0755); 258 chmod(fn.latin1(),0755);
219 atfilename = fn; 259 atfilename = fn;
220 triggerAtd( FALSE ); 260 triggerAtd( FALSE );
221 } else { 261 }
262 else {
222 qWarning("Cannot open atd file %s",fn.latin1()); 263 qWarning("Cannot open atd file %s",fn.latin1());
223 } 264 }
224 } 265 }
266#else
267 writeResumeAt ( at_secs );
268
269#endif
270
225 // Qt timers (does the actual alarm) 271 // Qt timers (does the actual alarm)
226 // from now in milliseconds 272 // from now in milliseconds
227 // 273 //
228 qDebug("AlarmServer waiting %d seconds",secs); 274 qDebug("AlarmServer waiting %d seconds",secs);
229 startTimer( 1000 * secs + 500 ); 275 startTimer( 1000 * secs + 500 );
230} 276}
@@ -239,17 +285,19 @@ void TimerReceiverObject::timerEvent( QTimerEvent * )
239#ifndef QT_NO_COP 285#ifndef QT_NO_COP
240 QCopEnvelope e( nearestTimerEvent->channel, 286 QCopEnvelope e( nearestTimerEvent->channel,
241 nearestTimerEvent->message ); 287 nearestTimerEvent->message );
242 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) 288 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime )
243 << nearestTimerEvent->data; 289 << nearestTimerEvent->data;
244#endif 290#endif
291
245 timerEventList.remove( nearestTimerEvent ); 292 timerEventList.remove( nearestTimerEvent );
246 needSave = TRUE; 293 needSave = TRUE;
247 } 294 }
248 setNearestTimerEvent(); 295 setNearestTimerEvent();
249 } else { 296 }
297 else {
250 resetTimer(); 298 resetTimer();
251 } 299 }
252 if ( needSave ) 300 if ( needSave )
253 saveState(); 301 saveState();
254} 302}
255 303
@@ -310,23 +358,26 @@ void AlarmServer::addAlarm ( QDateTime when, const QCString& channel,
310 if ( nearestTimerEvent ) { 358 if ( nearestTimerEvent ) {
311 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { 359 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) {
312 nearestTimerEvent = newTimerEventItem; 360 nearestTimerEvent = newTimerEventItem;
313 timerEventReceiver->killTimers(); 361 timerEventReceiver->killTimers();
314 timerEventReceiver->resetTimer(); 362 timerEventReceiver->resetTimer();
315 } 363 }
316 } else { 364 }
365 else {
317 nearestTimerEvent = newTimerEventItem; 366 nearestTimerEvent = newTimerEventItem;
318 timerEventReceiver->resetTimer(); 367 timerEventReceiver->resetTimer();
319 } 368 }
320 if ( needSave ) 369 if ( needSave )
321 saveState(); 370 saveState();
322 } else { 371 }
372 else {
323#ifndef QT_NO_COP 373#ifndef QT_NO_COP
324 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); 374 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" );
325 e << when << channel << message << data; 375 e << when << channel << message << data;
326#endif 376#endif
377
327 } 378 }
328} 379}
329 380
330/*! 381/*!
331 Deletes previously scheduled alarms which match \a when, \a channel, 382 Deletes previously scheduled alarms which match \a when, \a channel,
332 \a message, and \a data. 383 \a message, and \a data.
@@ -352,41 +403,47 @@ void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QC
352 time_t deleteTime = TimeConversion::toUTC( when ); 403 time_t deleteTime = TimeConversion::toUTC( when );
353 for ( ; *it; ++it ) { 404 for ( ; *it; ++it ) {
354 // if its a match, delete it 405 // if its a match, delete it
355 if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) 406 if ( ( (*it)->UTCtime == deleteTime || when.isNull() )
356 && ( channel.isNull() || (*it)->channel == channel ) 407 && ( channel.isNull() || (*it)->channel == channel )
357 && ( message.isNull() || (*it)->message == message ) 408 && ( message.isNull() || (*it)->message == message )
358 && ( data==-1 || (*it)->data == data ) ) 409 && ( data == -1 || (*it)->data == data ) ) {
359 {
360 // if it's first, then we need to update the timer 410 // if it's first, then we need to update the timer
361 if ( (*it) == nearestTimerEvent ) { 411 if ( (*it) == nearestTimerEvent ) {
362 timerEventList.remove(*it); 412 timerEventList.remove(*it);
363 setNearestTimerEvent(); 413 setNearestTimerEvent();
364 } else { 414 }
415 else {
365 timerEventList.remove(*it); 416 timerEventList.remove(*it);
366 } 417 }
367 needSave = TRUE; 418 needSave = TRUE;
368 } 419 }
369 } 420 }
370 if ( nearestTimerEvent ) 421 if ( nearestTimerEvent )
371 timerEventReceiver->resetTimer(); 422 timerEventReceiver->resetTimer();
372 } 423 }
373 if ( needSave ) 424 if ( needSave )
374 saveState(); 425 saveState();
375 } else { 426 }
427 else {
376#ifndef QT_NO_COP 428#ifndef QT_NO_COP
377 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); 429 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" );
378 e << when << channel << message << data; 430 e << when << channel << message << data;
379#endif 431#endif
432
380 } 433 }
381} 434}
382 435
383/*! 436/*!
384 Writes the system clock to the hardware clock. 437 Writes the system clock to the hardware clock.
385*/ 438*/
386void Global::writeHWClock() 439void Global::writeHWClock()
387{ 440{
441#ifdef USE_ATD
388 if ( !triggerAtd( TRUE ) ) { 442 if ( !triggerAtd( TRUE ) ) {
389 // atd not running? set it ourselves 443 // atd not running? set it ourselves
390 system("/sbin/hwclock --systohc"); // ##### UTC? 444 system("/sbin/hwclock --systohc"); // ##### UTC?
391 } 445 }
446#else
447 // hwclock is written on suspend
448#endif
392} 449}