/*** BU FUNCTIONS BU (3) *****/ /* Copy fileref to the file control block */ #include copy_fref(fref,fcb) char fcb[16], *fref; /* pointer to fileref */ { char c; /* scratch variable */ int i, /* fileref index variable */ j, /* FCB index variable */ k, /* scratch variable */ done; /* loop break flag */ if(fref[1] != ':' || fref[2] == '\0') return ERROR; /* No drive code separator or null fileref */ /* Calculate drive code from drive name and put in FCB */ fcb[0] = fref[0] - 'A' + 1; /* Process remainder of fileref */ done = FALSE; for(i = 2, j = 1; i <= 9; i++,j++) /* Skip drive code in fileref */ { switch(c = fref[i]) { case '.' : /* filetyp separator */ if(i == 2) return ERROR; /* null filename */ for( ; j <=8; j++) fcb[j] = ' '; /* pad out with trailing blanks */ done = TRUE; break; case '*' : /* match any following string */ for( ; j <=8; j++) fcb[j] = '?'; /* pad with trailing ?s */ i++; done = TRUE; break; case '\0' : /* end of fileref */ for( ; j <= 11; j++) fcb[j] = ' '; /* pad with trailing spaces */ return SUCCESS; case ',': /* illegal filename chars */ case ';': case ':': case '=': case '[': case ']': case '_': case '<': case '>': return ERROR; default: if(c >= '!' && c <= '~') fcb[j] = c ; /* copy char from fileref to FCB */ else return ERROR; /* non printable char or ' ' */ } if(done) break; } c = fref[i] ; if((c = fref[i] ) == '\0') /* end of fileref */ { for( ; j <= 11; j++ ) fcb[j] = ' '; return SUCCESS; } else if(c == '.') /* fileref separator */ { i++; k = i + 2; /* set limit of 3 chars */ for( ; i <=k; i++,j++) { done = FALSE; switch(c = fref[i]) { case '*' : /* match any following string */ for( ; j <=11; j++) fcb[j] = '?'; /* pad with trailing ?s */ return SUCCESS; case '\0' : /* end of fileref */ for( ; j <= 11; j++) fcb[j] = ' '; /* pad with trailing spaces */ return SUCCESS; case ',': /* illegal filetyp chars */ case ';': case ':': case '=': case '[': case ']': case '_': case '<': case '>': return ERROR; default: if(c >= '!' && c <= '~') fcb[j] = c ; /* copy char from fileref to FCB */ else return ERROR; /* non printable char or ' ' */ } } /* Return ERROR if filetype too long */ return (fref[i] == '\0' ? SUCCESS : ERROR) ; } else return ERROR ; /* filename too long */ } /* Error report */ error(n,s) int n; /* Error code */ char *s; /* Pointer to optional string */ { switch(n) { case USER_ERR: printf("\007** ERROR - No user number specified **\n"); break; case BAD_FREF: printf("\007** ERROR - Illegal file reference: %s **\n",s); break; case BAD_ARGS: printf("\007** ERROR - Illegal command line **\n"); break; case BAD_OPT: printf("\007** ERROR - Illegal command line option: "); printf(" %s **\n",s); break; case BAD_USER: printf("\007** ERROR - User number must be inside range"); printf(" of 0 to 15 **\n"); /* OR WHATEVER. WAS 31 */ break; case BAD_DRV: printf("\007** ERROR - Drive names must be inside range"); printf(" of 'A' to 'P' **\n"); break; case SET_FAIL: printf("\007** ERROR in setting/resetting file attributes **\n"); reset(); exit(0); break; case SAME_DRV: printf("\007** ERROR - Equal drives not valid for copying **\n"); break; case OPN_ERR: printf("\007** ERROR - Cannot open file %s **\n",s); reset(); exit(0); case READ_ERR: printf("\007** ERROR - Read error on file %s **\n",s); reset(); exit(0); case CLS_ERR: printf("\007** ERROR - Cannot close file %s **\n",s); reset(); exit(0); case BAD_VFY: printf("\007** ERROR - Failed verify on file %s **\n",s); reset(); exit(0); } printf("\nUsage: BU x[:afn] y [-AFHQCSn] -- for backup copying,\n"); printf(" OR : BU x[:afn] x [-AQCn] -- (SAME dr) for attribute setting\n\n"); printf(" where x = drive name of disk to be backed up\n"); printf(" y = drive name of backup disk\n\n"); printf(" and the optional arguments are:\n\n"); printf(" -A ALL files, regardless of status\n"); printf(" -F Fast copy (without verification)\n"); printf(" -H Hard disk (files may be split)\n"); printf(" -Q Query each file before backup\n"); printf(" -C Change disks after BU loaded\n"); printf(" -S System attribute copied to backup\n"); printf(" -n Backup USER 'n' files only (0-15)\n"); printf(" -afn Any legal CP/M ambiguous fileref\n\n"); printf(" Attribute setting is ASSUMED if drive names are equal.\n"); exit(0); } /* Request a new backup disk to be inserted in the output drive */ new_disk(fname,old_fcb,hard_disk,all_written) /* int hard_disk; is global, for splitting files -- in BU.H */ char *fname, *old_fcb; int all_written; { char d; printf("\007\n ** BACKUP DISK FULL **\n\n"); if(all_written == FALSE) /* ie, if need to start again from top */ { unlink(fname); if (hard_disk) printf("NO SPACE TO WRITE ANY OF THIS FILE.\n\n"); } else { if (hard_disk) printf(" WARNING: -H option active -- FILE WILL BE SPLIT\n\n"); } printf(" Options are to continue on new disk or abort "); do { puts("\n Type 'C' to continue, or 'A' to abort : "); d = toupper(getchar()); printf("\b%c",d); } while( (d != 'A') && (d != 'C') ); if(d == 'A') { printf("\bAborting...\n"); if(all_written == TRUE) /*here only with hard_disk */ unlink(fname); exit(0); } else { printf("\bContinuing in a moment...\n"); if( (hard_disk) && (all_written == TRUE) ) { /* Set the R/O attrib of the output file */ old_fcb[9] |= 0x80; bdos(SET_ATT,old_fcb); old_fcb[9] &= 0x7f; /* ..... and reset the fcb */ } do { puts("\n Insert new disk in back-up drive and hit 'C' again :"); d = toupper(getchar()); printf("\b%c",d); } while(d != 'C'); } puts("\n\n"); bdos(RESET_DRV,NULL); /* Reset drives */ } /* RESET user and drive codes to entry values */ reset() { bdos(USER_CODE,ent_user); bdos(SEL_DRV,ent_drv); } /* HACKING -- getting filename from an FCB for BDS format */ /* Routine to get filename.typ with blank padding into a contiguous * string with '.' separator and blanks extracted. Adapted from * 'wildexp.c' in the BDS package, with variations to take * account of the pointer addresses (in_file+2,in_fcb+1) passed to * the routine by the program. ie, enter with source->filename(raw) * and dest -> byte after dr:, while avoiding clearance of all the * bit 7s of the filetyp. */ hacking(dest,source) char *dest, *source; { int i,j; j = 0; /* clear only filename attributes */ for(i = 0; i < 8 ; i++) source[i] &= 0x7f; for (i = 0; i < 8; i++) { if (source[i] == ' ') break; dest[j++] = source[i]; } if (source[8] != ' ') dest[j++] = '.'; for (i = 8; i < 11; i++) { if (source[i] == ' ') break; if (source[i] == 0xa0 ) break; dest[j++] = source[i]; } dest[j] = '\0'; return dest; }