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