]>
Commit | Line | Data |
---|---|---|
2aa62f2b | 1 | /** @file\r |
2 | Internal function to generate temporary file name for tmpnam.\r | |
3 | \r | |
0c1992fb | 4 | Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r |
2aa62f2b | 5 | This program and the accompanying materials are licensed and made available\r |
6 | under the terms and conditions of the BSD License that accompanies this\r | |
7 | distribution. The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.php.\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | \r | |
13 | Copyright (c) 1987, 1993\r | |
14 | The Regents of the University of California. All rights reserved.\r | |
15 | \r | |
16 | Redistribution and use in source and binary forms, with or without\r | |
17 | modification, are permitted provided that the following conditions\r | |
18 | are met:\r | |
19 | 1. Redistributions of source code must retain the above copyright\r | |
20 | notice, this list of conditions and the following disclaimer.\r | |
21 | 2. Redistributions in binary form must reproduce the above copyright\r | |
22 | notice, this list of conditions and the following disclaimer in the\r | |
23 | documentation and/or other materials provided with the distribution.\r | |
24 | 3. Neither the name of the University nor the names of its contributors\r | |
25 | may be used to endorse or promote products derived from this software\r | |
26 | without specific prior written permission.\r | |
27 | \r | |
28 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r | |
29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r | |
30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r | |
31 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r | |
32 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r | |
33 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r | |
34 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r | |
35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r | |
36 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r | |
37 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r | |
38 | SUCH DAMAGE.\r | |
39 | \r | |
0c1992fb | 40 | mktemp.c 8.1 (Berkeley) 6/4/93\r |
2aa62f2b | 41 | NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp\r |
42 | **/\r | |
43 | #include <LibConfig.h>\r | |
44 | \r | |
45 | #if HAVE_NBTOOL_CONFIG_H\r | |
46 | #include "nbtool_config.h"\r | |
47 | #endif\r | |
48 | \r | |
d7ce7006 | 49 | #if !defined(HAVE_NBTOOL_CONFIG_H) || !defined(HAVE_MKSTEMP) || !defined(HAVE_MKDTEMP)\r |
2aa62f2b | 50 | \r |
51 | #include <sys/EfiCdefs.h>\r | |
2aa62f2b | 52 | \r |
53 | #include <sys/types.h>\r | |
54 | #include <sys/stat.h>\r | |
55 | \r | |
56 | #include <assert.h>\r | |
57 | #include <ctype.h>\r | |
58 | #include <errno.h>\r | |
59 | #include <fcntl.h>\r | |
60 | #include <stdio.h>\r | |
61 | #include <stdlib.h>\r | |
0c1992fb | 62 | #include <unistd.h>\r |
2aa62f2b | 63 | \r |
64 | #if HAVE_NBTOOL_CONFIG_H\r | |
65 | #define GETTEMP gettemp\r | |
66 | #else\r | |
67 | #include "reentrant.h"\r | |
68 | #include "local.h"\r | |
69 | #define GETTEMP __gettemp\r | |
70 | #endif\r | |
71 | \r | |
72 | int\r | |
73 | GETTEMP(\r | |
74 | char *path,\r | |
75 | int *doopen,\r | |
76 | int domkdir\r | |
77 | )\r | |
78 | {\r | |
79 | char *start, *trv;\r | |
80 | struct stat sbuf;\r | |
81 | \r | |
82 | /* To guarantee multiple calls generate unique names even if\r | |
83 | the file is not created. 676 different possibilities with 7\r | |
84 | or more X's, 26 with 6 or less. */\r | |
85 | static char xtra[] = "aa";\r | |
86 | int xcnt = 0;\r | |
87 | \r | |
88 | _DIAGASSERT(path != NULL);\r | |
89 | /* doopen may be NULL */\r | |
90 | \r | |
91 | /* Move to end of path and count trailing X's. */\r | |
92 | for (trv = path; *trv; ++trv) {\r | |
93 | if (*trv == 'X') {\r | |
94 | xcnt++;\r | |
95 | }\r | |
96 | else {\r | |
97 | xcnt = 0;\r | |
98 | }\r | |
99 | }\r | |
100 | \r | |
101 | /* Use at least one from xtra. Use 2 if more than 6 X's. */\r | |
102 | if (*(trv - 1) == 'X')\r | |
103 | *--trv = xtra[0];\r | |
104 | if (xcnt > 6 && *(trv - 1) == 'X')\r | |
105 | *--trv = xtra[1];\r | |
106 | \r | |
107 | /* Set remaining X's to 0's. */\r | |
108 | while (*--trv == 'X') {\r | |
109 | *trv = '0';\r | |
110 | }\r | |
111 | \r | |
112 | /* update xtra for next call. */\r | |
113 | if (xtra[0] != 'z')\r | |
114 | xtra[0]++;\r | |
115 | else {\r | |
116 | xtra[0] = 'a';\r | |
117 | if (xtra[1] != 'z')\r | |
118 | xtra[1]++;\r | |
119 | else\r | |
120 | xtra[1] = 'a';\r | |
121 | }\r | |
122 | \r | |
123 | /*\r | |
124 | * check the target directory; if you have six X's and it\r | |
125 | * doesn't exist this runs for a *very* long time.\r | |
126 | */\r | |
127 | for (start = trv + 1;; --trv) {\r | |
128 | if (trv <= path)\r | |
129 | break;\r | |
130 | if (*trv == '/') {\r | |
131 | *trv = '\0';\r | |
132 | if (stat(path, &sbuf))\r | |
133 | return (0);\r | |
134 | if (!S_ISDIR(sbuf.st_mode)) {\r | |
135 | errno = ENOTDIR;\r | |
136 | return (0);\r | |
137 | }\r | |
138 | *trv = '/';\r | |
139 | break;\r | |
140 | }\r | |
141 | }\r | |
142 | \r | |
143 | for (;;) {\r | |
144 | if (doopen) {\r | |
145 | if ((*doopen =\r | |
146 | open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0)\r | |
147 | return (1);\r | |
148 | if (errno != EEXIST)\r | |
149 | return (0);\r | |
150 | } else if (domkdir) {\r | |
151 | if (mkdir(path, 0700) >= 0)\r | |
152 | return (1);\r | |
153 | if (errno != EEXIST)\r | |
154 | return (0);\r | |
155 | } else if (lstat(path, &sbuf))\r | |
156 | return (errno == ENOENT ? 1 : 0);\r | |
157 | \r | |
158 | /* tricky little algorithm for backward compatibility */\r | |
159 | for (trv = start;;) {\r | |
160 | if (!*trv)\r | |
161 | return (0);\r | |
162 | if (*trv == 'z') {\r | |
163 | *trv++ = 'a';\r | |
164 | }\r | |
165 | else {\r | |
166 | if (isdigit((unsigned char)*trv))\r | |
167 | *trv = 'a';\r | |
168 | else\r | |
169 | ++*trv;\r | |
170 | break;\r | |
171 | }\r | |
172 | }\r | |
173 | }\r | |
174 | /*NOTREACHED*/\r | |
175 | }\r | |
176 | \r | |
177 | #endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP */\r |