/* * File vms.c - assorted bletcherous hacks for VMS. Written by Eric Youngdale (1993). */ #ifdef VMS #include #include #include #include #include #define opendir fake_opendir #include "mkisofs.h" #undef opendir #include static struct RAB *rab; /* used for external mailfiles */ static int rms_status; static error_exit(char * text){ fprintf(stderr,"%s\n", text); exit(33); } char * strrchr(const char *, char); char * strdup(char * source){ char * pnt; pnt = (char *) e_malloc(strlen(source) + 1); strcpy(pnt, source); return pnt; } int VMS_stat(char * path, struct stat * spnt){ char * spath; char sbuffer[255]; char * pnt, *ppnt; char * pnt1; ppnt = strrchr(path,']'); if(ppnt) ppnt++; else ppnt = path; spath = path; if(strcmp(ppnt,".") == 0 || strcmp(ppnt,"..") == 0){ strcpy(sbuffer, path); /* Find end of actual name */ pnt = strrchr(sbuffer,']'); if(!pnt) return 0; pnt1 = pnt; while(*pnt1 != '[' && *pnt1 != '.') pnt1--; if(*pnt1 != '[' && strcmp(ppnt,"..") == 0) { pnt1--; while(*pnt1 != '[' && *pnt1 != '.') pnt1--; }; if(*pnt1 == '.') { *pnt1 = ']'; pnt = pnt1; while(*pnt != '.' && *pnt != ']') pnt++; *pnt++ = ']'; while(*pnt != '.' && *pnt != ']') pnt++; *pnt = 0; strcat(sbuffer,".DIR;1"); }; if(*pnt1 == '[') { pnt1++; *pnt1 = 0; strcat(pnt1,"000000]"); pnt1 = strrchr(path,'[') + 1; pnt = sbuffer + strlen(sbuffer); while(*pnt1 && *pnt1 != '.' && *pnt1 != ']') *pnt++ = *pnt1++; *pnt = 0; strcat(sbuffer,".DIR;1"); }; spath = sbuffer; }; return stat(spath, spnt); } static int dircontext[32] = {0,}; static char * searchpath[32]; static struct direct d_entry[32]; int optind = 0; char * optarg; int getopt(int argc, char *argv[], char * flags){ char * pnt; char c; optind++; if(*argv[optind] != '-') return EOF; optarg = 0; c = *(argv[optind]+1); pnt = (char *) strchr(flags, c); if(!pnt) return c; /* Not found */ if(pnt[1] == ':') { optind++; optarg = argv[optind]; }; return c; } void vms_path_fixup(char * name){ char * pnt1; pnt1 = name + strlen(name) - 6; /* First strip the .DIR;1 */ if(strcmp(pnt1, ".DIR;1") == 0) *pnt1 = 0; pnt1 = (char*) strrchr(name, ']'); if(pnt1) { if(pnt1[1] == 0) return; *pnt1 = '.'; strcat(name,"]"); return; }; pnt1 = (char*) strrchr(name, '>'); if(pnt1) { if(pnt1[1] == 0) return; *pnt1 = '.'; strcat(name,">"); return; }; } int opendir(char * path){ int i; for(i=1; i<32; i++) { if(dircontext[i] == 0){ dircontext[i] = -1; searchpath[i] = (char *) e_malloc(strlen(path) + 6); strcpy(searchpath[i], path); vms_path_fixup(searchpath[i]); strcat(searchpath[i],"*.*.*"); return i; }; }; exit(0); } struct direct * readdir(int context){ int i; char cresult[100]; char * pnt; int status; $DESCRIPTOR(dpath,searchpath[context]); $DESCRIPTOR(result,cresult); if(dircontext[context] == -1) { dircontext[context] = -2; strcpy(d_entry[context].d_name, "."); return &d_entry[context]; }; if(dircontext[context] == -2) { dircontext[context] = -3; strcpy(d_entry[context].d_name, ".."); return &d_entry[context]; }; if(dircontext[context] == -3) dircontext[context] = 0; dpath.dsc$w_length = strlen(searchpath[context]); lib$find_file(&dpath, &result, &dircontext[context], 0, 0, &status, 0); if(status == SS$_NOMOREFILES) return 0; /* Now trim trailing spaces from the name */ i = result.dsc$w_length - 1; while(i && cresult[i] == ' ') i--; cresult[i+1] = 0; /* Now locate the actual portion of the file we want */ pnt = (char *) strrchr(cresult,']'); if(pnt) pnt++; else pnt = cresult; strcpy(d_entry[context].d_name, pnt); return &d_entry[context]; } void closedir(int context){ lib$find_file_end(&dircontext[context]); free(searchpath[context]); searchpath[context] = (char *) 0; dircontext[context] = 0; } static open_file(char* fn){ /* this routine initializes a rab and fab required to get the correct definition of the external data file used by mail */ struct FAB * fab; rab = (struct RAB*) e_malloc(sizeof(struct RAB)); fab = (struct FAB*) e_malloc(sizeof(struct FAB)); *rab = cc$rms_rab; /* initialize RAB*/ rab->rab$l_fab = fab; *fab = cc$rms_fab; /* initialize FAB*/ fab->fab$l_fna = fn; fab->fab$b_fns = strlen(fn); fab->fab$w_mrs = 512; fab->fab$b_fac = FAB$M_BIO | FAB$M_GET; fab->fab$b_org = FAB$C_SEQ; fab->fab$b_rfm = FAB$C_FIX; fab->fab$l_xab = (char*) 0; rms_status = sys$open(rab->rab$l_fab); if(rms_status != RMS$_NORMAL && rms_status != RMS$_CREATED) error_exit("$OPEN"); rms_status = sys$connect(rab); if(rms_status != RMS$_NORMAL) error_exit("$CONNECT"); return 1; } static close_file(struct RAB * prab){ rms_status = sys$close(prab->rab$l_fab); free(prab->rab$l_fab); free(prab); if(rms_status != RMS$_NORMAL) error_exit("$CLOSE"); } #define NSECT 16 extern unsigned int last_extent_written; int vms_write_one_file(char * filename, int size, FILE * outfile){ int status, i; char buffer[SECTOR_SIZE * NSECT]; int count; int use; int remain; open_file(filename); remain = size; while(remain > 0){ use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain); use = ROUND_UP(use); /* Round up to nearest sector boundary */ memset(buffer, 0, use); rab->rab$l_ubf = buffer; rab->rab$w_usz = sizeof(buffer); status = sys$read(rab); fwrite(buffer, 1, use, outfile); last_extent_written += use/SECTOR_SIZE; if((last_extent_written % 1000) < use/SECTOR_SIZE) fprintf(stderr,"%d..", last_extent_written); remain -= use; }; close_file(rab); } #endif