]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/globals.c
00a73691cfb5eb8237ee3707b6d9f8b38112f5de
[thirdparty/cups.git] / cups / globals.c
1 /*
2 * "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $"
3 *
4 * Global variable access routines for CUPS.
5 *
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
8 *
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
19 * _cupsGlobalLock() - Lock the global mutex.
20 * _cupsGlobals() - Return a pointer to thread local storage
21 * _cupsGlobalUnlock() - Unlock the global mutex.
22 * DllMain() - Main entry for library.
23 * cups_globals_alloc() - Allocate and initialize global data.
24 * cups_globals_free() - Free global data.
25 * cups_globals_init() - Initialize environment variables.
26 */
27
28 /*
29 * Include necessary headers...
30 */
31
32 #include "cups-private.h"
33
34
35 /*
36 * Local globals...
37 */
38
39
40 static _cups_threadkey_t cups_globals_key = _CUPS_THREADKEY_INITIALIZER;
41 /* Thread local storage key */
42 #ifdef HAVE_PTHREAD_H
43 static pthread_once_t cups_globals_key_once = PTHREAD_ONCE_INIT;
44 /* One-time initialization object */
45 #endif /* HAVE_PTHREAD_H */
46 static _cups_mutex_t cups_global_mutex = _CUPS_MUTEX_INITIALIZER;
47 /* Global critical section */
48
49
50 /*
51 * Local functions...
52 */
53
54 static _cups_globals_t *cups_globals_alloc(void);
55 static void cups_globals_free(_cups_globals_t *g);
56 #ifdef HAVE_PTHREAD_H
57 static void cups_globals_init(void);
58 #endif /* HAVE_PTHREAD_H */
59
60
61 /*
62 * '_cupsGlobalLock()' - Lock the global mutex.
63 */
64
65 void
66 _cupsGlobalLock(void)
67 {
68 #ifdef HAVE_PTHREAD_H
69 pthread_mutex_lock(&cups_global_mutex);
70 #elif defined(WIN32)
71 EnterCriticalSection(&cups_global_mutex->m_criticalSection);
72 #endif /* HAVE_PTHREAD_H */
73 }
74
75
76 /*
77 * '_cupsGlobals()' - Return a pointer to thread local storage
78 */
79
80 _cups_globals_t * /* O - Pointer to global data */
81 _cupsGlobals(void)
82 {
83 _cups_globals_t *cg; /* Pointer to global data */
84
85
86 #ifdef HAVE_PTHREAD_H
87 /*
88 * Initialize the global data exactly once...
89 */
90
91 pthread_once(&cups_globals_key_once, cups_globals_init);
92 #endif /* HAVE_PTHREAD_H */
93
94 /*
95 * See if we have allocated the data yet...
96 */
97
98 if ((cg = (_cups_globals_t *)_cupsThreadGetData(cups_globals_key)) == NULL)
99 {
100 /*
101 * No, allocate memory as set the pointer for the key...
102 */
103
104 if ((cg = cups_globals_alloc()) != NULL)
105 _cupsThreadSetData(cups_globals_key, cg);
106 }
107
108 /*
109 * Return the pointer to the data...
110 */
111
112 return (cg);
113 }
114
115
116 /*
117 * '_cupsGlobalUnlock()' - Unlock the global mutex.
118 */
119
120 void
121 _cupsGlobalUnlock(void)
122 {
123 #ifdef HAVE_PTHREAD_H
124 pthread_mutex_unlock(&cups_global_mutex);
125 #elif defined(WIN32)
126 LeaveCriticalSection(&cups_global_mutex->m_criticalSection);
127 #endif /* HAVE_PTHREAD_H */
128 }
129
130
131 #ifdef WIN32
132 /*
133 * 'DllMain()' - Main entry for library.
134 */
135
136 BOOL WINAPI /* O - Success/failure */
137 DllMain(HINSTANCE hinst, /* I - DLL module handle */
138 DWORD reason, /* I - Reason */
139 LPVOID reserved) /* I - Unused */
140 {
141 _cups_globals_t *cg; /* Global data */
142
143
144 (void)hinst;
145 (void)reserved;
146
147 switch (reason)
148 {
149 case DLL_PROCESS_ATTACH : /* Called on library initialization */
150 InitializeCriticalSection(&cups_global_lock);
151
152 if ((cups_globals_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
153 return (FALSE);
154 break;
155
156 case DLL_THREAD_DETACH : /* Called when a thread terminates */
157 if ((cg = (_cups_globals_t *)TlsGetValue(cups_globals_key)) != NULL)
158 cups_globals_free(cg);
159 break;
160
161 case DLL_PROCESS_DETACH : /* Called when library is unloaded */
162 if ((cg = (_cups_globals_t *)TlsGetValue(cups_globals_key)) != NULL)
163 cups_globals_free(cg);
164
165 TlsFree(cups_globals_key);
166 DeleteCriticalSection(&cups_global_lock);
167 break;
168
169 default:
170 break;
171 }
172
173 return (TRUE);
174 }
175 #endif /* WIN32 */
176
177
178 /*
179 * 'cups_globals_alloc()' - Allocate and initialize global data.
180 */
181
182 static _cups_globals_t * /* O - Pointer to global data */
183 cups_globals_alloc(void)
184 {
185 _cups_globals_t *cg = malloc(sizeof(_cups_globals_t));
186 /* Pointer to global data */
187 #ifdef WIN32
188 HKEY key; /* Registry key */
189 DWORD size; /* Size of string */
190 static char installdir[1024], /* Install directory */
191 confdir[1024], /* Server root directory */
192 localedir[1024]; /* Locale directory */
193 #endif /* WIN32 */
194
195
196 if (!cg)
197 return (NULL);
198
199 /*
200 * Clear the global storage and set the default encryption and password
201 * callback values...
202 */
203
204 memset(cg, 0, sizeof(_cups_globals_t));
205 cg->encryption = (http_encryption_t)-1;
206 cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
207
208 /*
209 * Then set directories as appropriate...
210 */
211
212 #ifdef WIN32
213 /*
214 * Open the registry...
215 */
216
217 strcpy(installdir, "C:/Program Files/cups.org");
218
219 if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\cups.org", 0, KEY_READ,
220 &key))
221 {
222 /*
223 * Grab the installation directory...
224 */
225
226 size = sizeof(installdir);
227 RegQueryValueEx(key, "installdir", NULL, NULL, installdir, &size);
228 RegCloseKey(key);
229 }
230
231 snprintf(confdir, sizeof(confdir), "%s/conf", installdir);
232 snprintf(localedir, sizeof(localedir), "%s/locale", installdir);
233
234 if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
235 cg->cups_datadir = installdir;
236
237 if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
238 cg->cups_serverbin = installdir;
239
240 if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
241 cg->cups_serverroot = confdir;
242
243 if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
244 cg->cups_statedir = confdir;
245
246 if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
247 cg->localedir = localedir;
248
249 #else
250 # ifdef HAVE_GETEUID
251 if ((geteuid() != getuid() && getuid()) || getegid() != getgid())
252 # else
253 if (!getuid())
254 # endif /* HAVE_GETEUID */
255 {
256 /*
257 * When running setuid/setgid, don't allow environment variables to override
258 * the directories...
259 */
260
261 cg->cups_datadir = CUPS_DATADIR;
262 cg->cups_serverbin = CUPS_SERVERBIN;
263 cg->cups_serverroot = CUPS_SERVERROOT;
264 cg->cups_statedir = CUPS_STATEDIR;
265 cg->localedir = CUPS_LOCALEDIR;
266 }
267 else
268 {
269 /*
270 * Allow directories to be overridden by environment variables.
271 */
272
273 if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
274 cg->cups_datadir = CUPS_DATADIR;
275
276 if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
277 cg->cups_serverbin = CUPS_SERVERBIN;
278
279 if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
280 cg->cups_serverroot = CUPS_SERVERROOT;
281
282 if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
283 cg->cups_statedir = CUPS_STATEDIR;
284
285 if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
286 cg->localedir = CUPS_LOCALEDIR;
287 }
288 #endif /* WIN32 */
289
290 return (cg);
291 }
292
293
294 /*
295 * 'cups_globals_free()' - Free global data.
296 */
297
298 static void
299 cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
300 {
301 _ipp_buffer_t *buffer, /* Current IPP read/write buffer */
302 *next; /* Next buffer */
303
304
305 if (cg->last_status_message)
306 _cupsStrFree(cg->last_status_message);
307
308 for (buffer = cg->ipp_buffers; buffer; buffer = next)
309 {
310 next = buffer->next;
311 free(buffer);
312 }
313
314 cupsArrayDelete(cg->pwg_size_lut);
315 cupsArrayDelete(cg->leg_size_lut);
316
317 httpClose(cg->http);
318
319 cupsFileClose(cg->stdio_files[0]);
320 cupsFileClose(cg->stdio_files[1]);
321 cupsFileClose(cg->stdio_files[2]);
322
323 cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);
324
325 free(cg);
326 }
327
328
329 #ifdef HAVE_PTHREAD_H
330 /*
331 * 'cups_globals_init()' - Initialize environment variables.
332 */
333
334 static void
335 cups_globals_init(void)
336 {
337 /*
338 * Register the global data for this thread...
339 */
340
341 pthread_key_create(&cups_globals_key, (void (*)(void *))cups_globals_free);
342 }
343 #endif /* HAVE_PTHREAD_H */
344
345
346 /*
347 * End of "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $".
348 */