1 /*
2 * File vms.c - assorted bletcherous hacks for VMS.
3
4 Written by Eric Youngdale (1993).
5 */
6
7 #ifdef VMS
8 #include <rms.h>
9 #include <descrip.h>
10 #include <ssdef.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #define opendir fake_opendir
14 #include "mkisofs.h"
15 #undef opendir
16 #include <stdio.h>
17
18 static struct RAB *rab; /* used for external mailfiles */
19 static int rms_status;
20
error_exit(char * text)21 static error_exit(char * text){
22 fprintf(stderr,"%s\n", text);
23 exit(33);
24 }
25
26
27 char * strrchr(const char *, char);
28
strdup(char * source)29 char * strdup(char * source){
30 char * pnt;
31 pnt = (char *) e_malloc(strlen(source) + 1);
32 strcpy(pnt, source);
33 return pnt;
34 }
35
VMS_stat(char * path,struct stat * spnt)36 int VMS_stat(char * path, struct stat * spnt){
37 char * spath;
38 char sbuffer[255];
39 char * pnt, *ppnt;
40 char * pnt1;
41
42 ppnt = strrchr(path,']');
43 if(ppnt) ppnt++;
44 else ppnt = path;
45
46 spath = path;
47
48 if(strcmp(ppnt,".") == 0 || strcmp(ppnt,"..") == 0){
49 strcpy(sbuffer, path);
50
51 /* Find end of actual name */
52 pnt = strrchr(sbuffer,']');
53 if(!pnt) return 0;
54
55 pnt1 = pnt;
56 while(*pnt1 != '[' && *pnt1 != '.') pnt1--;
57
58 if(*pnt1 != '[' && strcmp(ppnt,"..") == 0) {
59 pnt1--;
60 while(*pnt1 != '[' && *pnt1 != '.') pnt1--;
61 };
62
63 if(*pnt1 == '.') {
64 *pnt1 = ']';
65 pnt = pnt1;
66 while(*pnt != '.' && *pnt != ']') pnt++;
67 *pnt++ = ']';
68 while(*pnt != '.' && *pnt != ']') pnt++;
69 *pnt = 0;
70 strcat(sbuffer,".DIR;1");
71 };
72
73 if(*pnt1 == '[') {
74 pnt1++;
75 *pnt1 = 0;
76 strcat(pnt1,"000000]");
77 pnt1 = strrchr(path,'[') + 1;
78 pnt = sbuffer + strlen(sbuffer);
79 while(*pnt1 && *pnt1 != '.' && *pnt1 != ']') *pnt++ = *pnt1++;
80 *pnt = 0;
81 strcat(sbuffer,".DIR;1");
82 };
83
84 spath = sbuffer;
85 };
86 return stat_filter(spath, spnt);
87 }
88
89 static int dircontext[32] = {0,};
90 static char * searchpath[32];
91 static struct direct d_entry[32];
92
93 int optind = 0;
94 char * optarg;
95
getopt(int argc,char * argv[],char * flags)96 int getopt(int argc, char *argv[], char * flags){
97 char * pnt;
98 char c;
99 optind++;
100 if(*argv[optind] != '-') return EOF;
101 optarg = 0;
102
103 c = *(argv[optind]+1);
104 pnt = (char *) strchr(flags, c);
105 if(!pnt) return c; /* Not found */
106 if(pnt[1] == ':') {
107 optind++;
108 optarg = argv[optind];
109 };
110 return c;
111 }
112
vms_path_fixup(char * name)113 void vms_path_fixup(char * name){
114 char * pnt1;
115 pnt1 = name + strlen(name) - 6;
116
117 /* First strip the .DIR;1 */
118 if(strcmp(pnt1, ".DIR;1") == 0) *pnt1 = 0;
119
120 pnt1 = (char*) strrchr(name, ']');
121 if(pnt1) {
122 if(pnt1[1] == 0) return;
123 *pnt1 = '.';
124 strcat(name,"]");
125 return;
126 };
127 pnt1 = (char*) strrchr(name, '>');
128 if(pnt1) {
129 if(pnt1[1] == 0) return;
130 *pnt1 = '.';
131 strcat(name,">");
132 return;
133 };
134 }
135
opendir(char * path)136 int opendir(char * path){
137 int i;
138 for(i=1; i<32; i++) {
139 if(dircontext[i] == 0){
140 dircontext[i] = -1;
141 searchpath[i] = (char *) e_malloc(strlen(path) + 6);
142 strcpy(searchpath[i], path);
143 vms_path_fixup(searchpath[i]);
144 strcat(searchpath[i],"*.*.*");
145 return i;
146 };
147 };
148 exit(0);
149 }
150
readdir(int context)151 struct direct * readdir(int context){
152 int i;
153 char cresult[100];
154 char * pnt;
155 int status;
156 $DESCRIPTOR(dpath,searchpath[context]);
157 $DESCRIPTOR(result,cresult);
158
159 if(dircontext[context] == -1) {
160 dircontext[context] = -2;
161 strcpy(d_entry[context].d_name, ".");
162 return &d_entry[context];
163 };
164
165 if(dircontext[context] == -2) {
166 dircontext[context] = -3;
167 strcpy(d_entry[context].d_name, "..");
168 return &d_entry[context];
169 };
170
171 if(dircontext[context] == -3) dircontext[context] = 0;
172
173 dpath.dsc$w_length = strlen(searchpath[context]);
174 lib$find_file(&dpath, &result, &dircontext[context],
175 0, 0, &status, 0);
176
177 if(status == SS$_NOMOREFILES) return 0;
178
179 /* Now trim trailing spaces from the name */
180 i = result.dsc$w_length - 1;
181 while(i && cresult[i] == ' ') i--;
182 cresult[i+1] = 0;
183
184 /* Now locate the actual portion of the file we want */
185
186 pnt = (char *) strrchr(cresult,']');
187 if(pnt) pnt++;
188 else
189 pnt = cresult;
190
191 strcpy(d_entry[context].d_name, pnt);
192 return &d_entry[context];
193 }
194
closedir(int context)195 void closedir(int context){
196 lib$find_file_end(&dircontext[context]);
197 free(searchpath[context]);
198 searchpath[context] = (char *) 0;
199 dircontext[context] = 0;
200 }
201
open_file(char * fn)202 static open_file(char* fn){
203 /* this routine initializes a rab and fab required to get the
204 correct definition of the external data file used by mail */
205 struct FAB * fab;
206
207 rab = (struct RAB*) e_malloc(sizeof(struct RAB));
208 fab = (struct FAB*) e_malloc(sizeof(struct FAB));
209
210 *rab = cc$rms_rab; /* initialize RAB*/
211 rab->rab$l_fab = fab;
212
213 *fab = cc$rms_fab; /* initialize FAB*/
214 fab->fab$l_fna = fn;
215 fab->fab$b_fns = strlen(fn);
216 fab->fab$w_mrs = 512;
217 fab->fab$b_fac = FAB$M_BIO | FAB$M_GET;
218 fab->fab$b_org = FAB$C_SEQ;
219 fab->fab$b_rfm = FAB$C_FIX;
220 fab->fab$l_xab = (char*) 0;
221
222 rms_status = sys$open(rab->rab$l_fab);
223 if(rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED)
224 error_exit("$OPEN");
225 rms_status = sys$connect(rab);
226 if(rms_status != RMS$_NORMAL)
227 error_exit("$CONNECT");
228 return 1;
229 }
230
close_file(struct RAB * prab)231 static close_file(struct RAB * prab){
232 rms_status = sys$close(prab->rab$l_fab);
233 free(prab->rab$l_fab);
234 free(prab);
235 if(rms_status != RMS$_NORMAL)
236 error_exit("$CLOSE");
237 }
238
239 #define NSECT 16
240 extern unsigned int last_extent_written;
241
vms_write_one_file(char * filename,int size,FILE * outfile)242 int vms_write_one_file(char * filename, int size, FILE * outfile){
243 int status, i;
244 char buffer[SECTOR_SIZE * NSECT];
245 int count;
246 int use;
247 int remain;
248
249 open_file(filename);
250
251 remain = size;
252
253 while(remain > 0){
254 use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain);
255 use = ROUND_UP(use); /* Round up to nearest sector boundary */
256 memset(buffer, 0, use);
257 rab->rab$l_ubf = buffer;
258 rab->rab$w_usz = sizeof(buffer);
259 status = sys$read(rab);
260 fwrite(buffer, 1, use, outfile);
261 last_extent_written += use/SECTOR_SIZE;
262 if((last_extent_written % 1000) < use/SECTOR_SIZE) fprintf(stderr,"%d..", last_extent_written);
263 remain -= use;
264 };
265
266 close_file(rab);
267 }
268 #endif
269