genericopenlibs/openenvcore/libc/src/stdio/mktemp.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * 
       
     3  * Copyright (c) 1987, 1993
       
     4  *	The Regents of the University of California.  All rights reserved.
       
     5  *
       
     6  * Redistribution and use in source and binary forms, with or without
       
     7  * modification, are permitted provided that the following conditions
       
     8  * are met:
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  * 4. Neither the name of the University nor the names of its contributors
       
    15  *    may be used to endorse or promote products derived from this software
       
    16  *    without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
       
    19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
       
    22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    28  * SUCH DAMAGE.
       
    29  * * Portions Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 
       
    30  */
       
    31 
       
    32 #if defined(LIBC_SCCS) && !defined(lint)
       
    33 static char sccsid[] = "@(#)mktemp.c	8.1 (Berkeley) 6/4/93";
       
    34 #endif /* LIBC_SCCS and not lint */
       
    35 #include <sys/cdefs.h>
       
    36 __FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.28 2003/02/16 17:29:10 nectar Exp $");
       
    37 
       
    38 #include "namespace.h"
       
    39 #include <sys/types.h>
       
    40 #include <sys/stat.h>
       
    41 #include <errno.h>
       
    42 #include <stdio.h>
       
    43 #include <stdlib.h>
       
    44 #include <string.h>
       
    45 #include <ctype.h>
       
    46 #include <unistd.h>
       
    47 #include "un-namespace.h"
       
    48 #include <fcntl.h>
       
    49 #include "common_def.h"
       
    50 
       
    51 
       
    52 #ifndef __SYMBIAN32__
       
    53 	char *_mktemp(char *);
       
    54 	static int _gettemp(char *, int *, int, int);
       
    55 #else
       
    56 	// _mktempfile accepts an extra parameter for flag 
       
    57 	// flag will be O_TMPFILE for a call by tmpfile and 0 for tempnam and mkstemp
       
    58 	char *_mktemp(char *, int);
       
    59 	static int _gettemp(char *, int *, int, int, int);
       
    60 	int	_mktmpfile(char *, int);
       
    61 #endif
       
    62 
       
    63 
       
    64 static const unsigned char padchar[] =
       
    65 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
       
    66 
       
    67 #ifdef __SYMBIAN_COMPILE_UNUSED__
       
    68 int
       
    69 mkstemps(path, slen)
       
    70 	char *path;
       
    71 	int slen;
       
    72 {
       
    73 	int fd;
       
    74 
       
    75 	return (_gettemp(path, &fd, 0, slen) ? fd : -1);
       
    76 }
       
    77 #endif
       
    78 
       
    79 EXPORT_C
       
    80 int
       
    81 mkstemp(path)
       
    82 	char *path;
       
    83 {
       
    84 	int fd;
       
    85 	#ifndef __SYMBIAN32__
       
    86 		return (_gettemp(path, &fd, 0, 0) ? fd : -1);
       
    87 	#else
       
    88 		return (_gettemp(path, &fd, 0, 0, 0) ? fd : -1);
       
    89 	#endif	
       
    90 }
       
    91 
       
    92 #ifdef __SYMBIAN_COMPILE_UNUSED__
       
    93 char *
       
    94 mkdtemp(path)
       
    95 	char *path;
       
    96 {
       
    97 	return (_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL);
       
    98 }
       
    99 #endif
       
   100 
       
   101 
       
   102 #ifndef __SYMBIAN32__
       
   103 	char *
       
   104 	_mktemp(path)
       
   105 		char *path;
       
   106 #else
       
   107 	char *
       
   108 	_mktemp(path, flag)
       
   109 		char *path;
       
   110 		int flag;
       
   111 #endif	//__SYMBIAN32__
       
   112 {	
       
   113 	#ifndef __SYMBIAN32__	
       
   114 		return (_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL);
       
   115 	#else
       
   116 		return (_gettemp(path, (int *)NULL, 0, 0, flag) ? path : (char *)NULL);
       
   117 	#endif
       
   118 }
       
   119 
       
   120 #ifndef __SYMBIAN32__
       
   121 __warn_references(mktemp,
       
   122     "warning: mktemp() possibly used unsafely; consider using mkstemp()");
       
   123 #endif //__SYMBIAN32__
       
   124 
       
   125 #ifdef __SYMBIAN_COMPILE_UNUSED__
       
   126 char *
       
   127 mktemp(path)
       
   128 	char *path;
       
   129 {
       
   130 	return (_mktemp(path));
       
   131 }
       
   132 #endif
       
   133 
       
   134 
       
   135 #ifdef __SYMBIAN32__
       
   136 	int
       
   137 	_mktmpfile(buf, flag)
       
   138 	char *buf;
       
   139 	int flag;
       
   140 		{
       
   141 		int fd;
       
   142 		return (_gettemp(buf, &fd, 0, 0, flag) ? fd : -1);
       
   143 		}
       
   144 
       
   145 #endif //__SYMBIAN32__
       
   146 
       
   147 
       
   148 #ifdef __SYMBIAN32__
       
   149 static int
       
   150 _gettemp(path, doopen, domkdir, slen, sflag)
       
   151 	char *path;
       
   152 	int *doopen;
       
   153 	int domkdir;
       
   154 	int slen;
       
   155 	int sflag;
       
   156 #else
       
   157 _gettemp(path, doopen, domkdir, slen)
       
   158 	char *path;
       
   159 	int *doopen;
       
   160 	int domkdir;
       
   161 	int slen;
       
   162 #endif //__SYMBIAN32__
       
   163 {
       
   164 	char *start, *trv, *suffp;
       
   165 	char *pad;
       
   166 	struct stat sbuf;
       
   167 	int rval;
       
   168 	uint32_t rand;
       
   169 
       
   170 	#ifdef __SYMBIAN32__
       
   171 	int count;
       
   172 	size_t len = strlen(path);
       
   173 	#endif //__SYMBIAN32__
       
   174 	
       
   175 	if (doopen != NULL && domkdir) {
       
   176 		errno = EINVAL;
       
   177 		return (0);
       
   178 	}
       
   179 	
       
   180 #ifdef __SYMBIAN32__	
       
   181 	// A single mkdir call introduced below instead of two separate 
       
   182 	// calls from tempnam.c and tmpfile.c
       
   183 	if (sflag)
       
   184 		{		
       
   185 		char *f = P_tmpdir;
       
   186 				
       
   187 		if (mkdir(f, 0666) == -1)
       
   188 			{
       
   189 			if (errno != EEXIST)
       
   190 				{
       
   191 				return -1;		//return from here	
       
   192 				}
       
   193 			}
       
   194 		}
       
   195 #endif//__SYMBIAN32__
       
   196 
       
   197 		
       
   198 	for (trv = path; *trv != '\0'; ++trv)
       
   199 		;
       
   200 	trv -= slen;
       
   201 	suffp = trv;
       
   202 	--trv;
       
   203 	
       
   204 	#ifdef __SYMBIAN32__
       
   205 	if (trv < path || len < 6 || strcmp(&path[len - 6], "XXXXXX")) {
       
   206 	#else
       
   207 	if (trv < path) {
       
   208 	#endif //__SYMBIAN32__
       
   209 		errno = EINVAL;
       
   210 		return (0);
       
   211 	}
       
   212 			
       
   213 	/* Fill space with random characters */
       
   214 	#ifndef __SYMBIAN32__
       
   215 	while (trv >= path && *trv == 'X') {
       
   216 	#else
       
   217 	count = 0;
       
   218 	while (trv >= path && count < 6) {
       
   219 	#endif //__SYMBIAN32__
       
   220 		rand = arc4random() % (sizeof(padchar) - 1);
       
   221 		*trv-- = padchar[rand];
       
   222 		#ifdef __SYMBIAN32__	
       
   223 		count++;
       
   224 		#endif //__SYMBIAN32__
       
   225 	}
       
   226 	start = trv + 1;
       
   227 
       
   228 	
       
   229 
       
   230 	
       
   231 	/*
       
   232 	 * check the target directory.
       
   233 	 */
       
   234 	if (doopen != NULL || domkdir) {
       
   235 		for (; trv > path; --trv) {
       
   236 			if (*trv == '/') {
       
   237 				*trv = '\0';
       
   238 				rval = stat(path, &sbuf);
       
   239 				*trv = '/';
       
   240 				if (rval != 0)
       
   241 					return (0);
       
   242 				if (!S_ISDIR(sbuf.st_mode)) {
       
   243 					errno = ENOTDIR;
       
   244 					return (0);
       
   245 				}
       
   246 				break;
       
   247 			}
       
   248 		}
       
   249 	}
       
   250 
       
   251 	for (;;) {
       
   252 		if (doopen) {
       
   253 		#ifndef __SYMBIAN32__
       
   254 			if ((*doopen =
       
   255 			    _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
       
   256 		#else
       
   257 			if ((*doopen =
       
   258 			    _open(path, O_CREAT|O_EXCL|O_RDWR|sflag, 0600)) >= 0)
       
   259 		#endif//__SYMBIAN32__
       
   260 				return (1);
       
   261 			if (errno != EEXIST)
       
   262 				return (0);
       
   263 		} else if (domkdir) {
       
   264 			if (mkdir(path, 0700) == 0)
       
   265 				return (1);
       
   266 			if (errno != EEXIST)
       
   267 				return (0);
       
   268 		} else if (lstat(path, &sbuf))
       
   269 			return (errno == ENOENT);
       
   270 
       
   271 		/* If we have a collision, cycle through the space of filenames */
       
   272 		for (trv = start;;) {
       
   273 			if (*trv == '\0' || trv == suffp)
       
   274 				return (0);
       
   275 			
       
   276 			#ifdef __SYMBIAN32__
       
   277 			pad = strchr((const char *)padchar, *trv);
       
   278 			#else
       
   279 			pad = strchr(padchar, *trv);
       
   280 			#endif //__SYMBIAN32__
       
   281 			
       
   282 			if (pad == NULL || *++pad == '\0')
       
   283 				*trv++ = padchar[0];
       
   284 			else {
       
   285 				*trv++ = *pad;
       
   286 				break;
       
   287 			}
       
   288 		}
       
   289 	}
       
   290 	/*NOTREACHED*/
       
   291 }