1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * System management functions for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
16*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
17*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/pwr_mgt/IOPMLib.h>
18*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker
21*5e7646d2SAndroid Build Coastguard Worker /*
22*5e7646d2SAndroid Build Coastguard Worker * The system management functions cover disk and power management which
23*5e7646d2SAndroid Build Coastguard Worker * are primarily used for portable computers.
24*5e7646d2SAndroid Build Coastguard Worker *
25*5e7646d2SAndroid Build Coastguard Worker * Disk management involves delaying the write of certain configuration
26*5e7646d2SAndroid Build Coastguard Worker * and state files to minimize the number of times the disk has to spin
27*5e7646d2SAndroid Build Coastguard Worker * up or flash to be written to.
28*5e7646d2SAndroid Build Coastguard Worker *
29*5e7646d2SAndroid Build Coastguard Worker * Power management support is currently only implemented on macOS, but
30*5e7646d2SAndroid Build Coastguard Worker * essentially we use four functions to let the OS know when it is OK to
31*5e7646d2SAndroid Build Coastguard Worker * put the system to sleep, typically when we are not in the middle of
32*5e7646d2SAndroid Build Coastguard Worker * printing a job. And on macOS we can also "sleep print" - basically the
33*5e7646d2SAndroid Build Coastguard Worker * system only wakes up long enough to service network requests and process
34*5e7646d2SAndroid Build Coastguard Worker * print jobs.
35*5e7646d2SAndroid Build Coastguard Worker */
36*5e7646d2SAndroid Build Coastguard Worker
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker /*
39*5e7646d2SAndroid Build Coastguard Worker * 'cupsdCleanDirty()' - Write dirty config and state files.
40*5e7646d2SAndroid Build Coastguard Worker */
41*5e7646d2SAndroid Build Coastguard Worker
42*5e7646d2SAndroid Build Coastguard Worker void
cupsdCleanDirty(void)43*5e7646d2SAndroid Build Coastguard Worker cupsdCleanDirty(void)
44*5e7646d2SAndroid Build Coastguard Worker {
45*5e7646d2SAndroid Build Coastguard Worker if (DirtyFiles & CUPSD_DIRTY_PRINTERS)
46*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllPrinters();
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker if (DirtyFiles & CUPSD_DIRTY_CLASSES)
49*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllClasses();
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker if (DirtyFiles & CUPSD_DIRTY_PRINTCAP)
52*5e7646d2SAndroid Build Coastguard Worker cupsdWritePrintcap();
53*5e7646d2SAndroid Build Coastguard Worker
54*5e7646d2SAndroid Build Coastguard Worker if (DirtyFiles & CUPSD_DIRTY_JOBS)
55*5e7646d2SAndroid Build Coastguard Worker {
56*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllJobs();
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
61*5e7646d2SAndroid Build Coastguard Worker job;
62*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(Jobs))
63*5e7646d2SAndroid Build Coastguard Worker if (job->dirty)
64*5e7646d2SAndroid Build Coastguard Worker cupsdSaveJob(job);
65*5e7646d2SAndroid Build Coastguard Worker }
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker if (DirtyFiles & CUPSD_DIRTY_SUBSCRIPTIONS)
68*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllSubscriptions();
69*5e7646d2SAndroid Build Coastguard Worker
70*5e7646d2SAndroid Build Coastguard Worker DirtyFiles = CUPSD_DIRTY_NONE;
71*5e7646d2SAndroid Build Coastguard Worker DirtyCleanTime = 0;
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker cupsdSetBusyState(0);
74*5e7646d2SAndroid Build Coastguard Worker }
75*5e7646d2SAndroid Build Coastguard Worker
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker * 'cupsdMarkDirty()' - Mark config or state files as needing a write.
79*5e7646d2SAndroid Build Coastguard Worker */
80*5e7646d2SAndroid Build Coastguard Worker
81*5e7646d2SAndroid Build Coastguard Worker void
cupsdMarkDirty(int what)82*5e7646d2SAndroid Build Coastguard Worker cupsdMarkDirty(int what) /* I - What file(s) are dirty? */
83*5e7646d2SAndroid Build Coastguard Worker {
84*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdMarkDirty(%c%c%c%c%c)",
85*5e7646d2SAndroid Build Coastguard Worker (what & CUPSD_DIRTY_PRINTERS) ? 'P' : '-',
86*5e7646d2SAndroid Build Coastguard Worker (what & CUPSD_DIRTY_CLASSES) ? 'C' : '-',
87*5e7646d2SAndroid Build Coastguard Worker (what & CUPSD_DIRTY_PRINTCAP) ? 'p' : '-',
88*5e7646d2SAndroid Build Coastguard Worker (what & CUPSD_DIRTY_JOBS) ? 'J' : '-',
89*5e7646d2SAndroid Build Coastguard Worker (what & CUPSD_DIRTY_SUBSCRIPTIONS) ? 'S' : '-');
90*5e7646d2SAndroid Build Coastguard Worker
91*5e7646d2SAndroid Build Coastguard Worker if (what == CUPSD_DIRTY_PRINTCAP && !Printcap)
92*5e7646d2SAndroid Build Coastguard Worker return;
93*5e7646d2SAndroid Build Coastguard Worker
94*5e7646d2SAndroid Build Coastguard Worker DirtyFiles |= what;
95*5e7646d2SAndroid Build Coastguard Worker
96*5e7646d2SAndroid Build Coastguard Worker if (!DirtyCleanTime)
97*5e7646d2SAndroid Build Coastguard Worker DirtyCleanTime = time(NULL) + DirtyCleanInterval;
98*5e7646d2SAndroid Build Coastguard Worker
99*5e7646d2SAndroid Build Coastguard Worker cupsdSetBusyState(0);
100*5e7646d2SAndroid Build Coastguard Worker }
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker /*
104*5e7646d2SAndroid Build Coastguard Worker * 'cupsdSetBusyState()' - Let the system know when we are busy doing something.
105*5e7646d2SAndroid Build Coastguard Worker */
106*5e7646d2SAndroid Build Coastguard Worker
107*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetBusyState(int working)108*5e7646d2SAndroid Build Coastguard Worker cupsdSetBusyState(int working) /* I - Doing significant work? */
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
111*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
112*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p; /* Current printer */
113*5e7646d2SAndroid Build Coastguard Worker int newbusy; /* New busy state */
114*5e7646d2SAndroid Build Coastguard Worker static int busy = 0; /* Current busy state */
115*5e7646d2SAndroid Build Coastguard Worker static const char * const busy_text[] =
116*5e7646d2SAndroid Build Coastguard Worker { /* Text for busy states */
117*5e7646d2SAndroid Build Coastguard Worker "Not busy",
118*5e7646d2SAndroid Build Coastguard Worker "Dirty files",
119*5e7646d2SAndroid Build Coastguard Worker "Printing jobs",
120*5e7646d2SAndroid Build Coastguard Worker "Printing jobs and dirty files",
121*5e7646d2SAndroid Build Coastguard Worker "Active clients",
122*5e7646d2SAndroid Build Coastguard Worker "Active clients and dirty files",
123*5e7646d2SAndroid Build Coastguard Worker "Active clients and printing jobs",
124*5e7646d2SAndroid Build Coastguard Worker "Active clients, printing jobs, and dirty files"
125*5e7646d2SAndroid Build Coastguard Worker };
126*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
127*5e7646d2SAndroid Build Coastguard Worker static IOPMAssertionID keep_awake = 0;/* Keep the system awake while printing */
128*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker /*
132*5e7646d2SAndroid Build Coastguard Worker * Figure out how busy we are...
133*5e7646d2SAndroid Build Coastguard Worker */
134*5e7646d2SAndroid Build Coastguard Worker
135*5e7646d2SAndroid Build Coastguard Worker newbusy = (DirtyCleanTime ? 1 : 0) |
136*5e7646d2SAndroid Build Coastguard Worker ((working || cupsArrayCount(ActiveClients) > 0) ? 4 : 0);
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs);
139*5e7646d2SAndroid Build Coastguard Worker job;
140*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(PrintingJobs))
141*5e7646d2SAndroid Build Coastguard Worker {
142*5e7646d2SAndroid Build Coastguard Worker if ((p = job->printer) != NULL)
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < p->num_reasons; i ++)
145*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(p->reasons[i], "connecting-to-device"))
146*5e7646d2SAndroid Build Coastguard Worker break;
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker if (!p->num_reasons || i >= p->num_reasons)
149*5e7646d2SAndroid Build Coastguard Worker break;
150*5e7646d2SAndroid Build Coastguard Worker }
151*5e7646d2SAndroid Build Coastguard Worker }
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker if (job)
154*5e7646d2SAndroid Build Coastguard Worker newbusy |= 2;
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
157*5e7646d2SAndroid Build Coastguard Worker "cupsdSetBusyState: newbusy=\"%s\", busy=\"%s\"",
158*5e7646d2SAndroid Build Coastguard Worker busy_text[newbusy], busy_text[busy]);
159*5e7646d2SAndroid Build Coastguard Worker
160*5e7646d2SAndroid Build Coastguard Worker /*
161*5e7646d2SAndroid Build Coastguard Worker * Manage state changes...
162*5e7646d2SAndroid Build Coastguard Worker */
163*5e7646d2SAndroid Build Coastguard Worker
164*5e7646d2SAndroid Build Coastguard Worker if (newbusy != busy)
165*5e7646d2SAndroid Build Coastguard Worker busy = newbusy;
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
168*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(PrintingJobs) > 0 && !keep_awake)
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting NetworkClientActive.");
171*5e7646d2SAndroid Build Coastguard Worker
172*5e7646d2SAndroid Build Coastguard Worker IOPMAssertionCreateWithName(kIOPMAssertNetworkClientActive,
173*5e7646d2SAndroid Build Coastguard Worker kIOPMAssertionLevelOn,
174*5e7646d2SAndroid Build Coastguard Worker CFSTR("org.cups.cupsd"), &keep_awake);
175*5e7646d2SAndroid Build Coastguard Worker }
176*5e7646d2SAndroid Build Coastguard Worker else if (cupsArrayCount(PrintingJobs) == 0 && keep_awake)
177*5e7646d2SAndroid Build Coastguard Worker {
178*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing power assertion.");
179*5e7646d2SAndroid Build Coastguard Worker IOPMAssertionRelease(keep_awake);
180*5e7646d2SAndroid Build Coastguard Worker keep_awake = 0;
181*5e7646d2SAndroid Build Coastguard Worker }
182*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
183*5e7646d2SAndroid Build Coastguard Worker }
184*5e7646d2SAndroid Build Coastguard Worker
185*5e7646d2SAndroid Build Coastguard Worker
186*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
187*5e7646d2SAndroid Build Coastguard Worker /*
188*5e7646d2SAndroid Build Coastguard Worker * This is the Apple-specific system event code. It works by creating
189*5e7646d2SAndroid Build Coastguard Worker * a worker thread that waits for events from the OS and relays them
190*5e7646d2SAndroid Build Coastguard Worker * to the main thread via a traditional pipe.
191*5e7646d2SAndroid Build Coastguard Worker */
192*5e7646d2SAndroid Build Coastguard Worker
193*5e7646d2SAndroid Build Coastguard Worker /*
194*5e7646d2SAndroid Build Coastguard Worker * Include MacOS-specific headers...
195*5e7646d2SAndroid Build Coastguard Worker */
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker # include <notify.h>
198*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/IOKitLib.h>
199*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/IOMessage.h>
200*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/ps/IOPowerSources.h>
201*5e7646d2SAndroid Build Coastguard Worker # include <IOKit/pwr_mgt/IOPMLib.h>
202*5e7646d2SAndroid Build Coastguard Worker # include <SystemConfiguration/SystemConfiguration.h>
203*5e7646d2SAndroid Build Coastguard Worker # include <pthread.h>
204*5e7646d2SAndroid Build Coastguard Worker
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker /*
207*5e7646d2SAndroid Build Coastguard Worker * Constants...
208*5e7646d2SAndroid Build Coastguard Worker */
209*5e7646d2SAndroid Build Coastguard Worker
210*5e7646d2SAndroid Build Coastguard Worker # define SYSEVENT_CANSLEEP 0x1 /* Decide whether to allow sleep or not */
211*5e7646d2SAndroid Build Coastguard Worker # define SYSEVENT_WILLSLEEP 0x2 /* Computer will go to sleep */
212*5e7646d2SAndroid Build Coastguard Worker # define SYSEVENT_WOKE 0x4 /* Computer woke from sleep */
213*5e7646d2SAndroid Build Coastguard Worker # define SYSEVENT_NETCHANGED 0x8 /* Network changed */
214*5e7646d2SAndroid Build Coastguard Worker # define SYSEVENT_NAMECHANGED 0x10 /* Computer name changed */
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker /*
218*5e7646d2SAndroid Build Coastguard Worker * Structures...
219*5e7646d2SAndroid Build Coastguard Worker */
220*5e7646d2SAndroid Build Coastguard Worker
221*5e7646d2SAndroid Build Coastguard Worker typedef struct cupsd_sysevent_s /*** System event data ****/
222*5e7646d2SAndroid Build Coastguard Worker {
223*5e7646d2SAndroid Build Coastguard Worker unsigned char event; /* Event bit field */
224*5e7646d2SAndroid Build Coastguard Worker io_connect_t powerKernelPort; /* Power context data */
225*5e7646d2SAndroid Build Coastguard Worker long powerNotificationID; /* Power event data */
226*5e7646d2SAndroid Build Coastguard Worker } cupsd_sysevent_t;
227*5e7646d2SAndroid Build Coastguard Worker
228*5e7646d2SAndroid Build Coastguard Worker
229*5e7646d2SAndroid Build Coastguard Worker typedef struct cupsd_thread_data_s /*** Thread context data ****/
230*5e7646d2SAndroid Build Coastguard Worker {
231*5e7646d2SAndroid Build Coastguard Worker cupsd_sysevent_t sysevent; /* System event */
232*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerRef timerRef; /* Timer to delay some change *
233*5e7646d2SAndroid Build Coastguard Worker * notifications */
234*5e7646d2SAndroid Build Coastguard Worker } cupsd_thread_data_t;
235*5e7646d2SAndroid Build Coastguard Worker
236*5e7646d2SAndroid Build Coastguard Worker
237*5e7646d2SAndroid Build Coastguard Worker /*
238*5e7646d2SAndroid Build Coastguard Worker * Local globals...
239*5e7646d2SAndroid Build Coastguard Worker */
240*5e7646d2SAndroid Build Coastguard Worker
241*5e7646d2SAndroid Build Coastguard Worker static pthread_t SysEventThread = NULL;
242*5e7646d2SAndroid Build Coastguard Worker /* Thread to host a runloop */
243*5e7646d2SAndroid Build Coastguard Worker static pthread_mutex_t SysEventThreadMutex = { 0 };
244*5e7646d2SAndroid Build Coastguard Worker /* Coordinates access to shared gloabals */
245*5e7646d2SAndroid Build Coastguard Worker static pthread_cond_t SysEventThreadCond = { 0 };
246*5e7646d2SAndroid Build Coastguard Worker /* Thread initialization complete condition */
247*5e7646d2SAndroid Build Coastguard Worker static CFRunLoopRef SysEventRunloop = NULL;
248*5e7646d2SAndroid Build Coastguard Worker /* The runloop. Access must be protected! */
249*5e7646d2SAndroid Build Coastguard Worker static CFStringRef ComputerNameKey = NULL,
250*5e7646d2SAndroid Build Coastguard Worker /* Computer name key */
251*5e7646d2SAndroid Build Coastguard Worker BTMMKey = NULL, /* Back to My Mac key */
252*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyIPv4 = NULL,
253*5e7646d2SAndroid Build Coastguard Worker /* Network global IPv4 key */
254*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyIPv6 = NULL,
255*5e7646d2SAndroid Build Coastguard Worker /* Network global IPv6 key */
256*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyDNS = NULL,
257*5e7646d2SAndroid Build Coastguard Worker /* Network global DNS key */
258*5e7646d2SAndroid Build Coastguard Worker HostNamesKey = NULL,
259*5e7646d2SAndroid Build Coastguard Worker /* Host name key */
260*5e7646d2SAndroid Build Coastguard Worker NetworkInterfaceKeyIPv4 = NULL,
261*5e7646d2SAndroid Build Coastguard Worker /* Netowrk interface key */
262*5e7646d2SAndroid Build Coastguard Worker NetworkInterfaceKeyIPv6 = NULL;
263*5e7646d2SAndroid Build Coastguard Worker /* Netowrk interface key */
264*5e7646d2SAndroid Build Coastguard Worker static cupsd_sysevent_t LastSysEvent; /* Last system event (for delayed sleep) */
265*5e7646d2SAndroid Build Coastguard Worker static int NameChanged = 0;/* Did we get a 'name changed' event during sleep? */
266*5e7646d2SAndroid Build Coastguard Worker static int PSToken = 0; /* Power source notifications */
267*5e7646d2SAndroid Build Coastguard Worker
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker /*
270*5e7646d2SAndroid Build Coastguard Worker * Local functions...
271*5e7646d2SAndroid Build Coastguard Worker */
272*5e7646d2SAndroid Build Coastguard Worker
273*5e7646d2SAndroid Build Coastguard Worker static void *sysEventThreadEntry(void);
274*5e7646d2SAndroid Build Coastguard Worker static void sysEventPowerNotifier(void *context, io_service_t service,
275*5e7646d2SAndroid Build Coastguard Worker natural_t messageType,
276*5e7646d2SAndroid Build Coastguard Worker void *messageArgument);
277*5e7646d2SAndroid Build Coastguard Worker static void sysEventConfigurationNotifier(SCDynamicStoreRef store,
278*5e7646d2SAndroid Build Coastguard Worker CFArrayRef changedKeys,
279*5e7646d2SAndroid Build Coastguard Worker void *context);
280*5e7646d2SAndroid Build Coastguard Worker static void sysEventTimerNotifier(CFRunLoopTimerRef timer, void *context);
281*5e7646d2SAndroid Build Coastguard Worker static void sysUpdate(void);
282*5e7646d2SAndroid Build Coastguard Worker static void sysUpdateNames(void);
283*5e7646d2SAndroid Build Coastguard Worker
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker /*
286*5e7646d2SAndroid Build Coastguard Worker * 'cupsdAllowSleep()' - Tell the OS it is now OK to sleep.
287*5e7646d2SAndroid Build Coastguard Worker */
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker void
cupsdAllowSleep(void)290*5e7646d2SAndroid Build Coastguard Worker cupsdAllowSleep(void)
291*5e7646d2SAndroid Build Coastguard Worker {
292*5e7646d2SAndroid Build Coastguard Worker cupsdCleanDirty();
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
295*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(LastSysEvent.powerKernelPort,
296*5e7646d2SAndroid Build Coastguard Worker LastSysEvent.powerNotificationID);
297*5e7646d2SAndroid Build Coastguard Worker }
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker /*
301*5e7646d2SAndroid Build Coastguard Worker * 'cupsdStartSystemMonitor()' - Start monitoring for system change.
302*5e7646d2SAndroid Build Coastguard Worker */
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker void
cupsdStartSystemMonitor(void)305*5e7646d2SAndroid Build Coastguard Worker cupsdStartSystemMonitor(void)
306*5e7646d2SAndroid Build Coastguard Worker {
307*5e7646d2SAndroid Build Coastguard Worker int flags; /* fcntl flags on pipe */
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker
310*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSystemMonitor()");
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker if (cupsdOpenPipe(SysEventPipes))
313*5e7646d2SAndroid Build Coastguard Worker {
314*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "System event monitor pipe() failed - %s!",
315*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
316*5e7646d2SAndroid Build Coastguard Worker return;
317*5e7646d2SAndroid Build Coastguard Worker }
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker cupsdAddSelect(SysEventPipes[0], (cupsd_selfunc_t)sysUpdate, NULL, NULL);
320*5e7646d2SAndroid Build Coastguard Worker
321*5e7646d2SAndroid Build Coastguard Worker /*
322*5e7646d2SAndroid Build Coastguard Worker * Set non-blocking mode on the descriptor we will be receiving notification
323*5e7646d2SAndroid Build Coastguard Worker * events on.
324*5e7646d2SAndroid Build Coastguard Worker */
325*5e7646d2SAndroid Build Coastguard Worker
326*5e7646d2SAndroid Build Coastguard Worker flags = fcntl(SysEventPipes[0], F_GETFL, 0);
327*5e7646d2SAndroid Build Coastguard Worker fcntl(SysEventPipes[0], F_SETFL, flags | O_NONBLOCK);
328*5e7646d2SAndroid Build Coastguard Worker
329*5e7646d2SAndroid Build Coastguard Worker /*
330*5e7646d2SAndroid Build Coastguard Worker * Start the thread that runs the runloop...
331*5e7646d2SAndroid Build Coastguard Worker */
332*5e7646d2SAndroid Build Coastguard Worker
333*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_init(&SysEventThreadMutex, NULL);
334*5e7646d2SAndroid Build Coastguard Worker pthread_cond_init(&SysEventThreadCond, NULL);
335*5e7646d2SAndroid Build Coastguard Worker pthread_create(&SysEventThread, NULL, (void *(*)(void *))sysEventThreadEntry, NULL);
336*5e7646d2SAndroid Build Coastguard Worker
337*5e7646d2SAndroid Build Coastguard Worker /*
338*5e7646d2SAndroid Build Coastguard Worker * Monitor for power source changes via dispatch queue...
339*5e7646d2SAndroid Build Coastguard Worker */
340*5e7646d2SAndroid Build Coastguard Worker
341*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSystemMonitor: IOPSGetTimeRemainingEstimate=%f", IOPSGetTimeRemainingEstimate());
342*5e7646d2SAndroid Build Coastguard Worker ACPower = IOPSGetTimeRemainingEstimate() == kIOPSTimeRemainingUnlimited;
343*5e7646d2SAndroid Build Coastguard Worker notify_register_dispatch(kIOPSNotifyPowerSource, &PSToken, dispatch_get_main_queue(), ^(int t) { (void)t;
344*5e7646d2SAndroid Build Coastguard Worker ACPower = IOPSGetTimeRemainingEstimate() == kIOPSTimeRemainingUnlimited; });
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker
347*5e7646d2SAndroid Build Coastguard Worker
348*5e7646d2SAndroid Build Coastguard Worker /*
349*5e7646d2SAndroid Build Coastguard Worker * 'cupsdStopSystemMonitor()' - Stop monitoring for system change.
350*5e7646d2SAndroid Build Coastguard Worker */
351*5e7646d2SAndroid Build Coastguard Worker
352*5e7646d2SAndroid Build Coastguard Worker void
cupsdStopSystemMonitor(void)353*5e7646d2SAndroid Build Coastguard Worker cupsdStopSystemMonitor(void)
354*5e7646d2SAndroid Build Coastguard Worker {
355*5e7646d2SAndroid Build Coastguard Worker CFRunLoopRef rl; /* The event handler runloop */
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopSystemMonitor()");
359*5e7646d2SAndroid Build Coastguard Worker
360*5e7646d2SAndroid Build Coastguard Worker if (SysEventThread)
361*5e7646d2SAndroid Build Coastguard Worker {
362*5e7646d2SAndroid Build Coastguard Worker /*
363*5e7646d2SAndroid Build Coastguard Worker * Make sure the thread has completed it's initialization and
364*5e7646d2SAndroid Build Coastguard Worker * stored it's runloop reference in the shared global.
365*5e7646d2SAndroid Build Coastguard Worker */
366*5e7646d2SAndroid Build Coastguard Worker
367*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_lock(&SysEventThreadMutex);
368*5e7646d2SAndroid Build Coastguard Worker
369*5e7646d2SAndroid Build Coastguard Worker if (!SysEventRunloop)
370*5e7646d2SAndroid Build Coastguard Worker pthread_cond_wait(&SysEventThreadCond, &SysEventThreadMutex);
371*5e7646d2SAndroid Build Coastguard Worker
372*5e7646d2SAndroid Build Coastguard Worker rl = SysEventRunloop;
373*5e7646d2SAndroid Build Coastguard Worker SysEventRunloop = NULL;
374*5e7646d2SAndroid Build Coastguard Worker
375*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_unlock(&SysEventThreadMutex);
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker if (rl)
378*5e7646d2SAndroid Build Coastguard Worker CFRunLoopStop(rl);
379*5e7646d2SAndroid Build Coastguard Worker
380*5e7646d2SAndroid Build Coastguard Worker pthread_join(SysEventThread, NULL);
381*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_destroy(&SysEventThreadMutex);
382*5e7646d2SAndroid Build Coastguard Worker pthread_cond_destroy(&SysEventThreadCond);
383*5e7646d2SAndroid Build Coastguard Worker }
384*5e7646d2SAndroid Build Coastguard Worker
385*5e7646d2SAndroid Build Coastguard Worker if (SysEventPipes[0] >= 0)
386*5e7646d2SAndroid Build Coastguard Worker {
387*5e7646d2SAndroid Build Coastguard Worker cupsdRemoveSelect(SysEventPipes[0]);
388*5e7646d2SAndroid Build Coastguard Worker cupsdClosePipe(SysEventPipes);
389*5e7646d2SAndroid Build Coastguard Worker }
390*5e7646d2SAndroid Build Coastguard Worker
391*5e7646d2SAndroid Build Coastguard Worker if (PSToken != 0)
392*5e7646d2SAndroid Build Coastguard Worker {
393*5e7646d2SAndroid Build Coastguard Worker notify_cancel(PSToken);
394*5e7646d2SAndroid Build Coastguard Worker PSToken = 0;
395*5e7646d2SAndroid Build Coastguard Worker }
396*5e7646d2SAndroid Build Coastguard Worker }
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker
399*5e7646d2SAndroid Build Coastguard Worker /*
400*5e7646d2SAndroid Build Coastguard Worker * 'sysEventThreadEntry()' - A thread to receive power and computer name
401*5e7646d2SAndroid Build Coastguard Worker * change notifications.
402*5e7646d2SAndroid Build Coastguard Worker */
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker static void * /* O - Return status/value */
sysEventThreadEntry(void)405*5e7646d2SAndroid Build Coastguard Worker sysEventThreadEntry(void)
406*5e7646d2SAndroid Build Coastguard Worker {
407*5e7646d2SAndroid Build Coastguard Worker io_object_t powerNotifierObj;
408*5e7646d2SAndroid Build Coastguard Worker /* Power notifier object */
409*5e7646d2SAndroid Build Coastguard Worker IONotificationPortRef powerNotifierPort;
410*5e7646d2SAndroid Build Coastguard Worker /* Power notifier port */
411*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreRef store = NULL;/* System Config dynamic store */
412*5e7646d2SAndroid Build Coastguard Worker CFRunLoopSourceRef powerRLS = NULL,/* Power runloop source */
413*5e7646d2SAndroid Build Coastguard Worker storeRLS = NULL;/* System Config runloop source */
414*5e7646d2SAndroid Build Coastguard Worker CFStringRef key[6], /* System Config keys */
415*5e7646d2SAndroid Build Coastguard Worker pattern[2]; /* System Config patterns */
416*5e7646d2SAndroid Build Coastguard Worker CFArrayRef keys = NULL, /* System Config key array*/
417*5e7646d2SAndroid Build Coastguard Worker patterns = NULL;/* System Config pattern array */
418*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreContext storeContext; /* Dynamic store context */
419*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerContext timerContext; /* Timer context */
420*5e7646d2SAndroid Build Coastguard Worker cupsd_thread_data_t threadData; /* Thread context data for the *
421*5e7646d2SAndroid Build Coastguard Worker * runloop notifiers */
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker /*
425*5e7646d2SAndroid Build Coastguard Worker * Register for power state change notifications
426*5e7646d2SAndroid Build Coastguard Worker */
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker memset(&threadData, 0, sizeof(threadData));
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker threadData.sysevent.powerKernelPort =
431*5e7646d2SAndroid Build Coastguard Worker IORegisterForSystemPower(&threadData, &powerNotifierPort,
432*5e7646d2SAndroid Build Coastguard Worker sysEventPowerNotifier, &powerNotifierObj);
433*5e7646d2SAndroid Build Coastguard Worker
434*5e7646d2SAndroid Build Coastguard Worker if (threadData.sysevent.powerKernelPort)
435*5e7646d2SAndroid Build Coastguard Worker {
436*5e7646d2SAndroid Build Coastguard Worker powerRLS = IONotificationPortGetRunLoopSource(powerNotifierPort);
437*5e7646d2SAndroid Build Coastguard Worker CFRunLoopAddSource(CFRunLoopGetCurrent(), powerRLS, kCFRunLoopDefaultMode);
438*5e7646d2SAndroid Build Coastguard Worker }
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker /*
441*5e7646d2SAndroid Build Coastguard Worker * Register for system configuration change notifications
442*5e7646d2SAndroid Build Coastguard Worker */
443*5e7646d2SAndroid Build Coastguard Worker
444*5e7646d2SAndroid Build Coastguard Worker memset(&storeContext, 0, sizeof(storeContext));
445*5e7646d2SAndroid Build Coastguard Worker storeContext.info = &threadData;
446*5e7646d2SAndroid Build Coastguard Worker
447*5e7646d2SAndroid Build Coastguard Worker store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"),
448*5e7646d2SAndroid Build Coastguard Worker sysEventConfigurationNotifier, &storeContext);
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker if (!ComputerNameKey)
451*5e7646d2SAndroid Build Coastguard Worker ComputerNameKey = SCDynamicStoreKeyCreateComputerName(kCFAllocatorDefault);
452*5e7646d2SAndroid Build Coastguard Worker
453*5e7646d2SAndroid Build Coastguard Worker if (!BTMMKey)
454*5e7646d2SAndroid Build Coastguard Worker BTMMKey = SCDynamicStoreKeyCreate(kCFAllocatorDefault,
455*5e7646d2SAndroid Build Coastguard Worker CFSTR("Setup:/Network/BackToMyMac"));
456*5e7646d2SAndroid Build Coastguard Worker
457*5e7646d2SAndroid Build Coastguard Worker if (!NetworkGlobalKeyIPv4)
458*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyIPv4 =
459*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault,
460*5e7646d2SAndroid Build Coastguard Worker kSCDynamicStoreDomainState,
461*5e7646d2SAndroid Build Coastguard Worker kSCEntNetIPv4);
462*5e7646d2SAndroid Build Coastguard Worker
463*5e7646d2SAndroid Build Coastguard Worker if (!NetworkGlobalKeyIPv6)
464*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyIPv6 =
465*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault,
466*5e7646d2SAndroid Build Coastguard Worker kSCDynamicStoreDomainState,
467*5e7646d2SAndroid Build Coastguard Worker kSCEntNetIPv6);
468*5e7646d2SAndroid Build Coastguard Worker
469*5e7646d2SAndroid Build Coastguard Worker if (!NetworkGlobalKeyDNS)
470*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyDNS =
471*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault,
472*5e7646d2SAndroid Build Coastguard Worker kSCDynamicStoreDomainState,
473*5e7646d2SAndroid Build Coastguard Worker kSCEntNetDNS);
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (!HostNamesKey)
476*5e7646d2SAndroid Build Coastguard Worker HostNamesKey = SCDynamicStoreKeyCreateHostNames(kCFAllocatorDefault);
477*5e7646d2SAndroid Build Coastguard Worker
478*5e7646d2SAndroid Build Coastguard Worker if (!NetworkInterfaceKeyIPv4)
479*5e7646d2SAndroid Build Coastguard Worker NetworkInterfaceKeyIPv4 =
480*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault,
481*5e7646d2SAndroid Build Coastguard Worker kSCDynamicStoreDomainState,
482*5e7646d2SAndroid Build Coastguard Worker kSCCompAnyRegex,
483*5e7646d2SAndroid Build Coastguard Worker kSCEntNetIPv4);
484*5e7646d2SAndroid Build Coastguard Worker
485*5e7646d2SAndroid Build Coastguard Worker if (!NetworkInterfaceKeyIPv6)
486*5e7646d2SAndroid Build Coastguard Worker NetworkInterfaceKeyIPv6 =
487*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault,
488*5e7646d2SAndroid Build Coastguard Worker kSCDynamicStoreDomainState,
489*5e7646d2SAndroid Build Coastguard Worker kSCCompAnyRegex,
490*5e7646d2SAndroid Build Coastguard Worker kSCEntNetIPv6);
491*5e7646d2SAndroid Build Coastguard Worker
492*5e7646d2SAndroid Build Coastguard Worker if (store && ComputerNameKey && HostNamesKey &&
493*5e7646d2SAndroid Build Coastguard Worker NetworkGlobalKeyIPv4 && NetworkGlobalKeyIPv6 && NetworkGlobalKeyDNS &&
494*5e7646d2SAndroid Build Coastguard Worker NetworkInterfaceKeyIPv4 && NetworkInterfaceKeyIPv6)
495*5e7646d2SAndroid Build Coastguard Worker {
496*5e7646d2SAndroid Build Coastguard Worker key[0] = ComputerNameKey;
497*5e7646d2SAndroid Build Coastguard Worker key[1] = BTMMKey;
498*5e7646d2SAndroid Build Coastguard Worker key[2] = NetworkGlobalKeyIPv4;
499*5e7646d2SAndroid Build Coastguard Worker key[3] = NetworkGlobalKeyIPv6;
500*5e7646d2SAndroid Build Coastguard Worker key[4] = NetworkGlobalKeyDNS;
501*5e7646d2SAndroid Build Coastguard Worker key[5] = HostNamesKey;
502*5e7646d2SAndroid Build Coastguard Worker
503*5e7646d2SAndroid Build Coastguard Worker pattern[0] = NetworkInterfaceKeyIPv4;
504*5e7646d2SAndroid Build Coastguard Worker pattern[1] = NetworkInterfaceKeyIPv6;
505*5e7646d2SAndroid Build Coastguard Worker
506*5e7646d2SAndroid Build Coastguard Worker keys = CFArrayCreate(kCFAllocatorDefault, (const void **)key,
507*5e7646d2SAndroid Build Coastguard Worker sizeof(key) / sizeof(key[0]),
508*5e7646d2SAndroid Build Coastguard Worker &kCFTypeArrayCallBacks);
509*5e7646d2SAndroid Build Coastguard Worker
510*5e7646d2SAndroid Build Coastguard Worker patterns = CFArrayCreate(kCFAllocatorDefault, (const void **)pattern,
511*5e7646d2SAndroid Build Coastguard Worker sizeof(pattern) / sizeof(pattern[0]),
512*5e7646d2SAndroid Build Coastguard Worker &kCFTypeArrayCallBacks);
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker if (keys && patterns &&
515*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreSetNotificationKeys(store, keys, patterns))
516*5e7646d2SAndroid Build Coastguard Worker {
517*5e7646d2SAndroid Build Coastguard Worker if ((storeRLS = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault,
518*5e7646d2SAndroid Build Coastguard Worker store, 0)) != NULL)
519*5e7646d2SAndroid Build Coastguard Worker {
520*5e7646d2SAndroid Build Coastguard Worker CFRunLoopAddSource(CFRunLoopGetCurrent(), storeRLS,
521*5e7646d2SAndroid Build Coastguard Worker kCFRunLoopDefaultMode);
522*5e7646d2SAndroid Build Coastguard Worker }
523*5e7646d2SAndroid Build Coastguard Worker }
524*5e7646d2SAndroid Build Coastguard Worker }
525*5e7646d2SAndroid Build Coastguard Worker
526*5e7646d2SAndroid Build Coastguard Worker if (keys)
527*5e7646d2SAndroid Build Coastguard Worker CFRelease(keys);
528*5e7646d2SAndroid Build Coastguard Worker
529*5e7646d2SAndroid Build Coastguard Worker if (patterns)
530*5e7646d2SAndroid Build Coastguard Worker CFRelease(patterns);
531*5e7646d2SAndroid Build Coastguard Worker
532*5e7646d2SAndroid Build Coastguard Worker /*
533*5e7646d2SAndroid Build Coastguard Worker * Set up a timer to delay the wake change notifications.
534*5e7646d2SAndroid Build Coastguard Worker *
535*5e7646d2SAndroid Build Coastguard Worker * The initial time is set a decade or so into the future, we'll adjust
536*5e7646d2SAndroid Build Coastguard Worker * this later.
537*5e7646d2SAndroid Build Coastguard Worker */
538*5e7646d2SAndroid Build Coastguard Worker
539*5e7646d2SAndroid Build Coastguard Worker memset(&timerContext, 0, sizeof(timerContext));
540*5e7646d2SAndroid Build Coastguard Worker timerContext.info = &threadData;
541*5e7646d2SAndroid Build Coastguard Worker
542*5e7646d2SAndroid Build Coastguard Worker threadData.timerRef =
543*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerCreate(kCFAllocatorDefault,
544*5e7646d2SAndroid Build Coastguard Worker CFAbsoluteTimeGetCurrent() + (86400L * 365L * 10L),
545*5e7646d2SAndroid Build Coastguard Worker 86400L * 365L * 10L, 0, 0, sysEventTimerNotifier,
546*5e7646d2SAndroid Build Coastguard Worker &timerContext);
547*5e7646d2SAndroid Build Coastguard Worker CFRunLoopAddTimer(CFRunLoopGetCurrent(), threadData.timerRef,
548*5e7646d2SAndroid Build Coastguard Worker kCFRunLoopDefaultMode);
549*5e7646d2SAndroid Build Coastguard Worker
550*5e7646d2SAndroid Build Coastguard Worker /*
551*5e7646d2SAndroid Build Coastguard Worker * Store our runloop in a global so the main thread can use it to stop us.
552*5e7646d2SAndroid Build Coastguard Worker */
553*5e7646d2SAndroid Build Coastguard Worker
554*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_lock(&SysEventThreadMutex);
555*5e7646d2SAndroid Build Coastguard Worker
556*5e7646d2SAndroid Build Coastguard Worker SysEventRunloop = CFRunLoopGetCurrent();
557*5e7646d2SAndroid Build Coastguard Worker
558*5e7646d2SAndroid Build Coastguard Worker pthread_cond_signal(&SysEventThreadCond);
559*5e7646d2SAndroid Build Coastguard Worker pthread_mutex_unlock(&SysEventThreadMutex);
560*5e7646d2SAndroid Build Coastguard Worker
561*5e7646d2SAndroid Build Coastguard Worker /*
562*5e7646d2SAndroid Build Coastguard Worker * Disappear into the runloop until it's stopped by the main thread.
563*5e7646d2SAndroid Build Coastguard Worker */
564*5e7646d2SAndroid Build Coastguard Worker
565*5e7646d2SAndroid Build Coastguard Worker CFRunLoopRun();
566*5e7646d2SAndroid Build Coastguard Worker
567*5e7646d2SAndroid Build Coastguard Worker /*
568*5e7646d2SAndroid Build Coastguard Worker * Clean up before exiting.
569*5e7646d2SAndroid Build Coastguard Worker */
570*5e7646d2SAndroid Build Coastguard Worker
571*5e7646d2SAndroid Build Coastguard Worker if (threadData.timerRef)
572*5e7646d2SAndroid Build Coastguard Worker {
573*5e7646d2SAndroid Build Coastguard Worker CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), threadData.timerRef,
574*5e7646d2SAndroid Build Coastguard Worker kCFRunLoopDefaultMode);
575*5e7646d2SAndroid Build Coastguard Worker CFRelease(threadData.timerRef);
576*5e7646d2SAndroid Build Coastguard Worker }
577*5e7646d2SAndroid Build Coastguard Worker
578*5e7646d2SAndroid Build Coastguard Worker if (threadData.sysevent.powerKernelPort)
579*5e7646d2SAndroid Build Coastguard Worker {
580*5e7646d2SAndroid Build Coastguard Worker CFRunLoopRemoveSource(CFRunLoopGetCurrent(), powerRLS,
581*5e7646d2SAndroid Build Coastguard Worker kCFRunLoopDefaultMode);
582*5e7646d2SAndroid Build Coastguard Worker IODeregisterForSystemPower(&powerNotifierObj);
583*5e7646d2SAndroid Build Coastguard Worker IOServiceClose(threadData.sysevent.powerKernelPort);
584*5e7646d2SAndroid Build Coastguard Worker IONotificationPortDestroy(powerNotifierPort);
585*5e7646d2SAndroid Build Coastguard Worker }
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker if (storeRLS)
588*5e7646d2SAndroid Build Coastguard Worker {
589*5e7646d2SAndroid Build Coastguard Worker CFRunLoopRemoveSource(CFRunLoopGetCurrent(), storeRLS,
590*5e7646d2SAndroid Build Coastguard Worker kCFRunLoopDefaultMode);
591*5e7646d2SAndroid Build Coastguard Worker CFRunLoopSourceInvalidate(storeRLS);
592*5e7646d2SAndroid Build Coastguard Worker CFRelease(storeRLS);
593*5e7646d2SAndroid Build Coastguard Worker }
594*5e7646d2SAndroid Build Coastguard Worker
595*5e7646d2SAndroid Build Coastguard Worker if (store)
596*5e7646d2SAndroid Build Coastguard Worker CFRelease(store);
597*5e7646d2SAndroid Build Coastguard Worker
598*5e7646d2SAndroid Build Coastguard Worker pthread_exit(NULL);
599*5e7646d2SAndroid Build Coastguard Worker }
600*5e7646d2SAndroid Build Coastguard Worker
601*5e7646d2SAndroid Build Coastguard Worker
602*5e7646d2SAndroid Build Coastguard Worker /*
603*5e7646d2SAndroid Build Coastguard Worker * 'sysEventPowerNotifier()' - Handle power notification events.
604*5e7646d2SAndroid Build Coastguard Worker */
605*5e7646d2SAndroid Build Coastguard Worker
606*5e7646d2SAndroid Build Coastguard Worker static void
sysEventPowerNotifier(void * context,io_service_t service,natural_t messageType,void * messageArgument)607*5e7646d2SAndroid Build Coastguard Worker sysEventPowerNotifier(
608*5e7646d2SAndroid Build Coastguard Worker void *context, /* I - Thread context data */
609*5e7646d2SAndroid Build Coastguard Worker io_service_t service, /* I - Unused service info */
610*5e7646d2SAndroid Build Coastguard Worker natural_t messageType, /* I - Type of message */
611*5e7646d2SAndroid Build Coastguard Worker void *messageArgument) /* I - Message data */
612*5e7646d2SAndroid Build Coastguard Worker {
613*5e7646d2SAndroid Build Coastguard Worker int sendit = 1; /* Send event to main thread? *
614*5e7646d2SAndroid Build Coastguard Worker * (0 = no, 1 = yes, 2 = delayed */
615*5e7646d2SAndroid Build Coastguard Worker cupsd_thread_data_t *threadData; /* Thread context data */
616*5e7646d2SAndroid Build Coastguard Worker
617*5e7646d2SAndroid Build Coastguard Worker
618*5e7646d2SAndroid Build Coastguard Worker threadData = (cupsd_thread_data_t *)context;
619*5e7646d2SAndroid Build Coastguard Worker
620*5e7646d2SAndroid Build Coastguard Worker (void)service; /* anti-compiler-warning-code */
621*5e7646d2SAndroid Build Coastguard Worker
622*5e7646d2SAndroid Build Coastguard Worker switch (messageType)
623*5e7646d2SAndroid Build Coastguard Worker {
624*5e7646d2SAndroid Build Coastguard Worker case kIOMessageCanSystemPowerOff :
625*5e7646d2SAndroid Build Coastguard Worker case kIOMessageCanSystemSleep :
626*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event |= SYSEVENT_CANSLEEP;
627*5e7646d2SAndroid Build Coastguard Worker break;
628*5e7646d2SAndroid Build Coastguard Worker
629*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillRestart :
630*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillPowerOff :
631*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillSleep :
632*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event |= SYSEVENT_WILLSLEEP;
633*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event &= ~SYSEVENT_WOKE;
634*5e7646d2SAndroid Build Coastguard Worker break;
635*5e7646d2SAndroid Build Coastguard Worker
636*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemHasPoweredOn :
637*5e7646d2SAndroid Build Coastguard Worker /*
638*5e7646d2SAndroid Build Coastguard Worker * Because powered on is followed by a net-changed event, delay
639*5e7646d2SAndroid Build Coastguard Worker * before sending it.
640*5e7646d2SAndroid Build Coastguard Worker */
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker sendit = 2;
643*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event |= SYSEVENT_WOKE;
644*5e7646d2SAndroid Build Coastguard Worker break;
645*5e7646d2SAndroid Build Coastguard Worker
646*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillNotPowerOff :
647*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillNotSleep :
648*5e7646d2SAndroid Build Coastguard Worker # ifdef kIOMessageSystemWillPowerOn
649*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillPowerOn :
650*5e7646d2SAndroid Build Coastguard Worker # endif /* kIOMessageSystemWillPowerOn */
651*5e7646d2SAndroid Build Coastguard Worker default:
652*5e7646d2SAndroid Build Coastguard Worker sendit = 0;
653*5e7646d2SAndroid Build Coastguard Worker break;
654*5e7646d2SAndroid Build Coastguard Worker }
655*5e7646d2SAndroid Build Coastguard Worker
656*5e7646d2SAndroid Build Coastguard Worker switch (messageType)
657*5e7646d2SAndroid Build Coastguard Worker {
658*5e7646d2SAndroid Build Coastguard Worker case kIOMessageCanSystemPowerOff :
659*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
660*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageCanSystemPowerOff message.");
661*5e7646d2SAndroid Build Coastguard Worker break;
662*5e7646d2SAndroid Build Coastguard Worker case kIOMessageCanSystemSleep :
663*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
664*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageCannSystemSleep message.");
665*5e7646d2SAndroid Build Coastguard Worker break;
666*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillRestart :
667*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
668*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillRestart message.");
669*5e7646d2SAndroid Build Coastguard Worker break;
670*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillPowerOff :
671*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
672*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillPowerOff message.");
673*5e7646d2SAndroid Build Coastguard Worker break;
674*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillSleep :
675*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
676*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillSleep message.");
677*5e7646d2SAndroid Build Coastguard Worker break;
678*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemHasPoweredOn :
679*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
680*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemHasPoweredOn message.");
681*5e7646d2SAndroid Build Coastguard Worker break;
682*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillNotPowerOff :
683*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
684*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillNotPowerOff message.");
685*5e7646d2SAndroid Build Coastguard Worker break;
686*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillNotSleep :
687*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
688*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillNotSleep message.");
689*5e7646d2SAndroid Build Coastguard Worker break;
690*5e7646d2SAndroid Build Coastguard Worker # ifdef kIOMessageSystemWillPowerOn
691*5e7646d2SAndroid Build Coastguard Worker case kIOMessageSystemWillPowerOn :
692*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
693*5e7646d2SAndroid Build Coastguard Worker "Got kIOMessageSystemWillPowerOn message.");
694*5e7646d2SAndroid Build Coastguard Worker break;
695*5e7646d2SAndroid Build Coastguard Worker # endif /* kIOMessageSystemWillPowerOn */
696*5e7646d2SAndroid Build Coastguard Worker default:
697*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Got unknown power message %d.",
698*5e7646d2SAndroid Build Coastguard Worker (int)messageType);
699*5e7646d2SAndroid Build Coastguard Worker break;
700*5e7646d2SAndroid Build Coastguard Worker }
701*5e7646d2SAndroid Build Coastguard Worker
702*5e7646d2SAndroid Build Coastguard Worker if (sendit == 0)
703*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(threadData->sysevent.powerKernelPort,
704*5e7646d2SAndroid Build Coastguard Worker (long)messageArgument);
705*5e7646d2SAndroid Build Coastguard Worker else
706*5e7646d2SAndroid Build Coastguard Worker {
707*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.powerNotificationID = (long)messageArgument;
708*5e7646d2SAndroid Build Coastguard Worker
709*5e7646d2SAndroid Build Coastguard Worker if (sendit == 1)
710*5e7646d2SAndroid Build Coastguard Worker {
711*5e7646d2SAndroid Build Coastguard Worker /*
712*5e7646d2SAndroid Build Coastguard Worker * Send the event to the main thread now.
713*5e7646d2SAndroid Build Coastguard Worker */
714*5e7646d2SAndroid Build Coastguard Worker
715*5e7646d2SAndroid Build Coastguard Worker write(SysEventPipes[1], &threadData->sysevent,
716*5e7646d2SAndroid Build Coastguard Worker sizeof(threadData->sysevent));
717*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event = 0;
718*5e7646d2SAndroid Build Coastguard Worker }
719*5e7646d2SAndroid Build Coastguard Worker else
720*5e7646d2SAndroid Build Coastguard Worker {
721*5e7646d2SAndroid Build Coastguard Worker /*
722*5e7646d2SAndroid Build Coastguard Worker * Send the event to the main thread after 1 to 2 seconds.
723*5e7646d2SAndroid Build Coastguard Worker */
724*5e7646d2SAndroid Build Coastguard Worker
725*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerSetNextFireDate(threadData->timerRef,
726*5e7646d2SAndroid Build Coastguard Worker CFAbsoluteTimeGetCurrent() + 2);
727*5e7646d2SAndroid Build Coastguard Worker }
728*5e7646d2SAndroid Build Coastguard Worker }
729*5e7646d2SAndroid Build Coastguard Worker }
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker
732*5e7646d2SAndroid Build Coastguard Worker /*
733*5e7646d2SAndroid Build Coastguard Worker * 'sysEventConfigurationNotifier()' - Network configuration change notification
734*5e7646d2SAndroid Build Coastguard Worker * callback.
735*5e7646d2SAndroid Build Coastguard Worker */
736*5e7646d2SAndroid Build Coastguard Worker
737*5e7646d2SAndroid Build Coastguard Worker static void
sysEventConfigurationNotifier(SCDynamicStoreRef store,CFArrayRef changedKeys,void * context)738*5e7646d2SAndroid Build Coastguard Worker sysEventConfigurationNotifier(
739*5e7646d2SAndroid Build Coastguard Worker SCDynamicStoreRef store, /* I - System data (unused) */
740*5e7646d2SAndroid Build Coastguard Worker CFArrayRef changedKeys, /* I - Changed data */
741*5e7646d2SAndroid Build Coastguard Worker void *context) /* I - Thread context data */
742*5e7646d2SAndroid Build Coastguard Worker {
743*5e7646d2SAndroid Build Coastguard Worker cupsd_thread_data_t *threadData; /* Thread context data */
744*5e7646d2SAndroid Build Coastguard Worker
745*5e7646d2SAndroid Build Coastguard Worker
746*5e7646d2SAndroid Build Coastguard Worker threadData = (cupsd_thread_data_t *)context;
747*5e7646d2SAndroid Build Coastguard Worker
748*5e7646d2SAndroid Build Coastguard Worker (void)store; /* anti-compiler-warning-code */
749*5e7646d2SAndroid Build Coastguard Worker
750*5e7646d2SAndroid Build Coastguard Worker CFRange range = CFRangeMake(0, CFArrayGetCount(changedKeys));
751*5e7646d2SAndroid Build Coastguard Worker
752*5e7646d2SAndroid Build Coastguard Worker if (CFArrayContainsValue(changedKeys, range, ComputerNameKey) ||
753*5e7646d2SAndroid Build Coastguard Worker CFArrayContainsValue(changedKeys, range, BTMMKey))
754*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event |= SYSEVENT_NAMECHANGED;
755*5e7646d2SAndroid Build Coastguard Worker else
756*5e7646d2SAndroid Build Coastguard Worker {
757*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event |= SYSEVENT_NETCHANGED;
758*5e7646d2SAndroid Build Coastguard Worker
759*5e7646d2SAndroid Build Coastguard Worker /*
760*5e7646d2SAndroid Build Coastguard Worker * Indicate the network interface list needs updating...
761*5e7646d2SAndroid Build Coastguard Worker */
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker NetIFUpdate = 1;
764*5e7646d2SAndroid Build Coastguard Worker }
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker /*
767*5e7646d2SAndroid Build Coastguard Worker * Because we registered for several different kinds of change notifications
768*5e7646d2SAndroid Build Coastguard Worker * this callback usually gets called several times in a row. We use a timer to
769*5e7646d2SAndroid Build Coastguard Worker * de-bounce these so we only end up generating one event for the main thread.
770*5e7646d2SAndroid Build Coastguard Worker */
771*5e7646d2SAndroid Build Coastguard Worker
772*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerSetNextFireDate(threadData->timerRef,
773*5e7646d2SAndroid Build Coastguard Worker CFAbsoluteTimeGetCurrent() + 5);
774*5e7646d2SAndroid Build Coastguard Worker }
775*5e7646d2SAndroid Build Coastguard Worker
776*5e7646d2SAndroid Build Coastguard Worker
777*5e7646d2SAndroid Build Coastguard Worker /*
778*5e7646d2SAndroid Build Coastguard Worker * 'sysEventTimerNotifier()' - Handle delayed event notifications.
779*5e7646d2SAndroid Build Coastguard Worker */
780*5e7646d2SAndroid Build Coastguard Worker
781*5e7646d2SAndroid Build Coastguard Worker static void
sysEventTimerNotifier(CFRunLoopTimerRef timer,void * context)782*5e7646d2SAndroid Build Coastguard Worker sysEventTimerNotifier(
783*5e7646d2SAndroid Build Coastguard Worker CFRunLoopTimerRef timer, /* I - Timer information */
784*5e7646d2SAndroid Build Coastguard Worker void *context) /* I - Thread context data */
785*5e7646d2SAndroid Build Coastguard Worker {
786*5e7646d2SAndroid Build Coastguard Worker cupsd_thread_data_t *threadData; /* Thread context data */
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker
789*5e7646d2SAndroid Build Coastguard Worker (void)timer;
790*5e7646d2SAndroid Build Coastguard Worker
791*5e7646d2SAndroid Build Coastguard Worker threadData = (cupsd_thread_data_t *)context;
792*5e7646d2SAndroid Build Coastguard Worker
793*5e7646d2SAndroid Build Coastguard Worker /*
794*5e7646d2SAndroid Build Coastguard Worker * If an event is still pending send it to the main thread.
795*5e7646d2SAndroid Build Coastguard Worker */
796*5e7646d2SAndroid Build Coastguard Worker
797*5e7646d2SAndroid Build Coastguard Worker if (threadData->sysevent.event)
798*5e7646d2SAndroid Build Coastguard Worker {
799*5e7646d2SAndroid Build Coastguard Worker write(SysEventPipes[1], &threadData->sysevent,
800*5e7646d2SAndroid Build Coastguard Worker sizeof(threadData->sysevent));
801*5e7646d2SAndroid Build Coastguard Worker threadData->sysevent.event = 0;
802*5e7646d2SAndroid Build Coastguard Worker }
803*5e7646d2SAndroid Build Coastguard Worker }
804*5e7646d2SAndroid Build Coastguard Worker
805*5e7646d2SAndroid Build Coastguard Worker
806*5e7646d2SAndroid Build Coastguard Worker /*
807*5e7646d2SAndroid Build Coastguard Worker * 'sysUpdate()' - Update the current system state.
808*5e7646d2SAndroid Build Coastguard Worker */
809*5e7646d2SAndroid Build Coastguard Worker
810*5e7646d2SAndroid Build Coastguard Worker static void
sysUpdate(void)811*5e7646d2SAndroid Build Coastguard Worker sysUpdate(void)
812*5e7646d2SAndroid Build Coastguard Worker {
813*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
814*5e7646d2SAndroid Build Coastguard Worker cupsd_sysevent_t sysevent; /* The system event */
815*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p; /* Printer information */
816*5e7646d2SAndroid Build Coastguard Worker
817*5e7646d2SAndroid Build Coastguard Worker
818*5e7646d2SAndroid Build Coastguard Worker /*
819*5e7646d2SAndroid Build Coastguard Worker * Drain the event pipe...
820*5e7646d2SAndroid Build Coastguard Worker */
821*5e7646d2SAndroid Build Coastguard Worker
822*5e7646d2SAndroid Build Coastguard Worker while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent))
823*5e7646d2SAndroid Build Coastguard Worker == sizeof(sysevent))
824*5e7646d2SAndroid Build Coastguard Worker {
825*5e7646d2SAndroid Build Coastguard Worker if (sysevent.event & SYSEVENT_CANSLEEP)
826*5e7646d2SAndroid Build Coastguard Worker {
827*5e7646d2SAndroid Build Coastguard Worker /*
828*5e7646d2SAndroid Build Coastguard Worker * If there are active printers that don't have the connecting-to-device
829*5e7646d2SAndroid Build Coastguard Worker * or cups-waiting-for-job-completed printer-state-reason then cancel the
830*5e7646d2SAndroid Build Coastguard Worker * sleep request, i.e., these reasons indicate a job that is not actively
831*5e7646d2SAndroid Build Coastguard Worker * doing anything...
832*5e7646d2SAndroid Build Coastguard Worker */
833*5e7646d2SAndroid Build Coastguard Worker
834*5e7646d2SAndroid Build Coastguard Worker for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
835*5e7646d2SAndroid Build Coastguard Worker p;
836*5e7646d2SAndroid Build Coastguard Worker p = (cupsd_printer_t *)cupsArrayNext(Printers))
837*5e7646d2SAndroid Build Coastguard Worker {
838*5e7646d2SAndroid Build Coastguard Worker if (p->job)
839*5e7646d2SAndroid Build Coastguard Worker {
840*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < p->num_reasons; i ++)
841*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(p->reasons[i], "connecting-to-device") ||
842*5e7646d2SAndroid Build Coastguard Worker !strcmp(p->reasons[i], "cups-waiting-for-job-completed"))
843*5e7646d2SAndroid Build Coastguard Worker break;
844*5e7646d2SAndroid Build Coastguard Worker
845*5e7646d2SAndroid Build Coastguard Worker if (!p->num_reasons || i >= p->num_reasons)
846*5e7646d2SAndroid Build Coastguard Worker break;
847*5e7646d2SAndroid Build Coastguard Worker }
848*5e7646d2SAndroid Build Coastguard Worker }
849*5e7646d2SAndroid Build Coastguard Worker
850*5e7646d2SAndroid Build Coastguard Worker if (p)
851*5e7646d2SAndroid Build Coastguard Worker {
852*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO,
853*5e7646d2SAndroid Build Coastguard Worker "System sleep canceled because printer %s is active.",
854*5e7646d2SAndroid Build Coastguard Worker p->name);
855*5e7646d2SAndroid Build Coastguard Worker IOCancelPowerChange(sysevent.powerKernelPort,
856*5e7646d2SAndroid Build Coastguard Worker sysevent.powerNotificationID);
857*5e7646d2SAndroid Build Coastguard Worker }
858*5e7646d2SAndroid Build Coastguard Worker else
859*5e7646d2SAndroid Build Coastguard Worker {
860*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep.");
861*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(sysevent.powerKernelPort,
862*5e7646d2SAndroid Build Coastguard Worker sysevent.powerNotificationID);
863*5e7646d2SAndroid Build Coastguard Worker }
864*5e7646d2SAndroid Build Coastguard Worker }
865*5e7646d2SAndroid Build Coastguard Worker
866*5e7646d2SAndroid Build Coastguard Worker if (sysevent.event & SYSEVENT_WILLSLEEP)
867*5e7646d2SAndroid Build Coastguard Worker {
868*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep.");
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker Sleeping = 1;
871*5e7646d2SAndroid Build Coastguard Worker
872*5e7646d2SAndroid Build Coastguard Worker cupsdCleanDirty();
873*5e7646d2SAndroid Build Coastguard Worker
874*5e7646d2SAndroid Build Coastguard Worker /*
875*5e7646d2SAndroid Build Coastguard Worker * If we have no printing jobs, allow the power change immediately.
876*5e7646d2SAndroid Build Coastguard Worker * Otherwise set the SleepJobs time to 10 seconds in the future when
877*5e7646d2SAndroid Build Coastguard Worker * we'll take more drastic measures...
878*5e7646d2SAndroid Build Coastguard Worker */
879*5e7646d2SAndroid Build Coastguard Worker
880*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayCount(PrintingJobs) == 0)
881*5e7646d2SAndroid Build Coastguard Worker {
882*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
883*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(sysevent.powerKernelPort,
884*5e7646d2SAndroid Build Coastguard Worker sysevent.powerNotificationID);
885*5e7646d2SAndroid Build Coastguard Worker }
886*5e7646d2SAndroid Build Coastguard Worker else
887*5e7646d2SAndroid Build Coastguard Worker {
888*5e7646d2SAndroid Build Coastguard Worker /*
889*5e7646d2SAndroid Build Coastguard Worker * If there are active printers that don't have the connecting-to-device
890*5e7646d2SAndroid Build Coastguard Worker * or cups-waiting-for-job-completed printer-state-reasons then delay the
891*5e7646d2SAndroid Build Coastguard Worker * sleep request, i.e., these reasons indicate a job is active...
892*5e7646d2SAndroid Build Coastguard Worker */
893*5e7646d2SAndroid Build Coastguard Worker
894*5e7646d2SAndroid Build Coastguard Worker for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
895*5e7646d2SAndroid Build Coastguard Worker p;
896*5e7646d2SAndroid Build Coastguard Worker p = (cupsd_printer_t *)cupsArrayNext(Printers))
897*5e7646d2SAndroid Build Coastguard Worker {
898*5e7646d2SAndroid Build Coastguard Worker if (p->job)
899*5e7646d2SAndroid Build Coastguard Worker {
900*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < p->num_reasons; i ++)
901*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(p->reasons[i], "connecting-to-device") ||
902*5e7646d2SAndroid Build Coastguard Worker !strcmp(p->reasons[i], "cups-waiting-for-job-completed"))
903*5e7646d2SAndroid Build Coastguard Worker break;
904*5e7646d2SAndroid Build Coastguard Worker
905*5e7646d2SAndroid Build Coastguard Worker if (!p->num_reasons || i >= p->num_reasons)
906*5e7646d2SAndroid Build Coastguard Worker break;
907*5e7646d2SAndroid Build Coastguard Worker }
908*5e7646d2SAndroid Build Coastguard Worker }
909*5e7646d2SAndroid Build Coastguard Worker
910*5e7646d2SAndroid Build Coastguard Worker if (p)
911*5e7646d2SAndroid Build Coastguard Worker {
912*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_INFO,
913*5e7646d2SAndroid Build Coastguard Worker "System sleep delayed because printer %s is active.",
914*5e7646d2SAndroid Build Coastguard Worker p->name);
915*5e7646d2SAndroid Build Coastguard Worker
916*5e7646d2SAndroid Build Coastguard Worker LastSysEvent = sysevent;
917*5e7646d2SAndroid Build Coastguard Worker SleepJobs = time(NULL) + 10;
918*5e7646d2SAndroid Build Coastguard Worker }
919*5e7646d2SAndroid Build Coastguard Worker else
920*5e7646d2SAndroid Build Coastguard Worker {
921*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
922*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(sysevent.powerKernelPort,
923*5e7646d2SAndroid Build Coastguard Worker sysevent.powerNotificationID);
924*5e7646d2SAndroid Build Coastguard Worker }
925*5e7646d2SAndroid Build Coastguard Worker }
926*5e7646d2SAndroid Build Coastguard Worker }
927*5e7646d2SAndroid Build Coastguard Worker
928*5e7646d2SAndroid Build Coastguard Worker if (sysevent.event & SYSEVENT_WOKE)
929*5e7646d2SAndroid Build Coastguard Worker {
930*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep.");
931*5e7646d2SAndroid Build Coastguard Worker IOAllowPowerChange(sysevent.powerKernelPort,
932*5e7646d2SAndroid Build Coastguard Worker sysevent.powerNotificationID);
933*5e7646d2SAndroid Build Coastguard Worker Sleeping = 0;
934*5e7646d2SAndroid Build Coastguard Worker
935*5e7646d2SAndroid Build Coastguard Worker /*
936*5e7646d2SAndroid Build Coastguard Worker * Make sure jobs that were queued prior to the system going to sleep don't
937*5e7646d2SAndroid Build Coastguard Worker * get canceled right away...
938*5e7646d2SAndroid Build Coastguard Worker */
939*5e7646d2SAndroid Build Coastguard Worker
940*5e7646d2SAndroid Build Coastguard Worker if (MaxJobTime > 0)
941*5e7646d2SAndroid Build Coastguard Worker {
942*5e7646d2SAndroid Build Coastguard Worker cupsd_job_t *job; /* Current job */
943*5e7646d2SAndroid Build Coastguard Worker
944*5e7646d2SAndroid Build Coastguard Worker for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
945*5e7646d2SAndroid Build Coastguard Worker job;
946*5e7646d2SAndroid Build Coastguard Worker job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
947*5e7646d2SAndroid Build Coastguard Worker {
948*5e7646d2SAndroid Build Coastguard Worker if (job->cancel_time)
949*5e7646d2SAndroid Build Coastguard Worker {
950*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
951*5e7646d2SAndroid Build Coastguard Worker "job-cancel-after",
952*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_INTEGER);
953*5e7646d2SAndroid Build Coastguard Worker
954*5e7646d2SAndroid Build Coastguard Worker if (cancel_after)
955*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
956*5e7646d2SAndroid Build Coastguard Worker else
957*5e7646d2SAndroid Build Coastguard Worker job->cancel_time = time(NULL) + MaxJobTime;
958*5e7646d2SAndroid Build Coastguard Worker }
959*5e7646d2SAndroid Build Coastguard Worker }
960*5e7646d2SAndroid Build Coastguard Worker }
961*5e7646d2SAndroid Build Coastguard Worker
962*5e7646d2SAndroid Build Coastguard Worker if (NameChanged)
963*5e7646d2SAndroid Build Coastguard Worker sysUpdateNames();
964*5e7646d2SAndroid Build Coastguard Worker
965*5e7646d2SAndroid Build Coastguard Worker cupsdCheckJobs();
966*5e7646d2SAndroid Build Coastguard Worker }
967*5e7646d2SAndroid Build Coastguard Worker
968*5e7646d2SAndroid Build Coastguard Worker if (sysevent.event & SYSEVENT_NETCHANGED)
969*5e7646d2SAndroid Build Coastguard Worker {
970*5e7646d2SAndroid Build Coastguard Worker if (Sleeping)
971*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
972*5e7646d2SAndroid Build Coastguard Worker "System network configuration changed - "
973*5e7646d2SAndroid Build Coastguard Worker "ignored while sleeping.");
974*5e7646d2SAndroid Build Coastguard Worker else
975*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
976*5e7646d2SAndroid Build Coastguard Worker "System network configuration changed.");
977*5e7646d2SAndroid Build Coastguard Worker }
978*5e7646d2SAndroid Build Coastguard Worker
979*5e7646d2SAndroid Build Coastguard Worker if (sysevent.event & SYSEVENT_NAMECHANGED)
980*5e7646d2SAndroid Build Coastguard Worker {
981*5e7646d2SAndroid Build Coastguard Worker if (Sleeping)
982*5e7646d2SAndroid Build Coastguard Worker {
983*5e7646d2SAndroid Build Coastguard Worker NameChanged = 1;
984*5e7646d2SAndroid Build Coastguard Worker
985*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
986*5e7646d2SAndroid Build Coastguard Worker "Computer name or BTMM domains changed - ignored while "
987*5e7646d2SAndroid Build Coastguard Worker "sleeping.");
988*5e7646d2SAndroid Build Coastguard Worker }
989*5e7646d2SAndroid Build Coastguard Worker else
990*5e7646d2SAndroid Build Coastguard Worker {
991*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG,
992*5e7646d2SAndroid Build Coastguard Worker "Computer name or BTMM domains changed.");
993*5e7646d2SAndroid Build Coastguard Worker
994*5e7646d2SAndroid Build Coastguard Worker sysUpdateNames();
995*5e7646d2SAndroid Build Coastguard Worker }
996*5e7646d2SAndroid Build Coastguard Worker }
997*5e7646d2SAndroid Build Coastguard Worker }
998*5e7646d2SAndroid Build Coastguard Worker }
999*5e7646d2SAndroid Build Coastguard Worker
1000*5e7646d2SAndroid Build Coastguard Worker
1001*5e7646d2SAndroid Build Coastguard Worker /*
1002*5e7646d2SAndroid Build Coastguard Worker * 'sysUpdateNames()' - Update computer and/or BTMM domains.
1003*5e7646d2SAndroid Build Coastguard Worker */
1004*5e7646d2SAndroid Build Coastguard Worker
1005*5e7646d2SAndroid Build Coastguard Worker static void
sysUpdateNames(void)1006*5e7646d2SAndroid Build Coastguard Worker sysUpdateNames(void)
1007*5e7646d2SAndroid Build Coastguard Worker {
1008*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *p; /* Current printer */
1009*5e7646d2SAndroid Build Coastguard Worker
1010*5e7646d2SAndroid Build Coastguard Worker
1011*5e7646d2SAndroid Build Coastguard Worker NameChanged = 0;
1012*5e7646d2SAndroid Build Coastguard Worker
1013*5e7646d2SAndroid Build Coastguard Worker /*
1014*5e7646d2SAndroid Build Coastguard Worker * De-register the individual printers...
1015*5e7646d2SAndroid Build Coastguard Worker */
1016*5e7646d2SAndroid Build Coastguard Worker
1017*5e7646d2SAndroid Build Coastguard Worker for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
1018*5e7646d2SAndroid Build Coastguard Worker p;
1019*5e7646d2SAndroid Build Coastguard Worker p = (cupsd_printer_t *)cupsArrayNext(Printers))
1020*5e7646d2SAndroid Build Coastguard Worker cupsdDeregisterPrinter(p, 1);
1021*5e7646d2SAndroid Build Coastguard Worker
1022*5e7646d2SAndroid Build Coastguard Worker # if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1023*5e7646d2SAndroid Build Coastguard Worker /*
1024*5e7646d2SAndroid Build Coastguard Worker * Update the computer name and BTMM domain list...
1025*5e7646d2SAndroid Build Coastguard Worker */
1026*5e7646d2SAndroid Build Coastguard Worker
1027*5e7646d2SAndroid Build Coastguard Worker cupsdUpdateDNSSDName();
1028*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_DNSSD || HAVE_AVAHI */
1029*5e7646d2SAndroid Build Coastguard Worker
1030*5e7646d2SAndroid Build Coastguard Worker /*
1031*5e7646d2SAndroid Build Coastguard Worker * Now re-register them...
1032*5e7646d2SAndroid Build Coastguard Worker */
1033*5e7646d2SAndroid Build Coastguard Worker
1034*5e7646d2SAndroid Build Coastguard Worker for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
1035*5e7646d2SAndroid Build Coastguard Worker p;
1036*5e7646d2SAndroid Build Coastguard Worker p = (cupsd_printer_t *)cupsArrayNext(Printers))
1037*5e7646d2SAndroid Build Coastguard Worker cupsdRegisterPrinter(p);
1038*5e7646d2SAndroid Build Coastguard Worker }
1039*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
1040