blob: 1a402bf40cc8bf99030cfc80619121504672ab29 [file] [log] [blame]
Lev Walkin4b102252004-08-19 13:29:18 +00001#include "asn1c_internal.h"
Lev Walkin79f54952004-08-13 16:58:19 +00002#include <asn1c_compat.h>
3
Lev Walkin79f54952004-08-13 16:58:19 +00004#ifdef HAVE_SYS_PARAM_H
5#include <sys/param.h> /* For MAXPATHLEN */
6#endif
7
8#ifndef MAXPATHLEN
9#define MAXPATHLEN 1024
10#endif
11
Lev Walkin4b102252004-08-19 13:29:18 +000012#ifndef DEFFILEMODE /* Normally in <sys/stat.h> */
13#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
14#endif
15
16FILE *
17asn1c_open_file(const char *name, const char *ext) {
18 int created = 1;
19 struct stat sb;
20 char *fname;
21 int len;
22 FILE *fp;
23 int fd;
24
25 /*
26 * Compute filenames.
27 */
28 len = strlen(name) + strlen(ext) + 1;
29 fname = alloca(len);
30 snprintf(fname, len, "%s%s", name, ext);
31
32 /*
33 * Create files.
34 */
35 fd = open(fname, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE);
36 if(fd == -1 && errno == EEXIST) {
37 fd = open(fname, O_WRONLY, DEFFILEMODE);
38 created = 0;
39 }
40 if(fd == -1) {
41 perror(fname);
42 return NULL;
43 }
44
45 /*
46 * Check sanity.
47 */
48 if(fstat(fd, &sb) || !S_ISREG(sb.st_mode)) {
49 fprintf(stderr, "%s: Not a regular file\n", fname);
50 if(created) unlink(fname);
51 close(fd);
52 return NULL;
53 }
54
55 (void)ftruncate(fd, 0);
56
57 /*
58 * Convert file descriptor into file pointer.
59 */
60 fp = fdopen(fd, "w");
61 if(fp == NULL) {
62 if(created) unlink(fname);
63 close(fd);
64 }
65 return fp;
66}
67
68
Lev Walkin79f54952004-08-13 16:58:19 +000069char *
70a1c_basename(const char *path) {
71 static char strbuf[MAXPATHLEN];
72 const char *pend;
73 const char *name;
74
75 pend = path + strlen(path);
76 if(pend == path) {
77 strcpy(strbuf, ".");
78 return strbuf;
79 }
80
81 /* Skip tailing slashes */
82 for(pend--; pend > path && *pend == '/'; pend--);
83
84 if(pend == path && *path == '/') {
85 strcpy(strbuf, "/");
86 return strbuf;
87 }
88
89 for(name = pend; name > path && name[-1] != '/'; name--);
90
Lev Walkin4b102252004-08-19 13:29:18 +000091 if((pend - name) >= (int)sizeof(strbuf) - 1) {
Lev Walkin79f54952004-08-13 16:58:19 +000092 errno = ENAMETOOLONG;
93 return 0;
94 }
95
96 memcpy(strbuf, name, pend - name + 1);
97 strbuf[pend - name + 1] = '\0';
98
99 return strbuf;
100}
101
102
103char *
104a1c_dirname(const char *path) {
105 static char strbuf[MAXPATHLEN];
106 const char *pend;
107 const char *last = 0;
108 int in_slash = 0;
109
110 /* One-pass determination of the last char of the pathname */
111 for(pend = path; ; pend++) {
Lev Walkin79f54952004-08-13 16:58:19 +0000112 switch(*pend) {
113 case '\0': break;
114 case '/':
115 if(!in_slash) {
116 last = pend;
117 in_slash = 1;
118 }
119 continue;
120 default:
121 if(in_slash) in_slash = 0;
122 continue;
123 }
124 break;
125 }
Lev Walkin79f54952004-08-13 16:58:19 +0000126
127 if(last <= path) {
128 strcpy(strbuf, *path == '/' ? "/" : ".");
129 return strbuf;
130 }
131
132 if(!last) {
133 strcpy(strbuf, "/");
134 return strbuf;
135 }
136
Lev Walkin4b102252004-08-19 13:29:18 +0000137 if((last - path) >= (int)sizeof(strbuf)) {
Lev Walkin79f54952004-08-13 16:58:19 +0000138 errno = ENAMETOOLONG;
139 return 0;
140 }
141
142 memcpy(strbuf, path, last - path);
143 strbuf[last - path] = '\0';
144
145 return strbuf;
146}
147