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