/*** BU FUNCTIONS -- BU (2) ****/ #include /* ----------------------------------------------------------*/ /* Search for first or next directory entry */ /* #start srch_file routine */ /* Global definitions, declarations in BU.H -- Commented out here * #define SRCH_F 17 * #define SRCH_N 18 * #define NULL 0 * #define SET_DMA 26 * int next_flag; */ srch_file(fcb_ptr,next_flag) char *fcb_ptr; /* pointer to file control block */ { char sf_fcb[36]; /* file control block buffer */ int dirent, /* index of directory entry in DMA */ x; /* array initialisation variable */ bdos(SET_DMA,0x80); /* set DMA address to 80h */ if(!(next_flag)) { setmem(&sf_cur[0],32,NULL); setmem(&sf_fcb[0],36,NULL); movmem(fcb_ptr,sf_fcb,12); /* load FCB buffer */ dirent = bdos(SRCH_F,sf_fcb) ; } else { movmem(fcb_ptr,sf_fcb,12); /* load FCB buffer */ setmem(&sf_fcb[12],4,NULL); dirent = bdos(SRCH_N,sf_fcb) ; } return ( (dirent > 3) ? ERROR : dirent); } /* end srchfile routine */ /* ----------------------------------------------------------*/ /* #start split_copy routine */ /* Routine for copying under hard_disk option. * logic strategy is that if file is not copied, * it's either written out some sectors (in which * case, it can be split into different files) or * it's written out NO sectors (in which case it * should exit and try again) OR it's finished * writing the file out completely and should * return and loop for next file. * Where VALID writing's done, attribute bits * are set on output file, and file_done flag * is set TRUE -- else FALSE while program * loops. */ split_copy(in_fcb,out_fcb,in_file,out_file) char in_file[15], out_file[15], in_fcb[33], out_fcb[33]; /* hard_disk and fast_copy are int globals * hard_disk is true here */ { /* split_copy function start */ int all_written, start_file, endv_file, seg_no; register i,j; start_file = 0; /* initialize file position pointer */ seg_no = 0; /* and split file segment number */ do { /* do while not all_written start */ /* * Reset the R/O attribute of output file * so that the input file can be copied to it * NOTE - removed error check, as not at all * certain about the (largely undocumented) returns * from bdos with SET_ATT function, or of BDS's * support of it. */ bdos(SET_ATT,out_fcb); /* * Do copying and get result. New result if disk is full * is offset+1, to avoid confusion with NULL= NOT disk full. * Otherwise, out_file might have directory entry opened, * but no room for data, returning offset==NULL ! * file sector limits should mean no confusion * over sectors written /not written/null */ all_written = TRUE; endv_file = copy_file(in_file,out_file,start_file); if( endv_file == start_file + 1 ) /* ie, no sectors written */ all_written = FALSE; else { all_written = TRUE; if(!(fast_copy)) verify_file(in_file,out_file,start_file); if(endv_file == NULL) { in_fcb[11] |= 0x80; /* set input arc */ bdos(SET_ATT,in_fcb); } out_fcb[9] |= 0x80; /* done output, so r/o */ bdos(SET_ATT,out_fcb); } if(endv_file != NULL) { new_disk(out_file,out_fcb,hard_disk,all_written); --endv_file; if(endv_file != start_file ) { /* IE, WHEN FILE HAS A BIT WRITTEN * Append segment number to filename */ seg_no++; for(j = 2; j <= 6 ; j++) /* spaces now '-' */ { /* start for j '-' */ if(out_fcb[j] == ' ') out_fcb [j] = '-'; } /* end for j '-' */ out_fcb[7] = seg_no/10 + '0'; /* append segno */ out_fcb[8] = seg_no%10 + '0'; out_fcb[9] &= 0x7f; /* make output file r/w */ hacking(out_file+2,out_fcb+1); /* (dest,source)*/ } /*endif endv_file>0 */ printf(" %2d %s --> %s\n", cur_user,in_file,out_file); } if(all_written == TRUE) start_file = endv_file; } /* end do while loop until all written */ while( start_file != NULL); } /* #end split_copy routine */ /**---------------------------------------------------------**/ /* #start one_copy routine */ /* Copying without splitting files between disks */ one_copy(in_fcb,out_fcb,in_file,out_file) char *in_fcb, *out_fcb, *in_file, *out_file; /* hard_disk is a global which should be false for this routine */ /* fast_copy is another global which may be false or true */ { int all_written; do { /* Reset the R/O attrib of output file (if it exists ) */ bdos(SET_ATT,out_fcb); if(copy_file(in_file,out_file,0) != NULL) { /* Disk was full -- erase partially written file, * and ask for new disk or abort instruction. */ all_written = FALSE; new_disk(out_file,out_fcb,hard_disk,all_written); } else { all_written = TRUE; if(!(fast_copy)) verify_file(in_file,out_file,0); out_fcb[9] |= 0x80; bdos(SET_ATT,out_fcb); in_fcb[11] |= 0x80; bdos(SET_ATT,in_fcb); } } while(!(all_written)); } /* #end one_copy routine */ /* ----------------------------------------------------------- */ /* Copy file starting at 'offset' from beginning */ copy_file(in_file,out_file,offset) char *in_file, /* input fileref */ *out_file; /* output fileref */ int offset; { char *workbuf, /* input file buffer */ *buff_ptr; /* pointer to position in 'workbuf[]' */ register in_cnt, /* character counts for unbuffered I/O */ out_cnt; int fd_in, /* input file descriptor */ fd_out, /* output */ sectors, /* count of sectors for read and write */ in_sects, /* temp variable for count of sectors read */ full_disk, /* flag for failure to write outfile */ out_sects; /* written sectors (fewer legs sometimes) */ unsigned buf_size ; /* memory allocation */ /* 'read()' accepts a max. of 32768 bytes. Allocate as much * memory as possible up to this for input , using 128 * byte decrements. */ full_disk = FALSE; buf_size = 32768; /* initial memory allocation size */ do { if(workbuf = alloc(buf_size)) break; } while(buf_size -= 128); sectors = (buf_size)/128; /* Open input file for unbuffered read-only access */ if((fd_in = open(in_file,O_RDONLY)) == ERROR ) error(OPN_ERR,in_file); /* Create the output file by deleting it (if it exists) then * opening it for unbuffered write-only access */ if((fd_out = creat(out_file)) == ERROR) error(OPN_ERR,out_file); /* Initialise input file position pointer to 'offset' */ seek(fd_in,offset,0); /* Copy input to output file by buffering data via 'workbuf[]' */ do { in_sects =(read(fd_in,workbuf,sectors)); if(in_sects == ERROR) error(READ_ERR,in_file); else in_cnt = (in_sects*128); buff_ptr = workbuf; /* initialise 'workbuf[]' pointer */ out_cnt = 0; /* and out_cnt */ /* Write contents of 'workbuf[]' to output in 128 byte lots until * either the buffer is written or a write error occurs. Since ^Z) * char CP/M uses as EOF is a valid file character for non-ASCII * files, 'read()' always reads the last 128 byte record of a file * under CP/M. */ do { out_sects =(write(fd_out,buff_ptr,in_sects)); /* Assuming an error means a full disk/directory....*/ if(out_sects < in_sects) { full_disk = TRUE; break; } buff_ptr =(buff_ptr + (in_sects*128)); out_cnt = in_cnt = (in_sects*128); /* forces exit while */ } while(in_cnt > out_cnt); /* until end of buffer */ offset += out_sects; if(full_disk == TRUE) break; } while(in_cnt == buf_size); /* until end of file */ free(workbuf); /* deallocate buffer space */ if(close(fd_in) == ERROR) /* Close the files */ error(CLS_ERR,in_file); if(close(fd_out) == ERROR) error(CLS_ERR,out_file); /* On full disk return offset PLUS 1 for input , else NULL * to show completion of file copy. -- the increment is * to distinguish between a file in which NO sectors could be * written, and that for which ALL have been written . */ return (full_disk ? (offset+1) : NULL); } /* end copy_file routine */ /***********************************************************/ /* Compare portion of input file starting at 'offset' * with output file */ verify_file(in_file,out_file,offset) char *in_file, /* input fileref */ *out_file; /* output ditto */ int offset; /* inputfile offset */ { register match_cnt; /* scratch variable */ int out_cnt, /* char counts for unbuffered I/O */ sectors, /* variable for read and write */ oksects, /* no of sectors from out_file */ fd_in, /* input file descriptor */ fd_out; /* guess?*/ char *veribuf, /* dynamically allocated */ *in_ptr, *out_ptr; unsigned buf_size; /* allocate 2 areas using 256 byte decrements (128 for each) for * use by 'read()' and 'write()', each of which work with max of * 32768 bytes */ buf_size = 65280; /* bds assigns here */ do { if(veribuf = alloc(buf_size)) break; } while(buf_size -= 256); /* Divide buffer in two for in_ptr and out_ptr */ buf_size /= 2; sectors = (buf_size/128); if((fd_in = open(in_file,O_RDONLY)) == ERROR) /* Open files */ error(OPN_ERR,in_file); if((fd_out = open(out_file,O_RDONLY)) == ERROR) /* Open files*/ error(OPN_ERR,out_file); seek(fd_in,offset,0); /* initialise file position pointer */ /* Read in characters from both files and compare. */ do { in_ptr = veribuf; /* Assign buffer pointers */ out_ptr = in_ptr + buf_size; if((read(fd_in,in_ptr,sectors)) == ERROR ) error(READ_ERR,in_file); oksects = (out_cnt = read(fd_out,out_ptr,sectors)); if (oksects == ERROR) error(READ_ERR,out_file); else out_cnt = (oksects*128); match_cnt = out_cnt ; if(!(memcmp(in_ptr,out_ptr,match_cnt))) { /* if they fail to match */ if(close(fd_out) == ERROR) error(CLS_ERR,out_file); unlink(out_file); error(BAD_VFY,out_file); } } while(out_cnt == buf_size); /* end of UNTIL (EOF outfile)*/ free(veribuf); if(close(fd_in) == ERROR) error(CLS_ERR,in_file); if(close(fd_out) == ERROR) error(CLS_ERR,out_file); } /*end verify_file routine */ /*****************************************************************/