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