/* // bbcim.c (bbc diskbeeld manipulatie): SINGLE DENSITY, DD extensions and more. // Copyright (c) W.H. Scholten 1996, 1997 // Permission to use, copy, modify, distribute, but NOT to sell this software // and its documentation for any purpose is hereby granted without fee, // provided that the above copyright notice appear in all copies and // that both that copyright notice and this permission notice appear in // supporting documentation, and that the name of the copyright holder // not be used in advertising or publicity pertaining to distribution // of the software without specific, written prior permission. The // copyright holder makes no representations about the suitability of // this software for any purpose. It is provided "as is" without express // or implied warranty. // // THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS // SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER // RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF // CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // // Send comments and bug-reports to // // wouters@cistron.nl // // Send flames to /dev/null. // // It works under linux (1.2.13/GCC 2.7.0, 2.0.18/GCC 2.7.2). */ /* OVERVIEW OF CHANGES IN BBCIM. First bbcim version was 0.60 (I think), a combination of separate programs. Changes in 0.83 (from 0.70): + xcrc implemented + -ed may work on a mac (LET ME KNOW): uncomment #define MAC + -e options now in any order + -e, -x and -y: if a file exists, you can choose whether to overwrite or rename. c seeks immediately before read/write in add-loop, otherwise segmentation faults sometimes (bug in GCC?). c fixed small mistake in xcrc. Changes in 0.91 (from 0.83): + 'use' added. + -s file overwrite choice. + -e file {list} c -x : rename file to itself fixed (no overwrite question) c -xcrc: filenames < 7 char's now OK. c -s : L before load address (as in xbeeb's __CATALOG__) is now acceptable. Changes in 0.92: + -ab : adds bare files, otherwise info file is used by default. c : -e; b->s, info file is now added by default, b=bare. Changes in 0.93-beta (9-3-97): + code cleaned up with explicit type conversions + added code to replace characters in filenames (usually not needed in linux); e.g. '/' gives problems. + Help in english Changes in 0.94-beta (16-3-97): c w62 conversion now included in bbcim. Changes in 0.95-beta (30-6-97): c w62 conversion: if there are less than 32 files, only one diskimage is made. c disknames without a . didn't extract with -ed (as the dir name was equal to the diskimage name). Added a rename. c cleaned up 'mkdir' selection. You now have 3 choices. + Compiles on DOS without changes. Bugs and 'features': - several files in a diskimage can have the same name (can be useful) (i.e. -a doesn't overwrite) - -e: name checking in diskimage is case dependant. If in doubt: it's not a bug, it is a feature! */ #define VERSION "0.95-beta 2" /*************** CONFIGURATION *********************/ /* Comment out for english messages: */ /* #define NL */ #define SYSTEM_MKDIR /* Make directory: UNIX_MKDIR, MAC_MKDIR, or SYSTEM_MKDIR (using system("mkdir.."); ) */ /* #define NO_COMMAND_LINE */ /* If you can't give parameters on the command line use this (useless?) */ #define REPLACE_MANY /* Characters to be replaced in filenames: Most filesystems can't handle all characters from bbc filenames. Add whatever you need for your system. I've put the minimum for linux in REPLACE_FEW. */ #ifdef REPLACE_FEW char filenamechar_bad[] = {'/'}; char filenamechar_replace[] = {'_'}; #endif #ifdef REPLACE_MANY char filenamechar_bad[] = { '\\', '/', ':', '*', '?', '\"', '<', '>', '|' }; char filenamechar_replace[] = { '_' , '_', '_', '_', '_', '_' , '_', '_', '_' }; #endif /************ END OF CONFIGURATION ***********************/ #include #include #include #ifdef MAC_MKDIR #include #endif #ifdef UNIX_MKDIR #include #include #include #endif #ifdef SYSTEM_MKDIR #endif /* Should use this in various places: #include struct stat file_stat; if (stat(filename, file_stat)<0) perror("can't open file\n"); */ /* Byte offsets in diskimage */ #define DFStitle0_7 0 #define DFStitle8_11 256 #define DFS accessct 256+0x04 #define DFSentries 256+5 #define DFSbootsec 256+6 #define DFSsectondiskL 256+0x07 /*next offsets +n*8 for each file */ #define DFSfilename 8 #define DFSdirectory 0x0f #define DFSloadaddrL 256+8 #define DFSloadaddrM 256+9 #define DFSexecaddrL 256+0x0a #define DFSexecaddrM 256+0x0b #define DFSlengthL 256+0x0c #define DFSlengthM 256+0x0d #define DFSeellddss 256+0x0e #define DFSstartsecL 256+0x0f typedef unsigned char byt; /* NB invoer en bbcnaam mogen niet zelfde string zijn */ /* void invoer_naar_bbcnaam(char *invoer, char *bbcnaam) { if (invoer[1]=='.') strncpy(bbcnaam, invoer,9); else { bbcnaam[0]='$'; bbcnaam[1]='.'; strncpy(bbcnaam+2, invoer, 7); } bbcnaam[9]=0; } */ void reduceer_unix_naam(char *unixnaam, char *bbcnaam) { if (bbcnaam[0]=='$') strcpy(unixnaam,bbcnaam+2); else { unixnaam[0]=bbcnaam[0]; strcpy(unixnaam+1,bbcnaam+2); } } #include "overschrijf.c" #include "nieuw_diskb.c" #include "diskb_add.c" #include "diskb_del.c" #include "expand_im.c" #include "minimaliseer.c" #include "intersplits.c" #include "ddos2dfs.c" #include "w62.c" #include "splits_cat.c" #include "bbc_crc.c" #include "xbeeb.c" #include "archief.c" int filenamechar_no=sizeof(filenamechar_bad); /* number of char's to be checked for replacement */ void use() { printf("Opties: -e[s/d,#,b,r] -a[b,r] -d -c -crc -min -40/80/max\n" \ " -y -icrc -s[#]\n" \ " -x -xcrc\n" \ " -splitds -interss -ddos2dfs -w62dfs\n" \ " -V -H\n\n"); } int main(int argc, char *argv[]) { FILE *fpdisk, *fpcat, *fpextract, *fpinfo; char disk[50], catalogus[50], extract[50], info_naam[50], basisnaam[50]; char bbcdisk_naam[15], bbcfile_naam[15]; char unix_bbcfile_naam[15]; char testnaam[15]; char optstring[20]; unsigned char byte,H; long filesizesum=0; int extr=0, extr_dir=0, cat=0, expand=0, min=0, bcrc=0, short_name=0; int add=0, info=0 /* don't use info files */, no_bbc_dir=0, remove_file=0, remove_disk=0; int extr_list=0; int bad_option=1; int options=1; int i, j, rfiles, bootoption, antwoord, k; unsigned char files=0; unsigned int sectorsondisk; long file; int locked; unsigned char eellddss; long startsector; long loadaddress, execaddress, length; unsigned int crc; #ifdef UNIX_MKDIR mode_t dir_mode; #endif #if defined(MAC_MKDIR) || defined(SYSTEM_MKDIR) char actie[60]; #endif #ifdef NO_COMMAND_LINE argc=1; #endif if (argc < 2) { #ifdef NL printf("Welke optie?"); #else printf("Which option?"); #endif scanf("%20s", optstring); options=0; } else strcpy(optstring, argv[1]); /* 1e SELECTIE */ if (!strcmp(optstring,"-V")){ printf(" bbcim %s (c) WHS 1996,1997\n\n",VERSION); exit(0); } if (!strcmp(optstring,"-H")) { #ifdef NL printf("Commando overzicht\n" \ " -c diskbeeld : toon bestanden in diskbeeld\n" \ " -e[s/d,#,b,r] diskbeeld [{lijst}]: bestanden uit diskbeeld halen\n" \ " -a[b,r] diskbeeld {lijst} : bestanden in diskbeeld plaatsen\n" \ " -d diskbeeld {lijst} : verwijder bestanden uit diskbeeld\n" \ " -40/-80/-max diskbeeld : grootte van diskbeeld wijzigen\n" \ " -min diskbeeld : diskbeeld minimaliseren\n" \ " -crc diskbeeld : bereken CRC's van bestanden in diskbeeld\n" \ " -y {lijst} : archief bestanden bijwerken\n" \ " -s[#] bestand : splits tekst bestand in .inf bestanden\n\n" \ " -x {lijst} : archief bestanden omzetten naar xbeeb formaat\n" \ " -icrc {lijst} : controleer CRC's van archief bestanden\n"\ " -xcrc : controleer CRC's in xbeeb dir (de huidige dir)\n"\ " -interss (sd/dd) B0 B1 B2 : enkelzijdig naar dubbelzijdig diskbeeld\n"\ " -splitds (sd/dd) B : dubbelzijdig naar enkelzijdig diskbeeld\n"\ " -ddos2dfs ddosbeeld : splits enkelzijdig DDOS diskbeeld in DFS diskbeelden\n"\ " -w62dfs w62beeld : splits een watford 62 bestanden diskbeeld in 2 DFS diskbeelden\n"\ " -V : toon versie\n\n"); #else printf("Command overview\n" \ " -c diskimage : show files in diskimage\n" \ " -e[s/d,#,b,r] diskimage [{list}]: extract files from diskimage\n" \ " -a[b,r] diskimage {list} : put files in diskimage\n" \ " -d diskimage {list} : remove files from diskimage\n" \ " -40/-80/-max diskimage : change size of diskimage\n" \ " -min diskimage : minimize diskimage\n" \ " -crc diskimage : calculate CRC's of files in diskimage\n" \ " -y {list} : cleanup archive file information\n" \ " -s[#] file : split a text file in .inf files\n\n" \ " -x {list} : convert archive files to xbeeb format\n" \ " -icrc {list} : check CRC's of archive files\n"\ " -xcrc : check CRC's in xbeeb dir (the current dir)\n"\ " -interss (sd/dd) B0 B1 B2 : single sided to double sided diskimage conversion\n"\ " -splitds (sd/dd) B : double sided to single sided diskimage conversion\n"\ " -ddos2dfs ddosbeeld : split single sided DDOS diskimage in DFS diskimages\n"\ " -w62dfs w62image : split a watford 62 file diskimage in 2 DFS diskimages\n"\ " -V : show version\n\n"); #endif exit(0); } if (!strcmp(optstring,"-interss")) {interss(argc, argv, options); exit(0);} if (!strcmp(optstring,"-splitds")) {splitds(argc, argv, options); exit(0);} if (!strcmp(optstring,"-ddos2dfs")) {ddos2dfs(argc, argv, options); exit(0);} if (!strcmp(optstring,"-w62dfs")) {w62dfs(argc, argv, options); exit(0);} if (!strcmp(optstring,"-d")) {del_from_im(argc, argv, options); exit(0);} if (!strcmp(optstring,"-s")) {split_cat(argc, argv, options, optstring); exit(0);} if (!strcmp(optstring,"-x")) {xbeeb(argc, argv, options); exit(0);} if (!strcmp(optstring,"-y")) {cleanup(argc, argv, options); exit(0);} if (!strcmp(optstring,"-icrc")) {icrc(argc, argv, options); exit(0);} if (!strcmp(optstring,"-xcrc")) {xcrc(argc, argv, options); exit(0);} /* BEKIJK NU DE RESTERENDE OPTIES */ if (!strcmp(optstring,"-c")) {cat=1; bad_option=0;} if (!strncmp(optstring,"-e",2)) { extr=1; bad_option=0; info=1; for (i=2; i2)); fread(&byte,1,1,fpdisk); bootoption=byte >> 4; H=byte & 3; fread(&byte,1,1,fpdisk); sectorsondisk=byte+H*256L; if (extr && !extr_list) fpcat=fopen(catalogus,"w"); else fpcat=stdout; /*if (extr_list) fpcat=NULL;*/ if (extr_list) goto skip_diskinfo; #ifdef NL fprintf(fpcat,"\nDiskette :%s",bbcdisk_naam); if (strlen(bbcdisk_naam)==0) fprintf(fpcat, "(geen naam)"); fprintf(fpcat,"\n%d sectoren op de diskette\n",sectorsondisk); #else fprintf(fpcat,"\nDisk :%s",bbcdisk_naam); if (strlen(bbcdisk_naam)==0) fprintf(fpcat, "(no name)"); fprintf(fpcat,"\n%d sectors on disk\n",sectorsondisk); #endif #ifdef NL fprintf(fpcat, "bootoptie: "); #else fprintf(fpcat, "bootoption: "); #endif switch(bootoption) { case 0 : #ifdef NL fprintf(fpcat, "geen"); #else fprintf(fpcat, "none"); #endif break; case 1 : fprintf(fpcat, "*LOAD !BOOT");break; case 2 : fprintf(fpcat, "*RUN !BOOT");break; case 3 : fprintf(fpcat, "*EXEC !BOOT"); } fprintf(fpcat,"\n"); #ifdef NL fprintf(fpcat, "Bestand Laad Start Lengte Toegang startsector\n"); #else fprintf(fpcat, "File Load Exec Length Access startsector\n"); #endif skip_diskinfo: /*Hoofdlus: alle bestanden opzoeken*/ if (files>0) { int extr_list_no=0; for(file=0;file>7; bbcfile_naam[0]=(byte & 0x7F); bbcfile_naam[1]='.'; fseek(fpdisk,file+8L,SEEK_SET); /* for(i=0; i<7; i++) { fread(&byte,1,1,fpdisk); bbcfile_naam[i+2]=byte; } */ fread(bbcfile_naam+2,1,7,fpdisk); bbcfile_naam[9]=0; /* spaties aan het einde van bbc naam weghalen: geeft anders bestands namen met spaties (in linux). */ for (i=8;i>0 && (bbcfile_naam[i]==' '); i--); bbcfile_naam[i+1]=0; #if DEBUG printf(bbcfile_naam); #endif /* IF FILE LIST GIVEN, SEE IF NAME IS IN DISKIMAGE */ if (extr_list) { int found=0; for (i=options+2; i1 BUT DISALLOWS VIEWING DOS CAT OF VOL 0A WITH STANDARD DFS ROUTINES. */ /* LOADADDRESS */ fseek(fpdisk,file+256L+8L,0); fread(&byte,1,1,fpdisk); fread(&H,1,1,fpdisk); loadaddress=H*256L+byte+(eellddss & 0x0C)*16384L; if (loadaddress & 0x30000) loadaddress |=0xFF0000; /* EXECADDRESS */ fread(&byte,1,1,fpdisk); fread(&H,1,1,fpdisk); execaddress=(int)(H)*256L+byte+(int)(eellddss & 0xC0)*4L*256L; if (execaddress & 0x30000) execaddress |=0xFF0000; /* FILELENGTE */ fread(&byte,1,1,fpdisk); fread(&H,1,1,fpdisk); length=H*256L+byte+(eellddss & 0x30)*16L*256L; filesizesum +=length; /* UITVOER VAN DEZE GEGEVENS NAAR CATALOGUS */ if (!extr_list) { fprintf(fpcat,"%-9s %6X %6X %6X", bbcfile_naam, (int) loadaddress, (int) execaddress, (int) length); if (locked) fprintf(fpcat," Locked"); else fprintf(fpcat," "); /*VOOR CRC UITLIJNEN*/ } strcpy(unix_bbcfile_naam, bbcfile_naam); /* Name check: replace certain characters in filenames (most filesystems can't handle all characters from bbc filenames) */ for (i=0; i