#include #include #include #ifndef UNIX #include #else #include #endif #include #include "aplinks.h" #include "disp_ctr.h" int epilogue(char *output_dir, unsigned char *fat_buffer[], unsigned char *dir_buffer[], unsigned char *data_buffer[], DIR_RANGE dir_range, int wtimes) { int cur_dir; int cur_ds_num; int cur_ds_bias; int nfiles; unsigned char fileinfo[32]; int sec_num; int wdir; cur_dir = 0; nfiles = 0; wdir = 0; while(cur_dir < ((dir_range.end - dir_range.start) + 1) * SECTOR_SIZE){ cur_ds_num = cur_dir / SECTOR_SIZE; cur_ds_bias = (cur_dir % SECTOR_SIZE); if((*(dir_buffer[cur_ds_num] + cur_ds_bias) != 0x00) && (*(dir_buffer[cur_ds_num] + cur_ds_bias) != 0xe5)){ memcpy(fileinfo, (dir_buffer[cur_ds_num] + cur_ds_bias), 32); if(fileinfo[ATTR_OFFS] & DIR_ATTR){ sec_num = *(dir_buffer[cur_ds_num] + cur_ds_bias + FAT_LL); sec_num += (*(dir_buffer[cur_ds_num] + cur_ds_bias + FAT_HH) << 8); nfiles += write_dir(output_dir, fileinfo, sec_num, fat_buffer, data_buffer, wtimes, &wdir); } else{ nfiles += write_file(fileinfo, output_dir, fat_buffer, data_buffer, wtimes); } } cur_dir += 32; } if(wdir > 0){ displist_c_printf(-1, "%d 個のディレクトリを作成しました。\n", wdir); } if(nfiles == 0){ /* displist_c_printf(-1, "No file wrote.\n"); */ /* displist_c_printf(-1, "書き出したファイルはありません。\n"); */ ; } /* else if(nfiles == 1){ displist_c_printf(-1, "%d file wrote.\n", nfiles); } else{ displist_c_printf(-1, "%d files wrote.\n", nfiles); } */ else{ displist_c_printf(-1, "%d 個のファイルを書き出しました。\n", nfiles); } #ifdef DIRDEBUG { FILE *tmpfp; int i; tmpfp = fopen("dirbuffer", "w"); for(cur_dir = 0; cur_dir < 12; cur_dir++){ fprintf(tmpfp, "%d\n", cur_dir); for(i = 0; i < 128; i++){ fprintf(tmpfp, "%d:%c(%x)\n", i, *(fat_buffer[cur_dir] + i), *(fat_buffer[cur_dir] + i)); } fprintf(tmpfp, "\n"); } for(cur_dir = 0; cur_dir < 32; cur_dir++){ fprintf(tmpfp, "dir:%d\n", cur_dir); for(i = 0; i < 128; i++){ fprintf(tmpfp, "%d:%c(%x)\n", i, *(dir_buffer[cur_dir] + i), *(dir_buffer[cur_dir] + i)); } fprintf(tmpfp, "\n"); } for(cur_dir = 0; cur_dir < 32; cur_dir++){ fprintf(tmpfp, "data:%d\n", cur_dir); for(i = 0; i < 128; i++){ fprintf(tmpfp, "%d:%c(%x)\n", i, *(data_buffer[cur_dir] + i), *(data_buffer[cur_dir] + i)); } fprintf(tmpfp, "\n"); } fclose(tmpfp); } #endif return 0; } int make_name(char *output_dir, unsigned char fileinfo[], char pathfilename[], char filename[]) { char basename[9]; char ext[4]; int i; strcpy(basename, ""); for(i = 0; i < 8; i++){ if(fileinfo[i] == ' '){ break; } basename[i] = fileinfo[i]; } basename[i] = '\0'; strcpy(ext, ""); for(i = 0; i < 3; i++){ if(fileinfo[8 + i] == ' '){ break; } ext[i] = fileinfo[8 + i]; } ext[i] = '\0'; strcpy(pathfilename, ""); if(strcmp(output_dir, "") != 0){ if(*(output_dir + strlen(output_dir) - 1) != DIR_DELIM){ sprintf(pathfilename, "%s%c", output_dir, DIR_DELIM); } else{ sprintf(pathfilename, "%s", output_dir); /* strcat(fullpathname, "\\"); */ } } #ifdef UNIX if((fileinfo[ATTR_OFFS] & INVISIBLE) == INVISIBLE){ strcat(pathfilename, "."); } #endif strcpy(filename, basename); if(strcmp(ext, "") != 0){ strcat(filename, "."); strcat(filename, ext); } strcat(pathfilename, filename); return 0; } /* Originally programmed by N. Kon */ int get_fat(int fat_num, unsigned char *fat_buffer[]) { int next_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((fat_num % 2) == 0){ next_fat_num = (*(fat_buffer[fs_num_l] + fs_bias_l) & 0xff); next_fat_num += ((*(fat_buffer[fs_num_h] + fs_bias_h) & 0x0f) << 8); } else{ next_fat_num = ((*(fat_buffer[fs_num_l] + fs_bias_l) & 0xf0) >> 4); next_fat_num += (*(fat_buffer[fs_num_h] + fs_bias_h) << 4); } return next_fat_num; } int write_file(unsigned char fileinfo[], char *output_dir, unsigned char *fat_buffer[], unsigned char*data_buffer[], int wtimes) { int fat_num; char pathfilename[MAX_DIR_LEN + MAX_FILE_LEN]; char filename[MAX_FILE_LEN]; long filesize; long remain_size; FILE *fp; int condition; int i; int warn; unsigned int timeword, dateword; int retval; warn = WRI_PRO_W; retval = 0; make_name(output_dir, fileinfo, pathfilename, filename); if((fileinfo[ATTR_OFFS] & (NORM_ATTR | WRI_PROTECT)) == NORM_ATTR){ if((fp = fopen(pathfilename, "wb")) == NULL){ displist_c_printf(2, "ファイル \"%s\" を書き出し用に開けませんでした。\n", pathfilename); displist_c_printf(2, " Skip this file.\n"); return retval; } else{ filesize = fileinfo[FILESIZE_HH]; filesize = (filesize << 8) + fileinfo[FILESIZE_MM]; filesize = (filesize << 8) + fileinfo[FILESIZE_LL]; displist_c_printf(-1, "Writing "); displist_c_printf(5, "%s ", pathfilename); fat_num = fileinfo[FAT_LL]; fat_num +=(fileinfo[FAT_HH] << 8); remain_size = filesize; condition = NULL; /* NULL のロジックをあとで逆にする。 */ do{ displist_c_printf(-1, "."); if(data_buffer[fat_num - 2] != NULL){ if(remain_size >= SECTOR_SIZE){ if(fwrite(data_buffer[fat_num - 2], SECTOR_SIZE, 1, fp) != 1){ displist_c_printf(2, "Can't write! (Disk full?)\n"); condition = !NULL; fclose(fp); break; } else{ remain_size -= SECTOR_SIZE; } } else{ i = 0; while(remain_size > 0){ if(fputc(*(data_buffer[fat_num - 2] + i), fp) == EOF){ displist_c_printf(2, "Can't write! (Disk full?)\n"); condition = !NULL; fclose(fp); break; } i++; remain_size--; } } } fat_num = get_fat(fat_num, fat_buffer); }while((fat_num != 0xff0) && (condition == NULL)); fclose(fp); retval = 1; if(condition == NULL){ displist_c_printf(-1, " done."); } else{ displist_c_printf(3, "Incompretely done.\n"); } if(remain_size == 0){ displist_c_printf(-1, " File size %ld is Ok.\n", filesize); } else{ displist_c_printf(3, " File size %ld is not correct.\n", filesize - remain_size); } if(wtimes == ON){ timeword = (fileinfo[TIME_HH] << 8); timeword += fileinfo[TIME_LL]; dateword = (fileinfo[DATE_HH]<< 8); dateword += fileinfo[DATE_LL]; set_filetime(pathfilename, dateword, timeword); } } } else if((fileinfo[ATTR_OFFS] & WRI_PROTECT) == WRI_PROTECT){ if((warn & WRI_PRO_W) == WRI_PRO_W){ displist_c_printf(6, "ライトプロテクト属性ファイル"); displist_c_printf(4, " %s ", filename); displist_c_printf(6, "を書き出さずに続行します。\n"); return retval; } } return retval; } int write_dir(char *output_dir, unsigned char fileinfo[], int sec_num, unsigned char *fat_buffer[], unsigned char *data_buffer[], int wtimes, int *wdir) { int nfiles; int i; int subdir_sec_num; char pathfilename[MAX_DIR_LEN]; char dir_name[MAX_FILE_LEN]; unsigned char subfileinfo[32]; DIR *dir_p; /* FILE *fp; */ char buf[256]; extern int errno; nfiles = 0; make_name(output_dir, fileinfo, pathfilename, dir_name); if((dir_p = opendir(pathfilename)) == NULL){ while(1){ #ifdef UNIX if(mkdir(pathfilename, S_IRWXU) != 0){ #else if(mkdir(pathfilename) != 0){ #endif if(errno == EEXIST){ displist_c_printf(6, "%s というファイルが存在するので、%s というディレクトリを作れません。\n", pathfilename, pathfilename); } else{ displist_c_printf(2, "ディレクトリ %s を作成できませんでした。\n", pathfilename); } displist_c_printf(-1, "適当な名前のディレクトリを入力してください。\n"); fgets(buf, sizeof(buf), stdin); sscanf(buf, "%s", pathfilename); } else{ displist_c_printf(6, "ディレクトリ %s を作成しました。\n", pathfilename); (*wdir)++; break; } } } else{ closedir(dir_p); } nfiles = 0; do{ if(data_buffer[sec_num - 2] != NULL){ for(i = 0; i < 4; i++){ memcpy(subfileinfo, (data_buffer[sec_num - 2] + i * 32), 32); if(subfileinfo[0] == 0x00){ return nfiles; } if(subfileinfo[0] == '.'){ continue; } if(subfileinfo[ATTR_OFFS] & DIR_ATTR){ subdir_sec_num = subfileinfo[FAT_LL]; subdir_sec_num += (subfileinfo[FAT_HH] << 8); nfiles += write_dir(pathfilename, subfileinfo, subdir_sec_num, fat_buffer, data_buffer, wtimes, wdir); } else{ nfiles += write_file(subfileinfo, pathfilename, fat_buffer, data_buffer, wtimes); } } } sec_num = get_fat(sec_num, fat_buffer); }while(sec_num != 0xff0); return nfiles; }