xref: /openbsd/gnu/usr.sbin/mkhybrid/src/vms.c (revision 68cbdb5e)
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