1 #include "asn1c_internal.h"
2 #include "asn1c_compat.h"
4 /* Normally file permissions are (DEFFILEMODE & ~umask(2)) */
5 #ifndef DEFFILEMODE /* Normally in <sys/stat.h> */
8 #define DEFFILEMODE (S_IREAD|S_IWRITE)
9 #define REASONABLE_FILE_MODE DEFFILEMODE
11 #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
12 #define REASONABLE_FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
14 #else /* !DEFFILEMODE */
16 #define REASONABLE_FILE_MODE DEFFILEMODE
18 #define REASONABLE_FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
23 int mkstemp(char *template) {
24 char *tmpFN = _mktemp(template);
26 return open(tmpFN, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
35 #define mkstemp(foo) mkstemps(foo, 0)
39 asn1c_open_file(const char *destdir, const char *name, const char *ext,
53 ret = snprintf(fname, sizeof(fname), "%s%s%s%s", destdir ? destdir : "",
54 name, ext, opt_tmpname ? ".XXXXXX" : "");
55 assert(ret > 0 && ret < (ssize_t)sizeof(fname));
59 * Create temporary file.
64 /* fchmod() does not respect umask */
65 (void)fchmod(fd, REASONABLE_FILE_MODE);
70 * Create specified file, or open the old one.
72 fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
73 if(fd == -1 && errno == EEXIST) {
74 fd = open(fname, O_WRONLY, DEFFILEMODE);
80 if(destdir && stat(destdir, &st) == -1) {
81 fprintf(stderr, "%s: No such directory\n", destdir);
93 if(fstat(fd, &sb) || !S_ISREG(sb.st_mode)) {
94 fprintf(stderr, "%s: Not a regular file\n", fname);
95 if(created) unlink(fname);
100 if(ftruncate(fd, 0) == -1) {
101 fprintf(stderr, "%s: ftruncate failed: %s\n",
102 fname, strerror(errno));
103 if(created) unlink(fname);
111 * Convert file descriptor into file pointer.
113 fp = fdopen(fd, "w");
115 if(created) unlink(fname);
120 /* Return the temporary file name */
122 *opt_tmpname = strdup(fname);
126 if(created) unlink(fname);
136 a1c_basename(const char *path, const char *destdir) {
137 static char strbuf[PATH_MAX];
143 strncpy(strbuf, destdir, PATH_MAX - 1);
144 strbuf[PATH_MAX - 1] = '\0';
145 sbuf = strbuf + strlen(strbuf);
147 pend = path + strlen(path);
153 /* Skip tailing slashes */
154 for(pend--; pend > path && *pend == '/'; pend--);
156 if(pend == path && *path == '/') {
161 for(name = pend; name > path && name[-1] != '/'; name--);
163 if((pend - name) >= (int)sizeof(strbuf) - 1) {
164 errno = ENAMETOOLONG;
168 memcpy(sbuf, name, pend - name + 1);
169 sbuf[pend - name + 1] = '\0';
176 a1c_dirname(const char *path) {
177 static char strbuf[PATH_MAX];
179 const char *last = 0;
182 /* One-pass determination of the last char of the pathname */
183 for(pend = path; ; pend++) {
193 if(in_slash) in_slash = 0;
200 strcpy(strbuf, *path == '/' ? "/" : ".");
209 if((last - path) >= (int)sizeof(strbuf)) {
210 errno = ENAMETOOLONG;
214 memcpy(strbuf, path, last - path);
215 strbuf[last - path] = '\0';