]>
diplodocus.org Git - nmh/blob - uip/mkstemp.c
1 /* mkstemp.c -- create a temporary file
3 * This code is Copyright (c) 2014 by the authors of nmh.
4 * See the COPYRIGHT file in the root directory of the nmh
5 * distribution for complete copyright information.
8 /* define NMH to 0 to remove dependencies on nmh. */
15 #endif /* HAVE_CONFIG_H */
22 #if ! defined HAVE_MKSTEMPS
23 # define HAVE_MKSTEMPS 0
24 #endif /* ! HAVE_MKSTEMPS */
26 static char *build_template(const char *, const char *, const char *);
27 static void process_args(int, char **, const char **, const char **, const char **);
30 * Use a template of the form:
31 * [directory/][prefix]XXXXXX[suffix]
32 * where some of those named components might be null. suffix is only
33 * supported if HAVE_MKSTEMPS.
37 main(int argc
, char *argv
[])
39 const char *directory
= "", *prefix
= "", *suffix
= "";
44 process_args(argc
, argv
, &directory
, &prefix
, &suffix
);
45 if ((template = build_template(directory
, prefix
, suffix
)) == NULL
) {
49 if ((suffix_len
= strlen(suffix
)) > 0) {
51 if ((fd
= mkstemps(template, suffix_len
)) < 0) { perror("mkstemps"); }
52 # else /* ! HAVE_MKSTEMPS */
54 # endif /* ! HAVE_MKSTEMPS */
56 if ((fd
= mkstemp(template)) < 0) { perror("mkstemp"); }
60 (void) puts(template);
66 return fd
>= 0 ? 0 : 1;
71 build_template(const char *directory
, const char *prefix
, const char *suffix
)
73 const char pattern
[] = "XXXXXX";
74 size_t len
, directory_len
, pathsep_len
, prefix_len
, suffix_len
;
77 directory_len
= strlen(directory
);
78 if (directory_len
> 0) {
80 if (directory
[directory_len
- 1] == '/') {
81 /* Will insert a '/' separately, so truncate the one provided
82 in the directory name. */
88 prefix_len
= strlen(prefix
);
89 suffix_len
= strlen(suffix
);
90 /* sizeof pattern includes its final NULL, so don't add another. */
91 len
= directory_len
+ pathsep_len
+ prefix_len
+ sizeof pattern
+
94 if ((template = malloc(len
))) {
97 (void) strncpy(tp
, directory
, directory_len
);
100 if (pathsep_len
== 1) { *tp
++ = '/'; }
102 (void) strncpy(tp
, prefix
, prefix_len
);
105 (void) strncpy(tp
, pattern
, sizeof pattern
- 1);
106 tp
+= sizeof pattern
- 1;
108 (void) strncpy(tp
, suffix
, suffix_len
);
109 /* tp += suffix_len; */
111 template[len
-1] = '\0';
123 #include "sbr/getarguments.h"
124 #include "sbr/smatch.h"
125 #include "sbr/ambigsw.h"
126 #include "sbr/print_version.h"
127 #include "sbr/print_help.h"
128 #include "sbr/error.h"
133 # define MHFIXMSG_SWITCHES \
134 X("directory", 0, DIRECTORYSW) \
135 X("prefix", 0, PREFIXSW) \
136 X("suffix", 0, SUFFIXSW) \
137 X("version", 0, VERSIONSW) \
139 #else /* ! HAVE_MKSTEMPS */
140 # define MHFIXMSG_SWITCHES \
141 X("directory", 0, DIRECTORYSW) \
142 X("prefix", 0, PREFIXSW) \
143 X("version", 0, VERSIONSW) \
145 #endif /* ! HAVE_MKSTEMPS */
147 #define X(sw, minchars, id) id,
148 DEFINE_SWITCH_ENUM(MHFIXMSG
);
151 #define X(sw, minchars, id) { sw, minchars, id },
152 DEFINE_SWITCH_ARRAY(MHFIXMSG
, switches
);
156 process_args(int argc
, char **argv
, const char **directory
,
157 const char **prefix
, const char **suffix
)
159 char **argp
, **arguments
, *cp
, buf
[100];
162 # endif /* ! HAVE_MKSTEMPS */
164 if (nmh_init(argv
[0], true, false)) { done(1); }
165 arguments
= getarguments (invo_name
, argc
, argv
, 1);
171 while ((cp
= *argp
++)) {
173 switch (smatch(++cp
, switches
)) {
175 ambigsw(cp
, switches
);
178 inform("-%s unknown", cp
);
179 (void) snprintf(buf
, sizeof buf
, "%s [switches]", invo_name
);
180 print_help(buf
, switches
, 1);
183 (void) snprintf(buf
, sizeof buf
, "%s [switches]", invo_name
);
184 print_help(buf
, switches
, 1);
187 print_version(invo_name
);
191 /* Allow the directory to start with '-'. */
192 if ((cp
= *argp
++) == NULL
) {
193 die("missing argument to %s", argp
[-2]);
199 /* Allow the prefix to start with '-'. */
200 if ((cp
= *argp
++) == NULL
) {
201 die("missing argument to %s", argp
[-2]);
208 /* Allow the suffix to start with '-'. */
209 if ((cp
= *argp
++) == NULL
) {
210 die("missing argument to %s", argp
[-2]);
214 # endif /* HAVE_MKSTEMPS */
221 process_args(int argc
, char **argv
, const char **directory
,
222 const char **prefix
, const char **suffix
)
226 "usage: %s [-h] [-d directory] [-p prefix] [-s suffix]\n";
227 const char optstring
[] = "d:hp:s:";
228 # else /* ! HAVE_MKSTEMPS */
229 const char usage
[] = "usage: %s [-h] [-d directory] [-p prefix]\n";
230 const char optstring
[] = "d:hp:";
231 # endif /* ! HAVE_MKSTEMPS */
234 while ((opt
= getopt(argc
, argv
, optstring
)) != -1) {
246 (void) printf(usage
, argv
[0]);
249 (void) fprintf(stderr
, usage
, argv
[0]);