home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / compat / stdio / mktemp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-23  |  2.6 KB  |  119 lines

  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.  
  71.  
  72.  
  73. #ifdef TEST
  74. int
  75. main ()
  76. {
  77.   char *s, *s0;
  78.  
  79.   s = strdup (s0 = "/usr/foo/dddddddXXXXXX");
  80.   mktemp (s);
  81.   printf ("%s -> %s\n", s0, s);
  82.  
  83.   s = strdup (s0 = "/usr/foo/ddddddXXXXXX");
  84.   mktemp (s);
  85.   printf ("%s -> %s\n", s0, s);
  86.  
  87.   s = strdup (s0 = "/usr/foo/dddddXXXXXX");
  88.   mktemp (s);
  89.   printf ("%s -> %s\n", s0, s);
  90.  
  91.   s = strdup (s0 = "/usr/foo/ddddXXXXXX");
  92.   mktemp (s);
  93.   printf ("%s -> %s\n", s0, s);
  94.  
  95.   s = strdup (s0 = "/usr/foo/dddXXXXXX");
  96.   mktemp (s);
  97.   printf ("%s -> %s\n", s0, s);
  98.  
  99.   s = strdup (s0 = "/usr/foo/.dddXXXXXX");
  100.   mktemp (s);
  101.   printf ("%s -> %s\n", s0, s);
  102.  
  103.   s = strdup (s0 = "/usr/foo/dddXXYXXX");
  104.   mktemp (s);
  105.   printf ("%s -> %s\n", s0, s);
  106.  
  107.   s = strdup (s0 = "/usr/foo/XXXXXX");
  108.   mktemp (s);
  109.   printf ("%s -> %s\n", s0, s);
  110.  
  111.   s = strdup (s0 = "/usr/foo/XXXXXXXX");
  112.   mktemp (s);
  113.   printf ("%s -> %s\n", s0, s);
  114.  
  115.   return 0;
  116. }
  117. #endif
  118.  
  119.