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 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 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 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 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 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 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 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 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 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 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 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