1
by Clint Adams
Apply patch from Robert Millan to not ship installkernel and |
1 |
#include <stdio.h> |
2 |
#include <unistd.h> |
|
3 |
#include <stdlib.h> |
|
3
by Clint Adams
Start shipping and installing a starter /etc/shells. |
4 |
#ifdef HAVE_GETOPT_H
|
1
by Clint Adams
Apply patch from Robert Millan to not ship installkernel and |
5 |
#include <getopt.h> |
3
by Clint Adams
Start shipping and installing a starter /etc/shells. |
6 |
#endif /* HAVE_GETOPT_H */ |
1
by Clint Adams
Apply patch from Robert Millan to not ship installkernel and |
7 |
#include <errno.h> |
8 |
#include <sys/types.h> |
|
9 |
#include <sys/stat.h> |
|
10 |
#include <fcntl.h> |
|
11 |
#include <string.h> |
|
12 |
||
13 |
char *progname; |
|
14 |
||
15 |
void
|
|
16 |
usage (int status) |
|
17 |
{
|
|
18 |
if (status) |
|
19 |
fprintf(stderr, "Try `%s --help' for more information.\n", progname); |
|
20 |
else
|
|
21 |
printf("Usage: %s [OPTION]\n\n" |
|
22 |
"Create a temporary file in a safe manner.\n\n" |
|
23 |
"-d, --directory=DIR place temporary file in DIR\n" |
|
24 |
"-p, --prefix=STRING set temporary file's prefix to STRING\n" |
|
25 |
"-s, --suffix=STRING set temporary file's suffix to STRING\n" |
|
26 |
"-m, --mode=MODE open with MODE instead of 0600\n" |
|
27 |
"-n, --name=FILE use FILE instead of tempnam(3)\n" |
|
28 |
" --help display this help and exit\n" |
|
29 |
" --version output version information and exit\n", progname); |
|
30 |
exit(status); |
|
31 |
}
|
|
32 |
||
33 |
||
34 |
void
|
|
35 |
syserror (const char *fx) |
|
36 |
{
|
|
37 |
perror(fx); |
|
38 |
exit(1); |
|
39 |
}
|
|
40 |
||
41 |
||
42 |
int
|
|
43 |
parsemode (const char *in, mode_t *out) |
|
44 |
{
|
|
45 |
char *endptr; |
|
46 |
long int mode; |
|
47 |
mode = strtol(in, &endptr, 8); |
|
48 |
if (*endptr || mode<0 || mode>07777) |
|
49 |
return 1; |
|
50 |
*out = (mode_t) mode; |
|
51 |
return 0; |
|
52 |
}
|
|
53 |
||
54 |
||
55 |
int
|
|
56 |
main (int argc, char **argv) |
|
57 |
{
|
|
58 |
char *name=0, *dir=0, *pfx=0, *sfx=0; |
|
59 |
mode_t mode = 0600; |
|
60 |
int fd, optc; |
|
61 |
struct option long_options[] = { |
|
62 |
{"prefix", required_argument, 0, 'p'}, |
|
63 |
{"suffix", required_argument, 0, 's'}, |
|
64 |
{"directory", required_argument, 0, 'd'}, |
|
65 |
{"mode", required_argument, 0, 'm'}, |
|
66 |
{"name", required_argument, 0, 'n'}, |
|
67 |
{"help", no_argument, 0, 'h'}, |
|
68 |
{"version", no_argument, 0, 'v'}, |
|
69 |
{0, 0, 0, 0} |
|
70 |
};
|
|
71 |
progname = argv[0]; |
|
72 |
||
73 |
while ((optc = getopt_long (argc, argv, "p:s:d:m:n:", long_options, 0)) |
|
74 |
!= EOF) { |
|
75 |
switch (optc) { |
|
76 |
case 0: |
|
77 |
break; |
|
78 |
case 'p': |
|
79 |
pfx = optarg; |
|
80 |
break; |
|
81 |
case 's': |
|
82 |
sfx = optarg; |
|
83 |
break; |
|
84 |
case 'd': |
|
85 |
dir = optarg; |
|
86 |
break; |
|
87 |
case 'm': |
|
88 |
if (parsemode(optarg, &mode)) { |
|
89 |
fprintf(stderr, "Invalid mode `%s'. Mode must be octal.\n", optarg); |
|
90 |
usage(1); |
|
91 |
}
|
|
92 |
break; |
|
93 |
case 'n': |
|
94 |
name = optarg; |
|
95 |
break; |
|
96 |
case 'h': |
|
97 |
usage(0); |
|
98 |
case 'v': |
|
99 |
puts("tempfile " PACKAGE_VERSION); |
|
100 |
exit(0); |
|
101 |
default: |
|
102 |
usage(1); |
|
103 |
}
|
|
104 |
}
|
|
105 |
||
106 |
if (name) { |
|
107 |
if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, mode)) < 0) |
|
108 |
syserror("open"); |
|
109 |
}
|
|
110 |
||
111 |
else { |
|
112 |
for (;;) { |
|
113 |
if (!(name = tempnam(dir, pfx))) |
|
114 |
syserror("tempnam"); |
|
115 |
if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, mode)) < 0) { |
|
116 |
if (errno == EEXIST) { |
|
117 |
free(name); |
|
118 |
continue; |
|
119 |
}
|
|
120 |
syserror("open"); |
|
121 |
}
|
|
122 |
if (sfx) { |
|
123 |
char *namesfx; |
|
124 |
if (!(namesfx = malloc(strlen(name) + strlen(sfx) + 1))) |
|
125 |
syserror("malloc"); |
|
126 |
strcpy(namesfx, name); |
|
127 |
strcat(namesfx, sfx); |
|
128 |
if (link(name, namesfx) < 0) { |
|
129 |
if (errno == EEXIST) { |
|
130 |
if (unlink(name) < 0) |
|
131 |
syserror("unlink"); |
|
132 |
free(name); |
|
133 |
free(namesfx); |
|
134 |
continue; |
|
135 |
}
|
|
136 |
syserror("link"); |
|
137 |
}
|
|
138 |
if (unlink(name) < 0) |
|
139 |
syserror("unlink"); |
|
140 |
free(name); |
|
141 |
name = namesfx; |
|
142 |
}
|
|
143 |
break; |
|
144 |
}
|
|
145 |
}
|
|
146 |
||
147 |
if (close(fd)) |
|
148 |
syserror("close"); |
|
149 |
puts(name); |
|
150 |
exit(0); |
|
151 |
}
|