:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / crtdll / io / mktemp.c
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  *              Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details 
4  * PROJECT:     ReactOS system libraries
5  * FILE:        lib/crtdll/io/mktemp.c
6  * PURPOSE:     Makes a temp file based on a template
7  * PROGRAMER:   DJ Delorie
8                                 Boudewijn Dekker
9  * UPDATE HISTORY:
10  *              28/12/98: Appropriated for the Reactos Kernel
11  */
12
13 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
14 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
15
16 #include <crtdll/stdio.h>
17 #include <crtdll/string.h>
18 #include <crtdll/io.h>
19
20
21 char* _mktemp (char *_template)
22 {
23   static int count = 0;
24   char *cp, *dp;
25   int i, len, xcount, loopcnt;
26
27  
28
29   len = strlen (_template);
30   cp = _template + len;
31
32   xcount = 0;
33   while (xcount < 6 && cp > _template && cp[-1] == 'X')
34     xcount++, cp--;
35
36   if (xcount) {
37     dp = cp;
38     while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
39       dp--;
40
41     /* Keep the first characters of the template, but turn the rest into
42        Xs.  */
43     while (cp > dp + 8 - xcount) {
44       *--cp = 'X';
45       xcount = (xcount >= 6) ? 6 : 1 + xcount;
46     }
47
48     /* If dots occur too early -- squash them.  */
49     while (dp < cp) {
50       if (*dp == '.') *dp = 'a';
51       dp++;
52     }
53
54     /* Try to add ".tmp" to the filename.  Truncate unused Xs.  */
55     if (cp + xcount + 3 < _template + len)
56       strcpy (cp + xcount, ".tmp");
57     else
58       cp[xcount] = 0;
59
60     /* This loop can run up to 2<<(5*6) times, or about 10^9 times.  */
61     for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) {
62       int c = count++;
63       for (i = 0; i < xcount; i++, c >>= 5)
64         cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
65       if (_access(_template,0) == -1)
66         return _template;
67     }
68   }
69
70   /* Failure:  truncate the template and return NULL.  */
71   *_template = 0;
72   return 0;
73 }