Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <libc/bss.h>
  5. #include <unistd.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8.  
  9. static int mktemp_count = -1;
  10.  
  11. char *
  12. mktemp (char *_template)
  13. {
  14.   static int count = 0;
  15.   char *cp, *dp;
  16.   int i, len, xcount, loopcnt;
  17.  
  18.   /* Reinitialize counter if we were restarted (emacs).  */
  19.   if (__bss_count != mktemp_count)
  20.     {
  21.       mktemp_count = __bss_count;
  22.       count = 0;
  23.     }
  24.  
  25.   len = strlen (_template);
  26.   cp = _template + len;
  27.  
  28.   xcount = 0;
  29.   while (xcount < 6 && cp > _template && cp[-1] == 'X')
  30.     xcount++, cp--;
  31.  
  32.   if (xcount) {
  33.     dp = cp;
  34.     while (dp > _template && dp[-1] != '/' && dp[-1] != '\\' && dp[-1] != ':')
  35.       dp--;
  36.  
  37.     /* Keep the first characters of the template, but turn the rest into
  38.        Xs.  */
  39.     while (cp > dp + 8 - xcount) {
  40.       *--cp = 'X';
  41.       xcount = (xcount >= 6) ? 6 : 1 + xcount;
  42.     }
  43.  
  44.     /* If dots occur too early -- squash them.  */
  45.     while (dp < cp) {
  46.       if (*dp == '.') *dp = 'a';
  47.       dp++;
  48.     }
  49.  
  50.     /* Try to add ".tmp" to the filename.  Truncate unused Xs.  */
  51.     if (cp + xcount + 3 < _template + len)
  52.       strcpy (cp + xcount, ".tmp");
  53.     else
  54.       cp[xcount] = 0;
  55.  
  56.     /* This loop can run up to 2<<(5*6) times, or about 10^9 times.  */
  57.     for (loopcnt = 0; loopcnt < (1 << (5 * xcount)); loopcnt++) {
  58.       int c = count++;
  59.       for (i = 0; i < xcount; i++, c >>= 5)
  60.         cp[i] = "abcdefghijklmnopqrstuvwxyz012345"[c & 0x1f];
  61.       if (!__file_exists(_template))
  62.         return _template;
  63.     }
  64.   }
  65.  
  66.   /* Failure:  truncate the template and return NULL.  */
  67.   *_template = 0;
  68.   return 0;
  69. }
  70.