home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / mktemp.c < prev    next >
Text File  |  1994-09-23  |  3KB  |  118 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)mktemp.c    5.8 (Berkeley - modified) 10/16/89";
  20. #endif /* LIBC_SCCS and not lint */
  21. #ifdef OSK
  22. #include <types.h>
  23. #include <file.h>
  24. #include <stat.h>
  25. #else
  26. #include <sys/types.h>
  27. #include <sys/file.h>
  28. #include <sys/stat.h>
  29. #endif
  30. #include <errno.h>
  31. #include <stdio.h>
  32. #include <ctype.h>
  33.  
  34. #ifndef S_ISDIR
  35. #define S_ISDIR(m)    ((m & 0170000) == 0040000)
  36. #endif
  37.  
  38. mkstemp(path)
  39.     char *path;
  40. {
  41.     int fd;
  42.  
  43.     return (_gettemp(path, &fd) ? fd : -1);
  44. }
  45.  
  46. char *
  47. mktemp(path)
  48.     char *path;
  49. {
  50.     return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
  51. }
  52.  
  53. static
  54. _gettemp(path, doopen)
  55.     char *path;
  56.     register int *doopen;
  57. {
  58.     extern int errno;
  59.     register char *start, *trv;
  60.     struct stat sbuf;
  61.     u_int pid;
  62.  
  63.     pid = getpid();
  64.     for (trv = path; *trv; ++trv);        /* extra X's get set to 0's */
  65.     while (*--trv == 'X') {
  66.         *trv = (pid % 10) + '0';
  67.         pid /= 10;
  68.     }
  69.  
  70.     /*
  71.      * check the target directory; if you have six X's and it
  72.      * doesn't exist this runs for a *very* long time.
  73.      */
  74.     for (start = trv + 1;; --trv) {
  75.         if (trv <= path)
  76.             break;
  77.         if (*trv == '/') {
  78.             *trv = '\0';
  79.             if (stat(path, &sbuf))
  80.                 return(0);
  81.             if (!S_ISDIR(sbuf.st_mode)) {
  82.                 errno = ENOTDIR;
  83.                 return(0);
  84.             }
  85.             *trv = '/';
  86.             break;
  87.         }
  88.     }
  89.  
  90.     for (;;) {
  91.         if (doopen) {
  92.             if ((*doopen =
  93.                 open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  94.                 return(1);
  95.             if (errno != EEXIST)
  96.                 return(0);
  97.         }
  98.         else if (stat(path, &sbuf))
  99.             return(errno == ENOENT ? 1 : 0);
  100.  
  101.         /* tricky little algorithm for backward compatibility */
  102.         for (trv = start;;) {
  103.             if (!*trv)
  104.                 return(0);
  105.             if (*trv == 'z')
  106.                 *trv++ = 'a';
  107.             else {
  108.                 if (isdigit(*trv))
  109.                     *trv = 'a';
  110.                 else
  111.                     ++*trv;
  112.                 break;
  113.             }
  114.         }
  115.     }
  116.     /*NOTREACHED*/
  117. }
  118.