source: trunk/athena/bin/discuss/edsc/mktemp.c @ 6956

Revision 6956, 2.4 KB checked in by probe, 31 years ago (diff)
Initial revision
Line 
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)
19static char sccsid[] = "@(#)mktemp.c    5.7 (Berkeley) 6/27/88";
20#endif /* LIBC_SCCS and not lint */
21
22#include <sys/types.h>
23#include <sys/file.h>
24#include <sys/stat.h>
25#include <errno.h>
26#include <stdio.h>
27#include <ctype.h>
28
29#define YES     1
30#define NO      0
31
32mkstemp(as)
33        char    *as;
34{
35        int     fd;
36
37        return (_gettemp(as, &fd) ? fd : -1);
38}
39
40char *
41mktemp(as)
42        char    *as;
43{
44        return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
45}
46
47static
48_gettemp(as, doopen)
49        char    *as;
50        register int    *doopen;
51{
52        extern int      errno;
53        register char   *start, *trv;
54        struct stat     sbuf;
55        u_int   pid;
56
57        pid = getpid();
58
59        /* extra X's get set to 0's */
60        for (trv = as; *trv; ++trv);
61        while (*--trv == 'X') {
62                *trv = (pid % 10) + '0';
63                pid /= 10;
64        }
65
66        /*
67         * check for write permission on target directory; if you have
68         * six X's and you can't write the directory, this will run for
69         * a *very* long time.
70         */
71        for (start = ++trv; trv > as && *trv != '/'; --trv);
72        if (*trv == '/') {
73                *trv = '\0';
74                if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))
75                        return(NO);
76                *trv = '/';
77        }
78        else if (stat(".", &sbuf) == -1)
79                return(NO);
80
81        for (;;) {
82                if (doopen) {
83                    if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
84                        return(YES);
85                    if (errno != EEXIST)
86                        return(NO);
87                }
88                else if (stat(as, &sbuf))
89                        return(errno == ENOENT ? YES : NO);
90
91                /* tricky little algorithm for backward compatibility */
92                for (trv = start;;) {
93                        if (!*trv)
94                                return(NO);
95                        if (*trv == 'z')
96                                *trv++ = 'a';
97                        else {
98                                if (isdigit(*trv))
99                                        *trv = 'a';
100                                else
101                                        ++*trv;
102                                break;
103                        }
104                }
105        }
106        /*NOTREACHED*/
107}
Note: See TracBrowser for help on using the repository browser.