/* Hack for filenames under dos, use a file with unix->dos mappings */ #include <stdio.h> #include <string.h> /* functions are dos_fname,dos_fopen, dos_rename */ #define ACT_READ 0 #define ACT_CREATE 1 #define ACT_DELETE 2 #define REC_SIZE 280 #define DOS_OFFSET 250 #define SLASH_CHAR '\\' #define SLASH_STRING "\\" int check_file(char * name) { FILE * temp_file; temp_file=fopen(name,"r"); if (temp_file != NULL) { fclose(temp_file); return 0; } temp_file=fopen(name,"w"); if (temp_file != NULL) { fclose(temp_file); return 1; } return 0; } char * dos_fname( char * filename, int action) { char pathname[1024]; char unix_filename[255]; static char buffer[2048]; char dos_filename[13]; int a,b,slashpos,dos_dot_pos; char c; char * dest_ptr; char unix_name_len; FILE * dirlist; int num_recs,dir_size,pathpos,cur_len; int found, lastdeleted; int firstdot; /* first convert pathname */ /* Split into pathname and filename. */ slashpos=-1; b=0; dir_size=0; pathpos=0; firstdot=1; for (a=0; filename[a] != '\0'; a++) { c=filename[a]; if (c=='/') { c=SLASH_CHAR; slashpos=a; pathpos=b; dir_size=-1; } if (c=='.') { if (firstdot) firstdot=0; else c='_'; } if (dir_size < 8) { pathname[b++]=c; dir_size++; } } if (slashpos < 1) { pathname[0]='.'; pathname[1]='\0'; } else pathname[pathpos]='\0'; dest_ptr=unix_filename; for (a=slashpos+1; filename[a] != '\0'; a++) *(dest_ptr++)=filename[a]; *dest_ptr='\0'; unix_name_len=a-(slashpos+1); /* Open dirlist */ strcpy(buffer,pathname); strcat(buffer,SLASH_STRING "__unix.dir"); dirlist=fopen(buffer,"rb"); if ( (dirlist == NULL) && action != ACT_CREATE) { fprintf(stderr,"Could not find dirlist file.\n\r"); return NULL; } found=0; lastdeleted=-1; num_recs=0; if ( dirlist != NULL ) { fread( &num_recs, sizeof(int), 1, dirlist); if (num_recs > 0 ) { for (a=1; a <= num_recs; a++) { fseek( dirlist, REC_SIZE * a, SEEK_SET); if (fgetc(dirlist) == 'D') { lastdeleted=a; break; } cur_len=fgetc(dirlist); if ( cur_len != unix_name_len ) continue; found=1; for (b=slashpos+1; filename[b] != '\0'; b++) { if (fgetc(dirlist) != filename[b]) { found=0; break; } } if (found && fgetc(dirlist) != ' ') found=0; if ( found ) break; } } if (found) { fseek( dirlist, REC_SIZE * a + DOS_OFFSET, SEEK_SET); fread( &dos_filename, 12, 1, dirlist); dos_filename[12]='\0'; for (a=11; a > -1; a--) /* Remove blank spaces at end of filename */ { if (dos_filename[a]==' ') dos_filename[a]='\0'; else break; } if (a==-1) /* Blank dos filename */ { fprintf(stderr,"Invalid dos filename in doshack for file %s, deleting\n\r",filename); fseek( dirlist, REC_SIZE * a, SEEK_SET); fputc( 'D', dirlist); found=0; } if (action == ACT_DELETE) { fseek( dirlist, REC_SIZE * a, SEEK_SET); fputc( 'D', dirlist); } } fclose(dirlist); } if (!found) { if (action != ACT_CREATE) { fprintf(stderr,"Could not find file %s.\n\r",filename); return NULL; } /* Create an entry for a new file. */ /* Split name into prefix and suffix */ for (a=0; a < 8; a++) { if (unix_filename[a]=='.' || unix_filename[a]=='\0') break; dos_filename[a]=unix_filename[a]; } dos_dot_pos=a; b=a; /* b measures the pos in dos_filename */ if (unix_filename[a] != '\0' ) { if (unix_filename[a] == '.' ) a++; dos_filename[b++]='.'; for ( ; b < 12 ; b++) { if (unix_filename[a] == '\0' ) break; else { if (unix_filename[a] == '.' ) dos_filename[b] = '_'; else dos_filename[b] = unix_filename[a]; a++; } } } dos_filename[b]='\0'; /* We now have a dosified original name. */ strcpy(buffer, pathname); strcat(buffer, SLASH_STRING); slashpos=strlen(buffer); strcat(buffer, dos_filename); if ( ! check_file(buffer) ) { /* now do some jiggery pokery */ buffer[slashpos+dos_dot_pos]='.'; for (a=0; a < 1000; a++) { sprintf(buffer+slashpos+dos_dot_pos+1,"%03i",a); /* Replace suffix with 3 dig. number */ if ( check_file(buffer) ) break; } sprintf(dos_filename+dos_dot_pos+1,"%03i",a); if (a==1000) { fprintf(stderr,"Could not work out a dos filename for %s.\n\r",filename); return NULL; } } strcpy(buffer,pathname); strcat(buffer,SLASH_STRING "__unix.dir"); dirlist=fopen(buffer,"r+b"); if (dirlist == NULL) dirlist=fopen(buffer,"w+b"); if (dirlist == NULL) { fprintf(stderr,"Could not create a dirlist file.\n\r"); return NULL; } if (lastdeleted == -1) { num_recs++; lastdeleted=num_recs; fseek(dirlist,0,SEEK_SET); fwrite(&num_recs, sizeof(int), 1, dirlist); } fseek( dirlist, REC_SIZE * lastdeleted, SEEK_SET); fputc( ' ', dirlist); fputc( unix_name_len, dirlist); fprintf(dirlist, "%s ", unix_filename); fseek( dirlist, REC_SIZE * lastdeleted + DOS_OFFSET, SEEK_SET); fprintf(dirlist, "%s \n\r", dos_filename); fclose(dirlist); } strcpy(buffer,pathname); strcat(buffer,SLASH_STRING); strcat(buffer,dos_filename); fprintf(stderr,"Converted %s to %s\n\r",filename,buffer); return buffer; } FILE * dos_fopen(char * filename, char * mode) { /* Currently only deal with a, r, w */ char * dos_filename; int action; if (!strcmp(filename,"nul")) return fopen(filename, mode); if (mode[0]=='r') action=ACT_READ; else action=ACT_CREATE; dos_filename=dos_fname(filename, action); if (dos_filename==NULL) return NULL; return fopen(dos_filename, mode); } int dos_rename(char * old, char * new) { char * temp; char old_dos[255], new_dos[255]; FILE * temp_file; if ( (temp=dos_fname(old, ACT_READ)) == NULL) return -1; strcpy(old_dos, temp); temp=dos_fname(new, ACT_CREATE); if ( temp == NULL) return -1; strcpy(new_dos, temp); if (rename (old_dos, new_dos) == -1) { if ( (temp_file=fopen(new_dos,"r"))!= NULL) fclose(temp_file); else dos_fname(new, ACT_DELETE); return -1; } dos_fname(old, ACT_DELETE); return 0; }