#include #include #include #include #ifndef UNIX #include #include #endif #include "aplinks.h" #include "disp_ctr.h" #define RENAMED 1 #define NOT_RENAMED 0 #if 0 static int cur_dir; static int cur_ds_num; static int cur_ds_bias; #endif static int last_fat_num = 2; #if 0 /* ちょっとあることをもくろんだけど、無理っぽい(^^; */ int set_filelist(FILELIST filelist[], int nfile, char *fullpathname) { char dir_name[MAX_DIR_LEN]; char filename[MAX_FILE_LEN]; char ren_filename[13]; char basename[9]; char ext[4]; int ren_chk; int i, j; int idx; long ren_num; char ren_num_buf[9]; get_dirname(fullpathname, dir_name); /* フルパスからディレクトリ名を得る*/ get_filename(fullpathname, filename); /* フルパスからファイル名を得る */ ren_chk = make_base_ext(filename, basename, ext, &(filelist[nfile].attr)); /* ファイル名からベースネームと拡張子を得る。 このとき、ベースネームを 8 文字に正規化する。 戻り値は、正規化時にリネームしたかどうか。 ドットファイルは、先頭のドットを取り、不可視属性とする */ filelist[nfile].fullpathname = malloc(strlen(fullpathname) + 1); strcpy(filelist[nfile].fullpathname, fullpathname); filelist[nfile].dir_name = malloc(strlen(dir_name) + 1); strcpy(filelist[nfile].dir_name, dir_name); filelist[nfile].filename = malloc(strlen(filename) + 1); strcpy(filelist[nfile].filename, filename); /* リネームしたために同名になってしまったファイル名の処理 */ ren_num = 0; for(i = 0; i < nfile; i++){ if((strcmp(filelist[i].basename, basename) == 0) && (strcmp(filelist[i].ext, ext) == 0)){ for(j = 7; j >= 0; j--){ /* 番号付けリネームをするファイルは */ if(basename[j] == ' '){ /* 空白文字をアンダースコアに */ basename[j] = '_'; /* 置き換える */ } } sprintf(ren_num_buf, "%ld", ren_num); idx = 7; for(j = (strlen(ren_num_buf) - 1); j >= 0; j--){ basename[idx] = ren_num_buf[j]; idx--; } ren_num++; i = 0; } } strcpy(filelist[nfile].basename, basename); strcpy(filelist[nfile].ext, ext); for(i = 0; i < 8; i++){ if(basename[i] == ' '){ break; } ren_filename[i] = basename[i]; } if(ext[0] == ' '){ ren_filename[i] = '\0'; } else{ ren_filename[i] = '.'; idx = i + 1; for(i = 0; i < 3; i++){ if(ext[i] == ' '){ break; } ren_filename[idx + i] = ext[i]; } ren_filename[idx + i] = '\0'; } if(strcmp(ren_filename, filename) != 0){ /* if(ren_chk == RENAMED){ */ displist_c_printf(-1, "Renaming "); displist_c_printf(5, "%s", filename); displist_c_printf(-1, " -> "); displist_c_printf(5, "%s", ren_filename); displist_c_printf(-1, ".\n"); } return 0; } #endif int get_drv_dirname(char fullpathname[], char drv[], char dir_name[]) { int i; int dir_end; int full_idx; #ifdef UNIX if(fullpathname[0] == DIR_DELIM){ drv[0] = DIR_DELIM; drv[1] = '\0'; full_idx = 1; } else{ drv[0] = '\0'; full_idx = 0; } #else if(fullpathname[1] == ':'){ drv[0] = fullpathname[0]; drv[1] = fullpathname[1]; if(fullpathname[2] == DIR_DELIM){ drv[2] = fullpathname[2]; drv[3] = '\0'; full_idx = 3; } else{ drv[2] = '\0'; full_idx = 2; } } else{ drv[0] = '\0'; full_idx = 0; } #endif for(dir_end = strlen(fullpathname); dir_end >= full_idx; dir_end--){ if(fullpathname[dir_end] == DIR_DELIM){ dir_end--; break; } } if(dir_end == full_idx){ i = full_idx; while(1){ dir_name[i - full_idx] = fullpathname[i]; if(fullpathname[i] == '\0'){ break; } i++; } } for(i = full_idx; i <= dir_end; i++){ dir_name[i - full_idx] = fullpathname[i]; } dir_name[i - full_idx] = '\0'; return 0; } int get_filename(char *fullpathname, char *filename) { char *basename_top; int i; if((basename_top = strrchr(fullpathname, DIR_DELIM)) == NULL){ #ifndef UNIX if((basename_top = strrchr(fullpathname, ':')) == NULL){ basename_top = fullpathname; } else{ basename_top++; } #else basename_top = fullpathname; #endif } else{ basename_top++; } i = 0; while(1){ *(filename + i) = *(basename_top + i); if(*(basename_top + i) == '\0'){ break; } i++; } return 0; } int make_base_ext(char filename[], char basename[], char ext[], int *attr) { int i; int retval; int filename_idx; int ext_idx; retval = NOT_RENAMED; *attr = NORM_ATTR; if(filename[0] == '.'){ filename_idx = 1; *attr |= INVISIBLE; /* ドットファイルは不可視属性にする */ } else{ filename_idx = 0; } for(i = 0; i < 8; i++){ basename[i] = filename[filename_idx + i]; if((filename[filename_idx + i] == '\0') || (filename[filename_idx + i] == '.')){ break; } } if((filename[filename_idx + i] != '\0') && (filename[filename_idx + i] !='.')){ retval = RENAMED; } for(; i < 8; i++){ basename[i] = ' '; } basename[8] = '\0'; ext_idx = strlen(filename); for(i = strlen(filename);i > 0; i--){ if(filename[i] == '.'){ ext_idx = i + 1; break; } } for(i = ext_idx; i < (ext_idx + 3); i++){ if(filename[i] == '\0'){ break; } ext[i - ext_idx] = filename[i]; } for(;i < (ext_idx + 3); i++){ ext[i - ext_idx] = ' '; } ext[3] = '\0'; return retval; } /* Originally programmed by N. Kon */ int put_fat(int fat_num, int value, unsigned char *fat_buffer[], FAT_RANGE fat_range) /* put_fat(last_fat_num - 1, last_fat_num) というふうに呼ばれる */ { int fat_loc; int fs_num_l, fs_num_h; int fs_bias_l, fs_bias_h; fat_num *= 3; fat_loc = fat_num / 2; get_fs_num_bias(fat_loc, &fs_num_l, &fs_bias_l, &fs_num_h, &fs_bias_h); if(fs_num_h > fat_range.end){ displist_c_printf(2, "FAT の容量を越えました。%d\n", fs_num_h); exit(0); } if((fat_num % 2) == 0){ /* 呼出側の last_fat_num が奇数 */ *(fat_buffer[fs_num_l] + fs_bias_l) = (value & 0xff); *(fat_buffer[fs_num_h] + fs_bias_h) = (*(fat_buffer[fs_num_h] + fs_bias_h) & 0xf0) + (value >> 8); } else{ *(fat_buffer[fs_num_l] + fs_bias_l) = (*(fat_buffer[fs_num_l] + fs_bias_l) & 0x0f) + ((value & 0x0f) << 4); *(fat_buffer[fs_num_h] + fs_bias_h) = value >> 4; } return 0; } int takedir(char *sdir, int sfile_num, char *sfile[], unsigned char *fat_buffer[], unsigned char *dir_buffer[], unsigned char *data_buffer[], FAT_RANGE fat_range, DIR_RANGE dir_range, DATA_RANGE data_range, int rmode, int mdir, int timg) { int dirent_ds_num; int dirent_ds_bias; long dirent; char fullpathname[MAX_DIR_LEN]; int i; int retval; #ifdef UNIX DIR *disk_dirp; /* 実ディスクのディレクトリポインタ(stream) */ DIR *chk_disk_dirp; /* 実ディスクのディレクトリポインタ(stream) */ struct dirent *disk_dirent; /* 実ディスクのディレクトリエントリ */ int nfiles; #else int dirfind, filefind; char sdir_name[MAX_DIR_LEN]; char sfile_name[MAX_DIR_LEN]; struct ffblk file_ffblks[SFILE_NUM]; struct ffblk dir_ffblks; #endif if((dirent = chg_make_dir(sdir, mdir, &last_fat_num, dir_range, dir_buffer, fat_range, fat_buffer, data_buffer)) == -1){ return -1; } dirent_ds_num = (int)(dirent / SECTOR_SIZE); dirent_ds_bias= (int)(dirent % SECTOR_SIZE); #ifdef UNIX if(strcmp(sfile[0], "*.*") == 0){ if((disk_dirp = opendir(sdir)) == NULL){ displist_c_printf(2, "ディレクトリ %s を開くことができませんでした。\n", sdir); return -1; } nfiles = 0; while((disk_dirent = readdir(disk_dirp)) != NULL){ if( (strcmp(disk_dirent->d_name, ".") == 0) || (strcmp(disk_dirent->d_name, "..") == 0)){ continue; } if(strcmp(sdir, "") == 0){ strcpy(fullpathname, disk_dirent->d_name); } else{ sprintf(fullpathname, "%s%c%s", sdir, DIR_DELIM, disk_dirent->d_name); } if((chk_disk_dirp = opendir(fullpathname)) == NULL){ if(data_buffer[dirent_ds_num] != NULL){ if((mdir == ON) && (strcmp(sdir, "") != 0)){ retval = read_file(fullpathname, data_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } else{ retval = read_file(fullpathname, dir_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } if(retval != -1){ dirent_ds_bias += 32; if(dirent_ds_bias == SECTOR_SIZE){ dirent_ds_bias = 0; dirent_ds_num++; } } } else{ bell(); } } else{ closedir(chk_disk_dirp); if(rmode == ON){ displist_c_printf(5, "ディレクトリ %s を再帰下降探索します。\n", fullpathname); retval = takedir(fullpathname, 1, sfile, fat_buffer, dir_buffer, data_buffer, fat_range, dir_range, data_range, rmode, mdir, timg); if(retval != -1){ dirent_ds_bias += 32; if(dirent_ds_bias == SECTOR_SIZE){ dirent_ds_bias = 0; dirent_ds_num++; } } } else{ displist_c_printf(6, "ディレクトリ %s の再帰下降探索は行いません。\n", fullpathname); } } } if(closedir(disk_dirp) != 0){ displist_c_printf(2, "ディレクトリを閉じることができませんでした。\n"); } return nfiles; } else{ if(strcmp(sdir, "") == 0){ strcpy(fullpathname, sfile[0]); } else{ sprintf(fullpathname, "%s%c%s", sdir, DIR_DELIM, sfile[0]); } if(data_buffer[dirent_ds_num] != NULL){ if((mdir == ON) && (strcmp(sdir, "") != 0)){ read_file(fullpathname, data_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } else{ read_file(fullpathname, dir_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } } else{ bell(); } return 0; } #else /* ファイルサーチ */ if(strcmp(sdir, "") == 0){ sprintf(sdir_name, "*.*"); } else if(*(sdir + (strlen(sdir) - 1)) == DIR_DELIM){ sprintf(sdir_name, "%s*.*", sdir); } else{ sprintf(sdir_name, "%s%c*.*", sdir, DIR_DELIM); } if(timg == ON){ /* ディスクイメージ順にファイルを取り込む */ dirfind = findfirst(sdir_name, &dir_ffblks, FA_DIREC | FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH); while(!dirfind){ if(*(dir_ffblks.ff_name) != '.'){ break; } dirfind = findnext(&dir_ffblks); } for(i = 0; i < sfile_num; i++){ if(strcmp(sdir, "") == 0){ sprintf(sfile_name, "%s", sfile[i]); } else{ sprintf(sfile_name, "%s%c%s", sdir, DIR_DELIM, sfile[i]); } findfirst(sfile_name, &(file_ffblks[i]), FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH); } while(!dirfind){ if((dir_ffblks.ff_attrib & 0x10) == 0x10){ sprintf(sdir_name, "%s%c%s", sdir, DIR_DELIM, dir_ffblks.ff_name); displist_c_printf(5, "%s 再帰モードにしたがった処理", sdir_name); getchar(); } for(i = 0; i < sfile_num; i++){ if(strcmp(dir_ffblks.ff_name, file_ffblks[i].ff_name) == 0){ printf("%s を読み込む", file_ffblks[i].ff_name); getchar(); findnext(&(file_ffblks[i])); } } dirfind = findnext(&dir_ffblks); } } else{ /* 引数指定順にファイルを取り込む */ for(i = 0; i < sfile_num; i++){ if(strcmp(sdir, "") == 0){ sprintf(sfile_name, "%s", sfile[i]); } else if(*(sdir + (strlen(sdir) - 1)) == DIR_DELIM){ sprintf(sfile_name, "%s%s", sdir, sfile[i]); } else{ sprintf(sfile_name, "%s%c%s", sdir, DIR_DELIM, sfile[i]); } if(fclose(fopen(sfile_name, "rb")) == 0){ if((mdir == ON) && (haveto_chg(sdir) == 1)){ retval = read_file(sfile_name, data_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } else{ retval = read_file(sfile_name, dir_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } if(retval != -1){ dirent += 32; dirent_ds_num = (int)(dirent / SECTOR_SIZE); dirent_ds_bias= (int)(dirent % SECTOR_SIZE); } } else{ /* おそらく、ワイルドカードを含んでいる。 */ filefind = findfirst(sfile_name, &(file_ffblks[i]), FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH); dirent = (long)dirent_ds_num * SECTOR_SIZE; dirent += dirent_ds_bias; while(!filefind){ if(data_buffer[dirent_ds_num] != NULL){ if(strcmp(file_ffblks[i].ff_name, ".") == 0){ /* '.' ディレクトリの処理 */ /* ここに処理が移ることは、まずない。 */ displist_c_printf(5, ". da!\n"); #if 0 set_dirent_info(data_buffer[dirent_ds_num], dirent_ds_bias, dirent->d_name, " ", DIR_ATTR | WRI_PROTECT); *(data_buffer[dirent_ds_num] + dirent_ds_bias + FAT_LL) (thisdir_sec_num & 0xff); *(data_buffer[dirent_ds_num] + dirent_ds_bias + FAT_HH) = (thisdir_sec_num >> 8); #endif } else if(strcmp(file_ffblks[i].ff_name, "..") == 0){ /* '..' ディレクトリの処理 */ /* ここに処理が移ることは、まずない。 */ displist_c_printf(5, ".. da!\n"); #if 0 set_dirent_info(data_buffer[dirent_ds_num], dirent_ds_bias, dirent->d_name, " ", DIR_ATTR | WRI_PROTECT); *(data_buffer[dirent_ds_num] + dirent_ds_bias + FAT_LL) = (parentdir_sec_num & 0xff); *(data_buffer[dirent_ds_num] + dirent_ds_bias + FAT_HH) = parentdir_sec_num >> 8); #endif } else{ if(strcmp(sdir, "") == 0){ sprintf(fullpathname, "%s", file_ffblks[i].ff_name); } else if(*(sdir + (strlen(sdir) - 1)) == DIR_DELIM){ sprintf(fullpathname, "%s%s", sdir, file_ffblks[i].ff_name); } else{ sprintf(fullpathname, "%s%c%s", sdir,DIR_DELIM,file_ffblks[i].ff_name); } if((mdir == ON) && (haveto_chg(sdir) == 1)){ retval = read_file(fullpathname, data_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } else{ retval = read_file(fullpathname, dir_buffer[dirent_ds_num], dirent_ds_bias, fat_buffer, data_buffer, data_range, fat_range, mdir); } if(retval != -1){ dirent += 32; dirent_ds_num = (int)(dirent / SECTOR_SIZE); dirent_ds_bias= (int)(dirent % SECTOR_SIZE); } } } else{ bell(); } filefind = findnext(&file_ffblks[i]); } if(rmode == ON){ dirfind = findfirst(sdir_name, &dir_ffblks, FA_DIREC | FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH); while(!dirfind){ if(*(dir_ffblks.ff_name) != '.'){ break; } dirfind = findnext(&dir_ffblks); } while(!dirfind){ if((dir_ffblks.ff_attrib & 0x10) == 0x10){ if(strcmp(sdir, "") == 0){ sprintf(sdir_name, "%s", dir_ffblks.ff_name); } else if(*(sdir + (strlen(sdir) - 1)) == DIR_DELIM){ sprintf(sdir_name, "%s%s", sdir, dir_ffblks.ff_name); } else{ sprintf(sdir_name, "%s%c%s", sdir, DIR_DELIM, dir_ffblks.ff_name); } displist_c_printf(5, "ディレクトリ %s を再帰下降探索します。\n", sdir_name); takedir(sdir_name, sfile_num, sfile, fat_buffer, dir_buffer, data_buffer, fat_range, dir_range, data_range, rmode, mdir, timg); } dirfind = findnext(&dir_ffblks); } } } } } return 0; #endif } int set_dirent_info(unsigned char *dirent_buffer, int dirent_bias, char *basename, char *ext, int attr) { int i; char *basename_p; char *ext_p; if(dirent_buffer == NULL){ return -1; } basename_p = basename; for(i = 0; i < 8; i++){ if(*(basename_p) != '\0'){ *(dirent_buffer + dirent_bias + i) = *(basename_p); basename_p++; } else{ *(dirent_buffer + dirent_bias + i) = 0x20; /* ' ' */ } } ext_p = ext; for(i = 0; i < 3; i++){ if(*(ext_p) != '\0'){ *(dirent_buffer + dirent_bias + 8 + i) = *(ext_p); ext_p++; } else{ *(dirent_buffer + dirent_bias + 8 + i) = 0x20; /* ' ' */ } } /* 属性を格納 */ *(dirent_buffer + dirent_bias + ATTR_OFFS) = (attr | WRI_PROTECT); /* ファイルサイズを 0 として格納 */ *(dirent_buffer + dirent_bias + FILESIZE_LL) = 0; *(dirent_buffer + dirent_bias + FILESIZE_MM) = 0; *(dirent_buffer + dirent_bias + FILESIZE_HH) = 0; /* タイムスタンプはあとで */ return 0; } int count_file(char *fullpathname) { DIR *dir_p; int file_num; if((dir_p = opendir(fullpathname)) == NULL){ displist_c_printf(2, "%s ディレクトリを開けませんでした。\n"); return -1; } file_num = 0; while(readdir(dir_p) != NULL){ file_num++; } closedir(dir_p); return file_num; } int read_file(char *fullpathname, unsigned char *dirent_buffer, int dirent_ds_bias, unsigned char *fat_buffer[], unsigned char *data_buffer[], DATA_RANGE data_range, FAT_RANGE fat_range, int mdir) { FILE *fp; long filesize; char filename[MAX_FILE_LEN]; char Lfilename[13]; char basename[9]; char ext[4]; int attr; int i; unsigned int dateword, timeword; int read_count; unsigned char read_buf[SECTOR_SIZE + 1]; if((fp = fopen(fullpathname, "rb")) == NULL){ displist_c_printf(2, "ファイル %s を開くことができませんでした。\n", fullpathname); return -1; } fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, 0, SEEK_SET); get_filename(fullpathname, filename); chk_get_Lname(fullpathname, filename, Lfilename, mdir); if(strcmp(filename, Lfilename) != 0){ displist_c_printf(6, "ファイル名を %s から %s に L: 内で変更しました。\n", filename, Lfilename); } displist_c_printf(-1, "読み込み中 \"%s\" ", fullpathname); if((((filesize - 1) / SECTOR_SIZE) + 1) > (((data_range.end - data_range.start) + 1) - (last_fat_num - 2)) || (dirent_buffer == NULL)){ displist_c_printf(2, "L: の空き容量が足りません。\n"); displist_c_printf(2, "ファイル %s を読み込まずに続行します。\n", fullpathname); fclose(fp); return -1; } make_base_ext(Lfilename, basename, ext, &attr); if(filename[0] == '.'){ attr = INVISIBLE | NORM_ATTR; } else{ attr = NORM_ATTR; } /* basename をセット */ for(i = 0; i < 8; i++){ *(dirent_buffer + dirent_ds_bias + i) = basename[i]; } /* 拡張子をセット */ for(i = 0; i < 3; i++){ *(dirent_buffer + dirent_ds_bias + 8 + i) = ext[i]; } /* 属性をセット */ *(dirent_buffer + dirent_ds_bias + ATTR_OFFS) = (attr | WRI_PROTECT); /* ドットファイルのとき、attr には 不可視属性が入っている */ /* MS-DOS 形式でタイムスタンプをセット */ get_filetime(fullpathname, &dateword, &timeword); *(dirent_buffer + dirent_ds_bias + TIME_HH) = (timeword & 0xff00) >> 8; *(dirent_buffer + dirent_ds_bias + TIME_LL) = timeword & 0x00ff; *(dirent_buffer + dirent_ds_bias + DATE_HH) = (dateword & 0xff00) >> 8; *(dirent_buffer + dirent_ds_bias + DATE_LL) = dateword & 0x00ff; /* ファイルサイズをセット */ *(dirent_buffer + dirent_ds_bias + FILESIZE_LL) = (int)(filesize & 0x000000ffL); *(dirent_buffer + dirent_ds_bias + FILESIZE_MM) = (int)((filesize >> 8) & 0x000000ffL); *(dirent_buffer + dirent_ds_bias + FILESIZE_HH) = (int)((filesize >> 16) & 0x000000ffL); /* ファイル内容を格納する先頭セクタ番号をセット */ *(dirent_buffer + dirent_ds_bias + FAT_LL) = last_fat_num & 0xff; *(dirent_buffer + dirent_ds_bias + FAT_HH) = last_fat_num >> 8; while((read_count = fread(read_buf, sizeof(unsigned char), SECTOR_SIZE, fp)) == SECTOR_SIZE){ displist_c_printf(-1, "."); if(data_buffer[last_fat_num - 2] != NULL){ memcpy(data_buffer[last_fat_num - 2], read_buf, SECTOR_SIZE); } else{ bell(); /* あとで EMS に読むようにする。 */ } put_fat(last_fat_num, last_fat_num + 1, fat_buffer, fat_range); last_fat_num++; } if(data_buffer[last_fat_num - 2] != NULL){ for(i = 0; i < read_count; i++){ *(data_buffer[last_fat_num - 2] + i) = read_buf[i]; } } else{ bell(); /* あとで EMS に読むようにする。 */ } if(read_count > 0){ displist_c_printf(-1, "."); } displist_c_printf(-1, "\n"); put_fat(last_fat_num, 0xff0, fat_buffer, fat_range); last_fat_num++; fclose(fp); return 1; }