source: proiecte/PPPP/gdm/common/mkdtemp.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 4.9 KB
Line 
1/* Copyright (C) 1999, 2001-2002 Free Software Foundation, Inc.
2   This file is part of the GNU C Library.
3
4   The GNU C Library is free software; you can redistribute it and/or
5   modify it under the terms of the GNU Library General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   The GNU C Library is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   Library General Public License for more details.
13
14   You should have received a copy of the GNU Library General Public
15   License along with the GNU C Library; see the file COPYING.LIB.  If not,
16   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17   Boston, MA 02111-1307, USA.  */
18
19/* Extracted from misc/mkdtemp.c and sysdeps/posix/tempname.c.  */
20
21#ifdef HAVE_CONFIG_H
22# include "config.h"
23#endif
24
25/* Specification.  */
26#include "mkdtemp.h"
27
28#include <errno.h>
29#ifndef __set_errno
30# define __set_errno(Val) errno = (Val)
31#endif
32
33#include <stddef.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include <stdio.h>
38#ifndef TMP_MAX
39# define TMP_MAX 238328
40#endif
41
42#if HAVE_STDINT_H_WITH_UINTMAX || _LIBC
43# include <stdint.h>
44#endif
45
46#if HAVE_INTTYPES_H_WITH_UINTMAX || _LIBC
47# include <inttypes.h>
48#endif
49
50#if HAVE_UNISTD_H || _LIBC
51# include <unistd.h>
52#endif
53
54#if HAVE_GETTIMEOFDAY || _LIBC
55# if HAVE_SYS_TIME_H || _LIBC
56#  include <sys/time.h>
57# endif
58#else
59# if HAVE_TIME_H || _LIBC
60#  include <time.h>
61# endif
62#endif
63
64#include <sys/stat.h>
65#if STAT_MACROS_BROKEN
66# undef S_ISDIR
67#endif
68#if !defined S_ISDIR && defined S_IFDIR
69# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
70#endif
71#if !S_IRUSR && S_IREAD
72# define S_IRUSR S_IREAD
73#endif
74#if !S_IRUSR
75# define S_IRUSR 00400
76#endif
77#if !S_IWUSR && S_IWRITE
78# define S_IWUSR S_IWRITE
79#endif
80#if !S_IWUSR
81# define S_IWUSR 00200
82#endif
83#if !S_IXUSR && S_IEXEC
84# define S_IXUSR S_IEXEC
85#endif
86#if !S_IXUSR
87# define S_IXUSR 00100
88#endif
89
90#if !_LIBC
91# define __getpid getpid
92# define __gettimeofday gettimeofday
93# define __mkdir mkdir
94#endif
95
96/* Use the widest available unsigned type if uint64_t is not
97   available.  The algorithm below extracts a number less than 62**6
98   (approximately 2**35.725) from uint64_t, so ancient hosts where
99   uintmax_t is only 32 bits lose about 3.725 bits of randomness,
100   which is better than not having mkstemp at all.  */
101#if !defined UINT64_MAX && !defined uint64_t
102# define uint64_t uintmax_t
103#endif
104
105/* These are the characters used in temporary filenames.  */
106static const char letters[] =
107"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
108
109/* Generate a temporary file name based on TMPL.  TMPL must match the
110   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
111   does not exist at the time of the call to __gen_tempname.  TMPL is
112   overwritten with the result.
113
114   KIND is:
115   __GT_DIR:            create a directory, which will be mode 0700.
116
117   We use a clever algorithm to get hard-to-predict names. */
118static int
119gen_tempname (tmpl)
120     char *tmpl;
121{
122  int len;
123  char *XXXXXX;
124  static uint64_t value;
125  uint64_t random_time_bits;
126  int count, fd = -1;
127  int save_errno = errno;
128
129  len = strlen (tmpl);
130  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
131    {
132      __set_errno (EINVAL);
133      return -1;
134    }
135
136  /* This is where the Xs start.  */
137  XXXXXX = &tmpl[len - 6];
138
139  /* Get some more or less random data.  */
140#ifdef RANDOM_BITS
141  RANDOM_BITS (random_time_bits);
142#else
143# if HAVE_GETTIMEOFDAY || _LIBC
144  {
145    struct timeval tv;
146    __gettimeofday (&tv, NULL);
147    random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec;
148  }
149# else
150  random_time_bits = time (NULL);
151# endif
152#endif
153  value += random_time_bits ^ __getpid ();
154
155  for (count = 0; count < TMP_MAX; value += 7777, ++count)
156    {
157      uint64_t v = value;
158
159      /* Fill in the random bits.  */
160      XXXXXX[0] = letters[v % 62];
161      v /= 62;
162      XXXXXX[1] = letters[v % 62];
163      v /= 62;
164      XXXXXX[2] = letters[v % 62];
165      v /= 62;
166      XXXXXX[3] = letters[v % 62];
167      v /= 62;
168      XXXXXX[4] = letters[v % 62];
169      v /= 62;
170      XXXXXX[5] = letters[v % 62];
171
172      fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
173
174      if (fd >= 0)
175        {
176          __set_errno (save_errno);
177          return fd;
178        }
179      else if (errno != EEXIST)
180        return -1;
181    }
182
183  /* We got out of the loop because we ran out of combinations to try.  */
184  __set_errno (EEXIST);
185  return -1;
186}
187
188/* Generate a unique temporary directory from TEMPLATE.
189   The last six characters of TEMPLATE must be "XXXXXX";
190   they are replaced with a string that makes the filename unique.
191   The directory is created, mode 700, and its name is returned.
192   (This function comes from OpenBSD.) */
193char *
194mkdtemp (template)
195     char *template;
196{
197  if (gen_tempname (template))
198    return NULL;
199  else
200    return template;
201}
Note: See TracBrowser for help on using the repository browser.