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;
    }
}
Beispiel #2
0
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;
	}
}
Beispiel #3
0
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");
    }
  }
}
Beispiel #4
0
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;
    }
}