]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/globals.c
Merge changes from CUPS 1.6svn-r10188, including changes for <rdar://problem/10127258...
[thirdparty/cups.git] / cups / globals.c
CommitLineData
ef416fc2 1/*
b19ccc9e 2 * "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $"
ef416fc2 3 *
71e16022 4 * Global variable access routines for CUPS.
ef416fc2 5 *
71e16022 6 * Copyright 2007-2010 by Apple Inc.
f7deaa1a 7 * Copyright 1997-2007 by Easy Software Products, all rights reserved.
ef416fc2 8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 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/".
ef416fc2 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
6d2f911b
MS
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.
ef416fc2 26 */
27
28/*
29 * Include necessary headers...
30 */
31
71e16022 32#include "cups-private.h"
ef416fc2 33
34
35/*
6d2f911b 36 * Local globals...
ef416fc2 37 */
38
f8b3a85b 39
6d2f911b
MS
40static _cups_threadkey_t cups_globals_key = _CUPS_THREADKEY_INITIALIZER;
41 /* Thread local storage key */
42#ifdef HAVE_PTHREAD_H
43static pthread_once_t cups_globals_key_once = PTHREAD_ONCE_INIT;
44 /* One-time initialization object */
45#endif /* HAVE_PTHREAD_H */
46static _cups_mutex_t cups_global_mutex = _CUPS_MUTEX_INITIALIZER;
47 /* Global critical section */
f8b3a85b 48
f8b3a85b 49
6d2f911b
MS
50/*
51 * Local functions...
52 */
f8b3a85b 53
6d2f911b
MS
54static _cups_globals_t *cups_globals_alloc(void);
55static void cups_globals_free(_cups_globals_t *g);
56#ifdef HAVE_PTHREAD_H
57static void cups_globals_init(void);
58#endif /* HAVE_PTHREAD_H */
f8b3a85b 59
f8b3a85b 60
6d2f911b
MS
61/*
62 * '_cupsGlobalLock()' - Lock the global mutex.
63 */
f8b3a85b 64
6d2f911b
MS
65void
66_cupsGlobalLock(void)
67{
68#ifdef HAVE_PTHREAD_H
69 pthread_mutex_lock(&cups_global_mutex);
70#elif defined(WIN32)
cc754834 71 EnterCriticalSection(&cups_global_mutex.m_criticalSection);
6d2f911b
MS
72#endif /* HAVE_PTHREAD_H */
73}
f8b3a85b 74
f8b3a85b 75
6d2f911b
MS
76/*
77 * '_cupsGlobals()' - Return a pointer to thread local storage
78 */
f8b3a85b 79
6d2f911b
MS
80_cups_globals_t * /* O - Pointer to global data */
81_cupsGlobals(void)
82{
83 _cups_globals_t *cg; /* Pointer to global data */
f8b3a85b 84
f8b3a85b 85
6d2f911b
MS
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)
5180a04c
MS
99 {
100 /*
6d2f911b 101 * No, allocate memory as set the pointer for the key...
5180a04c 102 */
ef416fc2 103
6d2f911b
MS
104 if ((cg = cups_globals_alloc()) != NULL)
105 _cupsThreadSetData(cups_globals_key, cg);
5180a04c 106 }
ef416fc2 107
6d2f911b
MS
108 /*
109 * Return the pointer to the data...
110 */
ef416fc2 111
6d2f911b
MS
112 return (cg);
113}
5180a04c 114
5180a04c 115
6d2f911b
MS
116/*
117 * '_cupsGlobalUnlock()' - Unlock the global mutex.
118 */
5180a04c 119
6d2f911b
MS
120void
121_cupsGlobalUnlock(void)
122{
123#ifdef HAVE_PTHREAD_H
124 pthread_mutex_unlock(&cups_global_mutex);
125#elif defined(WIN32)
cc754834 126 LeaveCriticalSection(&cups_global_mutex.m_criticalSection);
6d2f911b 127#endif /* HAVE_PTHREAD_H */
ef416fc2 128}
129
130
6d2f911b 131#ifdef WIN32
ef416fc2 132/*
6d2f911b 133 * 'DllMain()' - Main entry for library.
ef416fc2 134 */
135
6d2f911b
MS
136BOOL WINAPI /* O - Success/failure */
137DllMain(HINSTANCE hinst, /* I - DLL module handle */
138 DWORD reason, /* I - Reason */
139 LPVOID reserved) /* I - Unused */
140{
141 _cups_globals_t *cg; /* Global data */
ef416fc2 142
ef416fc2 143
6d2f911b
MS
144 (void)hinst;
145 (void)reserved;
ef416fc2 146
6d2f911b
MS
147 switch (reason)
148 {
149 case DLL_PROCESS_ATTACH : /* Called on library initialization */
cc754834 150 InitializeCriticalSection(&cups_global_mutex.m_criticalSection);
6d2f911b
MS
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);
ef416fc2 164
6d2f911b 165 TlsFree(cups_globals_key);
cc754834 166 DeleteCriticalSection(&cups_global_mutex.m_criticalSection);
6d2f911b
MS
167 break;
168
169 default:
170 break;
171 }
172
173 return (TRUE);
174}
175#endif /* WIN32 */
ef416fc2 176
177
178/*
6d2f911b 179 * 'cups_globals_alloc()' - Allocate and initialize global data.
ef416fc2 180 */
181
6d2f911b
MS
182static _cups_globals_t * /* O - Pointer to global data */
183cups_globals_alloc(void)
ef416fc2 184{
6d2f911b
MS
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
ef416fc2 195
6d2f911b
MS
196 if (!cg)
197 return (NULL);
ef416fc2 198
5180a04c 199 /*
6d2f911b
MS
200 * Clear the global storage and set the default encryption and password
201 * callback values...
ef416fc2 202 */
203
6d2f911b 204 memset(cg, 0, sizeof(_cups_globals_t));
7cf5915e
MS
205 cg->encryption = (http_encryption_t)-1;
206 cg->password_cb = (cups_password_cb2_t)_cupsGetPassword;
207 cg->any_root = 1;
208 cg->expired_certs = 1;
209 cg->expired_root = 1;
ef416fc2 210
211 /*
6d2f911b
MS
212 * Then set directories as appropriate...
213 */
214
215#ifdef WIN32
216 /*
217 * Open the registry...
ef416fc2 218 */
219
6d2f911b
MS
220 strcpy(installdir, "C:/Program Files/cups.org");
221
222 if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\cups.org", 0, KEY_READ,
223 &key))
ef416fc2 224 {
225 /*
6d2f911b 226 * Grab the installation directory...
ef416fc2 227 */
228
6d2f911b
MS
229 size = sizeof(installdir);
230 RegQueryValueEx(key, "installdir", NULL, NULL, installdir, &size);
231 RegCloseKey(key);
232 }
233
234 snprintf(confdir, sizeof(confdir), "%s/conf", installdir);
235 snprintf(localedir, sizeof(localedir), "%s/locale", installdir);
236
237 if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
238 cg->cups_datadir = installdir;
ef416fc2 239
6d2f911b
MS
240 if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
241 cg->cups_serverbin = installdir;
242
243 if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
244 cg->cups_serverroot = confdir;
245
246 if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
247 cg->cups_statedir = confdir;
248
249 if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
250 cg->localedir = localedir;
251
252#else
253# ifdef HAVE_GETEUID
254 if ((geteuid() != getuid() && getuid()) || getegid() != getgid())
255# else
256 if (!getuid())
257# endif /* HAVE_GETEUID */
258 {
ef416fc2 259 /*
6d2f911b
MS
260 * When running setuid/setgid, don't allow environment variables to override
261 * the directories...
ef416fc2 262 */
263
6d2f911b
MS
264 cg->cups_datadir = CUPS_DATADIR;
265 cg->cups_serverbin = CUPS_SERVERBIN;
266 cg->cups_serverroot = CUPS_SERVERROOT;
267 cg->cups_statedir = CUPS_STATEDIR;
268 cg->localedir = CUPS_LOCALEDIR;
ef416fc2 269 }
6d2f911b
MS
270 else
271 {
272 /*
273 * Allow directories to be overridden by environment variables.
274 */
ef416fc2 275
6d2f911b
MS
276 if ((cg->cups_datadir = getenv("CUPS_DATADIR")) == NULL)
277 cg->cups_datadir = CUPS_DATADIR;
ef416fc2 278
6d2f911b
MS
279 if ((cg->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
280 cg->cups_serverbin = CUPS_SERVERBIN;
ef416fc2 281
6d2f911b
MS
282 if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
283 cg->cups_serverroot = CUPS_SERVERROOT;
ef416fc2 284
6d2f911b
MS
285 if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
286 cg->cups_statedir = CUPS_STATEDIR;
ef416fc2 287
6d2f911b
MS
288 if ((cg->localedir = getenv("LOCALEDIR")) == NULL)
289 cg->localedir = CUPS_LOCALEDIR;
290 }
291#endif /* WIN32 */
292
293 return (cg);
ef416fc2 294}
295
296
297/*
6d2f911b 298 * 'cups_globals_free()' - Free global data.
ef416fc2 299 */
300
301static void
6d2f911b 302cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */
ef416fc2 303{
dcb445bc 304 _cups_buffer_t *buffer, /* Current read/write buffer */
1f6f3dbc 305 *next; /* Next buffer */
fa73b229 306
307
e53920b9 308 if (cg->last_status_message)
5f64df29 309 _cupsStrFree(cg->last_status_message);
e53920b9 310
dcb445bc 311 for (buffer = cg->cups_buffers; buffer; buffer = next)
1f6f3dbc
MS
312 {
313 next = buffer->next;
314 free(buffer);
315 }
316
c168a833 317 cupsArrayDelete(cg->leg_size_lut);
f14324a7
MS
318 cupsArrayDelete(cg->ppd_size_lut);
319 cupsArrayDelete(cg->pwg_size_lut);
c168a833 320
6d2f911b 321 httpClose(cg->http);
ef416fc2 322
7cf5915e
MS
323 _httpFreeCredentials(cg->tls_credentials);
324
6d2f911b
MS
325 cupsFileClose(cg->stdio_files[0]);
326 cupsFileClose(cg->stdio_files[1]);
327 cupsFileClose(cg->stdio_files[2]);
ef416fc2 328
6d2f911b 329 cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);
ef416fc2 330
6d2f911b
MS
331 free(cg);
332}
333
334
335#ifdef HAVE_PTHREAD_H
ef416fc2 336/*
6d2f911b 337 * 'cups_globals_init()' - Initialize environment variables.
ef416fc2 338 */
339
6d2f911b
MS
340static void
341cups_globals_init(void)
ef416fc2 342{
ef416fc2 343 /*
6d2f911b 344 * Register the global data for this thread...
ef416fc2 345 */
346
6d2f911b 347 pthread_key_create(&cups_globals_key, (void (*)(void *))cups_globals_free);
ef416fc2 348}
349#endif /* HAVE_PTHREAD_H */
350
351
352/*
b19ccc9e 353 * End of "$Id: globals.c 7870 2008-08-27 18:14:10Z mike $".
ef416fc2 354 */