upload tizen2.0 source
[framework/uifw/xorg/lib/libice.git] / src / authutil.c
1 /******************************************************************************
2
3
4 Copyright 1993, 1998  The Open Group
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25
26 Author: Ralph Mor, X Consortium
27 ******************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include <X11/ICE/ICElib.h>
33 #include "ICElibint.h"
34 #include <X11/ICE/ICEutil.h>
35 #include <X11/Xos.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38
39 #include <time.h>
40 #define Time_t time_t
41 #ifdef __UNIXOS2__
42 extern char* getenv(const char*);
43 #define link rename
44 #endif
45 #ifndef X_NOT_POSIX
46 #include <unistd.h>
47 #else
48 #ifndef WIN32
49 extern unsigned sleep ();
50 #else
51 #define link rename
52 #endif
53 #endif
54
55 static Status read_short (FILE *file, unsigned short *shortp);
56 static Status read_string (FILE *file, char **stringp);
57 static Status read_counted_string (FILE *file, unsigned short *countp, char **stringp);
58 static Status write_short (FILE *file, unsigned short s);
59 static Status write_string (FILE *file, char *string);
60 static Status write_counted_string (FILE *file, unsigned short count, char *string);
61
62
63 \f
64 /*
65  * The following routines are for manipulating the .ICEauthority file
66  * These are utility functions - they are not part of the standard
67  * ICE library specification.
68  */
69
70 char *
71 IceAuthFileName (void)
72 {
73     static char slashDotICEauthority[] = "/.ICEauthority";
74     char        *name;
75     static char *buf;
76     static int  bsize;
77     int         size;
78 #if defined(WIN32) || defined(__UNIXOS2__)
79 #ifndef PATH_MAX
80 #define PATH_MAX 512
81 #endif
82     char        dir[PATH_MAX];
83 #endif
84
85     if ((name = getenv ("ICEAUTHORITY")))
86         return (name);
87
88     name = getenv ("HOME");
89
90     if (!name)
91     {
92 #ifdef WIN32
93     register char *ptr1;
94     register char *ptr2;
95     int len1 = 0, len2 = 0;
96
97     if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
98         len1 = strlen (ptr1);
99         len2 = strlen (ptr2);
100     } else if ((ptr2 = getenv("USERNAME"))) {
101         len1 = strlen (ptr1 = "/users/");
102         len2 = strlen (ptr2);
103     }
104     if ((len1 + len2 + 1) < PATH_MAX) {
105         sprintf (dir, "%s%s", ptr1, (ptr2) ? ptr2 : "");
106         name = dir;
107     }
108     if (!name)
109 #endif
110 #ifdef __UNIXOS2__
111         strcpy (dir,"c:");
112         name = dir;
113         if (!name)
114 #endif
115         return (NULL);
116     }
117
118     size = strlen (name) + strlen (&slashDotICEauthority[1]) + 2;
119
120     if (size > bsize)
121     {
122         if (buf)
123             free (buf);
124         buf = malloc ((unsigned) size);
125         if (!buf)
126             return (NULL);
127         bsize = size;
128     }
129
130     strcpy (buf, name);
131     strcat (buf, slashDotICEauthority + (name[1] == '\0' ? 1 : 0));
132
133     return (buf);
134 }
135
136
137 \f
138 int
139 IceLockAuthFile (
140         char    *file_name,
141         int     retries,
142         int     timeout,
143         long    dead
144 )
145 {
146     char        creat_name[1025], link_name[1025];
147     struct stat statb;
148     Time_t      now;
149     int         creat_fd = -1;
150
151     if ((int) strlen (file_name) > 1022)
152         return (IceAuthLockError);
153
154     strcpy (creat_name, file_name);
155     strcat (creat_name, "-c");
156     strcpy (link_name, file_name);
157     strcat (link_name, "-l");
158
159     if (stat (creat_name, &statb) != -1)
160     {
161         now = time ((Time_t *) 0);
162
163         /*
164          * NFS may cause ctime to be before now, special
165          * case a 0 deadtime to force lock removal
166          */
167
168         if (dead == 0 || now - statb.st_ctime > dead)
169         {
170             unlink (creat_name);
171             unlink (link_name);
172         }
173     }
174
175     while (retries > 0)
176     {
177         if (creat_fd == -1)
178         {
179             creat_fd = creat (creat_name, 0666);
180
181             if (creat_fd == -1)
182             {
183                 if (errno != EACCES)
184                     return (IceAuthLockError);
185             }
186             else
187                 close (creat_fd);
188         }
189
190         if (creat_fd != -1)
191         {
192             if (link (creat_name, link_name) != -1)
193                 return (IceAuthLockSuccess);
194
195             if (errno == ENOENT)
196             {
197                 creat_fd = -1;  /* force re-creat next time around */
198                 continue;
199             }
200
201             if (errno != EEXIST)
202                 return (IceAuthLockError);
203         }
204
205         sleep ((unsigned) timeout);
206         --retries;
207     }
208
209     return (IceAuthLockTimeout);
210 }
211
212
213 \f
214 void
215 IceUnlockAuthFile (
216         char    *file_name
217 )
218 {
219 #ifndef WIN32
220     char        creat_name[1025];
221 #endif
222     char        link_name[1025];
223
224     if ((int) strlen (file_name) > 1022)
225         return;
226
227 #ifndef WIN32
228     strcpy (creat_name, file_name);
229     strcat (creat_name, "-c");
230 #endif
231     strcpy (link_name, file_name);
232     strcat (link_name, "-l");
233
234 #ifndef WIN32
235     unlink (creat_name);
236 #endif
237     unlink (link_name);
238 }
239
240
241 \f
242 IceAuthFileEntry *
243 IceReadAuthFileEntry (
244         FILE    *auth_file
245 )
246 {
247     IceAuthFileEntry    local;
248     IceAuthFileEntry    *ret;
249
250     local.protocol_name = NULL;
251     local.protocol_data = NULL;
252     local.network_id = NULL;
253     local.auth_name = NULL;
254     local.auth_data = NULL;
255
256     if (!read_string (auth_file, &local.protocol_name))
257         return (NULL);
258
259     if (!read_counted_string (auth_file,
260         &local.protocol_data_length, &local.protocol_data))
261         goto bad;
262
263     if (!read_string (auth_file, &local.network_id))
264         goto bad;
265
266     if (!read_string (auth_file, &local.auth_name))
267         goto bad;
268
269     if (!read_counted_string (auth_file,
270         &local.auth_data_length, &local.auth_data))
271         goto bad;
272
273     if (!(ret = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry))))
274         goto bad;
275
276     *ret = local;
277
278     return (ret);
279
280  bad:
281
282     if (local.protocol_name) free (local.protocol_name);
283     if (local.protocol_data) free (local.protocol_data);
284     if (local.network_id) free (local.network_id);
285     if (local.auth_name) free (local.auth_name);
286     if (local.auth_data) free (local.auth_data);
287
288     return (NULL);
289 }
290
291
292 \f
293 void
294 IceFreeAuthFileEntry (
295         IceAuthFileEntry        *auth
296 )
297 {
298     if (auth)
299     {
300         if (auth->protocol_name) free (auth->protocol_name);
301         if (auth->protocol_data) free (auth->protocol_data);
302         if (auth->network_id) free (auth->network_id);
303         if (auth->auth_name) free (auth->auth_name);
304         if (auth->auth_data) free (auth->auth_data);
305         free ((char *) auth);
306     }
307 }
308
309
310 \f
311 Status
312 IceWriteAuthFileEntry (
313         FILE                    *auth_file,
314         IceAuthFileEntry        *auth
315 )
316 {
317     if (!write_string (auth_file, auth->protocol_name))
318         return (0);
319
320     if (!write_counted_string (auth_file,
321         auth->protocol_data_length, auth->protocol_data))
322         return (0);
323
324     if (!write_string (auth_file, auth->network_id))
325         return (0);
326
327     if (!write_string (auth_file, auth->auth_name))
328         return (0);
329
330     if (!write_counted_string (auth_file,
331         auth->auth_data_length, auth->auth_data))
332         return (0);
333
334     return (1);
335 }
336
337
338 \f
339 IceAuthFileEntry *
340 IceGetAuthFileEntry (
341         const char      *protocol_name,
342         const char      *network_id,
343         const char      *auth_name
344 )
345 {
346     FILE                *auth_file;
347     char                *filename;
348     IceAuthFileEntry    *entry;
349
350     if (!(filename = IceAuthFileName ()))
351         return (NULL);
352
353     if (access (filename, R_OK) != 0)           /* checks REAL id */
354         return (NULL);
355
356     if (!(auth_file = fopen (filename, "rb")))
357         return (NULL);
358
359     for (;;)
360     {
361         if (!(entry = IceReadAuthFileEntry (auth_file)))
362             break;
363
364         if (strcmp (protocol_name, entry->protocol_name) == 0 &&
365             strcmp (network_id, entry->network_id) == 0 &&
366             strcmp (auth_name, entry->auth_name) == 0)
367         {
368             break;
369         }
370
371         IceFreeAuthFileEntry (entry);
372     }
373
374     fclose (auth_file);
375
376     return (entry);
377 }
378
379
380 \f
381 /*
382  * local routines
383  */
384
385 static Status
386 read_short (FILE *file, unsigned short *shortp)
387 {
388     unsigned char   file_short[2];
389
390     if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
391         return (0);
392
393     *shortp = file_short[0] * 256 + file_short[1];
394     return (1);
395 }
396
397
398 static Status
399 read_string (FILE *file, char **stringp)
400
401 {
402     unsigned short  len;
403     char            *data;
404
405     if (!read_short (file, &len))
406         return (0);
407
408     data = malloc ((unsigned) len + 1);
409
410     if (!data)
411             return (0);
412
413     if (len != 0)
414     {
415         if (fread (data, (int) sizeof (char), (int) len, file) != len)
416         {
417             free (data);
418             return (0);
419         }
420
421     }
422     data[len] = '\0';
423
424     *stringp = data;
425
426     return (1);
427 }
428
429
430 static Status
431 read_counted_string (FILE *file, unsigned short *countp, char **stringp)
432 {
433     unsigned short  len;
434     char            *data;
435
436     if (!read_short (file, &len))
437         return (0);
438
439     if (len == 0)
440     {
441         data = NULL;
442     }
443     else
444     {
445         data = malloc ((unsigned) len);
446
447         if (!data)
448             return (0);
449
450         if (fread (data, (int) sizeof (char), (int) len, file) != len)
451         {
452             free (data);
453             return (0);
454         }
455     }
456
457     *stringp = data;
458     *countp = len;
459
460     return (1);
461 }
462
463
464 static Status
465 write_short (FILE *file, unsigned short s)
466 {
467     unsigned char   file_short[2];
468
469     file_short[0] = (s & (unsigned) 0xff00) >> 8;
470     file_short[1] = s & 0xff;
471
472     if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
473         return (0);
474
475     return (1);
476 }
477
478
479 static Status
480 write_string (FILE *file, char *string)
481 {
482     unsigned short count = strlen (string);
483
484     if (!write_short (file, count))
485         return (0);
486
487     if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
488         return (0);
489
490     return (1);
491 }
492
493
494 static Status
495 write_counted_string (FILE *file, unsigned short count, char *string)
496 {
497     if (!write_short (file, count))
498         return (0);
499
500     if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
501         return (0);
502
503     return (1);
504 }