void systemEventCallback(void* refCon, io_service_t service, natural_t messageType, void* messageArgument) { Event event; switch (messageType) { case kIOMessageCanSystemSleep: event = SystemEventsManager::getEvent(SYSTEM_SLEEP); if (event.isPrevented()) { IOCancelPowerChange(rootPort, (long)messageArgument); } else { if (event.isRegistered()) SystemEventsManager::executeCallback(event.getCallback()); IOAllowPowerChange(rootPort, (long)messageArgument); } break; case kIOMessageSystemWillSleep: IOAllowPowerChange(rootPort, (long)messageArgument); break; case kIOMessageSystemWillPowerOn: break; case kIOMessageSystemHasPoweredOn: event = SystemEventsManager::getEvent(SYSTEM_WAKE); if (event.isRegistered()) SystemEventsManager::executeCallback(event.getCallback()); break; default: break; } }
void powerCallback (void *rootPort, io_service_t y, natural_t msgType, void *msgArgument) { int result; char *s; /* fprintf (stderr, "powerCallback: message_type %08lx, arg %08lx\n", (long unsigned int) msgType, (long unsigned int) msgArgument); */ switch (msgType) { case kIOMessageCanSystemSleep : if (args.allowsleepcommand == NULL) { result = 0; message (LOG_INFO, "allow sleep\n"); } else if (args.allowsleepcommand == DENY_SLEEP) { result = -1; message (LOG_INFO, "deny sleep\n"); } else { result = system(args.allowsleepcommand); s = (! WIFEXITED(result) || WEXITSTATUS(result)) ? "deny" : "allow"; message (LOG_INFO, "%s sleep: %s: exit=%s status=%d\n", s, args.allowsleepcommand, WIFEXITED(result) ? "ok" : "err", WEXITSTATUS(result)); result = ! WIFEXITED(result) || WEXITSTATUS(result); } if (result) IOCancelPowerChange (* (io_connect_t *) rootPort, (long) msgArgument); else IOAllowPowerChange (* (io_connect_t *) rootPort, (long) msgArgument); break; case kIOMessageSystemWillSleep : if (args.sleepcommand) message (LOG_INFO, "sleep: %s: %d\n", args.sleepcommand, system(args.sleepcommand)); IOAllowPowerChange (* (io_connect_t *) rootPort, (long) msgArgument); break; case kIOMessageSystemWillNotSleep : if (args.cantsleepcommand) message (LOG_INFO, "can't sleep: %s: %d\n", args.cantsleepcommand, system(args.cantsleepcommand)); else message (LOG_INFO, "can't sleep\n"); break; case kIOMessageSystemHasPoweredOn : setupIdleTimer (); if (args.wakeupcommand) message (LOG_INFO, "wakeup: %s: %d\n", args.wakeupcommand, system(args.wakeupcommand)); break; } }
static void sysUpdate(void) { int i; /* Looping var */ cupsd_sysevent_t sysevent; /* The system event */ cupsd_printer_t *p; /* Printer information */ /* * Drain the event pipe... */ while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent)) == sizeof(sysevent)) { if (sysevent.event & SYSEVENT_CANSLEEP) { /* * If there are active printers that don't have the connecting-to-device * printer-state-reason then cancel the sleep request (i.e. this reason * indicates a job that is not yet connected to the printer)... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { if (p->job) { for (i = 0; i < p->num_reasons; i ++) if (!strcmp(p->reasons[i], "connecting-to-device")) break; if (!p->num_reasons || i >= p->num_reasons) break; } } if (p) { cupsdLogMessage(CUPSD_LOG_INFO, "System sleep canceled because printer %s is active", p->name); IOCancelPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); } else { cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep"); IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); } } if (sysevent.event & SYSEVENT_WILLSLEEP) { cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep"); Sleeping = 1; for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Deregistering local printer \"%s\"", p->name); cupsdDeregisterPrinter(p, 0); } cupsdCleanDirty(); #ifdef kIOPMAssertionTypeDenySystemSleep /* * Remove our assertion as needed since the user wants the system to * sleep (different than idle sleep)... */ if (dark_wake) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing dark wake assertion."); IOPMAssertionRelease(dark_wake); dark_wake = 0; } #endif /* kIOPMAssertionTypeDenySystemSleep */ /* * If we have no printing jobs, allow the power change immediately. * Otherwise set the SleepJobs time to 15 seconds in the future when * we'll take more drastic measures... */ if (cupsArrayCount(PrintingJobs) == 0) IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); else { /* * If there are active printers that don't have the connecting-to-device * printer-state-reason then delay the sleep request (i.e. this reason * indicates a job that is not yet connected to the printer)... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { if (p->job) { for (i = 0; i < p->num_reasons; i ++) if (!strcmp(p->reasons[i], "connecting-to-device")) break; if (!p->num_reasons || i >= p->num_reasons) break; } } if (p) { LastSysEvent = sysevent; SleepJobs = time(NULL) + 10; } else { IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); } } } if (sysevent.event & SYSEVENT_WOKE) { cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep"); IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); Sleeping = 0; #ifdef kIOPMAssertionTypeDenySystemSleep if (cupsArrayCount(PrintingJobs) > 0 && !dark_wake) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting dark wake."); IOPMAssertionCreateWithName(kIOPMAssertionTypeDenySystemSleep, kIOPMAssertionLevelOn, CFSTR("org.cups.cupsd"), &dark_wake); } #endif /* kIOPMAssertionTypeDenySystemSleep */ cupsdCheckJobs(); } if (sysevent.event & SYSEVENT_NETCHANGED) { if (!Sleeping) cupsdLogMessage(CUPSD_LOG_DEBUG, "System network configuration changed"); else cupsdLogMessage(CUPSD_LOG_DEBUG, "System network configuration changed; " "ignored while sleeping"); } if (sysevent.event & SYSEVENT_NAMECHANGED) { if (!Sleeping) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Computer name or BTMM domains changed"); /* * De-register the individual printers... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) cupsdDeregisterPrinter(p, 1); # if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) /* * Update the computer name and BTMM domain list... */ cupsdUpdateDNSSDName(); # endif /* HAVE_DNSSD || HAVE_AVAHI */ /* * Now re-register them... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) cupsdRegisterPrinter(p); } else cupsdLogMessage(CUPSD_LOG_DEBUG, "Computer name or BTMM domains changed; ignored while " "sleeping"); } } }
static void sysUpdate(void) { int i; /* Looping var */ cupsd_sysevent_t sysevent; /* The system event */ cupsd_printer_t *p; /* Printer information */ /* * Drain the event pipe... */ while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent)) == sizeof(sysevent)) { if (sysevent.event & SYSEVENT_CANSLEEP) { /* * If there are active printers that don't have the connecting-to-device * printer-state-reason then cancel the sleep request (i.e. this reason * indicates a job that is not yet connected to the printer)... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { if (p->job) { for (i = 0; i < p->num_reasons; i ++) if (!strcmp(p->reasons[i], "connecting-to-device")) break; if (!p->num_reasons || i >= p->num_reasons) break; } } if (p) { cupsdLogMessage(CUPSD_LOG_INFO, "System sleep canceled because printer %s is active", p->name); IOCancelPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); } else { cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep"); IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); } } if (sysevent.event & SYSEVENT_WILLSLEEP) { cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep"); Sleeping = 1; for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { if (p->type & CUPS_PRINTER_DISCOVERED) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Deleting remote destination \"%s\"", p->name); cupsArraySave(Printers); cupsdDeletePrinter(p, 0); cupsArrayRestore(Printers); } else { cupsdLogMessage(CUPSD_LOG_DEBUG, "Deregistering local printer \"%s\"", p->name); cupsdDeregisterPrinter(p, 0); } } cupsdCleanDirty(); /* * If we have no printing jobs, allow the power change immediately. * Otherwise set the SleepJobs time to 15 seconds in the future when * we'll take more drastic measures... */ if (cupsArrayCount(PrintingJobs) == 0) IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); else { LastSysEvent = sysevent; SleepJobs = time(NULL) + 15; } } if (sysevent.event & SYSEVENT_WOKE) { cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep"); IOAllowPowerChange(sysevent.powerKernelPort, sysevent.powerNotificationID); Sleeping = 0; cupsdCheckJobs(); } if (sysevent.event & SYSEVENT_NETCHANGED) { if (!Sleeping) { cupsdLogMessage(CUPSD_LOG_DEBUG, "System network configuration changed"); /* * Resetting browse_time before calling cupsdSendBrowseList causes * browse packets to be sent for local shared printers. */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) p->browse_time = 0; cupsdSendBrowseList(); cupsdRestartPolling(); } else cupsdLogMessage(CUPSD_LOG_DEBUG, "System network configuration changed; " "ignored while sleeping"); } if (sysevent.event & SYSEVENT_NAMECHANGED) { if (!Sleeping) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Computer name or BTMM domains changed"); /* * De-register the individual printers... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) cupsdDeregisterPrinter(p, 1); /* * Update the computer name and BTMM domain list... */ cupsdUpdateDNSSDName(); /* * Now re-register them... */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) { p->browse_time = 0; cupsdRegisterPrinter(p); } } else cupsdLogMessage(CUPSD_LOG_DEBUG, "Computer name or BTMM domains changed; ignored while " "sleeping"); } } }
// // The callback dispatcher // void IOPowerWatcher::ioCallback(void *refCon, io_service_t service, natural_t messageType, void *argument) { IOPowerWatcher *me = (IOPowerWatcher *)refCon; enum { allow, refuse, ignore } reaction; switch (messageType) { case kIOMessageSystemWillSleep: secdebug("powerwatch", "system will sleep"); me->systemWillSleep(); reaction = allow; break; case kIOMessageSystemHasPoweredOn: secdebug("powerwatch", "system has powered on"); me->systemIsWaking(); reaction = ignore; break; case kIOMessageSystemWillPowerOff: secdebug("powerwatch", "system will power off"); me->systemWillPowerDown(); reaction = allow; break; case kIOMessageSystemWillNotPowerOff: secdebug("powerwatch", "system will not power off"); reaction = ignore; break; case kIOMessageCanSystemSleep: secdebug("powerwatch", "can system sleep"); reaction = allow; break; case kIOMessageSystemWillNotSleep: secdebug("powerwatch", "system will not sleep"); reaction = ignore; break; case kIOMessageCanSystemPowerOff: secdebug("powerwatch", "can system power off"); reaction = allow; break; case kIOMessageSystemWillPowerOn: secdebug("powerwatch", "system will power on"); me->systemWillPowerOn(); reaction = ignore; break; default: secdebug("powerwatch", "type 0x%x message received (ignored)", messageType); reaction = ignore; break; } // handle acknowledgments switch (reaction) { case allow: secdebug("powerwatch", "calling IOAllowPowerChange"); IOAllowPowerChange(me->mKernelPort, long(argument)); break; case refuse: secdebug("powerwatch", "calling IOCancelPowerChange"); IOCancelPowerChange(me->mKernelPort, long(argument)); break; case ignore: secdebug("powerwatch", "sending no response"); break; } }