#include #include /* strncpy() */ #include /* open() */ #include /* close() */ #include /* strtol() */ #include #include #include "version.h" #include "prodos.h" int debug=0; static int ones_lookup[8]={ 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, }; static void usage(char *binary,int help) { printf("\n%s - version %s\n",binary,VERSION); printf("\tby Vince Weaver \n"); printf("\thttp://www.deater.net/weave/vmwprod/apple/\n\n"); if (help) { printf("Usage:\t%s [-b size] [-i interleave] " "[-s bootsector] device_name\n\n",binary); printf("\t-b size : size of image, in 512B blocks\n"); printf("\t-i interleave : PRODOS (default) or DOS33\n"); printf("\t-s filename : bootsector\n"); printf("\t-n volume : volume name\n"); printf("\t-2 : prepend a 2mg header\n"); printf("\n\n"); } exit(0); return; } int main(int argc, char **argv) { int num_blocks=280; int fd; char device[BUFSIZ]; char *endptr; int i,j,c; int result; unsigned char data_buffer[PRODOS_BYTES_PER_BLOCK]; struct voldir_t voldir; char volname[PRODOS_VOLNAME_LEN]; int volname_len; int interleave=PRODOS_INTERLEAVE_PRODOS; int num_voldirs=4,num_bitmaps,num_bitmap_blocks,ones_to_write; int make_2mg_header=0; unsigned char header_2mg[64]; strncpy(volname,"EMPTY",6); volname_len=strlen(volname); /* Parse Command Line Arguments */ while ((c = getopt (argc, argv,"b:i:s:n:hv2"))!=-1) { switch (c) { case 'b': num_blocks=strtol(optarg,&endptr,10); if ( endptr == optarg ) usage(argv[0], 1); break; case 'i': if (!strncasecmp(optarg,"prodos",6)) { interleave=PRODOS_INTERLEAVE_PRODOS; } else if (!strncasecmp(optarg,"dos33",5)) { interleave=PRODOS_INTERLEAVE_DOS33; } else { fprintf(stderr,"Error! Unknown interleave: %s\n",optarg); } break; case 's': fprintf(stderr,"Error! -s not implemented yet!\n"); break; case 'n': memset(volname,0,sizeof(volname)); volname_len=strlen(optarg); if (volname_len>PRODOS_VOLNAME_LEN) { fprintf(stderr,"Volname: %s is too long!\n",optarg); return -1; } memcpy(volname,optarg,volname_len); break; case '2': make_2mg_header=1; break; case 'v': usage(argv[0],0); case 'h': usage(argv[0],1); } } if (optind==argc) { printf("Error! Must include device name\n\n"); goto end_of_program; } strncpy(device,argv[optind],BUFSIZ-1); /***********************/ /* Sanity check values */ /***********************/ /* sectors: 2->32 (limited by 4-byte bitfields) */ if ((num_blocks<6) || (num_blocks>65535)) { printf("Number of blocks must be >6 and <65536\n\n"); goto end_of_program; } /* Open device */ fd=open(device,O_RDWR|O_CREAT|O_TRUNC,0666); if (fd<0) { fprintf(stderr,"Error opening %s (%s)\n", device,strerror(errno)); goto end_of_program; } /*****************/ /* init voldir */ /*****************/ memset(&voldir,0,sizeof(struct voldir_t)); voldir.fd=fd; voldir.interleave=interleave; if (make_2mg_header) { create_2mg_header(header_2mg,num_blocks); write(fd,header_2mg,64); voldir.image_offset=64; } else { voldir.image_offset=0; } voldir.storage_type=PRODOS_FILE_VOLUME_HDR; voldir.name_length=volname_len; memcpy(voldir.volume_name,volname,volname_len); voldir.total_blocks=num_blocks; voldir.version=0; voldir.min_version=0; voldir.access=0xc3; // FIXME voldir.entry_length=0x27; voldir.entries_per_block=13; voldir.bit_map_pointer=6; voldir.creation_time=prodos_time(time(NULL)); voldir.file_count=0; voldir.next_block=3; /******************/ /* clear out data */ /******************/ memset(data_buffer,0,PRODOS_BYTES_PER_BLOCK); /* create image */ for(i=0;i0) { data_buffer[0]=(PRODOS_VOLDIR_KEY_BLOCK+i-1)&0xff; data_buffer[1]=(PRODOS_VOLDIR_KEY_BLOCK+i-1)>>8; } /* next */ if (i>8; } result=prodos_write_block(&voldir,data_buffer,i+PRODOS_VOLDIR_KEY_BLOCK); } /*********************************/ /* create the bitmaps */ /*********************************/ num_bitmaps=num_blocks/8; num_bitmap_blocks=1+((num_bitmaps-1)/512); for(i=0;inum_blocks) { ones_to_write=512; } else { ones_to_write=num_blocks%(512*8); } if (debug) printf("Writing %d ones\n",ones_to_write); for(j=0;j