blob: ebc6d3f0db0fc950c9806fc65c5fd92d28525bd5 [file] [log] [blame]
vlm2248d712004-08-19 13:29:18 +00001#include "asn1c_internal.h"
vlm8a09e0f2005-02-25 14:20:30 +00002#include "asn1c_compat.h"
vlm1f1d8cb2004-08-13 16:58:19 +00003
4#ifndef MAXPATHLEN
5#define MAXPATHLEN 1024
6#endif
7
vlm2248d712004-08-19 13:29:18 +00008#ifndef DEFFILEMODE /* Normally in <sys/stat.h> */
vlm8a09e0f2005-02-25 14:20:30 +00009#ifdef WIN32
10#define DEFFILEMODE 0
11#else
vlm2248d712004-08-19 13:29:18 +000012#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
13#endif
vlm8a09e0f2005-02-25 14:20:30 +000014#endif
vlm2248d712004-08-19 13:29:18 +000015
16FILE *
17asn1c_open_file(const char *name, const char *ext) {
18 int created = 1;
vlm8a09e0f2005-02-25 14:20:30 +000019#ifndef WIN32
vlm2248d712004-08-19 13:29:18 +000020 struct stat sb;
vlm8a09e0f2005-02-25 14:20:30 +000021#endif
vlm2248d712004-08-19 13:29:18 +000022 char *fname;
vlm8a09e0f2005-02-25 14:20:30 +000023 size_t len;
vlm2248d712004-08-19 13:29:18 +000024 FILE *fp;
25 int fd;
26
27 /*
28 * Compute filenames.
29 */
30 len = strlen(name) + strlen(ext) + 1;
31 fname = alloca(len);
32 snprintf(fname, len, "%s%s", name, ext);
33
34 /*
35 * Create files.
36 */
37 fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
38 if(fd == -1 && errno == EEXIST) {
39 fd = open(fname, O_WRONLY, DEFFILEMODE);
40 created = 0;
41 }
42 if(fd == -1) {
43 perror(fname);
44 return NULL;
45 }
46
vlm8a09e0f2005-02-25 14:20:30 +000047#ifndef WIN32
vlm2248d712004-08-19 13:29:18 +000048 /*
49 * Check sanity.
50 */
51 if(fstat(fd, &sb) || !S_ISREG(sb.st_mode)) {
52 fprintf(stderr, "%s: Not a regular file\n", fname);
53 if(created) unlink(fname);
54 close(fd);
55 return NULL;
56 }
57
58 (void)ftruncate(fd, 0);
vlm8a09e0f2005-02-25 14:20:30 +000059#else
60 _chsize(fd, 0);
61#endif /* WIN32 */
vlm2248d712004-08-19 13:29:18 +000062
63 /*
64 * Convert file descriptor into file pointer.
65 */
66 fp = fdopen(fd, "w");
67 if(fp == NULL) {
68 if(created) unlink(fname);
69 close(fd);
70 }
71 return fp;
72}
73
74
vlm1f1d8cb2004-08-13 16:58:19 +000075char *
76a1c_basename(const char *path) {
77 static char strbuf[MAXPATHLEN];
78 const char *pend;
79 const char *name;
80
81 pend = path + strlen(path);
82 if(pend == path) {
83 strcpy(strbuf, ".");
84 return strbuf;
85 }
86
87 /* Skip tailing slashes */
88 for(pend--; pend > path && *pend == '/'; pend--);
89
90 if(pend == path && *path == '/') {
91 strcpy(strbuf, "/");
92 return strbuf;
93 }
94
95 for(name = pend; name > path && name[-1] != '/'; name--);
96
vlm2248d712004-08-19 13:29:18 +000097 if((pend - name) >= (int)sizeof(strbuf) - 1) {
vlm1f1d8cb2004-08-13 16:58:19 +000098 errno = ENAMETOOLONG;
99 return 0;
100 }
101
102 memcpy(strbuf, name, pend - name + 1);
103 strbuf[pend - name + 1] = '\0';
104
105 return strbuf;
106}
107
108
109char *
110a1c_dirname(const char *path) {
111 static char strbuf[MAXPATHLEN];
112 const char *pend;
113 const char *last = 0;
114 int in_slash = 0;
115
116 /* One-pass determination of the last char of the pathname */
117 for(pend = path; ; pend++) {
vlm1f1d8cb2004-08-13 16:58:19 +0000118 switch(*pend) {
119 case '\0': break;
120 case '/':
121 if(!in_slash) {
122 last = pend;
123 in_slash = 1;
124 }
125 continue;
126 default:
127 if(in_slash) in_slash = 0;
128 continue;
129 }
130 break;
131 }
vlm1f1d8cb2004-08-13 16:58:19 +0000132
133 if(last <= path) {
134 strcpy(strbuf, *path == '/' ? "/" : ".");
135 return strbuf;
136 }
137
138 if(!last) {
139 strcpy(strbuf, "/");
140 return strbuf;
141 }
142
vlm2248d712004-08-19 13:29:18 +0000143 if((last - path) >= (int)sizeof(strbuf)) {
vlm1f1d8cb2004-08-13 16:58:19 +0000144 errno = ENAMETOOLONG;
145 return 0;
146 }
147
148 memcpy(strbuf, path, last - path);
149 strbuf[last - path] = '\0';
150
151 return strbuf;
152}
153