branch update for HEAD-2003021201
[reactos.git] / lib / msvcrt / 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/msvcrt/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 <msvcrt/stdio.h>
17 #include <msvcrt/string.h>
18 #include <msvcrt/io.h>
19
20 #define NDEBUG
21 #include <msvcrt/msvcrtdbg.h>
22
23
24 char* _mktemp(char* _template)
25 {
26   static int count = 0;
27   char *cp, *dp;
28   int i, len, xcount, loopcnt;
29
30   DPRINT("_mktemp('%s')\n", _template);
31   len = strlen (_template);
32   cp = _template + len;
33
34   xcount = 0;
35   while (xcount < 6 && cp > _template && cp[-1] == 'X')
36     xcount++, cp--;
37
38   if (xcount) {
39     dp = cp;
40     while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
41       dp--;
42
43     /* Keep the first characters of the template, but turn the rest into
44        Xs.  */
45     while (cp > dp + 8 - xcount) {
46       *--cp = 'X';
47       xcount = (xcount >= 6) ? 6 : 1 + xcount;
48     }
49
50     /* If dots occur too early -- squash them.  */
51     while (dp < cp) {
52       if (*dp == '.') *dp = 'a';
53       dp++;
54     }
55
56     /* Try to add ".tmp" to the filename.  Truncate unused Xs.  */
57     if (cp + xcount + 3 < _template + len)
58       strcpy (cp + xcount, ".tmp");
59     else
60       cp[xcount] = 0;
61
62     /* This loop can run up to 2<<(5*6) times, or about 10^9 times.  */
63     for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) {
64       int c = count++;
65       for (i = 0; i < xcount; i++, c >>= 5)
66     cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
67       if (_access(_template,0) == -1)
68     return _template;
69     }
70   }
71
72   /* Failure:  truncate the template and return NULL.  */
73   *_template = 0;
74   return 0;
75 }